From 44d310903ed84d01f2204b6b0f57bb38f297d9b9 Mon Sep 17 00:00:00 2001 From: atagen Date: Sun, 15 Feb 2026 11:55:28 +1100 Subject: [PATCH] init --- flake.lock | 7 +++++ flake.nix | 35 +++++++++++++++++++++++++ niri-s76-bridge.nu | 64 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 106 insertions(+) create mode 100644 flake.lock create mode 100644 flake.nix create mode 100755 niri-s76-bridge.nu diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..5999137 --- /dev/null +++ b/flake.lock @@ -0,0 +1,7 @@ +{ + "nodes": { + "root": {} + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..8b57775 --- /dev/null +++ b/flake.nix @@ -0,0 +1,35 @@ +{ + description = "Passes focused Niri window's PID to System76 Scheduler."; + + outputs = _: { + + nixosModules.default = + { + config, + lib, + pkgs, + ... + }: + { + options.services.niri-s76-bridge = { + enable = lib.mkEnableOption "niri-s76-bridge service"; + }; + + config = lib.mkIf config.services.niri-s76-bridge.enable { + systemd.user.services.niri-s76-bridge = { + description = "Bridge between niri and System76 Scheduler"; + after = [ "graphical-session.target" ]; + partOf = [ "graphical-session.target" ]; + wantedBy = [ "graphical-session.target" ]; + + serviceConfig = { + Type = "simple"; + ExecStart = "${pkgs.nushell} ${./niri-s76-bridge.nu}"; + Restart = "on-failure"; + RestartSec = "5"; + }; + }; + }; + }; + }; +} diff --git a/niri-s76-bridge.nu b/niri-s76-bridge.nu new file mode 100755 index 0000000..2b5a2b1 --- /dev/null +++ b/niri-s76-bridge.nu @@ -0,0 +1,64 @@ + +def main [] { + def notify-scheduler [proc_id: int] { + print $"Forwarding PID ($proc_id) to scheduler" + busctl call com.system76.Scheduler /com/system76/Scheduler com.system76.Scheduler SetForegroundProcess u $"($proc_id)" + } + + print "niri-s76-bridge started" + niri msg -j event-stream | lines | reduce --fold [] { |line, windows| + let event = $line | from json + let event_type = $event | columns | first + + match $event_type { + "WindowsChanged" => { + mut acc = $windows + for w in $event.WindowsChanged.windows { + if $w.pid != null and $w.is_focused { + notify-scheduler $w.pid + } + if $w.pid != null { + let existing = $acc | where id == $w.id + if ($existing | is-empty) { + $acc = ($acc | append {id: $w.id, pid: $w.pid}) + } + } + } + $acc + } + "WindowOpenedOrChanged" => { + let w = $event.WindowOpenedOrChanged.window + if $w.is_focused and $w.pid != null { + notify-scheduler $w.pid + } + if $w.pid != null { + let existing = $windows | where id == $w.id + if ($existing | is-empty) { + $windows | append {id: $w.id, pid: $w.pid} + } else { + $windows + } + } else { + $windows + } + } + "WindowFocusChanged" => { + let focused_id = $event.WindowFocusChanged.id + if $focused_id != null { + let match = $windows | where id == $focused_id + if not ($match | is-empty) { + let focused_pid = $match.0.pid + if $focused_pid != null { + notify-scheduler $focused_pid + } + } + } + $windows + } + "WindowClosed" => { + $windows | where id != $event.WindowClosed.id + } + _ => $windows + } + } +}