macbook: add DWT daemon for bcm5974 touchpad
Hyprland's built-in disable-while-typing doesn't work on this MacBook because the keyboard and touchpad share the same USB device, breaking libinput's device pairing. Add a lightweight Python daemon that watches keyboard events and inhibits the touchpad via sysfs for 500ms after each keypress. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
2ed677bd8f
commit
8285fce24a
1 changed files with 60 additions and 0 deletions
|
|
@ -32,6 +32,66 @@
|
||||||
HandleLidSwitchExternalPower = "suspend";
|
HandleLidSwitchExternalPower = "suspend";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# Disable-while-typing daemon for the bcm5974 touchpad.
|
||||||
|
# Hyprland's built-in DWT doesn't work because the keyboard and
|
||||||
|
# touchpad share the same USB device, breaking libinput's pairing.
|
||||||
|
systemd.services.macbook-dwt = {
|
||||||
|
description = "Disable touchpad while typing (bcm5974)";
|
||||||
|
after = [ "systemd-udevd.service" ];
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
serviceConfig = {
|
||||||
|
Type = "simple";
|
||||||
|
Restart = "on-failure";
|
||||||
|
RestartSec = 3;
|
||||||
|
ExecStart = "${pkgs.python3.withPackages (p: [])}/bin/python3 ${pkgs.writeText "macbook-dwt.py" ''
|
||||||
|
import glob, os, select, struct, time
|
||||||
|
|
||||||
|
EVENT_SIZE = struct.calcsize("llHHi")
|
||||||
|
EV_KEY = 0x01
|
||||||
|
DWT_TIMEOUT = 0.5
|
||||||
|
|
||||||
|
def find_event(name):
|
||||||
|
for p in sorted(glob.glob("/sys/class/input/event*/device/name")):
|
||||||
|
with open(p) as f:
|
||||||
|
if name in f.read():
|
||||||
|
return p.split("/")[4]
|
||||||
|
return None
|
||||||
|
|
||||||
|
def main():
|
||||||
|
tp = find_event("bcm5974")
|
||||||
|
kb = find_event("Apple Internal Keyboard")
|
||||||
|
if not tp or not kb:
|
||||||
|
raise SystemExit(f"Devices not found: touchpad={tp}, keyboard={kb}")
|
||||||
|
|
||||||
|
inhibit = f"/sys/class/input/{tp}/device/inhibited"
|
||||||
|
active = False
|
||||||
|
last_key = 0.0
|
||||||
|
|
||||||
|
with open(f"/dev/input/{kb}", "rb") as f:
|
||||||
|
try:
|
||||||
|
while True:
|
||||||
|
timeout = max(0, DWT_TIMEOUT - (time.monotonic() - last_key)) if active else None
|
||||||
|
r, _, _ = select.select([f], [], [], timeout)
|
||||||
|
if r:
|
||||||
|
data = os.read(f.fileno(), EVENT_SIZE * 64)
|
||||||
|
for off in range(0, len(data) - EVENT_SIZE + 1, EVENT_SIZE):
|
||||||
|
_, _, typ, _, val = struct.unpack("llHHi", data[off:off + EVENT_SIZE])
|
||||||
|
if typ == EV_KEY and val:
|
||||||
|
last_key = time.monotonic()
|
||||||
|
if not active:
|
||||||
|
open(inhibit, "w").write("1")
|
||||||
|
active = True
|
||||||
|
if active and time.monotonic() - last_key >= DWT_TIMEOUT:
|
||||||
|
open(inhibit, "w").write("0")
|
||||||
|
active = False
|
||||||
|
finally:
|
||||||
|
open(inhibit, "w").write("0")
|
||||||
|
|
||||||
|
main()
|
||||||
|
''}";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
home-manager.users.fred = { pkgs, ... }: {
|
home-manager.users.fred = { pkgs, ... }: {
|
||||||
wayland.windowManager.hyprland.settings.monitor = [{
|
wayland.windowManager.hyprland.settings.monitor = [{
|
||||||
output = "";
|
output = "";
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue