Monday, May 20, 2019

#1 2010-07-21 04:49:56 pm

oldmanegan
Member
From:: Tampa, FL (sometimes)
Registered: 2009-08-10
Posts: 16

Detect Modifier Key down

I was reading through a forum post elsewhere and came upon the app this uses. I took a basic script an tested it for options and thought it may be of use to some.
It detects a modifier key (Option, Shift, etc.) down. Can be set to only detect a specific key or to report any modifier key.
(modified to include control key and explain the results better in the comments so it is self contained mostly)

Applescript:



------ Depends on getModKey app from Allan Craig
--- [url]http://allancraig.net/index.php?option=com_docman&Itemid=100[/url]
-- run this in an idle handler to get keys down or in some other fashion to capture a key down when the do shell executes
-- if you append to the quoted text at the end of the 'do shell' line a space and then the mod key name (such as 'option'), it will provide a boolean result on the status of the particular mod key state
-- I have provided several keys and combinations below, notice that they are additive in nature (see the combinations with the Option key)
-- I have the log message so that you can see the numeric value of the result returned, either the key value or the boolean

set ModKeyDown to my ModKeyDownCheck()
-----
set ModKeyAlert to ""
if ModKeyDown > 1 then
   if ModKeyDown = 256 then
       set ModKeyAlert to "Command key pressed"
   else if ModKeyDown = 512 then
       set ModKeyAlert to "Shift key pressed"
   else if ModKeyDown = 1024 then
       set ModKeyAlert to "Caps Lock on"
   else if ModKeyDown = 2048 then
       set ModKeyAlert to "Option key pressed"
   else if ModKeyDown = 2560 then -- note the key combinations cause addition of their values
       set ModKeyAlert to "Shift & Option keys pressed"
   else if ModKeyDown = 2816 then
       set ModKeyAlert to "Shift, Option & Command keys pressed"
   else if ModKeyDown = 3072 then
       set ModKeyAlert to "Caps Lock on & Option key pressed"
   else if ModKeyDown = 4096 then
       set ModKeyAlert to "Control key pressed"
   else if ModKeyDown = 4352 then
       set ModKeyAlert to "Control and Command keys pressed"
   else if ModKeyDown = 131072 then
       set ModKeyAlert to "Function key pressed"
   else if ModKeyDown = 133120 then
       set ModKeyAlert to "Function & Option keys pressed"
   end if
end if
-----
if ModKeyAlert ≠ "" then
   display alert ModKeyAlert
end if
-----
on ModKeyDownCheck()
   set ModKeyDown to do shell script "/Library/UnixApps/getModKey"
   (* use this if you wish only to monitor for Option key down:
   set ModKeyDown to do shell script "/Library/UnixApps/getModKey option"
   *)

   set ModKeyDown to ModKeyDown as integer
   log ModKeyDown
   -- set ModKeyDown to modKeyDown as boolean
   return ModKeyDown
end ModKeyDownCheck
-----

Model: MacBook (early 2009)
Browser: Safari 533.16
Operating System: Mac OS X (10.6)

Last edited by oldmanegan (2010-07-22 06:39:59 am)

Offline

 

#2 2010-07-22 03:42:06 am

McUsr
Member
From:: Southern Norway
Registered: 2010-04-07
Posts: 1776

Re: Detect Modifier Key down

Hello.

I just want to add that StefanK has made an alternative version that I find easier to use since you can specify the keys you want to listen to on the command line, and gets a true result if that condition of the keys were true at that moment. I'm not saying that the one is better than the other, just that there is an alternative. The version you describe is the obvious choice when listening for function keys. But can you get out which function key was pressed?

[code]checkModifierKeys(1)      BSD General Commands Manual     checkModifierKeys(1)

NAME
     checkModifierKeys, -- Modifier Key listener for the Mac Os X

SYNOPSIS
     checkModifierKeys, [shift | cmd | control | option | capslock]

