From 34bb9508303ca056b6774d5460c7e4a1d5432984 Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Mon, 18 May 2026 22:50:38 +0200 Subject: [PATCH] Keyboard nav --- shell/plugins/bar/widgets/powerPanel.qml | 55 +++++++++++++++++++++--- 1 file changed, 48 insertions(+), 7 deletions(-) diff --git a/shell/plugins/bar/widgets/powerPanel.qml b/shell/plugins/bar/widgets/powerPanel.qml index c28a7287..fc1e7bce 100644 --- a/shell/plugins/bar/widgets/powerPanel.qml +++ b/shell/plugins/bar/widgets/powerPanel.qml @@ -16,9 +16,20 @@ Item { property var systemInfo: ({}) property var profiles: [] property string activeProfile: "" + property int profileIndex: 0 function closePopout() { popupOpen = false } + function selectProfileByDelta(delta) { + if (profiles.length === 0) { profileIndex = 0; return } + profileIndex = Math.max(0, Math.min(profiles.length - 1, profileIndex + delta)) + } + + function activateSelectedProfile() { + if (profileIndex < 0 || profileIndex >= profiles.length) return + setProfile(profiles[profileIndex]) + } + function batteryIcon() { var device = UPower.displayDevice if (!device || !device.isPresent) return "" @@ -82,6 +93,11 @@ Item { } profiles = list activeProfile = active + if (profileIndex >= profiles.length) profileIndex = Math.max(0, profiles.length - 1) + if (popupOpen && activeProfile !== "") { + var idx = profiles.indexOf(activeProfile) + if (idx >= 0) profileIndex = idx + } } function setProfile(profile) { @@ -90,6 +106,15 @@ Item { actionProc.running = true } + onPopupOpenChanged: { + if (popupOpen) { + refresh() + var idx = profiles.indexOf(activeProfile) + profileIndex = idx >= 0 ? idx : 0 + Qt.callLater(function() { if (keyCatcher) keyCatcher.forceActiveFocus() }) + } + } + Component.onCompleted: refresh() implicitWidth: button.implicitWidth @@ -145,7 +170,7 @@ printf 'time\t%s\n' "$($OMARCHY_PATH/bin/omarchy-battery-remaining-time 2>/dev/n rightExtraMargin: 2 active: UPower.displayDevice && UPower.displayDevice.percentage <= 0.2 && UPower.onBattery tooltipText: "" - onPressed: function(b) { root.popupOpen = !root.popupOpen; if (root.popupOpen) root.refresh() } + onPressed: function(b) { root.popupOpen = !root.popupOpen } } KeyboardPanel { @@ -157,12 +182,22 @@ printf 'time\t%s\n' "$($OMARCHY_PATH/bin/omarchy-battery-remaining-time 2>/dev/n contentWidth: 340 contentHeight: column.implicitHeight + 28 - Column { - id: column - anchors.left: parent.left - anchors.right: parent.right - anchors.top: parent.top - spacing: 16 + PanelKeyCatcher { + id: keyCatcher + anchors.fill: parent + onMoveRequested: function(dx, dy) { + if (dx !== 0) root.selectProfileByDelta(dx) + else if (dy !== 0) root.selectProfileByDelta(dy) + } + onActivateRequested: root.activateSelectedProfile() + onCloseRequested: root.closePopout() + + Column { + id: column + anchors.left: parent.left + anchors.right: parent.right + anchors.top: parent.top + spacing: 16 Item { width: parent.width @@ -238,6 +273,7 @@ printf 'time\t%s\n' "$($OMARCHY_PATH/bin/omarchy-battery-remaining-time 2>/dev/n model: root.profiles CursorPill { required property var modelData + required property int index text: String(modelData).charAt(0).toUpperCase() + String(modelData).slice(1) foreground: root.bar.foreground background: Qt.rgba(root.bar.foreground.r, root.bar.foreground.g, root.bar.foreground.b, 0.04) @@ -247,13 +283,18 @@ printf 'time\t%s\n' "$($OMARCHY_PATH/bin/omarchy-battery-remaining-time 2>/dev/n horizontalPadding: 10 verticalPadding: 6 active: root.activeProfile === modelData + hasCursor: root.profileIndex === index onClicked: root.setProfile(modelData) + onHovered: function(h) { + if (h) root.profileIndex = index + } } } } } } } + } component InfoPair: Row { property string label: ""