fix(macos): refresh menu sessions without resizing

This commit is contained in:
Peter Steinberger
2025-12-26 22:48:58 +01:00
parent 353366ac54
commit d0293649cd
2 changed files with 29 additions and 1 deletions

View File

@@ -70,6 +70,7 @@
- Remote SSH tunnels now get health checks; Debug → Ports highlights unhealthy tunnels and offers Reset SSH tunnel.
- Menu bar session/node sections no longer reflow while open, keeping hover highlights aligned.
- Menu hover highlights now span the full width (including submenu arrows).
- Menu session rows now refresh while open without width changes (no more stuck “Loading sessions…”).
### Nodes & Canvas
- Debug status overlay gated and toggleable on macOS/iOS/Android nodes.

View File

@@ -16,6 +16,7 @@ final class MenuSessionsInjector: NSObject, NSMenuDelegate {
private var nodesLoadTask: Task<Void, Never>?
private var isMenuOpen = false
private var lastKnownMenuWidth: CGFloat?
private var menuOpenWidth: CGFloat?
private var cachedSnapshot: SessionStoreSnapshot?
private var cachedErrorText: String?
@@ -48,27 +49,38 @@ final class MenuSessionsInjector: NSObject, NSMenuDelegate {
func menuWillOpen(_ menu: NSMenu) {
self.originalDelegate?.menuWillOpen?(menu)
self.isMenuOpen = true
self.menuOpenWidth = self.currentMenuWidth(for: menu)
self.inject(into: menu)
self.injectNodes(into: menu)
// Refresh in background for the next open (but do not re-inject while open).
// Refresh in background for the next open; keep width stable while open.
self.loadTask?.cancel()
self.loadTask = Task { [weak self] in
guard let self else { return }
await self.refreshCache(force: false)
await MainActor.run {
guard self.isMenuOpen else { return }
self.inject(into: menu)
self.injectNodes(into: menu)
}
}
self.nodesLoadTask?.cancel()
self.nodesLoadTask = Task { [weak self] in
guard let self else { return }
await self.nodesStore.refresh()
await MainActor.run {
guard self.isMenuOpen else { return }
self.injectNodes(into: menu)
}
}
}
func menuDidClose(_ menu: NSMenu) {
self.originalDelegate?.menuDidClose?(menu)
self.isMenuOpen = false
self.menuOpenWidth = nil
self.loadTask?.cancel()
self.nodesLoadTask?.cancel()
}
@@ -736,6 +748,9 @@ final class MenuSessionsInjector: NSObject, NSMenuDelegate {
}
private func initialWidth(for menu: NSMenu) -> CGFloat {
if let openWidth = self.menuOpenWidth {
return max(300, openWidth)
}
let candidates: [CGFloat] = [
menu.size.width,
menu.minimumWidth,
@@ -785,9 +800,21 @@ final class MenuSessionsInjector: NSObject, NSMenuDelegate {
}
private func captureMenuWidthIfAvailable(from view: NSView) {
guard !self.isMenuOpen else { return }
guard let width = view.window?.contentView?.bounds.width, width > 0 else { return }
self.lastKnownMenuWidth = max(300, width)
}
private func currentMenuWidth(for menu: NSMenu) -> CGFloat {
let candidates: [CGFloat] = [
menu.size.width,
menu.minimumWidth,
self.lastKnownMenuWidth ?? 0,
self.fallbackWidth,
]
let resolved = candidates.max() ?? self.fallbackWidth
return max(300, resolved)
}
}
#if DEBUG