system wide hotkeys

timeyyy, updated 🕥 2022-10-10 17:48:20

System Hotkey

Multi platform system wide hotkeys for python 3,

Currently no mac or python2 support :(


the old

.. code-block:: bash

pip3 install system_hotkey

should do the trick

Windows ^^^^^^^ install pywin32

Linux ^^^^^ For x11 you should use xcffib <>_ (bsd license),

If for some reason you have to use the python xlib bindings (gpl license), a few fixes need be added first. See here <>_


Input Keysyms

System hotkeys uses the keysym names from xlib for everything besides modifiers.(although case insensitive) grep for vk_codes for a list of available chars. If you are unable to bind to a certain key please let us know.

You can bind directly to symbols such as ["',. etc Numpad keys can be binded by prefixing with kp_.

Supported modifiers include:

  • control
  • shift
  • super (windows key)
  • alt

InvalidKeyError will be raised if a key was not understood

.. code-block:: python

from system_hotkey import SystemHotkey
hk = SystemHotkey()
hk.register(('control', 'shift', 'h'), callback=lambda x: print("Easy!"))

A SystemRegisterError will be raised if a hotkey is already in use.

To unregister a hotkey

.. code-block:: python

hk.unregister(('control', 'shift', 'h'))

A KeyError will be raised if the combination is not already grabbed.

A UnregisterError will be raised if unregistering failed for any other reason.

If you want you can pass in a custom consumer:

.. code-block:: python

def some_func(self, event, hotkey, args):

hk = SystemHotkey(consumer=some_func)
hk.register(hotkey, arg1, arg2, arg3)

So you have a master function that receives all hotkey presses and can delegate as desired.

Note Modifier keys are independent of order i.e control + alt + del is the same as alt + control + del


  • Support for up to 3 modifiers and a key


  • I have only mapped most common keys, i have not experimented with Unicode/Japanese characters etc. It's only a matter of mapping a name to the keysym on Linux and virtual key code on windows.

  • binding to kp_left (key pad left) will also bind to kp_4, there is a flag (unite_kp) to toggle this behaviour but it is experimental

  • Requires an xserver (x11)...


Python 3.10.4 collections fix + added grave (`) key code

opened on 2022-10-10 17:35:07 by PyroCalzone

I tried the other pull requests and their fixes for python 3.10 didn't work for me. Disclaimer, I had to remove win32con.VK_MEDIA_STOP. It wouldn't work otherwise.

I also had a need to use the grave key in a key-bind so I added that functionality as well. Don't know how well this works for other machines because I didn't use win32con, as they don't have that bound either.

unable to catch SystemRegisterError exception

opened on 2022-09-28 11:29:35 by xun-xh


`from system_hotkey import *

def some_func(event, hotkey, args): print(event, hotkey, args)

try: hk = SystemHotkey(consumer=some_func) hk.register(('control', 'u')) hk_1 = SystemHotkey(consumer=some_func) hk_1.register(('control', 'u'), overwrite=True) print(456) except Exception as e: print(123)

while True: pass `

result: 456 Exception ignored in thread started by: <bound method SystemHotkey._nt_wait of <system_hotkey.system_hotkey.SystemHotkey object at 0x000002052BA864F0>> Traceback (most recent call last): File "D:\Xiv-Tool\venv\lib\site-packages\system_hotkey\", line 692, in _nt_wait remove_or_add() File "D:\Xiv-Tool\venv\lib\site-packages\system_hotkey\", line 304, in <lambda> self.hk_action_queue.put(lambda:nt_register()) File "D:\Xiv-Tool\venv\lib\site-packages\system_hotkey\", line 303, in nt_register self._the_grab(keycode, masks, uniq) File "D:\Xiv-Tool\venv\lib\site-packages\system_hotkey\", line 724, in _nt_the_grab raise SystemRegisterError(msg) system_hotkey.system_hotkey.SystemRegisterError: The bind could be in use elsewhere: u

Expected to print 123, but not

Fix 'AttrbuteError' in Python 3.10

opened on 2022-09-17 16:35:41 by DoooReyn None

Check whether the hotkey is available before binding

opened on 2022-01-26 09:49:54 by snwjas

Such as title

```python import ctypes import typing

from system_hotkey import SystemHotkey

user32 = ctypes.windll.user32

def is_hotkey_valid(hkobj: SystemHotkey, hk: typing.List[str]): hk = hkobj.order_hotkey(hk) try: keycode, masks = hkobj.parse_hotkeylist(hk) reg_hk_res = user32.RegisterHotKey(None, 1, masks, keycode) if reg_hk_res: user32.UnregisterHotKey(None, reg_hk_res) return True except: pass return False ```

docs: nits for README

opened on 2022-01-22 05:49:46 by jramnai

Some nits for README

Import ABC from for Python 3.10 compatibility.

opened on 2022-01-21 07:06:16 by tirkarthi

Fixes #25

timothy eichler
GitHub Repository