DESCRIPTION
     checkModifierKeys, Returns "1" to standard output if one of or more of
     the modifierkeys in the argumentlist were held down under execution or
     "0" if not.

AUTHOR
     Stefan Klieme

Darwin                           July 22, 2010                          Darwin[/code]
You can download StefanK's checkModifierKeys from here

Last edited by McUsr (2010-07-22 03:43:32 am)


Mercurial vcs is a joy to use for scripting.


Filed under: Modifier keys

Offline

 

#3 2010-07-22 05:22:20 am

oldmanegan
Member
From:: Tampa, FL (sometimes)
Registered: 2009-08-10
Posts: 16

Re: Detect Modifier Key down

Thanks.
Yes, with the method I listed one can get the specific mod key pressed, including key combinations, if the button parameter is left off of the do shell command (is shown this way in the script without he param option commented out).
I check out Stefan's method as well.

Offline

 

#4 2010-07-22 06:21:16 am

McUsr
Member
From:: Southern Norway
Registered: 2010-04-07
Posts: 1776

Re: Detect Modifier Key down

Hello.

The method you mention has great advantages, when you want to poll for different key combinations, as you will get by with one single do shell script command. That may be an advantage in some situations.

I checked out your alternative as well. Do you happen to know where I find the opcodes for the keys?
I really need the combinations for the control key as well.

Thanks in advance.

Last edited by McUsr (2010-07-22 06:26:37 am)


Mercurial vcs is a joy to use for scripting.


Filed under: Modifier keys

Offline

 

#5 2010-07-22 06:42:33 am

oldmanegan
Member
From:: Tampa, FL (sometimes)
Registered: 2009-08-10
Posts: 16

Re: Detect Modifier Key down

I have updated to include control (I ran it when the control key was down and looked in the log for the result). I did not know the opcodes originally, just acquired them through logging results as the script ran.

I have improved the comments to make it more easily understood (I hope).

The script is mostly the comments and the dialog to display the results of the do shell command. Otherwise it would be quite small.

Offline

 

#6 2010-07-22 06:50:44 am

McUsr
Member
From:: Southern Norway
Registered: 2010-04-07
Posts: 1776

Re: Detect Modifier Key down

Hello.

That didn't cross my mind at the moment. smile Thanks!

I re found the utility keycodes at Peter Maurers site (download link).
So I can easily test for the combinations I am interested in. -But I like the AS EventLog. smile

Last edited by McUsr (2010-07-22 06:52:50 am)


Mercurial vcs is a joy to use for scripting.


Filed under: Modifier keys

Offline

 

#7 2014-01-30 07:08:33 am

Jost
Member
Registered: 2005-12-12
Posts: 6

Re: Detect Modifier Key down

Thanks! Very useful form som of my applets. smile

Offline

 

#8 2016-05-24 04:16:13 pm

oscar
Member
Registered: 2007-06-13
Posts: 11

Re: Detect Modifier Key down

This should also tell you they modifier keys that are down, using "vanilla" Applescript

Applescript:


property vers : "1.0"

