diff options
| author | Danilo M. <danix@danix.xyz> | 2026-10-16 10:33:13 +0200 |
|---|---|---|
| committer | Danilo M. <danix@danix.xyz> | 2026-10-16 10:33:13 +0200 |
| commit | 2e792d039dffda512963a1697d52fde6754544a4 (patch) | |
| tree | fc7fab4a6d3804e11b7807b02c90770a85864185 | |
| parent | e1313ee7abb93a8a20f978ac152b462c9ef74a43 (diff) | |
| download | quickshell-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>
| -rw-r--r-- | desktop/modules/user/UserPage.qml | 35 |
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) } } } |
