From 181ce06a5b58dd684666f88678858ce41daa72a7 Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Fri, 22 May 2026 08:46:17 +0200 Subject: [PATCH] Tab to move quicker between sections --- shell/Ui/PanelKeyCatcher.qml | 6 ++++++ shell/plugins/panels/Audio.qml | 12 ++++++++++++ 2 files changed, 18 insertions(+) diff --git a/shell/Ui/PanelKeyCatcher.qml b/shell/Ui/PanelKeyCatcher.qml index 27e17d1f..27e5bebc 100644 --- a/shell/Ui/PanelKeyCatcher.qml +++ b/shell/Ui/PanelKeyCatcher.qml @@ -39,6 +39,7 @@ Item { signal activateRequested() signal closeRequested() signal deleteRequested() + signal tabRequested(int direction) signal textKey(string text) focus: true @@ -49,6 +50,11 @@ Item { if (event.key === Qt.Key_Escape) { closeRequested(); event.accepted = true; return } + if (event.key === Qt.Key_Tab || event.key === Qt.Key_Backtab) { + tabRequested((event.modifiers & Qt.ShiftModifier) || event.key === Qt.Key_Backtab ? -1 : 1) + event.accepted = true + return + } if (event.key === Qt.Key_Down || event.text === "j") { moveRequested(0, 1); event.accepted = true; return } diff --git a/shell/plugins/panels/Audio.qml b/shell/plugins/panels/Audio.qml index 1a4a35ec..e1c92151 100644 --- a/shell/plugins/panels/Audio.qml +++ b/shell/plugins/panels/Audio.qml @@ -169,6 +169,17 @@ Panel { } } + function moveSection(delta) { + var sections = visibleSections + if (sections.length === 0) return + var current = sections.indexOf(focusSection) + if (current < 0) current = delta > 0 ? -1 : 0 + var next = (current + delta + sections.length) % sections.length + focusSection = sections[next] + selectedIndex = sectionHasSlider(focusSection) ? -1 : 0 + cursorActive = true + } + // Adjust the slider associated with the focused section. Output and // input sliders are real volume controls; on stream rows h/l adjusts // that stream's volume (so keyboard parity with the inline slider). @@ -575,6 +586,7 @@ Panel { } onActivateRequested: if (root.cursorActive) root.activateCursor() onCloseRequested: root.close() + onTabRequested: function(direction) { root.moveSection(direction) } onTextKey: function(t) { // 'm' mutes whatever the cursor is on: focused section's slider // for output/input, the focused stream for streams.