Detect Keypress and Delay Until Key Released AppleScript

Viewed 1846

I am having trouble figuring out how to detect a key being pressed in AppleScript and how to delay until that key is released. I want to make a toggle for zoom, and I have everything else (I think). This is my current code

on idle
    set ztoggle to 0

    repeat

        --how do i make it so a key is needed to run this loop? maybe an 'if (im not sure what to put here) then' loop?--
            if (ztoggle = 1) then
                set ztoggle to 0
            else if (ztoggle = 0) then
                set ztoggle to 1
            end if
        --how do i make it so the program waits at this line until the key from before is released? i was thinking delay, but im not sure--


        if (ztoggle = 1) then
            tell application "System Events"
                key code 28 using {option down, command down}
            end tell
        end if

        set ztoggle to 0

    end repeat
end idle

Does anyone know how I would do this? Also, this is my first time trying anything with AppleScript, so if I messed up elsewhere, let me know.

2 Answers

This can be done without any 3rd-party additions, but instead calling into the cocoa framework:

use framework "Cocoa"
use scripting additions

global ca
set ca to current application

to isModifierPressed(modifier)
    ((ca's NSEvent's modifierFlags()) / modifier as integer) mod 2 is equal to 1
end isModifierPressed

repeat until isModifierPressed(ca's NSEventModifierFlagControl)
    delay 0.1 -- sad poll/wait loop :(
end repeat
display dialog "Control was pressed"

Note that NSEvent's modifierFlags() is a bitfield and NSEventModifierFlagControl is a 2n bit flag, these need to be bitwise-ANDed together to see if the key is held. AppleScript doesn't have bitwise operators (!!) so in this case the AND is emulated arithmetically - first by integer dividing the modifierFlags() bitfield by the NSEventModifierFlagControl bitflag, then seeing if the result is odd.

modifierFlags() only reports instantaneous modifier status, so we must poll it in a loop to wait for a keypress.

Other modifier keys may also be checked this way. They are:

Syntax Description
NSEventModifierFlagCapsLock The Caps Lock key has been pressed.
NSEventModifierFlagShift The Shift key has been pressed.
NSEventModifierFlagControl The Control key has been pressed.
NSEventModifierFlagOption The Option or Alt key has been pressed.
NSEventModifierFlagCommand The Command key has been pressed.
NSEventModifierFlagNumericPad A key in the numeric keypad or an arrow key has been pressed.
NSEventModifierFlagHelp The Help key has been pressed.
NSEventModifierFlagFunction A function key has been pressed.
NSEventModifierFlagDeviceIndependentFlagsMask Device-independent modifier flags are masked.
Related