aboutsummaryrefslogtreecommitdiffstats
path: root/desktop/modules/user
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-10-16 10:33:13 +0200
committerDanilo M. <danix@danix.xyz>2026-10-16 10:33:13 +0200
commit2e792d039dffda512963a1697d52fde6754544a4 (patch)
treefc7fab4a6d3804e11b7807b02c90770a85864185 /desktop/modules/user
parente1313ee7abb93a8a20f978ac152b462c9ef74a43 (diff)
downloadquickshell-2e792d039dffda512963a1697d52fde6754544a4.tar.gz
quickshell-2e792d039dffda512963a1697d52fde6754544a4.zip
feat(user): keyboard for the location suggestions
Up and Down move through the list, wrapping, and light the row as hover does; Enter takes it; Escape closes the list. With no list open the keys pass on, so Escape still leaves the page. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'desktop/modules/user')
-rw-r--r--desktop/modules/user/UserPage.qml35
1 files changed, 29 insertions, 6 deletions
diff --git a/desktop/modules/user/UserPage.qml b/desktop/modules/user/UserPage.qml
index 9fb81a6..4693801 100644
--- a/desktop/modules/user/UserPage.qml
+++ b/desktop/modules/user/UserPage.qml
@@ -142,9 +142,18 @@ Column {
// asks for an identifying User-Agent: the timer fires 1s after typing
// stops, and a reply to an older query is dropped by its sequence number.
property var places: []
+ // The suggestion Up/Down has reached, -1 for none; any new list resets it.
+ property int placeIndex: -1
+ onPlacesChanged: placeIndex = -1
property string placeQuery: ""
property int placeSeq: 0
+ function pickPlace(key, label) {
+ form.set(key, label);
+ form.placeSeq++;
+ form.places = [];
+ }
+
function lookup(text) {
form.places = [];
form.placeQuery = text.trim();
@@ -299,6 +308,22 @@ Column {
if (field.modelData.kind === "place") form.lookup(text);
}
onActiveFocusChanged: if (!activeFocus && field.modelData.kind === "place") form.places = []
+
+ // Up/Down move through the suggestions, Enter takes the
+ // highlighted one, Escape closes the list. With no list
+ // open the keys go on as usual, so Escape still leaves
+ // the page.
+ Keys.onPressed: event => {
+ const n = field.modelData.kind === "place" ? form.places.length : 0;
+ if (n === 0) return;
+ if (event.key === Qt.Key_Down) form.placeIndex = (form.placeIndex + 1) % n;
+ else if (event.key === Qt.Key_Up) form.placeIndex = (form.placeIndex + n - 1) % n;
+ else if ((event.key === Qt.Key_Return || event.key === Qt.Key_Enter) && form.placeIndex >= 0)
+ form.pickPlace(field.modelData.key, form.places[form.placeIndex]);
+ else if (event.key === Qt.Key_Escape) form.places = [];
+ else return;
+ event.accepted = true;
+ }
}
}
@@ -310,10 +335,12 @@ Column {
model: field.modelData.kind === "place" ? form.places : []
delegate: Rectangle {
required property string modelData
+ required property int index
width: parent.width
height: 30
radius: 6
- color: placeArea.containsMouse ? Qt.alpha(Theme.accent, 0.22) : Qt.alpha(Theme.surface, 0.6)
+ color: placeArea.containsMouse || index === form.placeIndex
+ ? Qt.alpha(Theme.accent, 0.22) : Qt.alpha(Theme.surface, 0.6)
Text {
anchors { fill: parent; leftMargin: 10; rightMargin: 10 }
verticalAlignment: Text.AlignVCenter
@@ -327,11 +354,7 @@ Column {
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
- onClicked: {
- form.set(field.modelData.key, parent.modelData);
- form.placeSeq++;
- form.places = [];
- }
+ onClicked: form.pickPlace(field.modelData.key, parent.modelData)
}
}
}