mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-10-22 03:04:01 -04:00
feat(tray): add IPC action to open tray menus (#2701)
* feat(tray): add IPC action to open tray menus * tray: open IPC-requested menus on the focused screen only --------- Co-authored-by: bbedward <[email protected]>
This commit is contained in:
@@ -1,25 +1,63 @@
|
||||
pragma Singleton
|
||||
|
||||
import Quickshell
|
||||
import Quickshell.Services.SystemTray
|
||||
import QtQuick
|
||||
|
||||
Singleton {
|
||||
id: root
|
||||
|
||||
property var activeTrayMenus: ({})
|
||||
property var _pendingMenuRequest: null
|
||||
|
||||
signal openTrayMenuRequested
|
||||
|
||||
function requestOpenMenu(itemId, screenName) {
|
||||
_pendingMenuRequest = {
|
||||
"itemId": itemId,
|
||||
"screenName": screenName
|
||||
};
|
||||
openTrayMenuRequested();
|
||||
}
|
||||
|
||||
// Every SystemTrayBar instance receives the signal; the claim ensures
|
||||
// exactly one opens the menu, preferring the requested screen
|
||||
function claimMenuRequest(instanceScreenName) {
|
||||
if (!_pendingMenuRequest)
|
||||
return null;
|
||||
if (_pendingMenuRequest.screenName && _pendingMenuRequest.screenName !== instanceScreenName)
|
||||
return null;
|
||||
const request = _pendingMenuRequest;
|
||||
_pendingMenuRequest = null;
|
||||
return request;
|
||||
}
|
||||
|
||||
function findTrayItem(itemId: string): var {
|
||||
if (!itemId)
|
||||
return null;
|
||||
|
||||
return SystemTray.items.values.find(item => {
|
||||
const id = item?.id || "";
|
||||
const title = item?.tooltipTitle || "";
|
||||
const fullKey = title ? `${id}::${title}` : id;
|
||||
return fullKey === itemId || id === itemId;
|
||||
});
|
||||
}
|
||||
|
||||
function registerMenu(screenName, menu) {
|
||||
if (!screenName || !menu) return
|
||||
const newMenus = Object.assign({}, activeTrayMenus)
|
||||
newMenus[screenName] = menu
|
||||
activeTrayMenus = newMenus
|
||||
if (!screenName || !menu)
|
||||
return;
|
||||
const newMenus = Object.assign({}, activeTrayMenus);
|
||||
newMenus[screenName] = menu;
|
||||
activeTrayMenus = newMenus;
|
||||
}
|
||||
|
||||
function unregisterMenu(screenName) {
|
||||
if (!screenName) return
|
||||
const newMenus = Object.assign({}, activeTrayMenus)
|
||||
delete newMenus[screenName]
|
||||
activeTrayMenus = newMenus
|
||||
if (!screenName)
|
||||
return;
|
||||
const newMenus = Object.assign({}, activeTrayMenus);
|
||||
delete newMenus[screenName];
|
||||
activeTrayMenus = newMenus;
|
||||
}
|
||||
|
||||
function closeHoverMenus() {
|
||||
@@ -36,12 +74,13 @@ Singleton {
|
||||
|
||||
function closeAllMenus() {
|
||||
for (const screenName in activeTrayMenus) {
|
||||
const menu = activeTrayMenus[screenName]
|
||||
if (!menu) continue
|
||||
const menu = activeTrayMenus[screenName];
|
||||
if (!menu)
|
||||
continue;
|
||||
if (typeof menu.close === "function") {
|
||||
menu.close()
|
||||
menu.close();
|
||||
} else if (menu.showMenu !== undefined) {
|
||||
menu.showMenu = false
|
||||
menu.showMenu = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+14
-14
@@ -2023,18 +2023,6 @@ Item {
|
||||
}
|
||||
|
||||
IpcHandler {
|
||||
function findTrayItem(itemId: string): var {
|
||||
if (!itemId)
|
||||
return null;
|
||||
|
||||
return SystemTray.items.values.find(item => {
|
||||
const id = item?.id || "";
|
||||
const title = item?.tooltipTitle || "";
|
||||
const fullKey = title ? `${id}::${title}` : id;
|
||||
return fullKey === itemId || id === itemId;
|
||||
});
|
||||
}
|
||||
|
||||
function list(): string {
|
||||
const items = SystemTray.items.values;
|
||||
if (items.length === 0)
|
||||
@@ -2050,7 +2038,7 @@ Item {
|
||||
}
|
||||
|
||||
function activate(itemId: string): string {
|
||||
const item = findTrayItem(itemId);
|
||||
const item = TrayMenuManager.findTrayItem(itemId);
|
||||
if (!item)
|
||||
return `ERROR: Tray item not found: ${itemId}`;
|
||||
|
||||
@@ -2058,8 +2046,20 @@ Item {
|
||||
return `SUCCESS: Activated ${itemId}`;
|
||||
}
|
||||
|
||||
function menu(itemId: string): string {
|
||||
const item = TrayMenuManager.findTrayItem(itemId);
|
||||
if (!item)
|
||||
return `ERROR: Tray item not found: ${itemId}`;
|
||||
|
||||
if (!item.hasMenu)
|
||||
return `ERROR: Tray item has no menu: ${itemId}`;
|
||||
|
||||
TrayMenuManager.requestOpenMenu(itemId, BarWidgetService.getFocusedScreenName());
|
||||
return `SUCCESS: Requested menu ${itemId}`;
|
||||
}
|
||||
|
||||
function status(itemId: string): string {
|
||||
const item = findTrayItem(itemId);
|
||||
const item = TrayMenuManager.findTrayItem(itemId);
|
||||
if (!item)
|
||||
return `ERROR: Tray item not found: ${itemId}`;
|
||||
|
||||
|
||||
@@ -83,6 +83,22 @@ BasePill {
|
||||
root.showForTrayItem(trayItem, anchorItem, parentScreen, root.isAtBottom, root.isVerticalOrientation, root.axis);
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: TrayMenuManager
|
||||
|
||||
function onOpenTrayMenuRequested() {
|
||||
const request = TrayMenuManager.claimMenuRequest(root.parentScreen?.name);
|
||||
if (!request)
|
||||
return;
|
||||
|
||||
const item = TrayMenuManager.findTrayItem(request.itemId);
|
||||
if (!item || !item.hasMenu)
|
||||
return;
|
||||
|
||||
root.showForTrayItem(item, root, parentScreen, root.isAtBottom, root.isVerticalOrientation, root.axis);
|
||||
}
|
||||
}
|
||||
|
||||
function openInlineTrayContextMenu(trayItem, areaItem, mouse, anchorItem) {
|
||||
if (!trayItem) {
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user