Skip to content

Instantly share code, notes, and snippets.

@luizomf
Last active November 22, 2025 14:59
Show Gist options
  • Select an option

  • Save luizomf/c492ef12a0f5d20eb70c2f0c263eb881 to your computer and use it in GitHub Desktop.

Select an option

Save luizomf/c492ef12a0f5d20eb70c2f0c263eb881 to your computer and use it in GitHub Desktop.
Um script que bloqueia o teclado do MacOS para eu fazer a limpeza. Basta pressionar ctrl+alt+q para destravar. Qualquer coisa mate o processo haha.
#!/usr/bin/env python3
# Command to run:
# uv run --with='pynput==1.8.1' pynput_helpers.py
# Também dá para rodar direto do gist:
# uv run --with='pynput==1.8.1' https://gist.github.com/luizomf/c492ef12a0f5d20eb70c2f0c263eb881
from collections.abc import Callable
from typing import Any
from pynput.keyboard import HotKey, Key, KeyCode, Listener
class GlobalHotKeys(Listener):
def __init__(
self, hotkeys: dict[str, Callable[..., None]], *args: Any, **kwargs: Any
) -> None:
self._hotkeys = [
HotKey(HotKey.parse(key), value) for key, value in hotkeys.items()
]
super().__init__(
on_press=self._on_press,
on_release=self._on_release,
*args, # noqa: B026
**kwargs,
)
def _on_press(
self,
key: Key | KeyCode | None,
injected: bool | None = False, # noqa: FBT001, FBT002
) -> None:
if not injected and key is not None:
for hotkey in self._hotkeys:
hotkey.press(self.canonical(key))
def _on_release(
self,
key: Key | KeyCode | None,
injected: bool | None = False, # noqa: FBT001, FBT002
) -> None:
if not injected and key is not None:
for hotkey in self._hotkeys:
hotkey.release(self.canonical(key))
class PynputHotkeys:
"""Classe para facilitar a criação de hotkeys do Pynput"""
def __init__(self) -> None:
"""Classe para facilitar a criação de hotkeys do Pynput
```python
Exemplo:
def say_my_name(name: str) -> None:
print(name)
hotkeys = PynputHotkeys()
hotkeys.add_hotkey("<ctrl>+<alt>+i", event.set)
hotkeys.add_hotkey("<ctrl>+<alt>+n", say_my_name, name="Heisenberg")
listener = keyboard.GlobalHotKeys(hotkeys.hotkeys)
listener.start()
```
"""
self.hotkeys: dict[str, Callable[..., None]] = {}
def add_hotkey[**P, R](
self, key: str, cb: Callable[P, R], *args: P.args, **kwargs: P.kwargs
) -> None:
"""Adiciona novas hotkeys com tipagem e callback
Args:
key (str): combinação de teclas, como em <ctrl>+<alt>+i
cb (callable): callback que será executado ao pressionar as teclas
args: os argumentos posicionais para o callback
kwargs: os argumentos nomeados para o callback
"""
self.hotkeys[key] = PynputHotkeys.create_hotkey_cb(cb, *args, **kwargs)
@staticmethod
def create_hotkey_cb[**P, R](
cb: Callable[P, R], *args: P.args, **kwargs: P.kwargs
) -> Callable[..., None]:
"""Wrapper do callback das keys que permite argumentos com tipagem"""
def on_activate() -> None:
cb(*args, **kwargs)
return on_activate
def start_pynput(pynput_hotkeys: PynputHotkeys) -> GlobalHotKeys:
"""Helper para facilitar a criação de hotkeys do Pynput
```python
Exemplo:
hotkeys = PynputHotkeys()
hotkeys.add_hotkey("<ctrl>+<alt>+i", lambda: print(123))
listener = start_pynput()
```
"""
listener = GlobalHotKeys(pynput_hotkeys.hotkeys, suppress=True)
listener.start()
return listener
def stop_pynput(listener: GlobalHotKeys) -> None:
print("Trying to stop")
listener.stop()
if __name__ == "__main__":
import time
quit_shortcut = "<ctrl>+<alt>+q"
hotkeys = PynputHotkeys()
hotkeys.add_hotkey(quit_shortcut, lambda: stop_pynput(listener))
listener = GlobalHotKeys(hotkeys.hotkeys, suppress=True)
listener.start()
while listener.is_alive():
print(f"Press {quit_shortcut} to quit {time.strftime('%H:%M:%S')}")
time.sleep(1)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment