diff --git a/hosts/FredOS-Macbook.nix b/hosts/FredOS-Macbook.nix index c5045a9..d0fc290 100644 --- a/hosts/FredOS-Macbook.nix +++ b/hosts/FredOS-Macbook.nix @@ -32,6 +32,66 @@ 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, ... }: { wayland.windowManager.hyprland.settings.monitor = [{ output = "";