1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2026-06-16 16:15:23 -04:00

feat(Launcher/Spotlight): improve context keyboard navigation and mode persistence (#2467)

* feat(Spotlight): fix submenu keyboard navigation

* feat(Launcher/Spotlight): disable persisting last mode when changed by triggers

* feat(Launcher/Spotlight): add option to disable last mode being persisted

* fix(Launcher/Spotlight): fix context menu keys navigation

* fix(NiriOverviewOverlay): fix context menu keys navigation and position
This commit is contained in:
Lucas
2026-05-22 09:53:45 -03:00
committed by GitHub
parent ef5de19f6b
commit eea039f575
12 changed files with 120 additions and 48 deletions
+6
View File
@@ -1179,6 +1179,12 @@ Singleton {
saveSettings(); saveSettings();
} }
function getLauncherRestoreMode() {
if (!SettingsData.rememberLastMode)
return "all";
return launcherLastMode || "all";
}
function setLauncherLastFileSearchType(type) { function setLauncherLastFileSearchType(type) {
launcherLastFileSearchType = type; launcherLastFileSearchType = type;
saveSettings(); saveSettings();
+1
View File
@@ -435,6 +435,7 @@ Singleton {
property int appLauncherGridColumns: 4 property int appLauncherGridColumns: 4
property bool spotlightCloseNiriOverview: true property bool spotlightCloseNiriOverview: true
property bool rememberLastQuery: false property bool rememberLastQuery: false
property bool rememberLastMode: true
property var spotlightSectionViewModes: ({}) property var spotlightSectionViewModes: ({})
onSpotlightSectionViewModesChanged: saveSettings() onSpotlightSectionViewModesChanged: saveSettings()
property var appDrawerSectionViewModes: ({}) property var appDrawerSectionViewModes: ({})
@@ -203,6 +203,7 @@ var SPEC = {
appLauncherGridColumns: { def: 4 }, appLauncherGridColumns: { def: 4 },
spotlightCloseNiriOverview: { def: true }, spotlightCloseNiriOverview: { def: true },
rememberLastQuery: { def: false }, rememberLastQuery: { def: false },
rememberLastMode: { def: true },
spotlightSectionViewModes: { def: {} }, spotlightSectionViewModes: { def: {} },
appDrawerSectionViewModes: { def: {} }, appDrawerSectionViewModes: { def: {} },
niriOverviewOverlayEnabled: { def: true }, niriOverviewOverlayEnabled: { def: true },
@@ -39,7 +39,7 @@ Item {
signal itemExecuted signal itemExecuted
signal searchCompleted signal searchCompleted
signal modeChanged(string mode) signal modeChanged(string mode, bool userInitiated)
signal queryChanged(string query) signal queryChanged(string query)
signal viewModeChanged(string sectionId, string mode) signal viewModeChanged(string sectionId, string mode)
signal searchQueryRequested(string query) signal searchQueryRequested(string query)
@@ -440,7 +440,7 @@ Item {
} }
} }
function setMode(mode, isAutoSwitch, fileTypeOverride) { function setMode(mode, isAutoSwitch, fileTypeOverride, notPersist) {
if (searchMode === mode) { if (searchMode === mode) {
if (mode === "files" && fileTypeOverride !== undefined && fileSearchType !== fileTypeOverride) { if (mode === "files" && fileTypeOverride !== undefined && fileSearchType !== fileTypeOverride) {
fileSearchType = fileTypeOverride; fileSearchType = fileTypeOverride;
@@ -458,7 +458,7 @@ Item {
if (mode === "files") { if (mode === "files") {
fileSearchType = fileTypeOverride !== undefined ? fileTypeOverride : (SessionData.launcherLastFileSearchType || "all"); fileSearchType = fileTypeOverride !== undefined ? fileTypeOverride : (SessionData.launcherLastFileSearchType || "all");
} }
modeChanged(mode); modeChanged(mode, !isAutoSwitch && notPersist !== true);
performSearch(); performSearch();
var filesInAll = mode === "all" && (SettingsData.dankLauncherV2IncludeFilesInAll || SettingsData.dankLauncherV2IncludeFoldersInAll) && searchQuery.length > 0; var filesInAll = mode === "all" && (SettingsData.dankLauncherV2IncludeFilesInAll || SettingsData.dankLauncherV2IncludeFoldersInAll) && searchQuery.length > 0;
if (mode === "files" || filesInAll) { if (mode === "files" || filesInAll) {
@@ -471,7 +471,7 @@ Item {
return; return;
autoSwitchedToFiles = false; autoSwitchedToFiles = false;
searchMode = previousSearchMode; searchMode = previousSearchMode;
modeChanged(previousSearchMode); modeChanged(previousSearchMode, false);
performSearch(); performSearch();
} }
@@ -1897,7 +1897,7 @@ Item {
if (browseTrigger && browseTrigger.length > 0) { if (browseTrigger && browseTrigger.length > 0) {
searchQueryRequested(browseTrigger); searchQueryRequested(browseTrigger);
} else { } else {
setMode("plugins"); setMode("plugins", false, undefined, true);
pluginFilter = browsePluginId; pluginFilter = browsePluginId;
performSearch(); performSearch();
} }
@@ -396,7 +396,7 @@ Item {
spotlightContent.searchField.text = query; spotlightContent.searchField.text = query;
} }
if (spotlightContent.controller) { if (spotlightContent.controller) {
var targetMode = mode || SessionData.launcherLastMode || "all"; var targetMode = mode || SessionData.getLauncherRestoreMode();
spotlightContent.controller.searchMode = targetMode; spotlightContent.controller.searchMode = targetMode;
spotlightContent.controller.activePluginId = ""; spotlightContent.controller.activePluginId = "";
spotlightContent.controller.activePluginName = ""; spotlightContent.controller.activePluginName = "";
@@ -539,8 +539,8 @@ Item {
Connections { Connections {
target: spotlightContent?.controller ?? null target: spotlightContent?.controller ?? null
function onModeChanged(mode) { function onModeChanged(mode, userInitiated) {
if (spotlightContent.controller.autoSwitchedToFiles) if (!userInitiated || !SettingsData.rememberLastMode)
return; return;
SessionData.setLauncherLastMode(mode); SessionData.setLauncherLastMode(mode);
} }
@@ -928,7 +928,11 @@ Item {
} }
} }
Keys.onPressed: event => root.spotlightContent?.activeContextMenu?.handleKey(event)
Keys.onEscapePressed: event => { Keys.onEscapePressed: event => {
root.spotlightContent?.activeContextMenu?.handleKey(event);
if (!event.accepted)
root.hide(); root.hide();
event.accepted = true; event.accepted = true;
} }
@@ -145,7 +145,7 @@ Item {
spotlightContent.closeTransientUi?.(); spotlightContent.closeTransientUi?.();
const targetQuery = query || (SettingsData.rememberLastQuery ? (SessionData.launcherLastQuery || "") : ""); const targetQuery = query || (SettingsData.rememberLastQuery ? (SessionData.launcherLastQuery || "") : "");
const targetMode = mode || SessionData.launcherLastMode || "all"; const targetMode = mode || SessionData.getLauncherRestoreMode();
if (spotlightContent.searchField) { if (spotlightContent.searchField) {
spotlightContent.searchField.text = targetQuery; spotlightContent.searchField.text = targetQuery;
@@ -489,7 +489,11 @@ Item {
} }
} }
Keys.onPressed: event => root.spotlightContent?.activeContextMenu?.handleKey(event)
Keys.onEscapePressed: event => { Keys.onEscapePressed: event => {
root.spotlightContent?.activeContextMenu?.handleKey(event);
if (!event.accepted)
root.hide(); root.hide();
event.accepted = true; event.accepted = true;
} }
@@ -148,7 +148,7 @@ Item {
spotlightContent.searchField.text = targetQuery; spotlightContent.searchField.text = targetQuery;
} }
if (spotlightContent.controller) { if (spotlightContent.controller) {
var targetMode = mode || SessionData.launcherLastMode || "all"; var targetMode = mode || SessionData.getLauncherRestoreMode();
spotlightContent.controller.searchMode = targetMode; spotlightContent.controller.searchMode = targetMode;
spotlightContent.controller.activePluginId = ""; spotlightContent.controller.activePluginId = "";
spotlightContent.controller.activePluginName = ""; spotlightContent.controller.activePluginName = "";
@@ -260,8 +260,8 @@ Item {
Connections { Connections {
target: spotlightContent?.controller ?? null target: spotlightContent?.controller ?? null
function onModeChanged(mode) { function onModeChanged(mode, userInitiated) {
if (spotlightContent.controller.autoSwitchedToFiles) if (!userInitiated || !SettingsData.rememberLastMode || (mode !== "all" && mode !== "apps"))
return; return;
SessionData.setLauncherLastMode(mode); SessionData.setLauncherLastMode(mode);
} }
@@ -536,7 +536,11 @@ Item {
} }
} }
Keys.onPressed: event => root.spotlightContent?.activeContextMenu?.handleKey(event)
Keys.onEscapePressed: event => { Keys.onEscapePressed: event => {
root.spotlightContent?.activeContextMenu?.handleKey(event);
if (!event.accepted)
root.hide(); root.hide();
event.accepted = true; event.accepted = true;
} }
@@ -17,6 +17,7 @@ FocusScope {
property alias controller: controller property alias controller: controller
property alias resultsList: resultsList property alias resultsList: resultsList
property alias actionPanel: actionPanel property alias actionPanel: actionPanel
readonly property alias activeContextMenu: contextMenu
property bool editMode: false property bool editMode: false
property var editingApp: null property var editingApp: null
@@ -340,6 +340,31 @@ Item {
return count; return count;
} }
function handleKey(event) {
if (!openState)
return;
switch (event.key) {
case Qt.Key_Down:
selectNext();
event.accepted = true;
return;
case Qt.Key_Up:
selectPrevious();
event.accepted = true;
return;
case Qt.Key_Return:
case Qt.Key_Enter:
activateSelected();
event.accepted = true;
return;
case Qt.Key_Left:
case Qt.Key_Escape:
hide();
event.accepted = true;
return;
}
}
function selectNext() { function selectNext() {
if (visibleItemCount > 0) { if (visibleItemCount > 0) {
keyboardNavigation = true; keyboardNavigation = true;
@@ -12,6 +12,7 @@ FocusScope {
property var parentModal: null property var parentModal: null
property alias searchField: searchInput property alias searchField: searchInput
property alias controller: searchController property alias controller: searchController
readonly property alias activeContextMenu: contextMenu
readonly property bool _hasQuery: searchInput.text.length > 0 readonly property bool _hasQuery: searchInput.text.length > 0
readonly property real _searchBarH: 56 readonly property real _searchBarH: 56
@@ -239,8 +240,8 @@ FocusScope {
Connections { Connections {
target: searchController target: searchController
function onModeChanged(mode) { function onModeChanged(mode, userInitiated) {
if (searchController.autoSwitchedToFiles) if (!userInitiated || !SettingsData.rememberLastMode)
return; return;
SessionData.setLauncherLastMode(mode); SessionData.setLauncherLastMode(mode);
} }
@@ -1121,6 +1121,15 @@ Item {
onToggled: checked => SessionData.setSearchAppActions(checked) onToggled: checked => SessionData.setSearchAppActions(checked)
} }
SettingsToggleRow {
settingKey: "rememberLastMode"
tags: ["launcher", "remember", "last", "mode", "tab"]
text: I18n.tr("Remember Last Mode")
description: I18n.tr("Restore the last selected mode (tab) when the launcher is opened")
checked: SettingsData.rememberLastMode
onToggled: checked => SettingsData.set("rememberLastMode", checked)
}
SettingsToggleRow { SettingsToggleRow {
settingKey: "rememberLastQuery" settingKey: "rememberLastQuery"
tags: ["launcher", "remember", "last", "search", "query"] tags: ["launcher", "remember", "last", "search", "query"]
@@ -338,6 +338,19 @@ Scope {
border.width: 1 border.width: 1
} }
FocusScope {
anchors.fill: parent
focus: true
Keys.onPressed: event => launcherContent.activeContextMenu?.handleKey(event)
Keys.onEscapePressed: event => {
launcherContent.activeContextMenu?.handleKey(event);
if (!event.accepted)
launcherContent.parentModal?.hide();
event.accepted = true;
}
LauncherContent { LauncherContent {
id: launcherContent id: launcherContent
anchors.fill: parent anchors.fill: parent
@@ -346,6 +359,8 @@ Scope {
property var fakeParentModal: QtObject { property var fakeParentModal: QtObject {
property bool spotlightOpen: spotlightContainer.visible property bool spotlightOpen: spotlightContainer.visible
property bool isClosing: niriOverviewScope.isClosing property bool isClosing: niriOverviewScope.isClosing
property real alignedX: spotlightContainer.x
property real alignedY: spotlightContainer.y
function hide() { function hide() {
if (niriOverviewScope.searchActive) { if (niriOverviewScope.searchActive) {
niriOverviewScope.hideSpotlight(); niriOverviewScope.hideSpotlight();
@@ -384,4 +399,5 @@ Scope {
} }
} }
} }
}
} }