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 <https://github.com/tych0/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 <https://github.com/timeyyy/system_hotkey/issues/6#issuecomment-265410255>
_
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:
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):
pass
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
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)...
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.
code:
`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:
test.py
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\system_hotkey.py", line 692, in _nt_wait
remove_or_add()
File "D:\Xiv-Tool\venv\lib\site-packages\system_hotkey\system_hotkey.py", line 304, in <lambda>
self.hk_action_queue.put(lambda:nt_register())
File "D:\Xiv-Tool\venv\lib\site-packages\system_hotkey\system_hotkey.py", line 303, in nt_register
self._the_grab(keycode, masks, uniq)
File "D:\Xiv-Tool\venv\lib\site-packages\system_hotkey\system_hotkey.py", 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
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 ```
Some nits for README
Fixes #25