feat(niri): add toggle functionality & OSD for touchpad control

This commit is contained in:
purian23 committed 2026-10-14 17:42:27 -04:00
1 parent 8ff7ce2cea
commit 3c13700fc5
13 files changed
+115

No files matched your search

@@ -90,6 +90,11 @@ binds {
spawn "dms" "ipc" "call" "brightness" "decrement" "5" "";
}
// === Input ===
XF86TouchpadToggle allow-when-locked=true repeat=false {
spawn "dms" "ipc" "call" "niri" "toggleTouchpad";
}
// === Window Management ===
Mod+Q repeat=false { close-window; }
Mod+F { maximize-column; }
+1
View File
@@ -133,6 +133,7 @@ func (n *NiriProvider) categorizeByAction(action string) string {
action == "suspend" ||
action == "do-screen-transition" ||
action == "toggle-keyboard-shortcuts-inhibit" ||
action == "toggle-touchpad" ||
strings.Contains(action, "dpms"):
return "System"
case action == "spawn":
@@ -79,6 +79,7 @@ func TestNiriCategorizeByAction(t *testing.T) {
{"close-window", "Window"},
{"spawn", "Execute"},
{"power-off-monitors", "System"},
{"toggle-touchpad", "System"},
{"screenshot-window", "Screenshot"},
{"toggle-overview", "Overview"},
{"next-window", "Alt-Tab"},
+5
View File
@@ -155,6 +155,11 @@ in {
allow-when-locked = true;
action = dms-ipc "brightness" "decrement" "5" "";
};
"XF86TouchpadToggle" = {
allow-when-locked = true;
repeat = false;
action = dms-ipc "niri" "toggleTouchpad";
};
"Mod+Alt+N" = {
allow-when-locked = true;
action = dms-ipc "night" "toggle";
+1
View File
@@ -39,6 +39,7 @@ const KEY_MAP = {
16777328: "XF86AudioLowerVolume",
16777329: "XF86AudioMute",
16842808: "XF86AudioMicMute",
16777488: "XF86TouchpadToggle",
16777344: "XF86AudioPlay",
16777345: "XF86AudioStop",
16777346: "XF86AudioPrev",
+4
View File
@@ -849,6 +849,10 @@ const NIRI_ACTIONS = {
id: "toggle-keyboard-shortcuts-inhibit",
label: "Toggle Shortcuts Inhibit"
},
{
id: "toggle-touchpad",
label: "Toggle Touchpad"
},
{
id: "quit",
label: "Quit niri"
+1
View File
@@ -1106,6 +1106,7 @@ Singleton {
property bool osdMicMuteEnabled: Spec.SPEC.osdMicMuteEnabled.def
property bool osdMicVolumeEnabled: Spec.SPEC.osdMicVolumeEnabled.def
property bool osdCapsLockEnabled: Spec.SPEC.osdCapsLockEnabled.def
property bool osdTouchpadEnabled: Spec.SPEC.osdTouchpadEnabled.def
property bool osdPowerProfileEnabled: Spec.SPEC.osdPowerProfileEnabled.def
property bool osdAudioOutputEnabled: Spec.SPEC.osdAudioOutputEnabled.def
property bool osdWorkspaceEnabled: Spec.SPEC.osdWorkspaceEnabled.def
@@ -1398,6 +1398,9 @@ var LOCAL_SPEC = {
osdCapsLockEnabled: {
def: true
},
osdTouchpadEnabled: {
def: true
},
osdPowerProfileEnabled: {
def: false
},
+6
View File
@@ -1315,6 +1315,12 @@ Item {
delegate: CapsLockOSD {}
}
Variants {
model: (SettingsData.osdTouchpadEnabled && CompositorService.isNiri) ? root.legacySystemLevelOsdScreens : []
delegate: TouchpadOSD {}
}
Variants {
model: SettingsData.osdAudioOutputEnabled ? SettingsData.getFilteredScreens("osd") : []
+34
View File
@@ -0,0 +1,34 @@
import QtQuick
import qs.Common
import qs.Services
import qs.Widgets
DOSD {
id: root
osdKind: "touchpad"
osdWidth: Theme.osdHeight
osdHeight: Theme.osdHeight
autoHideInterval: 2000
enableMouseInteraction: false
Connections {
target: NiriService
function onTouchpadToggled() {
if (SettingsData.osdTouchpadEnabled) {
root.show();
}
}
}
content: Item {
OsdIcon {
tonal: false
anchors.centerIn: parent
iconName: NiriService.touchpadDisabled ? "touchpad_mouse_off" : "touchpad_mouse"
iconColor: NiriService.touchpadDisabled ? Theme.outline : Theme.primary
}
}
}
+14
View File
@@ -1,5 +1,6 @@
import QtQuick
import qs.Common
import qs.Services
import qs.DCommon.Widgets
import qs.Modules.Settings.Widgets
@@ -48,6 +49,11 @@ Item {
"label": I18n.tr("Caps lock"),
"shown": SettingsData.osdCapsLockEnabled
},
{
"value": "touchpad",
"label": I18n.tr("Touchpad"),
"shown": SettingsData.osdTouchpadEnabled && CompositorService.isNiri
},
{
"value": "powerProfile",
"label": I18n.tr("Power profile"),
@@ -184,6 +190,14 @@ Item {
onToggled: checked => SettingsData.set("osdCapsLockEnabled", checked)
}
SettingsToggleRow {
settingKey: "osdTouchpadEnabled"
visible: CompositorService.isNiri
text: I18n.tr("Touchpad")
checked: SettingsData.osdTouchpadEnabled
onToggled: checked => SettingsData.set("osdTouchpadEnabled", checked)
}
SettingsToggleRow {
settingKey: "osdPowerProfileEnabled"
text: I18n.tr("Power profile")
+25
View File
@@ -41,6 +41,10 @@ Singleton {
property int currentKeyboardLayoutIndex: 0
property var keyboardLayoutNames: []
// niri never reports toggle-touchpad state, so this only tracks toggles issued through DMS.
property bool touchpadDisabled: false
signal touchpadToggled
property string configValidationOutput: ""
property bool hasInitialConnection: false
property bool suppressConfigToast: true
@@ -810,6 +814,19 @@ Singleton {
});
}
function toggleTouchpad() {
if (!CompositorService.isNiri)
return;
Proc.runCommand("niri-toggle-touchpad", ["niri", "msg", "action", "toggle-touchpad"], (output, exitCode) => {
if (exitCode !== 0) {
log.warn("toggle-touchpad failed, exit code:", exitCode);
return;
}
touchpadDisabled = !touchpadDisabled;
touchpadToggled();
});
}
function toggleOverview() {
return send({
"Action": {
@@ -1923,6 +1940,14 @@ window-rule {
return "SCREENSHOT_WINDOW_FAILED";
}
function toggleTouchpad(): string {
if (!CompositorService.isNiri) {
return "NIRI_NOT_AVAILABLE";
}
NiriService.toggleTouchpad();
return "TOUCHPAD_TOGGLED";
}
target: "niri"
}
}
@@ -8792,6 +8792,21 @@
"show"
]
},
{
"section": "osdTouchpadEnabled",
"label": "Touchpad",
"tabIndex": 18,
"category": "On-screen displays",
"keywords": [
"displays",
"indicator",
"osd",
"popup",
"screen",
"touchpad"
],
"conditionKey": "isNiri"
},
{
"section": "osdVolumeEnabled",
"label": "Volume",