diff --git a/README.md b/README.md index 0af7a3a..5b24c87 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ NixOS configuration for my Framework 12 laptop aka chi. Everything here is subject to change, and is for my own personal use. -The Framework hardware module, accelerometer-driven Niri rotation, on-screen keyboard, and optional touchscreen edge gestures make the convertible hardware usable outside a full desktop environment. +The Framework hardware module, accelerometer-driven Niri rotation, manually toggled on-screen keyboard, rotation-aware touchscreen edge gestures, and Powertop tunings make the convertible hardware usable outside a full desktop environment. It's widely vibe coded togther, but seems to be stable. I'm not doing anything that difficult here, and goes to show that anyone can waste electricity. @@ -12,7 +12,7 @@ It's widely vibe coded togther, but seems to be stable. I'm not doing anything t hosts/chi/ — host-specific config (chi, a Framework 12 laptop) modules/common.nix — shared settings (locale, firewall, fonts, nix settings) home/ — Home Manager modules, one file per topic - (shell, apps, emacs, niri, waybar, foot, khal, stylix, opencode) + (shell, apps, emacs, niri, ironbar, tablet, foot, khal, stylix, opencode) wallpapers/ — wallpapers (wp2002041.jpg also generates the stylix theme) ``` diff --git a/home/tablet.nix b/home/tablet.nix index 9e31e4f..cab6764 100644 --- a/home/tablet.nix +++ b/home/tablet.nix @@ -4,15 +4,66 @@ ... }: let niri = "${config.programs.niri.package}/bin/niri"; - touchscreen = "/dev/input/by-path/pci-0000:00:15.1-platform-i2c_designware.1-event"; + touchscreen = "/dev/input/by-path/pci-0000:00:15.0-platform-i2c_designware.0-event"; tabletGestures = pkgs.writeShellScript "tablet-gestures" '' - exec ${pkgs.lisgd}/bin/lisgd \ - -d ${touchscreen} \ - -t 120 \ - -m 900 \ - -g "2,LR,L,*,R,${niri} msg action focus-column-left" \ - -g "2,RL,R,*,R,${niri} msg action focus-column-right" \ - -g "2,DU,B,*,R,${niri} msg action toggle-overview" + set -eu + + lisgd_pid="" + sensor_pid="" + sensor_fifo="''${XDG_RUNTIME_DIR:-/tmp}/tablet-gestures-$$.fifo" + + cleanup() { + if [ -n "$lisgd_pid" ]; then + kill "$lisgd_pid" 2>/dev/null || true + wait "$lisgd_pid" 2>/dev/null || true + fi + if [ -n "$sensor_pid" ]; then + kill "$sensor_pid" 2>/dev/null || true + wait "$sensor_pid" 2>/dev/null || true + fi + rm -f "$sensor_fifo" + } + + start_lisgd() { + case "$1" in + normal) orientation=0 ;; + right-up) orientation=1 ;; + bottom-up) orientation=2 ;; + left-up) orientation=3 ;; + *) return ;; + esac + + if [ -n "$lisgd_pid" ]; then + kill "$lisgd_pid" 2>/dev/null || true + wait "$lisgd_pid" 2>/dev/null || true + fi + ${pkgs.lisgd}/bin/lisgd \ + -d ${touchscreen} \ + -o "$orientation" \ + -t 120 \ + -m 900 \ + -g "2,LR,L,*,R,${niri} msg action focus-column-left" \ + -g "2,RL,R,*,R,${niri} msg action focus-column-right" \ + -g "2,DU,B,*,R,${niri} msg action toggle-overview" & + lisgd_pid=$! + } + + trap cleanup EXIT INT TERM + + mkfifo "$sensor_fifo" + ${pkgs.iio-sensor-proxy}/bin/monitor-sensor --accel >"$sensor_fifo" & + sensor_pid=$! + + while IFS= read -r line; do + case "$line" in + *"orientation: normal"*|*"orientation changed: normal") start_lisgd normal ;; + *"orientation: right-up"*|*"orientation changed: right-up") start_lisgd right-up ;; + *"orientation: bottom-up"*|*"orientation changed: bottom-up") start_lisgd bottom-up ;; + *"orientation: left-up"*|*"orientation changed: left-up") start_lisgd left-up ;; + esac + done <"$sensor_fifo" + + exit 1 ''; in { home.packages = [ @@ -36,7 +87,7 @@ in { tablet-gestures = { Unit = { - Description = "Experimental Framework touchscreen edge gestures"; + Description = "Rotation-aware Framework touchscreen edge gestures"; PartOf = ["graphical-session.target"]; After = ["graphical-session.target"]; }; diff --git a/hosts/chi/configuration.nix b/hosts/chi/configuration.nix index 3a2d20d..b059d49 100644 --- a/hosts/chi/configuration.nix +++ b/hosts/chi/configuration.nix @@ -107,6 +107,7 @@ opencode prismlauncher nix-output-monitor + powertop age unzip ]; @@ -119,6 +120,9 @@ # Laptop power management (Framework 12, Intel) services.power-profiles-daemon.enable = true; + # Apply peripheral and device power-saving tunables at boot. PPD continues + # to manage the selectable CPU energy profiles at runtime. + powerManagement.powertop.enable = true; services.thermald.enable = true; services.fwupd.enable = true; # UPower daemon — ironbar's battery module reads battery state over zbus diff --git a/notes.md b/notes.md index 667338e..a57d5ac 100644 --- a/notes.md +++ b/notes.md @@ -4,10 +4,10 @@ The `nixos-hardware` Framework 12 module loads `pinctrl_tigerlake` in the initrd before `soc_button_array`, enables IIO sensors, installs `framework_tool`, and keeps firmware updates available through `fwupd`. `services.iio-niri` forwards accelerometer orientation to Niri for the internal `eDP-1` panel. -`home/tablet.nix` provides two optional user services: +`home/tablet.nix` provides two user services: -- `tablet-keyboard.service` keeps `wvkbd` hidden and ready to toggle from Ironbar or `Mod+Shift+K`. -- `tablet-gestures.service` maps two-finger swipes from the left/right edges to column navigation and a two-finger swipe from the bottom edge to Niri's overview. +- `tablet-keyboard.service` keeps `wvkbd` hidden and ready to toggle from Ironbar or `Mod+Shift+K`. It intentionally does not open automatically when entering tablet mode. +- `tablet-gestures.service` reads the internal ILIT2901 touchscreen, maps two-finger swipes from the left/right edges to column navigation, and maps a two-finger swipe from the bottom edge to Niri's overview. It follows accelerometer events and restarts `lisgd` with the matching orientation after the screen rotates. The gestures are experimental and can interfere with multi-touch drawing applications. Disable them with: @@ -25,6 +25,16 @@ systemctl status iio-sensor-proxy.service systemctl --user status iio-niri.service tablet-keyboard.service tablet-gestures.service ``` +The host enables NixOS's Powertop service, which applies `powertop --auto-tune` once at boot. `power-profiles-daemon` remains enabled for switching CPU energy profiles. If a peripheral develops autosuspend problems, test without the tunings using `sudo systemctl stop powertop.service` before disabling `powerManagement.powertop.enable`. + +Sources used for this setup: + +- [Niri switch events](https://niri-wm.github.io/niri/Configuration%3A-Switch-Events.html) documents tablet-mode hooks. They are not used to show the keyboard automatically here. +- [Niri touchscreen gestures discussion](https://github.com/niri-wm/niri/discussions/463) covers `lisgd`, rotation handling, Roland, and experimental native gesture work. +- [Framework 12 Sway tips](https://community.frame.work/t/sway-on-the-framework-laptop-12/73173) demonstrates the practical `wvkbd`, rotation, and touch-sized bar-control pattern. +- [Framework 12 tablet requirements](https://community.frame.work/t/what-are-the-linux-system-requirements-for-tablet-mode/71466) and the [tablet-mode recovery tracking thread](https://community.frame.work/t/fw12-problems-returning-from-tablet-mode-tracking-thread/71631) cover kernel module ordering and hardware failure modes. +- [The Tangled repository](https://tangled.org/molly.computer/nixos/tree/master) is the primary remote for this configuration. Tangled's public search currently exposes few comparable Framework 12 configurations. + ### software to investigate - `rnote`: touch-first handwritten notes and sketching. @@ -34,9 +44,13 @@ systemctl --user status iio-niri.service tablet-keyboard.service tablet-gestures - `papers`: document and PDF reader with a compact GTK interface. - `kdeconnect` or `localsend`: phone integration and local file transfer. - `kooha`: simple Wayland screen recording. -- `powertop` and `powerstat`: measure battery use before adding power tweaks. +- `powerstat`: compare actual battery use before and after Powertop tuning; `sudo powertop` provides interactive wakeup and device diagnostics. +- `swayidle`: automatic lock, display power-off, and suspend under Niri. +- `zramSwap`: compressed memory fallback during heavy builds or games; less urgent while the system has ample disk swap. +- Framework EC charge limits: cap charging around 80% for battery longevity after confirming support and preferred travel behavior. - `unl0kr`: touchscreen initrd unlock if disk encryption is added later. - `roland`: Niri-focused edge gesture daemon with better edge detection than `lisgd`, but it is lightly maintained and not packaged in nixpkgs. +- `sysboard`: another Niri-compatible on-screen keyboard worth comparing with `wvkbd`. - `squeekboard`: richer input-method behavior if its standalone compositor integration improves. ## pulling this config to a new system