shell: handle CTRL+BACKSPACE to clear filter#6307
Conversation
There was a problem hiding this comment.
Pull request overview
Adds support in the emoji panel overlay for Ctrl+Backspace to clear the entire search filter at once, while preserving existing Backspace behavior (delete one character).
Changes:
- Detects the
Controlmodifier alongsideBackspacein the panel key handler. - Clears
filterTextonCtrl+Backspace; otherwise deletes a single character onBackspace.
Tip
If you aren't ready for review, convert to a draft PR.
Click "Convert to draft" or run gh pr ready --undo.
Click "Ready for review" or run gh pr ready to reengage.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| } else if (event.key === Qt.Key_Backspace) { | ||
| if ((event.modifiers & Qt.ControlModifier) === Qt.ControlModifier) { | ||
| // CTRL+BACKSPACE: clear entire filter | ||
| root.setFilter("") | ||
| } else if (root.filterText.length > 0) { | ||
| // BACKSPACE: remove one character | ||
| root.setFilter(root.filterText.slice(0, -1)) | ||
| } | ||
| event.accepted = true | ||
| } else if (event.key === Qt.Key_Left) { |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.
Comments suppressed due to low confidence (1)
shell/plugins/emojis/Emojis.qml:213
- The
} else if (event.key === Qt.Key_Left)line is indented much deeper than the rest of thisif/else ifchain, which makes the control flow easy to misread. Align it with the other branches.
event.accepted = true
} else if (event.key === Qt.Key_Left) {
root.select(-1)
| } else if (event.key === Qt.Key_Backspace) { | ||
| if (root.filterText.length > 0) root.setFilter(root.filterText.slice(0, -1)) | ||
| if ((event.modifiers & Qt.ControlModifier) === Qt.ControlModifier) { | ||
| // CTRL+BACKSPACE: clear entire filter | ||
| root.setFilter("") | ||
| } else if (root.filterText.length > 0) { |
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 6 out of 6 changed files in this pull request and generated 6 comments.
Comments suppressed due to low confidence (2)
shell/plugins/emojis/Emojis.qml:212
- The
} else if (event.key === Qt.Key_Left)line is mis-indented compared to the rest of thisif/else ifchain, which makes the control flow harder to read and looks like an accidental edit.
} else if (event.key === Qt.Key_Left) {
shell/plugins/reminders/ReminderFlow.qml:145
- This block’s indentation is inconsistent, and the Ctrl modifier check is overly strict (
=== Qt.ControlModifierwon’t match when other modifiers are present). Consider using a bitmask test and reindenting for readability.
if ((event.modifiers & Qt.ControlModifier) === Qt.ControlModifier) {
// CTRL+BACKSPACE: clear entire filter
root.setFilter("")
} else if (root.filterText.length > 0) {
// BACKSPACE: remove one character
root.setFilter(root.filterText.slice(0, -1))
}
| event.accepted = true | ||
| } else if (event.key === Qt.Key_Backspace) { | ||
| if (root.filterText.length > 0) root.setFilter(root.filterText.slice(0, -1)) | ||
| if ((event.modifiers & Qt.ControlModifier) === Qt.ControlModifier) { |
| } else if (event.key === Qt.Key_Backspace) { | ||
| if (root.filterText.length > 0) root.setFilter(root.filterText.slice(0, -1)) | ||
| else root.goBack() | ||
| if ((event.modifiers & Qt.ControlModifier) === Qt.ControlModifier) { |
| event.accepted = true | ||
| } else if (event.key === Qt.Key_Backspace) { | ||
| if (root.filterText.length > 0) root.setFilter(root.filterText.slice(0, -1)) | ||
| if ((event.modifiers & Qt.ControlModifier) === Qt.ControlModifier) { |
| } else if (event.key === Qt.Key_Backspace && root.filterable) { | ||
| if (root.filterText.length > 0) | ||
| } else if (event.key === Qt.Key_Backspace && root.filterable) { | ||
| if ((event.modifiers & Qt.ControlModifier) === Qt.ControlModifier) { |
| event.accepted = true | ||
| } else if (event.key === Qt.Key_Backspace) { | ||
| if (root.filterText.length > 0) root.setFilter(root.filterText.slice(0, -1)) | ||
| if ((event.modifiers & Qt.ControlModifier) === Qt.ControlModifier) { |
| } else if (event.key === Qt.Key_Backspace) { | ||
| if (root.filterText.length > 0) root.setFilter(root.filterText.slice(0, -1)) | ||
| if ((event.modifiers & Qt.ControlModifier) === Qt.ControlModifier) { | ||
| // CTRL+BACKSPACE: clear entire filter | ||
| root.setFilter("") | ||
| } else if (root.filterText.length > 0) { | ||
| // BACKSPACE: remove one character | ||
| root.setFilter(root.filterText.slice(0, -1)) | ||
| } |
|
Could we align this with Qt’s standard keyboard behavior? Qt defines Suggested behavior:
Please also fix the indentation inconsistencies introduced in |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 6 out of 6 changed files in this pull request and generated 5 comments.
Comments suppressed due to low confidence (1)
shell/plugins/menu/Menu.qml:853
- CTRL+BACKSPACE is described as “clear the entire filter”, but the current implementation removes only the previous word. Consider making CTRL+BACKSPACE clear the full filter, and keep the existing goBack() behavior when the filter is already empty (even when Ctrl is held).
} else if (event.key === Qt.Key_Backspace) {
if (event.modifiers & Qt.ControlModifier) {
// CTRL+BACKSPACE: remove the previous word
root.setFilter(root.filterText.replace(/\s+$/, "").replace(/\S+$/, ""))
} else if (root.filterText.length > 0) {
// BACKSPACE: remove the previous character
root.setFilter(root.filterText.slice(0, -1))
} else {
root.goBack()
}
| } else if (event.key === Qt.Key_Backspace) { | ||
| if (root.filterText.length > 0) root.setFilter(root.filterText.slice(0, -1)) | ||
| if (event.modifiers & Qt.ControlModifier) { | ||
| // CTRL+BACKSPACE: remove the previous word | ||
| root.setFilter(root.filterText.replace(/\s+$/, "").replace(/\S+$/, "")) | ||
| } else if (root.filterText.length > 0) { | ||
| // BACKSPACE: remove the previous character | ||
| root.setFilter(root.filterText.slice(0, -1)) | ||
| } |
| } else if (event.key === Qt.Key_Backspace) { | ||
| if (root.filterText.length > 0) root.setFilter(root.filterText.slice(0, -1)) | ||
| if (event.modifiers & Qt.ControlModifier) { | ||
| // CTRL+BACKSPACE: remove the previous word | ||
| root.setFilter(root.filterText.replace(/\s+$/, "").replace(/\S+$/, "")) | ||
| } else if (root.filterText.length > 0) { | ||
| // BACKSPACE: remove the previous character | ||
| root.setFilter(root.filterText.slice(0, -1)) | ||
| } |
| } else if (event.key === Qt.Key_Backspace && root.filterable) { | ||
| if (root.filterText.length > 0) | ||
| if (event.modifiers & Qt.ControlModifier) { | ||
| // CTRL+BACKSPACE: remove the previous word | ||
| root.updateFilter(root.filterText.replace(/\s+$/, "").replace(/\S+$/, "")) | ||
| } else if (root.filterText.length > 0) { | ||
| // BACKSPACE: remove the previous character | ||
| root.updateFilter(root.filterText.slice(0, -1)) | ||
| } |
| } else if (event.key === Qt.Key_Backspace) { | ||
| if (root.filterText.length > 0) root.setFilter(root.filterText.slice(0, -1)) | ||
| if (event.modifiers & Qt.ControlModifier) { | ||
| // CTRL+BACKSPACE: remove the previous word | ||
| root.setFilter(root.filterText.replace(/\s+$/, "").replace(/\S+$/, "")) | ||
| } else if (root.filterText.length > 0) { | ||
| // BACKSPACE: remove the previous character | ||
| root.setFilter(root.filterText.slice(0, -1)) | ||
| } |
| } else if (event.key === Qt.Key_Backspace) { | ||
| if (root.filterText.length > 0) root.setFilter(root.filterText.slice(0, -1)) | ||
| if (event.modifiers & Qt.ControlModifier) { | ||
| // CTRL+BACKSPACE: remove the previous word | ||
| root.setFilter(root.filterText.replace(/\s+$/, "").replace(/\S+$/, "")) | ||
| } else if (root.filterText.length > 0) { | ||
| // BACKSPACE: remove the previous character | ||
| root.setFilter(root.filterText.slice(0, -1)) | ||
| } |
qt-standard-filter-shortcuts.mp4A video preview |
|
Hey @dhh, I also noticed that the Wi-Fi networks aren't being imported. I've already written a migration script for that. Would you prefer that I include it in this PR, or should I submit it in a separate PR after this one is merged? |
|
Always keep PRs focused on a single issue. |
|
Lots of duplicated code in this PR. Find a way to abstract and extract. |
|
Good call — the Ctrl+U / Ctrl+Backspace / Backspace handling was copy-pasted across all six searchable panels (clipboard, emojis, image-picker, launcher, menu, reminders). I've extracted it. The shared logic now lives in two pure helpers on the Util singleton (shell/Commons/Util.qml) |
| function isFilterEditKey(event) { | ||
| return event.key === Qt.Key_Backspace | ||
| || (event.key === Qt.Key_U && (event.modifiers & Qt.ControlModifier)) | ||
| } |
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 7 out of 7 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (1)
shell/plugins/menu/Menu.qml:844
- Menu back-navigation on an empty filter now only triggers when
event.modifiers === Qt.NoModifier. Previously it triggered for any Backspace press when the filter was empty, soShift+Backspace(which is commonly equivalent to Backspace) will no longer step back a menu level.
} else if (event.key === Qt.Key_Backspace && event.modifiers === Qt.NoModifier && root.filterText.length === 0) {
// BACKSPACE on an empty filter steps back a menu level
root.goBack()
event.accepted = true
} else if (Util.isFilterEditKey(event)) {
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 7 out of 7 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (1)
shell/plugins/menu/Menu.qml:844
- Menu back-navigation on an empty filter now only triggers for an unmodified Backspace. Previously, Shift+Backspace on an empty filter would also reach the Backspace handler and call goBack(); with the new Util.isFilterEditKey branch, Shift+Backspace will be treated as a filter edit key and will no longer step back a menu level. This is a likely regression for users who keep Shift held while navigating/typing.
Consider allowing both NoModifier and ShiftModifier for the empty-filter goBack() case, while still keeping Ctrl+Backspace as a word-delete.
} else if (event.key === Qt.Key_Backspace && event.modifiers === Qt.NoModifier && root.filterText.length === 0) {
// BACKSPACE on an empty filter steps back a menu level
root.goBack()
event.accepted = true
} else if (Util.isFilterEditKey(event)) {
Backspace/Ctrl+U on an empty filter no longer calls setFilter(""),
which was resetting the list selection back to the top. This also lets
the menu's empty-filter Backspace fall through to goBack() with any
modifier held, as it did before the Util extraction.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* emoji panel: handle CTRL+BACKSPACE to clear filter
* shell: handle CTRL+BACKSPACE to clear filter in all search overlays
* Indentation fix for pull request finding
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* menu filters: align keyboard editing with Qt standard shortcuts
* menu filters: extract shared filter-editing helpers
* Potential fix for pull request finding
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* potential fix for pull request findings
* Only treat filter edit keys as edits when they change the text
Backspace/Ctrl+U on an empty filter no longer calls setFilter(""),
which was resetting the list selection back to the top. This also lets
the menu's empty-filter Backspace fall through to goBack() with any
modifier held, as it did before the Util extraction.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
---------
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: David Heinemeier Hansson <david@hey.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Align filter-field editing with Qt's standard keyboard shortcuts across all menu panels (clipboard, emojis, image-picker, launcher, menu, reminders):
Previously Ctrl+Backspace cleared the whole field, diverging from Qt on KDE/GNOME. Preserves per-panel behavior (menu goBack, image-picker filterable gating) and fixes an indentation regression in the emoji handler.