mirror of
https://github.com/zoriya/noctalia-shell.git
synced 2026-06-02 18:42:04 +00:00
Tray: reverted all the mitigation now that the real issue has been fixed in Quickshell.
This commit is contained in:
+20
-144
@@ -19,136 +19,8 @@ PopupWindow {
|
|||||||
property string widgetSection: ""
|
property string widgetSection: ""
|
||||||
property int widgetIndex: -1
|
property int widgetIndex: -1
|
||||||
|
|
||||||
// Menu can be set directly (for submenus) or derived from trayItem
|
// Derive menu from trayItem (only used for non-submenus)
|
||||||
property var menu: null
|
readonly property QsMenuHandle menu: isSubMenu ? null : (trayItem ? trayItem.menu : null)
|
||||||
property var stableMenu: null // Debounced menu for opener binding
|
|
||||||
property var menuItems: []
|
|
||||||
property int loadRetryCount: 0
|
|
||||||
property bool isLoadingMenu: false // Mutex to prevent concurrent access
|
|
||||||
|
|
||||||
// Debounce timer to prevent rapid menu rebinding
|
|
||||||
Timer {
|
|
||||||
id: menuDebounceTimer
|
|
||||||
interval: 50
|
|
||||||
repeat: false
|
|
||||||
onTriggered: {
|
|
||||||
// Update stable menu only after debounce period
|
|
||||||
if (root.visible && root.menu) {
|
|
||||||
root.stableMenu = root.menu
|
|
||||||
} else {
|
|
||||||
root.stableMenu = null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Timer to defer menu loading to avoid freezing on opener.children access
|
|
||||||
// Uses retry mechanism with exponential backoff for reliability
|
|
||||||
Timer {
|
|
||||||
id: menuLoadTimer
|
|
||||||
interval: 50
|
|
||||||
repeat: false
|
|
||||||
onTriggered: {
|
|
||||||
// Early exit if not visible, no stable menu, or already loading
|
|
||||||
if (!root.visible || !root.stableMenu || root.isLoadingMenu) {
|
|
||||||
root.menuItems = []
|
|
||||||
root.loadRetryCount = 0
|
|
||||||
root.isLoadingMenu = false
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set loading flag to prevent concurrent access
|
|
||||||
root.isLoadingMenu = true
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (opener && opener.children && 'values' in opener.children) {
|
|
||||||
const values = opener.children.values
|
|
||||||
if (values && values.length > 0) {
|
|
||||||
root.menuItems = [...values]
|
|
||||||
root.loadRetryCount = 0 // Success, reset retry count
|
|
||||||
root.isLoadingMenu = false
|
|
||||||
} else {
|
|
||||||
// Empty menu - retry if we haven't exceeded max attempts
|
|
||||||
if (root.loadRetryCount < 3) {
|
|
||||||
root.loadRetryCount++
|
|
||||||
menuLoadTimer.interval = 150 * Math.pow(2, root.loadRetryCount - 1) // Exponential backoff: 150, 300, 600
|
|
||||||
root.isLoadingMenu = false // Release lock before retry
|
|
||||||
menuLoadTimer.running = true
|
|
||||||
} else {
|
|
||||||
// Max retries exceeded, give up gracefully
|
|
||||||
root.menuItems = []
|
|
||||||
root.loadRetryCount = 0
|
|
||||||
root.isLoadingMenu = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// opener.children not ready - retry if we haven't exceeded max attempts
|
|
||||||
if (root.loadRetryCount < 3) {
|
|
||||||
root.loadRetryCount++
|
|
||||||
menuLoadTimer.interval = 150 * Math.pow(2, root.loadRetryCount - 1) // Exponential backoff
|
|
||||||
root.isLoadingMenu = false // Release lock before retry
|
|
||||||
menuLoadTimer.running = true
|
|
||||||
} else {
|
|
||||||
// Max retries exceeded, give up gracefully
|
|
||||||
root.menuItems = []
|
|
||||||
root.loadRetryCount = 0
|
|
||||||
root.isLoadingMenu = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
Logger.w("TrayMenu", "Error accessing menu items:", e)
|
|
||||||
root.menuItems = []
|
|
||||||
root.loadRetryCount = 0
|
|
||||||
root.isLoadingMenu = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onVisibleChanged: {
|
|
||||||
if (visible && menu) {
|
|
||||||
// Cancel all pending operations
|
|
||||||
menuDebounceTimer.running = false
|
|
||||||
menuLoadTimer.running = false
|
|
||||||
root.isLoadingMenu = false
|
|
||||||
root.loadRetryCount = 0
|
|
||||||
|
|
||||||
// Start debounce for stable menu
|
|
||||||
menuDebounceTimer.running = true
|
|
||||||
} else if (!visible) {
|
|
||||||
// Clean up when hiding
|
|
||||||
menuDebounceTimer.running = false
|
|
||||||
menuLoadTimer.running = false
|
|
||||||
root.isLoadingMenu = false
|
|
||||||
root.loadRetryCount = 0
|
|
||||||
root.stableMenu = null
|
|
||||||
root.menuItems = []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onMenuChanged: {
|
|
||||||
// Cancel pending load whenever menu changes
|
|
||||||
menuLoadTimer.running = false
|
|
||||||
root.isLoadingMenu = false
|
|
||||||
root.loadRetryCount = 0
|
|
||||||
root.menuItems = []
|
|
||||||
|
|
||||||
if (visible && menu) {
|
|
||||||
// Restart debounce timer
|
|
||||||
menuDebounceTimer.running = false
|
|
||||||
menuDebounceTimer.running = true
|
|
||||||
} else {
|
|
||||||
menuDebounceTimer.running = false
|
|
||||||
root.stableMenu = null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onStableMenuChanged: {
|
|
||||||
if (visible && stableMenu) {
|
|
||||||
// Stable menu is ready, start loading
|
|
||||||
menuLoadTimer.interval = 150 // Reset to initial interval
|
|
||||||
menuLoadTimer.running = false
|
|
||||||
menuLoadTimer.running = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compute if current tray item is pinned
|
// Compute if current tray item is pinned
|
||||||
readonly property bool isPinned: {
|
readonly property bool isPinned: {
|
||||||
@@ -193,8 +65,10 @@ PopupWindow {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isSubMenu && trayItem && trayItem.menu) {
|
if (!opener.children || opener.children.values.length === 0) {
|
||||||
menu = trayItem.menu
|
//Logger.w("TrayMenu", "Menu not ready, delaying show")
|
||||||
|
Qt.callLater(() => showAt(item, x, y))
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
anchorItem = item
|
anchorItem = item
|
||||||
@@ -210,7 +84,7 @@ PopupWindow {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function hideMenu(closeWindow = true) {
|
function hideMenu() {
|
||||||
visible = false
|
visible = false
|
||||||
|
|
||||||
// Clean up all submenus recursively
|
// Clean up all submenus recursively
|
||||||
@@ -222,20 +96,23 @@ PopupWindow {
|
|||||||
child.subMenu = null
|
child.subMenu = null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Close the parent TrayMenuWindow if this is not a submenu
|
// Full-sized, transparent MouseArea to track the mouse.
|
||||||
// closeWindow parameter prevents infinite recursion
|
MouseArea {
|
||||||
if (closeWindow && !isSubMenu && screen) {
|
id: rootMouseArea
|
||||||
const trayMenuWindow = PanelService.getTrayMenuWindow(screen)
|
anchors.fill: parent
|
||||||
if (trayMenuWindow) {
|
hoverEnabled: true
|
||||||
trayMenuWindow.close()
|
}
|
||||||
}
|
|
||||||
}
|
Item {
|
||||||
|
anchors.fill: parent
|
||||||
|
Keys.onEscapePressed: root.hideMenu()
|
||||||
}
|
}
|
||||||
|
|
||||||
QsMenuOpener {
|
QsMenuOpener {
|
||||||
id: opener
|
id: opener
|
||||||
menu: root.stableMenu // Bind to debounced stable menu instead of raw menu
|
menu: root.menu
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
@@ -280,7 +157,7 @@ PopupWindow {
|
|||||||
spacing: 0
|
spacing: 0
|
||||||
|
|
||||||
Repeater {
|
Repeater {
|
||||||
model: root.menuItems
|
model: opener.children ? [...opener.children.values] : []
|
||||||
|
|
||||||
delegate: Rectangle {
|
delegate: Rectangle {
|
||||||
id: entry
|
id: entry
|
||||||
@@ -399,7 +276,6 @@ PopupWindow {
|
|||||||
entry.subMenu.anchorItem = entry
|
entry.subMenu.anchorItem = entry
|
||||||
entry.subMenu.anchorX = openLeft ? -overlap : overlap
|
entry.subMenu.anchorX = openLeft ? -overlap : overlap
|
||||||
entry.subMenu.anchorY = 0
|
entry.subMenu.anchorY = 0
|
||||||
entry.subMenu.menuLoadTrigger++
|
|
||||||
entry.subMenu.visible = true
|
entry.subMenu.visible = true
|
||||||
// Force anchor update with new position
|
// Force anchor update with new position
|
||||||
Qt.callLater(() => {
|
Qt.callLater(() => {
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ PanelWindow {
|
|||||||
function close() {
|
function close() {
|
||||||
visible = false
|
visible = false
|
||||||
if (trayMenu.item) {
|
if (trayMenu.item) {
|
||||||
trayMenu.item.hideMenu(false) // Don't close window again (prevents recursion)
|
trayMenu.item.hideMenu()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user