feat(Application Launcher): add option to ignore initial mouse position

This commit is contained in:
DuckySoLucky
2025-10-10 20:07:28 +02:00
parent 72b2b9e917
commit f0c44734bc
5 changed files with 66 additions and 5 deletions
+4
View File
@@ -354,6 +354,10 @@
"label": "Use App2Unit to launch applications", "label": "Use App2Unit to launch applications",
"description": "Uses an alternative launch method to better manage app processes and prevent issues." "description": "Uses an alternative launch method to better manage app processes and prevent issues."
}, },
"ignore-initial-mouse": {
"label": "Ignore initial mouse position",
"description": "When enabled, the launcher always defaults to the first item, ignoring where your mouse cursor is positioned. Selection only changes when you move the mouse."
},
"terminal-command": { "terminal-command": {
"label": "Terminal command", "label": "Terminal command",
"description": "Command to launch a terminal. E.g., 'kitty -e' or 'gnome-terminal --'." "description": "Command to launch a terminal. E.g., 'kitty -e' or 'gnome-terminal --'."
+3 -2
View File
@@ -1,5 +1,5 @@
{ {
"settingsVersion": 15, "settingsVersion": 16,
"bar": { "bar": {
"position": "top", "position": "top",
"backgroundOpacity": 1, "backgroundOpacity": 1,
@@ -104,7 +104,8 @@
"pinnedExecs": [], "pinnedExecs": [],
"useApp2Unit": false, "useApp2Unit": false,
"sortByMostUsed": true, "sortByMostUsed": true,
"terminalCommand": "xterm -e" "terminalCommand": "xterm -e",
"ignoreInitialMousePosition": false
}, },
"controlCenter": { "controlCenter": {
"position": "close_to_bar_button", "position": "close_to_bar_button",
+2 -1
View File
@@ -125,7 +125,7 @@ Singleton {
JsonAdapter { JsonAdapter {
id: adapter id: adapter
property int settingsVersion: 15 property int settingsVersion: 16
// bar // bar
property JsonObject bar: JsonObject { property JsonObject bar: JsonObject {
@@ -233,6 +233,7 @@ Singleton {
property bool useApp2Unit: false property bool useApp2Unit: false
property bool sortByMostUsed: true property bool sortByMostUsed: true
property string terminalCommand: "xterm -e" property string terminalCommand: "xterm -e"
property bool ignoreInitialMousePosition: true
} }
// control center // control center
+50 -2
View File
@@ -35,6 +35,7 @@ NPanel {
property var plugins: [] property var plugins: []
property var activePlugin: null property var activePlugin: null
property bool resultsReady: false property bool resultsReady: false
property bool ignoreMouseHover: false
readonly property int badgeSize: Math.round(Style.baseWidgetSize * 1.6 * scaling) readonly property int badgeSize: Math.round(Style.baseWidgetSize * 1.6 * scaling)
readonly property int entryHeight: Math.round(badgeSize + Style.marginM * 2 * scaling) readonly property int entryHeight: Math.round(badgeSize + Style.marginM * 2 * scaling)
@@ -94,6 +95,7 @@ NPanel {
// Lifecycle // Lifecycle
onOpened: { onOpened: {
resultsReady = false resultsReady = false
ignoreMouseHover = Settings.data.appLauncher.ignoreInitialMousePosition // Use setting value
// Notify plugins // Notify plugins
for (let plugin of plugins) { for (let plugin of plugins) {
@@ -110,6 +112,7 @@ NPanel {
onClosed: { onClosed: {
// Reset search text // Reset search text
searchText = "" searchText = ""
ignoreMouseHover = Settings.data.appLauncher.ignoreInitialMousePosition // Use setting value
// Notify plugins // Notify plugins
for (let plugin of plugins) { for (let plugin of plugins) {
@@ -154,6 +157,49 @@ NPanel {
color: Color.transparent color: Color.transparent
opacity: resultsReady ? 1.0 : 0.0 opacity: resultsReady ? 1.0 : 0.0
// Global MouseArea to detect mouse movement
MouseArea {
id: mouseMovementDetector
anchors.fill: parent
z: -999
hoverEnabled: true
propagateComposedEvents: true
acceptedButtons: Qt.NoButton
property real lastX: 0
property real lastY: 0
property bool initialized: false
onPositionChanged: mouse => {
// Store initial position
if (!initialized) {
lastX = mouse.x
lastY = mouse.y
initialized = true
return
}
// Check if mouse actually moved
const deltaX = Math.abs(mouse.x - lastX)
const deltaY = Math.abs(mouse.y - lastY)
if (deltaX > 1 || deltaY > 1) {
root.ignoreMouseHover = false
lastX = mouse.x
lastY = mouse.y
}
}
// Reset when launcher opens
Connections {
target: root
function onOpenedChanged() {
if (root.opened) {
mouseMovementDetector.initialized = false
}
}
}
}
Behavior on opacity { Behavior on opacity {
NumberAnimation { NumberAnimation {
duration: Style.animationFast duration: Style.animationFast
@@ -321,7 +367,7 @@ NPanel {
delegate: Rectangle { delegate: Rectangle {
id: entry id: entry
property bool isSelected: mouseArea.containsMouse || (index === selectedIndex) property bool isSelected: (!root.ignoreMouseHover && mouseArea.containsMouse) || (index === selectedIndex)
// Accessor for app id // Accessor for app id
property string appId: (modelData && modelData.appId) ? String(modelData.appId) : "" property string appId: (modelData && modelData.appId) ? String(modelData.appId) : ""
@@ -523,7 +569,9 @@ NPanel {
hoverEnabled: true hoverEnabled: true
cursorShape: Qt.PointingHandCursor cursorShape: Qt.PointingHandCursor
onEntered: { onEntered: {
selectedIndex = index if (!root.ignoreMouseHover) {
selectedIndex = index
}
} }
onClicked: mouse => { onClicked: mouse => {
if (mouse.button === Qt.LeftButton) { if (mouse.button === Qt.LeftButton) {
+7
View File
@@ -99,6 +99,13 @@ ColumnLayout {
onToggled: checked => Settings.data.appLauncher.useApp2Unit = checked onToggled: checked => Settings.data.appLauncher.useApp2Unit = checked
} }
NToggle {
label: I18n.tr("settings.launcher.settings.ignore-initial-mouse.label")
description: I18n.tr("settings.launcher.settings.ignore-initial-mouse.description")
checked: Settings.data.appLauncher.ignoreInitialMousePosition
onToggled: checked => Settings.data.appLauncher.ignoreInitialMousePosition = checked
}
NTextInput { NTextInput {
label: I18n.tr("settings.launcher.settings.terminal-command.label") label: I18n.tr("settings.launcher.settings.terminal-command.label")
description: I18n.tr("settings.launcher.settings.terminal-command.description") description: I18n.tr("settings.launcher.settings.terminal-command.description")