diff --git a/clients/quadraticpc/fht-compositor/scroll-accumulation.patch b/clients/quadraticpc/fht-compositor/scroll-accumulation.patch deleted file mode 100644 index 408619d..0000000 --- a/clients/quadraticpc/fht-compositor/scroll-accumulation.patch +++ /dev/null @@ -1,132 +0,0 @@ ---- a/src/state.rs -+++ b/src/state.rs -@@ -719,6 +719,9 @@ - pub seat: Seat, - pub keyboard: KeyboardHandle, - pub pointer: PointerHandle, -+ // Accumulated high-resolution scroll (in 1/120ths of a wheel notch), horizontal then vertical, -+ // for scroll bindings, so that they trigger once per notch rather than once per event. -+ pub scroll_binding_accumulator: (f64, f64), - pub clock: Clock, - pub suppressed_keys: HashMap, - // We store both the timer and the keysym used to trigger the key action. -@@ -967,6 +970,7 @@ - seat_state, - keyboard, - pointer, -+ scroll_binding_accumulator: (0.0, 0.0), - mapped_layer_surfaces: HashMap::new(), - lock_state: LockState::Unlocked, - focused_on_demand_layer_shell: None, ---- a/src/input/mod.rs -+++ b/src/input/mod.rs -@@ -569,56 +569,41 @@ - let mut handled = false; - - // Check vertical axis bindings using discrete amounts -- if let Some(discrete) = vertical_amount_discrete { -- if discrete > 0.0 { -- let mouse_pattern = fht_compositor_config::MousePattern( -- modifiers, -- fht_compositor_config::MouseInput::Axis( -- fht_compositor_config::MouseAxis::WheelUp, -- ), -- ); -- if let Some(action) = self.fht.config.mousebinds.get(&mouse_pattern).cloned() { -- self.process_mouse_action(0, action, SERIAL_COUNTER.next_serial()); -- handled = true; -- } -- } else if discrete < 0.0 { -- let mouse_pattern = fht_compositor_config::MousePattern( -- modifiers, -- fht_compositor_config::MouseInput::Axis( -- fht_compositor_config::MouseAxis::WheelDown, -- ), -- ); -- if let Some(action) = self.fht.config.mousebinds.get(&mouse_pattern).cloned() { -+ if let Some(discrete) = vertical_amount_discrete.filter(|discrete| *discrete != 0.0) { -+ let mouse_axis = if discrete > 0.0 { -+ fht_compositor_config::MouseAxis::WheelUp -+ } else { -+ fht_compositor_config::MouseAxis::WheelDown -+ }; -+ let mouse_pattern = fht_compositor_config::MousePattern( -+ modifiers, -+ fht_compositor_config::MouseInput::Axis(mouse_axis), -+ ); -+ if let Some(action) = self.fht.config.mousebinds.get(&mouse_pattern).cloned() { -+ handled = true; -+ if accumulate_scroll(&mut self.fht.scroll_binding_accumulator.1, discrete) { - self.process_mouse_action(0, action, SERIAL_COUNTER.next_serial()); -- handled = true; - } - } - } - - // Check horizontal axis bindings using discrete amounts - if !handled { -- if let Some(discrete) = horizontal_amount_discrete { -- if discrete > 0.0 { -- let mouse_pattern = fht_compositor_config::MousePattern( -- modifiers, -- fht_compositor_config::MouseInput::Axis( -- fht_compositor_config::MouseAxis::WheelRight, -- ), -- ); -- if let Some(action) = self.fht.config.mousebinds.get(&mouse_pattern).cloned() { -- self.process_mouse_action(0, action, SERIAL_COUNTER.next_serial()); -- handled = true; -- } -- } else if discrete < 0.0 { -- let mouse_pattern = fht_compositor_config::MousePattern( -- modifiers, -- fht_compositor_config::MouseInput::Axis( -- fht_compositor_config::MouseAxis::WheelLeft, -- ), -- ); -- if let Some(action) = self.fht.config.mousebinds.get(&mouse_pattern).cloned() { -+ if let Some(discrete) = horizontal_amount_discrete.filter(|discrete| *discrete != 0.0) -+ { -+ let mouse_axis = if discrete > 0.0 { -+ fht_compositor_config::MouseAxis::WheelRight -+ } else { -+ fht_compositor_config::MouseAxis::WheelLeft -+ }; -+ let mouse_pattern = fht_compositor_config::MousePattern( -+ modifiers, -+ fht_compositor_config::MouseInput::Axis(mouse_axis), -+ ); -+ if let Some(action) = self.fht.config.mousebinds.get(&mouse_pattern).cloned() { -+ handled = true; -+ if accumulate_scroll(&mut self.fht.scroll_binding_accumulator.0, discrete) { - self.process_mouse_action(0, action, SERIAL_COUNTER.next_serial()); -- handled = true; - } - } - } -@@ -1079,6 +1064,25 @@ - } - } - -+/// Accumulate high-resolution scroll for a scroll binding. -+/// -+/// High-resolution wheels send several events per notch, each with part of the 120 units of a -+/// notch, so we accumulate them and only trigger the binding once per full notch. Returns whether -+/// the binding should trigger. -+fn accumulate_scroll(accumulated: &mut f64, v120: f64) -> bool { -+ if accumulated.signum() != v120.signum() { -+ // Changed direction, start over -+ *accumulated = 0.0; -+ } -+ *accumulated += v120; -+ if accumulated.abs() >= 120.0 { -+ *accumulated -= 120.0 * accumulated.signum(); -+ true -+ } else { -+ false -+ } -+} -+ - /// Returns `true` if a VT switch key has been handled. - fn handle_vt_switch(backend: &mut Backend, key_state: KeyState, modified: Keysym) -> bool { - if key_state == KeyState::Released { diff --git a/flake.lock b/flake.lock index 0e209be..cadc7f4 100644 --- a/flake.lock +++ b/flake.lock @@ -1123,6 +1123,7 @@ "sable": "sable", "sable-next": "sable-next", "stylix": "stylix", + "v4l2loopback-package": "v4l2loopback-package", "wrapper-manager": "wrapper-manager" } }, @@ -1469,6 +1470,18 @@ "type": "github" } }, + "v4l2loopback-package": { + "flake": false, + "locked": { + "narHash": "sha256-Jel7EbTuktyhriWtL3u9P5+4ADP0FqGjgkcE2uVgPbo=", + "type": "file", + "url": "https://raw.githubusercontent.com/moni-dz/nixpkgs/v4l2loopback-depmod/pkgs/os-specific/linux/v4l2loopback/default.nix" + }, + "original": { + "type": "file", + "url": "https://raw.githubusercontent.com/moni-dz/nixpkgs/v4l2loopback-depmod/pkgs/os-specific/linux/v4l2loopback/default.nix" + } + }, "wrapper-manager": { "locked": { "lastModified": 1788355120, diff --git a/flake.nix b/flake.nix index ad9c2e8..1aeb05f 100755 --- a/flake.nix +++ b/flake.nix @@ -88,6 +88,11 @@ url = "file+https://raw.githubusercontent.com/j0hax/nixpkgs/lk-jwt-service-restructure/nixos/modules/services/matrix/lk-jwt-service.nix"; flake = false; }; + # TODO: remove once https://github.com/NixOS/nixpkgs/pull/575861 is merged + v4l2loopback-package = { + url = "file+https://raw.githubusercontent.com/moni-dz/nixpkgs/v4l2loopback-depmod/pkgs/os-specific/linux/v4l2loopback/default.nix"; + flake = false; + }; }; outputs = diff --git a/modules/desktop/obs.nix b/modules/desktop/obs.nix index 4b6f8f2..340a054 100644 --- a/modules/desktop/obs.nix +++ b/modules/desktop/obs.nix @@ -1,8 +1,15 @@ -{ pkgs, ... }: +{ pkgs, inputs, ... }: { programs.obs-studio = { enable = true; plugins = with pkgs.obs-studio-plugins; [ obs-pipewire-audio-capture ]; enableVirtualCamera = true; }; + + # TODO: remove once https://github.com/NixOS/nixpkgs/pull/575861 is merged + boot.kernelPackages = pkgs.linuxPackages.extend ( + final: _: { + v4l2loopback = final.callPackage inputs.v4l2loopback-package.outPath { }; + } + ); }