Applauncher Fixes

use execute() instead of a Process
Fix small issue with app order
This commit is contained in:
ly-sec 2025-07-12 17:58:32 +02:00
parent c50e148690
commit d828e3d323

View file

@ -75,10 +75,7 @@ PanelWindow {
} }
function updateFilter() { function updateFilter() {
var query = searchField.text ? searchField.text.toLowerCase() : ""; var query = searchField.text ? searchField.text.toLowerCase() : "";
// Sort apps alphabetically by name (case-insensitive) var apps = root.appModel.slice();
var apps = root.appModel.slice().sort(function(a, b) {
return a.name.toLowerCase().localeCompare(b.name.toLowerCase());
});
var results = []; var results = [];
// Calculator mode: starts with '=' // Calculator mode: starts with '='
if (query.startsWith("=")) { if (query.startsWith("=")) {
@ -96,16 +93,13 @@ PanelWindow {
} }
} }
} }
// Normal app search
if (!query || query.startsWith("=")) { if (!query || query.startsWith("=")) {
results = results.concat(apps); results = results.concat(apps.sort(function(a, b) {
return a.name.toLowerCase().localeCompare(b.name.toLowerCase());
}));
} else { } else {
var fuzzyResults = Fuzzysort.go(query, apps, { keys: ["name", "comment", "genericName"] }); var fuzzyResults = Fuzzysort.go(query, apps, { keys: ["name", "comment", "genericName"] });
// Sort fuzzy results alphabetically by name as well results = results.concat(fuzzyResults.map(function(r) { return r.obj; }));
var sortedFuzzy = fuzzyResults.map(function(r) { return r.obj; }).sort(function(a, b) {
return a.name.toLowerCase().localeCompare(b.name.toLowerCase());
});
results = results.concat(sortedFuzzy);
} }
root.filteredApps = results; root.filteredApps = results;
root.selectedIndex = 0; root.selectedIndex = 0;
@ -118,10 +112,13 @@ PanelWindow {
if (filteredApps.length > 0) if (filteredApps.length > 0)
selectedIndex = Math.max(selectedIndex - 1, 0); selectedIndex = Math.max(selectedIndex - 1, 0);
} }
function activateSelected() { function activateSelected() {
if (filteredApps.length === 0) if (filteredApps.length === 0)
return; return;
var modelData = filteredApps[selectedIndex]; var modelData = filteredApps[selectedIndex];
if (modelData.isCalculator) { if (modelData.isCalculator) {
Qt.callLater(function() { Qt.callLater(function() {
Quickshell.clipboardText = String(modelData.result); Quickshell.clipboardText = String(modelData.result);
@ -131,18 +128,22 @@ PanelWindow {
`${modelData.expr} = ${modelData.result} (copied to clipboard)` `${modelData.expr} = ${modelData.result} (copied to clipboard)`
]); ]);
}); });
} else if (modelData.execString) { } else if (modelData.execute) {
Quickshell.execDetached(["sh", "-c", modelData.execString]); modelData.execute();
} else if (modelData.exec) {
Quickshell.execDetached(["sh", "-c", modelData.exec]);
} else { } else {
if (!modelData.isCalculator) var execCmd = modelData.execString || modelData.exec || "";
console.warn("Cannot launch app:", modelData.name, "missing execString or exec", modelData); if (execCmd) {
execCmd = execCmd.replace(/\s?%[fFuUdDnNiCkvm]/g, '');
Quickshell.execDetached(["sh", "-c", execCmd.trim()]);
}
} }
appLauncherPanel.hidePanel(); appLauncherPanel.hidePanel();
searchField.text = ""; searchField.text = "";
} }
Component.onCompleted: updateFilter() Component.onCompleted: updateFilter()
ColumnLayout { ColumnLayout {
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
@ -157,6 +158,7 @@ PanelWindow {
color: Theme.outline color: Theme.outline
opacity: 0.10 opacity: 0.10
} }
// Search Bar // Search Bar
Rectangle { Rectangle {
id: searchBar id: searchBar
@ -215,18 +217,17 @@ PanelWindow {
Behavior on border.color { ColorAnimation { duration: 120 } } Behavior on border.color { ColorAnimation { duration: 120 } }
Behavior on border.width { NumberAnimation { duration: 120 } } Behavior on border.width { NumberAnimation { duration: 120 } }
} }
// App List Card // App List Card
Rectangle { Rectangle {
color: Theme.surface color: Theme.surface
radius: 20 radius: 20
//border.color: Theme.outline
//border.width: 1
Layout.fillWidth: true Layout.fillWidth: true
Layout.fillHeight: true Layout.fillHeight: true
clip: true clip: true
anchors.margins: 0 anchors.margins: 0
property int innerPadding: 16 property int innerPadding: 16
// Add an Item for padding
Item { Item {
anchors.top: parent.top anchors.top: parent.top
anchors.left: parent.left anchors.left: parent.left
@ -234,6 +235,7 @@ PanelWindow {
height: parent.innerPadding height: parent.innerPadding
visible: false visible: false
} }
ListView { ListView {
id: appList id: appList
anchors.fill: parent anchors.fill: parent
@ -247,6 +249,7 @@ PanelWindow {
height: 48 height: 48
property bool hovered: mouseArea.containsMouse property bool hovered: mouseArea.containsMouse
property bool isSelected: index === root.selectedIndex property bool isSelected: index === root.selectedIndex
Rectangle { Rectangle {
anchors.fill: parent anchors.fill: parent
color: hovered || isSelected ? Theme.accentPrimary : "transparent" color: hovered || isSelected ? Theme.accentPrimary : "transparent"
@ -257,6 +260,7 @@ PanelWindow {
Behavior on border.color { ColorAnimation { duration: 120 } } Behavior on border.color { ColorAnimation { duration: 120 } }
Behavior on border.width { NumberAnimation { duration: 120 } } Behavior on border.width { NumberAnimation { duration: 120 } }
} }
RowLayout { RowLayout {
anchors.fill: parent anchors.fill: parent
anchors.leftMargin: 10 anchors.leftMargin: 10
@ -284,6 +288,7 @@ PanelWindow {
color: Theme.accentPrimary color: Theme.accentPrimary
} }
} }
ColumnLayout { ColumnLayout {
Layout.fillWidth: true Layout.fillWidth: true
spacing: 1 spacing: 1
@ -306,6 +311,7 @@ PanelWindow {
Layout.fillWidth: true Layout.fillWidth: true
} }
} }
Item { Layout.fillWidth: true } Item { Layout.fillWidth: true }
Text { Text {
text: modelData.isCalculator ? "content_copy" : "chevron_right" text: modelData.isCalculator ? "content_copy" : "chevron_right"
@ -315,12 +321,14 @@ PanelWindow {
verticalAlignment: Text.AlignVCenter verticalAlignment: Text.AlignVCenter
} }
} }
Rectangle { Rectangle {
id: ripple id: ripple
anchors.fill: parent anchors.fill: parent
color: Theme.onAccent color: Theme.onAccent
opacity: 0.0 opacity: 0.0
} }
MouseArea { MouseArea {
id: mouseArea id: mouseArea
anchors.fill: parent anchors.fill: parent
@ -328,12 +336,13 @@ PanelWindow {
onClicked: { onClicked: {
ripple.opacity = 0.18 ripple.opacity = 0.18
rippleNumberAnimation.start() rippleNumberAnimation.start()
root.selectedIndex = index // update selection on click root.selectedIndex = index
root.activateSelected() root.activateSelected()
} }
onPressed: ripple.opacity = 0.18 onPressed: ripple.opacity = 0.18
onReleased: ripple.opacity = 0.0 onReleased: ripple.opacity = 0.0
} }
NumberAnimation { NumberAnimation {
id: rippleNumberAnimation id: rippleNumberAnimation
target: ripple target: ripple
@ -341,7 +350,7 @@ PanelWindow {
to: 0.0 to: 0.0
duration: 320 duration: 320
} }
// Divider (except last item)
Rectangle { Rectangle {
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right