on isModifierKeyPressed(checkKey)
   set modiferKeysDOWN to {command_down:false, option_down:false, control_down:false, shift_down:false, caps_down:false, numlock_down:false, function_down:false}
   
   if checkKey = "" or checkKey = "option" or checkKey = "alt" then
       if (do shell script "/usr/bin/python -c 'import Cocoa; print Cocoa.NSEvent.modifierFlags() & Cocoa.NSAlternateKeyMask '") > 1 then
           set option_down of modiferKeysDOWN to true
       end if
   end if
   
   if checkKey = "" or checkKey = "command" then
       if (do shell script "/usr/bin/python -c 'import Cocoa; print Cocoa.NSEvent.modifierFlags() & Cocoa.NSCommandKeyMask '") > 1 then
           set command_down of modiferKeysDOWN to true
       end if
   end if
   
   if checkKey = "" or checkKey = "shift" then
       if (do shell script "/usr/bin/python -c 'import Cocoa; print Cocoa.NSEvent.modifierFlags() & Cocoa.NSShiftKeyMask '") > 1 then
           set shift_down of modiferKeysDOWN to true
       end if
   end if
   
   if checkKey = "" or checkKey = "control" then
       if (do shell script "/usr/bin/python -c 'import Cocoa; print Cocoa.NSEvent.modifierFlags() & Cocoa.NSControlKeyMask '") > 1 then
           set control_down of modiferKeysDOWN to true
       end if
   end if
   
   if checkKey = "" or checkKey = "caps" or checkKey = "capslock" then
       if (do shell script "/usr/bin/python -c 'import Cocoa; print Cocoa.NSEvent.modifierFlags() & Cocoa.NSAlphaShiftKeyMask '") > 1 then
           set caps_down of modiferKeysDOWN to true
       end if
   end if
   
   if checkKey = "" or checkKey = "numlock" then
       if (do shell script "/usr/bin/python -c 'import Cocoa; print Cocoa.NSEvent.modifierFlags() & Cocoa.NSNumericPadKeyMask'") > 1 then
           set numlock_down of modiferKeysDOWN to true
       end if
   end if
   --Set if any key in the numeric keypad is pressed. The numeric keypad is generally on the right side of the keyboard. This is also set if any of the arrow keys are pressed
   
   if checkKey = "" or checkKey = "function" or checkKey = "func" or checkKey = "fn" then
       if (do shell script "/usr/bin/python -c 'import Cocoa; print Cocoa.NSEvent.modifierFlags() & Cocoa.NSFunctionKeyMask'") > 1 then
           set function_down of modiferKeysDOWN to true
       end if
   end if
   --Set if any function key is pressed. The function keys include the F keys at the top of most keyboards (F1, F2, and so on) and the navigation keys in the center of most keyboards (Help, Forward Delete, Home, End, Page Up, Page Down, and the arrow keys)
   
   return modiferKeysDOWN
end isModifierKeyPressed

You could call this by doing
my isModifierKeyPressed(""), and this will return all current modifier keys pulled as a record.

You can also specify which key to look at, which runs faster.
my isModifierKeyPressed("option")

So, an example:

display dialog command_down of my isModifierKeyPressed("command")
This would show true if the command key is being held down.

if you specify a key, all others will return as false.

EDIT:
Updated code, and examples

Last edited by oscar (2016-05-28 06:21:55 pm)

Offline

 

#9 2016-05-24 05:30:08 pm

Nigel Garvey
Moderator
From:: Warwickshire, England
Registered: 2002-11-20
Posts: 4868

Re: Detect Modifier Key down

I don't know if I'd call Python-invoking shell scripts "vanilla AppleScript", but that's very handy code. Thanks.  smile

The Python stuff is recognisably just making system calls, so I suppose the same thing could be achieved with less overhead using ASObjC:

Applescript:

use framework "Foundation"
use framework "AppKit"

