From e26c2874b53ddf68d7e97250b6cd147f4d2ab9b8 Mon Sep 17 00:00:00 2001 From: lysec Date: Sat, 25 Oct 2025 11:52:18 +0200 Subject: [PATCH] Launcher: add custom launch prefix --- Assets/Translations/de.json | 8 +++++ Assets/Translations/en.json | 8 +++++ Assets/Translations/es.json | 8 +++++ Assets/Translations/fr.json | 8 +++++ Assets/Translations/pt.json | 8 +++++ Assets/Translations/zh-CN.json | 10 ++++++- Assets/settings-default.json | 4 ++- Commons/Settings.qml | 2 ++ .../Launcher/Plugins/ApplicationsPlugin.qml | 21 ++++++++++++- Modules/Settings/Tabs/LauncherTab.qml | 30 ++++++++++++++++++- 10 files changed, 103 insertions(+), 4 deletions(-) diff --git a/Assets/Translations/de.json b/Assets/Translations/de.json index 9343f16c..0731099f 100644 --- a/Assets/Translations/de.json +++ b/Assets/Translations/de.json @@ -323,6 +323,14 @@ "terminal-command": { "label": "Terminalbefehl", "description": "Befehl zum Starten eines Terminals. Z.B. 'kitty -e' oder 'gnome-terminal --'." + }, + "custom-launch-prefix": { + "label": "Benutzerdefiniertes Start-Präfix", + "description": "Befehle mit einem benutzerdefinierten Launcher präfixieren (z.B. 'runapp' für systemd-Integration)." + }, + "custom-launch-prefix-enabled": { + "label": "Benutzerdefiniertes Start-Präfix aktivieren", + "description": "Verwenden Sie ein benutzerdefiniertes Präfix zum Starten von Anwendungen anstelle der Standardmethode." } } }, diff --git a/Assets/Translations/en.json b/Assets/Translations/en.json index 42b86d9d..8409738d 100644 --- a/Assets/Translations/en.json +++ b/Assets/Translations/en.json @@ -323,6 +323,14 @@ "terminal-command": { "label": "Terminal command", "description": "Command to launch a terminal. E.g., 'kitty -e' or 'gnome-terminal --'." + }, + "custom-launch-prefix": { + "label": "Custom launch prefix", + "description": "Prefix commands with a custom launcher (e.g., 'runapp' for systemd integration)." + }, + "custom-launch-prefix-enabled": { + "label": "Enable custom launch prefix", + "description": "Use a custom prefix for launching applications instead of the default method." } } }, diff --git a/Assets/Translations/es.json b/Assets/Translations/es.json index ea84a65b..59fd5722 100644 --- a/Assets/Translations/es.json +++ b/Assets/Translations/es.json @@ -323,6 +323,14 @@ "terminal-command": { "label": "Comando de terminal", "description": "Comando para iniciar un terminal. Por ejemplo, 'kitty -e' o 'gnome-terminal --'." + }, + "custom-launch-prefix": { + "label": "Prefijo de lanzamiento personalizado", + "description": "Prefijar comandos con un lanzador personalizado (ej. 'runapp' para integración con systemd)." + }, + "custom-launch-prefix-enabled": { + "label": "Habilitar prefijo de lanzamiento personalizado", + "description": "Usar un prefijo personalizado para lanzar aplicaciones en lugar del método predeterminado." } } }, diff --git a/Assets/Translations/fr.json b/Assets/Translations/fr.json index abbacdc0..0914fdf8 100644 --- a/Assets/Translations/fr.json +++ b/Assets/Translations/fr.json @@ -323,6 +323,14 @@ "terminal-command": { "label": "Commande du terminal", "description": "Commande pour lancer un terminal. Ex: 'kitty -e' ou 'gnome-terminal --'." + }, + "custom-launch-prefix": { + "label": "Préfixe de lancement personnalisé", + "description": "Préfixer les commandes avec un lanceur personnalisé (ex. 'runapp' pour l'intégration systemd)." + }, + "custom-launch-prefix-enabled": { + "label": "Activer le préfixe de lancement personnalisé", + "description": "Utiliser un préfixe personnalisé pour lancer les applications au lieu de la méthode par défaut." } } }, diff --git a/Assets/Translations/pt.json b/Assets/Translations/pt.json index 78885367..acfc7479 100644 --- a/Assets/Translations/pt.json +++ b/Assets/Translations/pt.json @@ -323,6 +323,14 @@ "terminal-command": { "label": "Comando do terminal", "description": "Comando para iniciar um terminal. Ex: 'kitty -e' ou 'gnome-terminal --'." + }, + "custom-launch-prefix": { + "label": "Prefixo de inicialização personalizado", + "description": "Prefixar comandos com um inicializador personalizado (ex. 'runapp' para integração systemd)." + }, + "custom-launch-prefix-enabled": { + "label": "Habilitar prefixo de inicialização personalizado", + "description": "Usar um prefixo personalizado para inicializar aplicativos em vez do método padrão." } } }, diff --git a/Assets/Translations/zh-CN.json b/Assets/Translations/zh-CN.json index 4c087b99..7133efb3 100644 --- a/Assets/Translations/zh-CN.json +++ b/Assets/Translations/zh-CN.json @@ -321,8 +321,16 @@ "description": "使用替代启动方法以更好地管理应用程序进程并防止问题。" }, "terminal-command": { - "description": "启动终端的命令。例如,“kitty -e”或“gnome-terminal --”。", + "description": "启动终端的命令。例如,"kitty -e"或"gnome-terminal --"。", "label": "终端命令" + }, + "custom-launch-prefix": { + "label": "自定义启动前缀", + "description": "使用自定义启动器前缀命令(例如,'runapp'用于systemd集成)。" + }, + "custom-launch-prefix-enabled": { + "label": "启用自定义启动前缀", + "description": "使用自定义前缀启动应用程序,而不是默认方法。" } } }, diff --git a/Assets/settings-default.json b/Assets/settings-default.json index 69787fe8..0582a0d3 100644 --- a/Assets/settings-default.json +++ b/Assets/settings-default.json @@ -111,7 +111,9 @@ "pinnedExecs": [], "useApp2Unit": false, "sortByMostUsed": true, - "terminalCommand": "xterm -e" + "terminalCommand": "xterm -e", + "customLaunchPrefixEnabled": false, + "customLaunchPrefix": "" }, "controlCenter": { "position": "close_to_bar_button", diff --git a/Commons/Settings.qml b/Commons/Settings.qml index 2268cec3..e84bf074 100644 --- a/Commons/Settings.qml +++ b/Commons/Settings.qml @@ -246,6 +246,8 @@ Singleton { property bool useApp2Unit: false property bool sortByMostUsed: true property string terminalCommand: "xterm -e" + property bool customLaunchPrefixEnabled: false + property string customLaunchPrefix: "" } // control center diff --git a/Modules/Launcher/Plugins/ApplicationsPlugin.qml b/Modules/Launcher/Plugins/ApplicationsPlugin.qml index 66ad3880..76113801 100644 --- a/Modules/Launcher/Plugins/ApplicationsPlugin.qml +++ b/Modules/Launcher/Plugins/ApplicationsPlugin.qml @@ -202,7 +202,26 @@ Item { // Record usage and persist asynchronously if (Settings.data.appLauncher.sortByMostUsed) recordUsage(app) - if (Settings.data.appLauncher.useApp2Unit && app.id) { + if (Settings.data.appLauncher.customLaunchPrefixEnabled && Settings.data.appLauncher.customLaunchPrefix) { + // Use custom launch prefix + const prefix = Settings.data.appLauncher.customLaunchPrefix.split(" ") + + if (app.runInTerminal) { + // For terminal apps, use the app command directly + const command = prefix.concat(app.command) + Quickshell.execDetached(command) + } else if (app.id) { + // For GUI apps, try to use the app name/executable name instead of desktop file + // This works better with commands like "niri msg action spawn --" + const appName = app.executableName || app.name.toLowerCase().replace(/\s+/g, '-') + const command = prefix.concat([appName]) + Quickshell.execDetached(command) + } else { + // Fallback to direct command execution + const command = prefix.concat(app.command) + Quickshell.execDetached(command) + } + } else if (Settings.data.appLauncher.useApp2Unit && app.id) { Logger.d("ApplicationsPlugin", `Using app2unit for: ${app.id}`) if (app.runInTerminal) Quickshell.execDetached(["app2unit", "--", app.id + ".desktop"]) diff --git a/Modules/Settings/Tabs/LauncherTab.qml b/Modules/Settings/Tabs/LauncherTab.qml index 88dfb6be..86cf97ee 100644 --- a/Modules/Settings/Tabs/LauncherTab.qml +++ b/Modules/Settings/Tabs/LauncherTab.qml @@ -96,11 +96,14 @@ ColumnLayout { label: I18n.tr("settings.launcher.settings.use-app2unit.label") description: I18n.tr("settings.launcher.settings.use-app2unit.description") checked: Settings.data.appLauncher.useApp2Unit && ProgramCheckerService.app2unitAvailable - enabled: ProgramCheckerService.app2unitAvailable + enabled: ProgramCheckerService.app2unitAvailable && !Settings.data.appLauncher.customLaunchPrefixEnabled opacity: ProgramCheckerService.app2unitAvailable ? 1.0 : 0.6 onToggled: checked => { if (ProgramCheckerService.app2unitAvailable) { Settings.data.appLauncher.useApp2Unit = checked + if (checked) { + Settings.data.appLauncher.customLaunchPrefixEnabled = false + } } } } @@ -115,6 +118,31 @@ ColumnLayout { } } + NToggle { + label: I18n.tr("settings.launcher.settings.custom-launch-prefix-enabled.label") + description: I18n.tr("settings.launcher.settings.custom-launch-prefix-enabled.description") + checked: Settings.data.appLauncher.customLaunchPrefixEnabled + enabled: !Settings.data.appLauncher.useApp2Unit + onToggled: checked => { + Settings.data.appLauncher.customLaunchPrefixEnabled = checked + if (checked) { + Settings.data.appLauncher.useApp2Unit = false + } + } + } + + NTextInput { + label: I18n.tr("settings.launcher.settings.custom-launch-prefix.label") + description: I18n.tr("settings.launcher.settings.custom-launch-prefix.description") + Layout.fillWidth: true + text: Settings.data.appLauncher.customLaunchPrefix + enabled: Settings.data.appLauncher.customLaunchPrefixEnabled + visible: Settings.data.appLauncher.customLaunchPrefixEnabled + onEditingFinished: { + Settings.data.appLauncher.customLaunchPrefix = text + } + } + NDivider { Layout.fillWidth: true Layout.topMargin: Style.marginXL