nixos/hosts/FredOS-Macbook.nix
rope 22c1b35360 macbook: add libinput quirk for native DWT on bcm5974
Tell libinput the Apple keyboard is internal so its built-in
disable-while-typing pairing works despite keyboard and touchpad
sharing the same USB device. Keep the custom DWT script as fallback.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-05-19 17:36:04 +01:00

174 lines
5.7 KiB
Nix

{ config, pkgs, lib, inputs, ... }:
{
config = lib.mkIf (config.networking.hostName == "FredOS-Macbook") {
environment.systemPackages = with pkgs; [
tlp
vesktop
adwaita-icon-theme
mission-center
vlc
geary
proton-vpn
onlyoffice-desktopeditors
woeusb
vscodium
];
nix.settings.max-jobs = 0;
services.tlp.enable = false;
services.power-profiles-daemon.enable = true;
boot.loader.systemd-boot.configurationLimit = 5;
boot.initrd.systemd.enable = true;
# Allow video group (fred) to write to /sys/class/backlight and /sys/class/leds
# (screen brightness and keyboard backlight)
hardware.acpilight.enable = true;
services.logind.settings.Login = {
HandleLidSwitch = "suspend";
HandleLidSwitchExternalPower = "suspend";
};
# Hint libinput that the Apple keyboard is internal, so its built-in
# DWT pairing works for the bcm5974 touchpad (keyboard and touchpad
# share the same USB device, which normally breaks pairing).
environment.etc."libinput/local-overrides.quirks".text = ''
[Apple MacBook Keyboard]
MatchProduct=Apple Internal Keyboard
AttrKeyboardIntegration=internal
'';
# Fallback DWT daemon in case the libinput quirk above isn't enough.
# TODO: remove this if the quirk works reliably.
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.3
# Modifier keycodes don't inhibit touchpad for these
MODIFIERS = {42, 54, 29, 97, 56, 100, 125, 126} # L/R Shift, Ctrl, Alt, Super
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, code, val = struct.unpack("llHHi", data[off:off + EVENT_SIZE])
if typ == EV_KEY and val and code not in MODIFIERS:
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 = "";
mode = "preferred";
position = "auto";
scale = "auto";
}];
# wob reads 0-100 integers from a FIFO and shows a progress bar overlay
systemd.user.services.wob = {
Unit = {
Description = "Wayland OSD Bar";
After = [ "graphical-session.target" ];
PartOf = [ "graphical-session.target" ];
};
Service = {
Type = "simple";
ExecStart = "${pkgs.writeShellScript "wob-start" ''
rm -f "%t/wob.fifo"
mkfifo "%t/wob.fifo"
tail -f "%t/wob.fifo" | ${pkgs.wob}/bin/wob
''}";
ExecStopPost = "${pkgs.coreutils}/bin/rm -f %t/wob.fifo";
Restart = "on-failure";
};
Install.WantedBy = [ "graphical-session.target" ];
};
systemd.user.services.ghostty-daemon = {
Unit = {
Description = "Ghostty warm instance (no window)";
After = [ "graphical-session.target" ];
PartOf = [ "graphical-session.target" ];
};
Service = {
Type = "simple";
ExecStart = "${pkgs.ghostty}/bin/ghostty --initial-window=false";
Restart = "always";
};
Install.WantedBy = [ "graphical-session.target" ];
};
systemd.user.services.nemo-warmup = {
Unit = {
Description = "Pre-warm Nemo file manager libraries";
After = [ "graphical-session.target" ];
PartOf = [ "graphical-session.target" ];
};
Service = {
Type = "oneshot";
ExecStart = "${pkgs.nemo}/bin/nemo --quit";
};
Install.WantedBy = [ "graphical-session.target" ];
};
systemd.user.services.kbd-backlight-init = {
Unit = {
Description = "Set keyboard backlight to 10% on login";
After = [ "graphical-session.target" ];
PartOf = [ "graphical-session.target" ];
};
Service = {
Type = "oneshot";
ExecStart = "${pkgs.brightnessctl}/bin/brightnessctl -d smc::kbd_backlight set 10%";
};
Install.WantedBy = [ "graphical-session.target" ];
};
};
};
}