on modifierKeysPressed()
   set modifierKeysDOWN to {command_down:false, option_down:false, control_down:false, shift_down:false}
   
   set |⌘| to current application
   set currentModifiers to |⌘|'s class "NSEvent"'s modifierFlags()
   
   tell modifierKeysDOWN
       set its option_down to (currentModifiers div (get |⌘|'s NSAlternateKeyMask) mod 2 is 1)
       set its command_down to (currentModifiers div (get |⌘|'s NSCommandKeyMask) mod 2 is 1)
       set its shift_down to (currentModifiers div (get |⌘|'s NSShiftKeyMask) mod 2 is 1)
       set its control_down to (currentModifiers div (get |⌘|'s NSControlKeyMask) mod 2 is 1)
   end tell
   
   return modifierKeysDOWN
end modifierKeysPressed

modifierKeysPressed()


NG

Offline

 

#10 2018-10-25 05:56:47 pm

gwhatley
Member
Registered: 2018-10-19
Posts: 2

Re: Detect Modifier Key down

Hello Nigel,

This script has proven incredibly helpful - thank you very much!

It led me to search this past weekend for another type of script, but to no avail.

Perhaps you know:

Is it possible, again using ASObjC in the same manner as your script, to detect and identify ANY keypress?

I’d like to:

(1) detect keypresses (including modifiers) specifically
(2) override the keys pressed —
(3) including (probably especially) any accompanying modifiers — to trigger scripts that do specific functions in specific software

[e.g., CTRL-1 triggers script A, COMMAND+OPTION-M triggers script B, etc.].

-- or any one of these steps?

The if / thens and the triggering of scripts I am familiar with; but not so the detecting, identifying and overriding of keypresses in ASObjC.

I have a lot of scripts that help me out with some professional software; and I can of course use keyboard shortcuts in Mac, or other software like Keyboard Maestro, but I’m interested in doing this myself — and am having a difficult time finding the answer.

Thank you again for this very helpful script,

Garrard.


Nigel Garvey wrote:

I don't know if I'd call Python-invoking shell scripts "vanilla AppleScript", but that's very handy code. Thanks.  smile

The Python stuff is recognisably just making system calls, so I suppose the same thing could be achieved with less overhead using ASObjC:

Applescript:

use framework "Foundation"
use framework "AppKit"

on modifierKeysPressed()
   set modifierKeysDOWN to {command_down:false, option_down:false, control_down:false, shift_down:false}
   
   set |⌘| to current application
   set currentModifiers to |⌘|'s class "NSEvent"'s modifierFlags()
   
   tell modifierKeysDOWN
       set its option_down to (currentModifiers div (get |⌘|'s NSAlternateKeyMask) mod 2 is 1)
       set its command_down to (currentModifiers div (get |⌘|'s NSCommandKeyMask) mod 2 is 1)
       set its shift_down to (currentModifiers div (get |⌘|'s NSShiftKeyMask) mod 2 is 1)
       set its control_down to (currentModifiers div (get |⌘|'s NSControlKeyMask) mod 2 is 1)
   end tell
   
   return modifierKeysDOWN
end modifierKeysPressed

modifierKeysPressed()



Model: Mac Pro (Mid 2012) 3.46 GHz 6-Core Intel
Browser: Chrome
Operating System: macOS 10.13


Filed under: keyDown key presses

Offline

 

#11 2018-10-26 10:00:28 am

Nigel Garvey
Moderator
From:: Warwickshire, England
Registered: 2002-11-20
Posts: 4868

Re: Detect Modifier Key down

Hi Garrard. Welcome to MacScripter.

Looking at the Xcode 10.0 documentation today, I couldn't see why my ASObjC script, derived from oscar's python code, was actually working! It uses modifierKeys as a class method of NSEvent, but the documentation doesn't explicitly indicate that it is one. Fortunately, the Xcode 8.2.6 documentation on my older machine does explicitly show that, so I'm now happier about the script.  smile

According to Xcode 10.0, the modifier flags used in the script are deprecated as from macOS 10.13. We're now supposed to use flags that were introduced in macOS 10.12. These new flags have the same values as the old, just much longer labels, so I don't see the point. But hey. The script should continue to work for a while as given above, but to hedge one's bets:

Applescript:

use AppleScript version "2.4" -- Mac OS 10.10 (Yosemite) or later
use framework "Foundation"
use framework "AppKit"
use scripting additions

on modifierKeysPressed()
   considering numeric strings
       set SierraOrLater to (system version of (system info) > "10.11.6")
   end considering
   
   set modifierKeysDOWN to {command_down:false, option_down:false, control_down:false, shift_down:false}
   
   set |⌘| to current application
   set currentModifiers to |⌘|'s class "NSEvent"'s modifierFlags()
   
   if (SierraOrLater) then
       -- Modifier flags introduced in macOS 10.12 (Sierra).
       tell modifierKeysDOWN
           set its option_down to (currentModifiers div (get |⌘|'s NSEventModifierFlagOption) mod 2 is 1)
           set its command_down to (currentModifiers div (get |⌘|'s NSEventModifierFlagCommand) mod 2 is 1)
           set its shift_down to (currentModifiers div (get |⌘|'s NSEventModifierFlagShift) mod 2 is 1)
           set its control_down to (currentModifiers div (get |⌘|'s NSEventModifierFlagControl) mod 2 is 1)
       end tell
   else
       -- Modifier flags deprecated as from macOS 10.13 (High Sierra).
       tell modifierKeysDOWN
           set its option_down to (currentModifiers div (get |⌘|'s NSAlternateKeyMask) mod 2 is 1)
           set its command_down to (currentModifiers div (get |⌘|'s NSCommandKeyMask) mod 2 is 1)
           set its shift_down to (currentModifiers div (get |⌘|'s NSShiftKeyMask) mod 2 is 1)
           set its control_down to (currentModifiers div (get |⌘|'s NSControlKeyMask) mod 2 is 1)
       end tell
   end if
   
   return modifierKeysDOWN
end modifierKeysPressed

modifierKeysPressed()

It looks as if other key event information has to be extracted from individual events taken from a queue, but I can't immediately see how to get hold of them.  hmm


NG

Offline

 

#12 2018-10-26 11:07:48 am

gwhatley
Member
Registered: 2018-10-19
Posts: 2

Re: Detect Modifier Key down

Great to know that this needs to be updated -- thank you so much again.

After learning AS over the last year, I see the limitations and advantages of it in conjunction with shell scripts making numerous calculations over very large arrays (lists).

Sometimes the shell calls (including grep, sed) slow down the process, and have needed to be replaced with clunky, longer AppleScript calculations, that just simply work faster over large, numerous repeat loops.

So peeking into ASObjC - introduced to me with this script - and seeing how easily and quickly this simple script works at doing something arguably complex from the AS point of view, gave me hope that there might ways to simplify the more interesting task of detecting, identifying & overriding key strokes.

Perhaps there is a way through ASObjC -- I do see that doing so through Cocoa is an avenue; but I'll need to start from scratch with the language (I've already followed an online instructional video to create a simple Hello World sample).

So part of this is impatience - but also curiosity and challenge.

Thank you for the quick reply, and beyond that, updated info.

G.

Offline

 

#13 2018-10-26 05:27:36 pm

Shane Stanley
Member
From:: Australia
Registered: 2002-12-07
Posts: 5653

Re: Detect Modifier Key down

Nigel Garvey wrote:

These new flags have the same values as the old, just much longer labels, so I don't see the point



The change is essentially to make them easier to use from Swift. Lots of enums have been similarly renamed in each of the past few OS revisions, and more are possible.

The old versions aren't likely to disappear any time soon. But if you want to future-proof — and past-proof — code, it's best to define properties with actual numerical values (which will never change). That way, the term is essentially a placeholder (which is what it is, in effect, in Objective-C).

So something like:

Applescript:

property NSEventModifierFlagCommand : 1048576
-- or:
property NSCommandKeyMask : 1048576

This has the added bonus of eliminating current application's.

Script Debugger will add them for you automatically if you use code-completion, like this:

Applescript:

-- classes, constants, and enums used
property NSEventModifierFlagCommand : a reference to 1048576
property NSCommandKeyMask : a reference to 1048576

The only down-side is that it makes cutting and pasting a bit trickier.


Shane Stanley <sstanley@myriad-com.com.au>
www.macosxautomation.com/applescript/apps/
latenightsw.com

Offline

 

#14 2018-10-26 05:58:51 pm

Shane Stanley
Member
From:: Australia
Registered: 2002-12-07
Posts: 5653

Re: Detect Modifier Key down

Nigel Garvey wrote:

It uses modifierKeys as a class method of NSEvent, but the documentation doesn't explicitly indicate that it is one.



They've introduced class properties, of which modifierKeys is one. Like instance properties, you just treat it like a method.


Shane Stanley <sstanley@myriad-com.com.au>
www.macosxautomation.com/applescript/apps/
latenightsw.com

Offline

 

#15 2018-10-27 02:08:51 am

Nigel Garvey
Moderator
From:: Warwickshire, England
Registered: 2002-11-20
Posts: 4868

Re: Detect Modifier Key down

Thanks for the info, Shane.

No script of mine will ever contain 'a reference to' a number!  wink


NG

Offline

 

#16 2018-10-27 04:46:01 am

Shane Stanley
Member
From:: Australia
Registered: 2002-12-07
Posts: 5653

Re: Detect Modifier Key down

Nigel Garvey wrote:

No script of mine will ever contain 'a reference to' a number!



That's a pity. It's quite a reasonable way of solving the copy-and-paste problem.


Shane Stanley <sstanley@myriad-com.com.au>
www.macosxautomation.com/applescript/apps/
latenightsw.com

Offline

 

#17 2018-10-27 01:33:54 pm

Nigel Garvey
Moderator
From:: Warwickshire, England
Registered: 2002-11-20
Posts: 4868

Re: Detect Modifier Key down

Hi Shane. I'm afraid I don't follow.

What copy-and-paste problem?

In post #13, you say that properties set to references to numbers make cutting and pasting a bit trickier; in post #16, you say they're a reasonable way of solving the copy-and-paste problem.

You've lost me.  hmm


NG

Offline

 

#18 2018-10-27 04:49:58 pm

Shane Stanley
Member
From:: Australia
Registered: 2002-12-07
Posts: 5653

Re: Detect Modifier Key down

Nigel Garvey wrote:

What copy-and-paste problem?



Suppose you have a long-ish script, and you want to use a section of it in another script. If that section defines Cocoa terminology via properties, it can get difficult: you need to copy and paste the code, work out which properties are used, and then copy and paste them too.

In post #13, you say that properties set to references to numbers make cutting and pasting a bit trickier; in post #16, you say they're a reasonable way of solving the copy-and-paste problem.

You've lost me.  hmm



If you use Script Debugger's code completion with Using Properties for Cocoa Terms selected, enums get entered as properties with their numerical values, but with a reference to. Cocoa classes and constants also use a reference to, but in those cases it serves a direct purpose.

But with enums it serves an indirect purpose: it acts as a flag that the property is, in fact, an enum, and not just some simple integer property your script uses (as you suggest, there can be no other logical reason). That can be visually useful, but it can also be taken advantage of when copying.

So if we go back to the example of copying a section of a script, if you choose Edit -> AppleScriptObjC -> Copy as Standalone Code, Script Debugger can work out which variables in the selection are defined as Cocoa terms (integer properties without a a reference to can be ignored, for starters), and expand the variables in-line so that the code on the clipboard includes the required instances of current application's inline. That means one (sort of) copy, and one paste.

(The in-lining isn't always perfect, but it covers most bases.)

Script Debugger could have used some other convention, but I think this one is pretty good: it's consistent with other Cocoa term declarations, it's harmless, and it's unlikely to result in false positives. Although we clearly forgot to factor in your sensitivities wink

In fact, much of the code I post here and elsewhere is written with Cocoa terms as properties, but I use Copy as Standalone Code for snippets to post, to keep it simple.


Shane Stanley <sstanley@myriad-com.com.au>
www.macosxautomation.com/applescript/apps/
latenightsw.com

Offline

 

#19 2018-10-28 02:23:02 am

Nigel Garvey
Moderator
From:: Warwickshire, England
Registered: 2002-11-20
Posts: 4868

Re: Detect Modifier Key down

Thanks, Shane. I understand what you were saying now.

Although we clearly forgot to factor in your sensitivities wink


lol

You wouldn't have had too, since I've yet to use SD's "Use Properties for Cocoa Terms".  wink  I've generally gone for local variables set a bit closer to where they're needed.


NG

Offline

 

Board footer

Powered by FluxBB

RSS (new topics) RSS (active topics)