pynput icon indicating copy to clipboard operation
pynput copied to clipboard

What is the darwin_intercept equivalent of the command key?

Open SpecialCharacter opened this issue 2 years ago • 9 comments

Description What is the darwin_intercept (= Mac) equivalent of the command key? I want to suppress it. (Or any control keys, as a matter of principle.)

Platform and pynput version MacOS Catalina 10.15.7 pynput version unknown

To Reproduce The example given in the documentation is chars == 'x', but the command key does not have a character associated with it. I tried exchanging it with virtualKey == 0x37, but it said "virtualKey is not defined".

SpecialCharacter avatar May 26 '22 17:05 SpecialCharacter

chars == 'cmd' and chars == cmd do not work either.

SpecialCharacter avatar May 27 '22 14:05 SpecialCharacter

Added virtualKey as third variable, but got an error message (along the lines of "third variable not found"). Does that mean I cannot use Quartz.CGEventKeyboardGetUnicodeString for this at all? But what then? I found CGEventCreateKeyboardEvent, but I want to listen, not create...

SpecialCharacter avatar Jun 01 '22 22:06 SpecialCharacter

OK, so apparently modifier keys are handled by CGEventGetFlags instead. Still an example would be nice (maybe the example in the documentation could be updated, as this will be valuable to other users?)... also because I usually don't work with macOS and have no idea how to program this... I guess Quartz.CGEventGetFlags(event) ... but then?

SpecialCharacter avatar Jun 03 '22 18:06 SpecialCharacter

To illustrate why: I want to assign some command key combinations (e.g., cmd + Q) new tasks. But so far, cmd + Q still closes programs, so I need to suppress that.

SpecialCharacter avatar Jun 12 '22 13:06 SpecialCharacter

OK, so if I use a True/False variable to check if the command key is pressed, I manage with elif cmd == True and length > 0 and chars == 'q': in the darwin_intercept part. The only strange thing is that "command key down, command key up, q" will trigger the behaviour as well (while I want it only for "command key down, q"). Any suggestions?

SpecialCharacter avatar Jun 12 '22 18:06 SpecialCharacter

Solved the "command key up" part, now it is triggered when pressing "cmd + Q" two times in sequence.

SpecialCharacter avatar Jun 12 '22 22:06 SpecialCharacter

This seems to do the trick:

from pynput import keyboard
from pynput.keyboard import Key, Controller
# --- initialise ---
cmd = False
# ======
def on_press(key):
    global cmd
    try:
        print('alphanumeric key {0} pressed'.format(
            key.char))
        # ...   
    except AttributeError:
        print('special key {0} pressed'.format(
            key))
        if key == Key.cmd:
            cmd = True
            # (modifier) # Windows key / MacOS Command key  
        # ...
# ======
def on_release(key):
    global cmd
    try:
        print('{0} released'.format(
            key))
        if key == keyboard.Key.esc:                             # <--- stop program
            # Stop listener
            return False
        elif key == Key.cmd:                                    # Win up # Apple up
            cmd = False
            # (modifier) # Windows key / MacOS Command key
    except AttributeError:
        print('on_release special key {0} released'.format(
            key)) # Am Ende löschen
        # nothing
# ======
def darwin_intercept(event_type, event):                        # pynput-internal definition
    import Quartz
    global cmd
    length, chars = Quartz.CGEventKeyboardGetUnicodeString(
        event, 100, None, None)
    if cmd == True and length > 0 and chars == 'q':             # Apple down + q
        return None
    else:
        return event
# ======
# Collect events until released
with keyboard.Listener(
        on_press=on_press,
        on_release=on_release,
        # Add suppressing events (darwin_intercept):
        darwin_intercept=darwin_intercept) as listener:
    listener.join()

However, when I let go of the q key while still pressing the control key, I get an unwanted second control key event. Any suggestions how to get rid of this?

SpecialCharacter avatar Jun 15 '22 19:06 SpecialCharacter

Thank you for your report, and I apologise for this late reply.

When working with macOS specific functionality, you may want to consult darwin_vks.py for a list of character codes.

For detecting cmd+Q, you may want to have a look on Quartz.CGEventGetFlags and Quartz.kCGEventFlagMaskCommand; I think that will let you drop your internal state.

moses-palmer avatar Jun 19 '22 16:06 moses-palmer

The command key is not listed in [darwin_vks.py] :(

How extract the cmd or AltGr flag from [Quartz.CGEventGetFlags]? I looked for examples, but there are few...

SpecialCharacter avatar Jul 06 '22 13:07 SpecialCharacter