1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2026-01-28 07:22:50 -05:00

systemtray: fix UI thread freeze when opening menu on Hyprland

- Similar pattern as fix from Noctalia
This commit is contained in:
bbedward
2025-11-15 17:57:23 -05:00
parent d11868b99f
commit 4cb652abd9

View File

@@ -645,11 +645,43 @@ Item {
property bool showMenu: false property bool showMenu: false
property var menuHandle: null property var menuHandle: null
property bool shouldLoadMenu: false
property var menuItems: []
ListModel { id: entryStack } ListModel { id: entryStack }
function topEntry() { function topEntry() {
return entryStack.count ? entryStack.get(entryStack.count - 1).handle : null return entryStack.count ? entryStack.get(entryStack.count - 1).handle : null
} }
onShouldLoadMenuChanged: {
if (shouldLoadMenu) {
loadMenuItemsSafely()
}
}
function loadMenuItemsSafely() {
menuLoadTimer.start()
}
Timer {
id: menuLoadTimer
interval: 50
repeat: false
onTriggered: {
try {
const currentOpener = entryStack.count ? subOpener : rootOpener
if (currentOpener && currentOpener.children && currentOpener.children.values) {
const values = currentOpener.children.values
if (values && values.length > 0) {
menuRoot.menuItems = [...values]
}
}
} catch (e) {
console.warn("Failed to load menu items:", e)
}
}
}
function showForTrayItem(item, anchor, screen, atBottom, vertical, axisObj) { function showForTrayItem(item, anchor, screen, atBottom, vertical, axisObj) {
trayItem = item trayItem = item
anchorItem = anchor anchorItem = anchor
@@ -657,7 +689,12 @@ Item {
isAtBottom = atBottom isAtBottom = atBottom
isVertical = vertical isVertical = vertical
axis = axisObj axis = axisObj
menuHandle = item?.menu
if (item && item.menu) {
menuHandle = item.menu
}
menuItems = []
if (parentScreen) { if (parentScreen) {
for (var i = 0; i < Quickshell.screens.length; i++) { for (var i = 0; i < Quickshell.screens.length; i++) {
@@ -669,6 +706,7 @@ Item {
} }
} }
shouldLoadMenu = true
showMenu = true showMenu = true
} }
@@ -690,17 +728,17 @@ Item {
entryStack.append({ handle: entry }); entryStack.append({ handle: entry });
const h = entry.menu || entry; menuItems = []
if (h && typeof h.updateLayout === "function") h.updateLayout();
submenuHydrator.menu = h; shouldLoadMenu = true
submenuHydrator.open();
Qt.callLater(() => submenuHydrator.close());
} }
function goBack() { function goBack() {
if (!entryStack.count) return; if (!entryStack.count) return;
entryStack.remove(entryStack.count - 1); entryStack.remove(entryStack.count - 1);
menuItems = []
Qt.callLater(() => loadMenuItemsSafely())
} }
width: 0 width: 0
@@ -879,14 +917,16 @@ Item {
} }
} }
QsMenuAnchor {
id: submenuHydrator
anchor.window: menuWindow
}
QsMenuOpener { QsMenuOpener {
id: rootOpener id: rootOpener
menu: menuRoot.menuHandle menu: menuRoot.menuHandle
onMenuChanged: {
if (menuRoot.shouldLoadMenu && !entryStack.count) {
menuRoot.menuItems = []
Qt.callLater(() => menuRoot.loadMenuItemsSafely())
}
}
} }
QsMenuOpener { QsMenuOpener {
@@ -895,6 +935,13 @@ Item {
const e = menuRoot.topEntry(); const e = menuRoot.topEntry();
return e ? (e.menu || e) : null; return e ? (e.menu || e) : null;
} }
onMenuChanged: {
if (menuRoot.shouldLoadMenu && entryStack.count) {
menuRoot.menuItems = []
Qt.callLater(() => menuRoot.loadMenuItemsSafely())
}
}
} }
@@ -1005,10 +1052,7 @@ Item {
} }
Repeater { Repeater {
model: entryStack.count model: menuRoot.menuItems
? (subOpener.children ? subOpener.children
: (menuRoot.topEntry()?.children || []))
: rootOpener.children
Rectangle { Rectangle {
property var menuEntry: modelData property var menuEntry: modelData