Skip to content

Commit 6664e04

Browse files
Fix hidden layout on non-primary displays
1 parent 6d83ac0 commit 6664e04

2 files changed

Lines changed: 16 additions & 2 deletions

File tree

‎CHANGELOG.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ All notable user-visible changes to OverflowBar are documented here.
44

55
## [Unreleased]
66

7+
- Made hidden-layout window discovery display-aware so selected icons can be moved on vertically arranged external displays and systems whose global menu-bar Y coordinate is not zero.
78
- Added an alternative third-party Homebrew Cask installation path backed by versioned GitHub Release artifacts and checksum validation; the DMG remains the recommended installation method.
89
- Isolated synthetic menu-bar activation events so unrelated applications keep their real pointer and hover state.
910
- Kept OverflowBar visible while an activated application's menu or popover is being used, rehiding it only after the transient UI is dismissed.

‎OverflowBar/Services/MenuBarLayoutManager.swift‎

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,13 @@ final class MenuBarLayoutManager {
382382
}
383383
}
384384

385+
private static func isMenuBarWindowFrame(_ frame: CGRect) -> Bool {
386+
if frame.maxX <= 0 && frame.minY >= 0 && frame.maxY <= 40 {
387+
return frame.width > 4 && frame.height > 4
388+
}
389+
return isVisibleMenuBarFrame(frame)
390+
}
391+
385392
private static func activeDisplayBounds() -> [CGRect] {
386393
var count: UInt32 = 0
387394
guard CGGetActiveDisplayList(0, nil, &count) == .success, count > 0 else { return [] }
@@ -394,13 +401,19 @@ final class MenuBarLayoutManager {
394401

395402
private static func fetchWindowRecords() -> [(id: CGWindowID, pid: pid_t, title: String, owner: String, frame: CGRect)] {
396403
let list = CGWindowListCopyWindowInfo(.optionAll, kCGNullWindowID) as? [[String: Any]] ?? []
397-
return list.compactMap { info in
404+
return list.compactMap { info -> (id: CGWindowID, pid: pid_t, title: String, owner: String, frame: CGRect)? in
398405
guard (info[kCGWindowLayer as String] as? Int) == 25,
399406
let id = info[kCGWindowNumber as String] as? Int,
400407
let pid = info[kCGWindowOwnerPID as String] as? Int,
401408
let b = info[kCGWindowBounds as String] as? [String: CGFloat] else { return nil }
402409
let frame = CGRect(x: b["X"] ?? 0, y: b["Y"] ?? 0, width: b["Width"] ?? 0, height: b["Height"] ?? 0)
403-
guard frame.minY == 0, frame.height <= 40 else { return nil }
410+
// Quartz window coordinates are global. On a vertically arranged
411+
// multi-display setup, or on systems that place the menu bar at a
412+
// non-zero global Y coordinate, the primary-display assumption
413+
// `frame.minY == 0` drops every real status-item window. Keep the
414+
// layout path aligned with the scanner's display-aware geometry
415+
// check, while still retaining offscreen hidden-section windows.
416+
guard Self.isMenuBarWindowFrame(frame) else { return nil }
404417
return (CGWindowID(id), pid_t(pid), info[kCGWindowName as String] as? String ?? "", info[kCGWindowOwnerName as String] as? String ?? "", frame)
405418
}
406419
}

0 commit comments

Comments
 (0)