pynput - non-specified key combo triggers hotkey fxn after ALT-TAB (Windows)

Viewed 25

Code I'm running in .ipynb file (jupyter notebook in VS Code):

from pynput import keyboard
def function_1():
    print('Function 1 activated')
with keyboard.GlobalHotKeys({
        '<alt>+<ctrl>+c': function_1}
        ) as h:
    h.join()

When this is running, pressing CTRL+ALT+C triggers function_1, as expected. Pressing CTRL+C (no ALT) does not trigger function_1, also as expected.

But if I press ALT-TAB to switch windows, CTRL+C now triggers function_1.

I changed the code to use '<alt>+<ctrl>+b' and get same result. CTRL+B will trigger if ALT-TAB is pressed beforehand.

Can anyone replicate or see what I'm doing wrong?

1 Answers

I don't have a problem with Ctrl+B with the following code:

import time
from random import randint as randy
from pynput import keyboard

# https://pynput.readthedocs.io/en/latest/keyboard.html#global-hotkeys    
def on_activate():
    print('Global hotkey activated!')
    global stop
    stop = True
    return False  # stop the listener

def for_canonical(f):
    return lambda k: f(listener.canonical(k))


# hotkey = keyboard.HotKey(keyboard.HotKey.parse('<ctrl>+<alt>+h'), on_activate)
# hotkey = keyboard.HotKey(keyboard.HotKey.parse('<ctrl>+<alt>+c'), on_activate)
# hotkey = keyboard.HotKey(keyboard.HotKey.parse('<ctrl>+c'), on_activate)
hotkey = keyboard.HotKey(keyboard.HotKey.parse('<ctrl>+b'), on_activate)
# create a non-blocking listener
listener = keyboard.Listener(on_press=for_canonical(hotkey.press), on_release=for_canonical(hotkey.release))
listener.start()

stop = False
while not stop:
    print(f"Rolling 2d6: {randy(1,6) + randy(1,6):2}")
    time.sleep(0.2)
print("Finished!")

The console shows:

>python3.9 -i pyn_hotkey.py
Rolling 2d6:  6
Rolling 2d6: 11
Rolling 2d6: 10
Rolling 2d6: 11
Rolling 2d6:  4
Rolling 2d6: 10
Rolling 2d6:  9
Global hotkey activated!
Finished!
>>> ^B

Note that in spite of my expectation, returning False doesn't stop the listener, so I'm not sure what's going on there; listener.stop() works.

Related