How to detect Modifier Keys on button-click?

Since I was unable to find anything about how to detect modifier-keys when a user clicks a button, I came up with my own solution which involved writing an ObjC class.

While that was an interesting exercise, it strikes me as odd that you’d have to go to such lengths to get such a basic bit of information. Am I missing something blindingly obvious?

I did google high and low how to do this in AppleScriptObjC and couldn’t find a straightforward answer.

I created the small program below that logs which modifier keys were pressed when a button was clicked in my window. The window just has one button linked to the getModifier_ method:

script KeysAppDelegate
	property parent : class "NSObject"
	property NSEvent : class "NSEvent"
	
	on getModifier_(sender)
		set modifierNumber to NSEvent's modifierFlags()
		if modifierNumber = 0 then log "No modifier keys were pressed"
		if modifierNumber = 2 ^ 16 then log "Caps Lock was engaged"
		if modifierNumber = 2 ^ 17 then log "Shift was pressed"
		if modifierNumber = 2 ^ 18 then log "Control was pressed"
		if modifierNumber = 2 ^ 19 then log "Option was pressed"
		if modifierNumber = 2 ^ 20 then log "Command was pressed"
	end getModifier_
	
end script

The codes for the various modifier keys can be found in the NSEvent class reference. If you have multiple keys pressed you just seem to get the sum of the individual codes.

Ric

Right, which is why it’s probably better to use div and mod, something like this:

on checkModifier_(sender)
set theMask to current application's NSAlternateKeyMask as integer
-- Available mask enums: NSAlphaShiftKeyMask, NSShiftKeyMask, NSControlKeyMask, NSAlternateKeyMask, NSCommandKeyMask,NSNumericPadKeyMask, NSHelpKeyMask, NSFunctionKeyMask
set theFlag to current application's NSEvent's modifierFlags() as integer
return ((theFlag div theMask) mod 2) as boolean
end checkModifier_


return ((theFlag div theMask) mod 2) as boolean

That was the one I couldn’t figure out. In fact, looking at it, I still can’t figure out how it works. Thanks Shane

I remember an ApplescriptObjC version from older posts.

Here is the one I have in my library

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

on modifierKeysPressed()
	local modifierKeysDOWN, currentModifiers
	set modifierKeysDOWN to {capslock_down:false, command_down:false, option_down:false, control_down:false, shift_down:false}
	set currentModifiers to current application's class "NSEvent"'s modifierFlags()
	
	tell modifierKeysDOWN
		set its capslock_down to (currentModifiers div 65536 mod 2 = 1) as boolean -- 2^16
		set its shift_down to (currentModifiers div 131072 mod 2 = 1) as boolean -- 2^17
		set its control_down to (currentModifiers div 262144 mod 2 = 1) as boolean -- 2^18
		set its option_down to (currentModifiers div 524288 mod 2 = 1) as boolean -- 2^19
		set its command_down to (currentModifiers div 1048576 mod 2 = 1) as boolean -- 2^20
	end tell
	
	return modifierKeysDOWN
end modifierKeysPressed

delay 2
modifierKeysPressed()