launcher: added sessionProvider for quick lock/shutdown, etc.. Fix #1592

This commit is contained in:
Lemmy
2026-01-27 14:44:14 -05:00
parent e366b04e55
commit 7dcfa6b246
4 changed files with 195 additions and 2 deletions
+8
View File
@@ -755,6 +755,14 @@ SmartPanel {
}
}
SessionProvider {
id: sessionProvider
Component.onCompleted: {
registerProvider(this);
Logger.d("Launcher", "Registered: SessionProvider");
}
}
// ---------------------------------------------------
panelContent: Rectangle {
id: ui
@@ -544,7 +544,7 @@ Item {
"description": app.genericName || app.comment || "",
"icon": app.icon || "application-x-executable",
"isImage": false,
"_score": (score !== undefined ? score : 0) + 1,
"_score": (score !== undefined ? score : 0),
"provider": root,
"onActivate": function () {
// Close the launcher/SmartPanel immediately without any animations.
@@ -0,0 +1,185 @@
import QtQuick
import Quickshell
import qs.Commons
import qs.Services.Compositor
import qs.Services.UI
Item {
id: root
// Provider metadata
property string name: I18n.tr("tooltips.session-menu")
property var launcher: null
property bool handleSearch: true
property string supportedLayouts: "list"
// Session actions with search keywords
readonly property var sessionActions: [
{
"action": "lock",
"labelKey": "common.lock",
"icon": "lock",
"keywords": ["lock", "screen", "secure"]
},
{
"action": "suspend",
"labelKey": "common.suspend",
"icon": "suspend",
"keywords": ["suspend", "sleep", "standby"]
},
{
"action": "hibernate",
"labelKey": "common.hibernate",
"icon": "hibernate",
"keywords": ["hibernate", "disk"]
},
{
"action": "reboot",
"labelKey": "common.reboot",
"icon": "reboot",
"keywords": ["reboot", "restart", "reload"]
},
{
"action": "logout",
"labelKey": "common.logout",
"icon": "logout",
"keywords": ["logout", "sign out", "exit", "leave"]
},
{
"action": "shutdown",
"labelKey": "common.shutdown",
"icon": "shutdown",
"keywords": ["shutdown", "power off", "turn off", "poweroff"]
}
]
function init() {
Logger.d("SessionProvider", "Initialized");
}
function getEnabledActions() {
var powerOptions = Settings.data.sessionMenu.powerOptions || [];
var enabledSet = {};
for (var i = 0; i < powerOptions.length; i++) {
if (powerOptions[i].enabled) {
enabledSet[powerOptions[i].action] = powerOptions[i];
}
}
var enabled = [];
for (var j = 0; j < sessionActions.length; j++) {
var action = sessionActions[j];
if (enabledSet[action.action]) {
enabled.push({
"action": action.action,
"labelKey": action.labelKey,
"icon": action.icon,
"keywords": action.keywords,
"command": enabledSet[action.action].command || ""
});
}
}
return enabled;
}
function getResults(query) {
if (!query)
return [];
var trimmed = query.trim();
if (!trimmed || trimmed.length < 2)
return [];
var enabledActions = getEnabledActions();
if (enabledActions.length === 0)
return [];
// Build searchable items with resolved translations
var items = [];
for (var i = 0; i < enabledActions.length; i++) {
var action = enabledActions[i];
var label = I18n.tr(action.labelKey);
items.push({
"action": action.action,
"icon": action.icon,
"label": label,
"command": action.command,
"searchText": [label.toLowerCase()].concat(action.keywords).join(" ")
});
}
var results = FuzzySort.go(trimmed, items, {
"keys": ["label", "searchText"],
"limit": 6
});
var launcherItems = [];
for (var j = 0; j < results.length; j++) {
var entry = results[j].obj;
var score = results[j].score;
launcherItems.push({
"name": entry.label,
"description": I18n.tr("tooltips.session-menu"),
"icon": entry.icon,
"isTablerIcon": true,
"isImage": false,
"_score": score - 1,
"provider": root,
"onActivate": createActivateHandler(entry.action, entry.command)
});
}
return launcherItems;
}
function createActivateHandler(action, command) {
return function () {
if (launcher)
launcher.close();
Qt.callLater(() => {
executeAction(action, command);
});
};
}
function executeAction(action, command) {
// If custom command is defined, execute it
if (command && command.trim() !== "") {
Logger.i("SessionProvider", "Executing custom command for action:", action, "Command:", command);
Quickshell.execDetached(["sh", "-lc", command]);
return;
}
// Otherwise, use default behavior
switch (action) {
case "lock":
if (PanelService.lockScreen && !PanelService.lockScreen.active) {
PanelService.lockScreen.active = true;
}
break;
case "suspend":
if (Settings.data.general.lockOnSuspend) {
CompositorService.lockAndSuspend();
} else {
CompositorService.suspend();
}
break;
case "hibernate":
CompositorService.hibernate();
break;
case "reboot":
CompositorService.reboot();
break;
case "logout":
CompositorService.logout();
break;
case "shutdown":
CompositorService.shutdown();
break;
}
}
}
@@ -85,7 +85,7 @@ Item {
"icon": "settings",
"isTablerIcon": true,
"isImage": false,
"_score": score,
"_score": score - 2,
"provider": root,
"onActivate": createActivateHandler(entry)
});