From e203e76ccc33e68ef1bbcd77d243e19feb314fe0 Mon Sep 17 00:00:00 2001 From: FormalSnake <90651091+FormalSnake@users.noreply.github.com> Date: Thu, 6 Aug 2026 01:46:42 +0100 Subject: [PATCH] powermenu: support user-defined custom power buttons (#2916) --- quickshell/Common/SettingsData.qml | 1 + quickshell/Common/settings/SettingsSpec.js | 1 + quickshell/Modals/PowerMenuModal.qml | 20 +++++++++++++++++++- 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/quickshell/Common/SettingsData.qml b/quickshell/Common/SettingsData.qml index c11f3bc13..37b07c6cf 100644 --- a/quickshell/Common/SettingsData.qml +++ b/quickshell/Common/SettingsData.qml @@ -973,6 +973,7 @@ Singleton { property string customPowerActionHibernate: "" property string customPowerActionReboot: "" property string customPowerActionPowerOff: "" + property var customPowerButtons: [] property bool updaterHideWidget: false property bool updaterCheckOnStart: false diff --git a/quickshell/Common/settings/SettingsSpec.js b/quickshell/Common/settings/SettingsSpec.js index ed6c1ddb7..35ec7e95f 100644 --- a/quickshell/Common/settings/SettingsSpec.js +++ b/quickshell/Common/settings/SettingsSpec.js @@ -526,6 +526,7 @@ var SPEC = { customPowerActionHibernate: { def: "" }, customPowerActionReboot: { def: "" }, customPowerActionPowerOff: { def: "" }, + customPowerButtons: { def: [] }, updaterHideWidget: { def: false }, updaterCheckOnStart: { def: false }, diff --git a/quickshell/Modals/PowerMenuModal.qml b/quickshell/Modals/PowerMenuModal.qml index 668b232d3..3e09b9273 100644 --- a/quickshell/Modals/PowerMenuModal.qml +++ b/quickshell/Modals/PowerMenuModal.qml @@ -129,6 +129,13 @@ DankModal { switchUserRequested(); return; } + if (action.startsWith("custom:")) { + const button = (SettingsData.customPowerButtons || [])[parseInt(action.slice(7), 10)]; + close(); + if (button?.command) + Quickshell.execDetached(["sh", "-c", button.command]); + return; + } close(); root.powerActionRequested(action, "", ""); } @@ -172,13 +179,14 @@ DankModal { function updateVisibleActions() { const allActions = SettingsData.powerMenuActions || ["reboot", "logout", "poweroff", "lock", "suspend", "restart"]; + const customButtons = SettingsData.customPowerButtons || []; visibleActions = allActions.filter(action => { if (action === "hibernate" && !SessionService.hibernateSupported) return false; if (action === "softreboot" && !SessionService.softRebootSupported) return false; return true; - }); + }).concat(customButtons.map((button, i) => "custom:" + i)); if (!SettingsData.powerMenuGridLayout) return; @@ -218,6 +226,14 @@ DankModal { } function getActionData(action) { + if (action.startsWith("custom:")) { + const button = (SettingsData.customPowerButtons || [])[parseInt(action.slice(7), 10)]; + return { + "icon": button?.icon || "terminal", + "label": button?.label || button?.command || "", + "key": "" + }; + } switch (action) { case "reboot": return { @@ -688,6 +704,7 @@ DankModal { height: 16 radius: 4 color: Theme.onSurface_12 + visible: gridButtonRect.actionData.key !== "" anchors.horizontalCenter: parent.horizontalCenter StyledText { @@ -820,6 +837,7 @@ DankModal { height: 20 radius: 4 color: Theme.onSurface_12 + visible: listButtonRect.actionData.key !== "" anchors { right: parent.right rightMargin: Theme.spacingM