Yes, this is possible - but more complicated. You can use low-level keyboard hooks (just an example).
def callback(n, w, l):
if keyboard.is_pressed("ctrl") and keyboard.is_pressed("f") and keyboard.is_pressed("o"):
perform_action()
return -1
return 0
whereas perform_action() is the method you're calling once the shortcut is performed. Both return
statements are crucial as they signal whether they shortcut was executed or not.
Now we have to implement the keyboard hook on a low-level:
from ctypes import windll, c_void_p, c_int, CFUNCTYPE
PROC = CFUNCTYPE(c_int, c_int, c_void_p, c_void_p)
CMPFUNC = PROC(callback)
hook = windll.user32.SetWindowsHookExA(
c_int(13),
CMPFUNC,
c_int(0),
c_int(0)
)
Explanation: FUNC
specifies the callback function via a void pointer. Important is hook = windll.user32.SetWindowsHookExA
- with the four arguments provided:
c_int(13)
is the type of hook we are intending to set: type 13 equals to WH_KEYBOARD_LL
which is a low-level keyboard hook!
FUNC
is the callback function that will be called when the keypress is detected
- and 4. handle the DLL and thread ID which are both not necessary in this simple example and thus we pass a 0.
So you can now use keyboard.wait("ctrl + f + o", suppress = True, trigger_on_release = True)
as long as you follow with the Unhook statement (for when the shortcut keys were actually pressed):
windll.user32.UnhookWindowsHookEx(hook_id)
.
The full code may be something along the lines of:
import keyboard
from ctypes import windll, c_void_p, c_int, CFUNCTYPE
def perform_action():
#...
def callback(n, w, l):
# As specified above
PROC = CFUNCTYPE(c_int, c_int, c_void_p, c_void_p)
CMPFUNC = PROC(callback)
hook = windll.user32.SetWindowsHookExA(
c_int(13),
CMPFUNC,
c_int(0),
c_int(0)
)
# Your original keyboard.wait - by the way, you might not need the two parameters?
keyboard.wait("ctrl + f + o", suppress=True, trigger_on_release=True)
# Unhook:
windll.user32.UnhookWindowsHookEx(hook_id)