From 6a16e4329841d034d75237402196e4c5832f85e9 Mon Sep 17 00:00:00 2001 From: tibssy Date: Wed, 18 Feb 2026 16:55:04 +0000 Subject: [PATCH] feat(bar-scroll-actions): implement Niri content scrolling for mouse wheel action --- Assets/settings-default.json | 1 - Commons/Settings.qml | 1 - Modules/Bar/Bar.qml | 12 +++++++----- Modules/Panels/Settings/Tabs/Bar/BehaviorSubTab.qml | 11 ++--------- Services/Compositor/CompositorService.qml | 7 +++++++ Services/Compositor/NiriService.qml | 9 +++++++++ 6 files changed, 25 insertions(+), 16 deletions(-) diff --git a/Assets/settings-default.json b/Assets/settings-default.json index f130d9f26..9f1fd7a08 100644 --- a/Assets/settings-default.json +++ b/Assets/settings-default.json @@ -68,7 +68,6 @@ } ] }, - "enableWorkspaceScroll": false, "mouseWheelAction": "none", "screenOverrides": [] }, diff --git a/Commons/Settings.qml b/Commons/Settings.qml index 125a8cf33..47ac55e6f 100644 --- a/Commons/Settings.qml +++ b/Commons/Settings.qml @@ -252,7 +252,6 @@ Singleton { } ] } - property bool enableWorkspaceScroll: false property string mouseWheelAction: "none" // Per-screen overrides for position and widgets // Format: [{ "name": "HDMI-1", "position": "left" }, { "name": "DP-1", "position": "bottom", "widgets": {...} }] diff --git a/Modules/Bar/Bar.qml b/Modules/Bar/Bar.qml index 0274004f8..1a1bef1aa 100644 --- a/Modules/Bar/Bar.qml +++ b/Modules/Bar/Bar.qml @@ -185,9 +185,7 @@ Item { property int barWheelAccumulatedDelta: 0 property bool barWheelCooldown: false readonly property string barWheelAction: { - if (Settings.data.bar.mouseWheelAction !== undefined && Settings.data.bar.mouseWheelAction !== "") - return Settings.data.bar.mouseWheelAction; - return Settings.data.bar.enableWorkspaceScroll ? "workspace" : "none"; + return Settings.data.bar.mouseWheelAction || "none"; } // Position and size the bar content based on orientation @@ -367,7 +365,7 @@ Item { id: barWheelHandler target: bar acceptedDevices: PointerDevice.Mouse | PointerDevice.TouchPad - enabled: bar.barWheelAction === "workspace" + enabled: bar.barWheelAction !== "none" onWheel: function (event) { if (bar.barWheelCooldown) @@ -386,7 +384,11 @@ Item { var direction = bar.barWheelAccumulatedDelta > 0 ? -1 : 1; if (Settings.data.general.reverseScroll) direction *= -1; - bar.switchWorkspaceByOffset(direction); + if (bar.barWheelAction === "workspace") { + bar.switchWorkspaceByOffset(direction); + } else if (bar.barWheelAction === "content") { + CompositorService.scrollWorkspaceContent(direction); + } bar.barWheelCooldown = true; barWheelDebounce.restart(); bar.barWheelAccumulatedDelta = 0; diff --git a/Modules/Panels/Settings/Tabs/Bar/BehaviorSubTab.qml b/Modules/Panels/Settings/Tabs/Bar/BehaviorSubTab.qml index 506a758e3..890f92d3a 100644 --- a/Modules/Panels/Settings/Tabs/Bar/BehaviorSubTab.qml +++ b/Modules/Panels/Settings/Tabs/Bar/BehaviorSubTab.qml @@ -10,11 +10,7 @@ ColumnLayout { spacing: Style.marginL Layout.fillWidth: true - readonly property string effectiveWheelAction: { - if (Settings.data.bar.mouseWheelAction !== undefined && Settings.data.bar.mouseWheelAction !== "") - return Settings.data.bar.mouseWheelAction; - return Settings.data.bar.enableWorkspaceScroll ? "workspace" : "none"; - } + readonly property string effectiveWheelAction: Settings.data.bar.mouseWheelAction || "none" NComboBox { Layout.fillWidth: true @@ -41,9 +37,6 @@ ColumnLayout { } currentKey: root.effectiveWheelAction defaultValue: Settings.getDefaultValue("bar.mouseWheelAction") - onSelected: key => { - Settings.data.bar.mouseWheelAction = key; - Settings.data.bar.enableWorkspaceScroll = (key === "workspace"); - } + onSelected: key => Settings.data.bar.mouseWheelAction = key } } diff --git a/Services/Compositor/CompositorService.qml b/Services/Compositor/CompositorService.qml index 2d5e5dfe3..7e65008b8 100644 --- a/Services/Compositor/CompositorService.qml +++ b/Services/Compositor/CompositorService.qml @@ -375,6 +375,13 @@ Singleton { } } + // Scrollable workspace content (Niri) + function scrollWorkspaceContent(direction) { + if (backend && backend.scrollWorkspaceContent) { + backend.scrollWorkspaceContent(direction); + } + } + // Get current workspace function getCurrentWorkspace() { for (var i = 0; i < workspaces.count; i++) { diff --git a/Services/Compositor/NiriService.qml b/Services/Compositor/NiriService.qml index b11a3b3d3..22b8ada2c 100644 --- a/Services/Compositor/NiriService.qml +++ b/Services/Compositor/NiriService.qml @@ -456,6 +456,15 @@ Item { } } + function scrollWorkspaceContent(direction) { + try { + var action = direction < 0 ? "focus-column-left" : "focus-column-right"; + Quickshell.execDetached(["niri", "msg", "action", action]); + } catch (e) { + Logger.e("NiriService", "Failed to scroll workspace content:", e); + } + } + function focusWindow(window) { try { Quickshell.execDetached(["niri", "msg", "action", "focus-window", "--id", window.id.toString()]);