-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcaps_beeper.py
More file actions
86 lines (66 loc) · 2.55 KB
/
caps_beeper.py
File metadata and controls
86 lines (66 loc) · 2.55 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
"""
caps_beeper.py v2
Beeps every time you type a letter while Caps Lock is ON.
Uses a single worker thread + queue so:
- No lag from spawning threads per keypress
- Beeps stop IMMEDIATELY when you turn Caps Lock off
Requirements:
pip install pynput
"""
import sys
import queue
import threading
import winsound
import ctypes
from pynput import keyboard
# ── Configuration ────────────────────────────────────────────────────────────
BEEP_FREQUENCY = 880 # Hz (A5)
BEEP_DURATION = 40 # ms
BEEP_ON_ALL_KEYS = False # True → beep on every key; False → letters only
# ─────────────────────────────────────────────────────────────────────────────
_beep_queue = queue.Queue(maxsize=3) # cap at 3 so stale beeps drain fast
def caps_lock_is_on() -> bool:
return bool(ctypes.WinDLL("User32.dll").GetKeyState(0x14) & 0x0001)
def _beep_worker():
"""Single background thread — consumes beep signals one at a time."""
while True:
_beep_queue.get() # wait for a signal
# Re-check caps state right before playing — drops stale beeps
if caps_lock_is_on():
winsound.Beep(BEEP_FREQUENCY, BEEP_DURATION)
_beep_queue.task_done()
def _enqueue_beep():
"""Put a beep request on the queue; drop silently if queue is full."""
try:
_beep_queue.put_nowait(1)
except queue.Full:
pass # typing faster than beeps can play — skip excess
def on_press(key):
if not caps_lock_is_on():
return
if BEEP_ON_ALL_KEYS:
_enqueue_beep()
return
try:
if key.char and key.char.isalpha():
_enqueue_beep()
except AttributeError:
pass
def main():
# Start the single worker thread
t = threading.Thread(target=_beep_worker, daemon=True)
t.start()
print("=" * 52)
print(" Caps Lock Beeper v2 is running.")
print(" Beeps on every letter typed while Caps Lock is ON.")
print(" Beeps stop immediately when you turn Caps Lock off.")
print(" Close this window (or Ctrl+C) to quit.")
print("=" * 52)
with keyboard.Listener(on_press=on_press) as listener:
try:
listener.join()
except KeyboardInterrupt:
print("\nStopped.")
sys.exit(0)
if __name__ == "__main__":
main()