Skip to content

Commit 602914b

Browse files
authored
Merge pull request #1 from jason5545/upstream-pr-batch
Batch merge upstream open PRs (auto-merged set)
2 parents 11edd39 + 298d39c commit 602914b

31 files changed

Lines changed: 1062 additions & 234 deletions

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
11
.DS_Store
22
build/
33
xcuserdata/
4+
5+
# https://github.com/jordanbaird/Ice/pull/795
6+
DerivedData/
7+

Ice.xcodeproj/project.pbxproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,7 @@
312312
CURRENT_PROJECT_VERSION = 1117;
313313
DEAD_CODE_STRIPPING = YES;
314314
DEVELOPMENT_ASSET_PATHS = "";
315+
DEVELOPMENT_TEAM = 4YPY82PC7M;
315316
ENABLE_HARDENED_RUNTIME = YES;
316317
ENABLE_PREVIEWS = YES;
317318
ENABLE_USER_SCRIPT_SANDBOXING = NO;
@@ -344,6 +345,7 @@
344345
CURRENT_PROJECT_VERSION = 1117;
345346
DEAD_CODE_STRIPPING = YES;
346347
DEVELOPMENT_ASSET_PATHS = "";
348+
DEVELOPMENT_TEAM = 4YPY82PC7M;
347349
ENABLE_HARDENED_RUNTIME = YES;
348350
ENABLE_PREVIEWS = YES;
349351
ENABLE_USER_SCRIPT_SANDBOXING = NO;

Ice/Bridging/Bridging.swift

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ extension Bridging {
124124

125125
private static func getMenuBarWindowList() -> [CGWindowID] {
126126
let windowCount = getWindowCount()
127+
Logger.bridging.debug("getMenuBarWindowList: total window count = \(windowCount)")
127128
var list = [CGWindowID](repeating: 0, count: windowCount)
128129
var realCount: Int32 = 0
129130
let result = CGSGetProcessMenuBarWindowList(
@@ -137,6 +138,23 @@ extension Bridging {
137138
Logger.bridging.error("CGSGetProcessMenuBarWindowList failed with error \(result.logString)")
138139
return []
139140
}
141+
Logger.bridging.debug("getMenuBarWindowList: found \(realCount) menu bar windows")
142+
143+
// Debug: check for Ice windows in the list
144+
let currentPID = ProcessInfo.processInfo.processIdentifier
145+
for windowID in list[..<Int(realCount)] {
146+
var pointer = UnsafeRawPointer(bitPattern: Int(windowID))
147+
if let array = CFArrayCreate(kCFAllocatorDefault, &pointer, 1, nil),
148+
let descList = CGWindowListCreateDescriptionFromArray(array) as? [[CFString: Any]],
149+
let desc = descList.first,
150+
let ownerPID = desc[kCGWindowOwnerPID] as? pid_t,
151+
ownerPID == currentPID {
152+
let layer = desc[kCGWindowLayer] as? Int ?? -1
153+
let title = desc[kCGWindowName] as? String ?? "nil"
154+
Logger.bridging.debug("Ice window in menubar list: windowID=\(windowID), layer=\(layer), title=\(title), expectedLayer=\(Int(kCGStatusWindowLevel))")
155+
}
156+
}
157+
140158
return [CGWindowID](list[..<Int(realCount)])
141159
}
142160

Ice/Events/EventManager.swift

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ final class EventManager {
2424
guard let self else {
2525
return event
2626
}
27+
if handleOpenSettingsFallback(with: event) {
28+
return event
29+
}
2730
switch event.type {
2831
case .leftMouseDown:
2932
handleShowOnClick()
@@ -265,6 +268,27 @@ extension EventManager {
265268
appState.menuBarManager.showRightClickMenu(at: mouseLocation)
266269
}
267270

271+
// MARK: Handle Open Settings Fallback
272+
273+
private func handleOpenSettingsFallback(with event: NSEvent) -> Bool {
274+
guard
275+
let appState,
276+
!appState.settingsManager.advancedSettingsManager.showContextMenuOnRightClick,
277+
event.type == .leftMouseDown || event.type == .rightMouseDown,
278+
isMouseInsideMenuBar
279+
else {
280+
return false
281+
}
282+
283+
let modifiers = event.modifierFlags.intersection(.deviceIndependentFlagsMask)
284+
guard modifiers.contains([.option, .command]) else {
285+
return false
286+
}
287+
288+
appState.appDelegate?.openSettingsWindow()
289+
return true
290+
}
291+
268292
// MARK: Handle Prevent Show On Hover
269293

270294
private func handlePreventShowOnHover(with event: NSEvent) {
@@ -452,6 +476,11 @@ extension EventManager {
452476
else {
453477
return false
454478
}
479+
480+
if !NSScreen.screensHaveSeparateSpaces && screen != NSScreen.screens.first {
481+
return false
482+
}
483+
455484
if appState.menuBarManager.isMenuBarHiddenBySystem || appState.isActiveSpaceFullscreen {
456485
if
457486
let mouseLocation = MouseCursor.locationCoreGraphics,

Ice/Main/AppState.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,9 @@ final class AppState: ObservableObject {
188188
itemManager.performSetup()
189189
imageCache.performSetup()
190190
updatesManager.performSetup()
191+
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { [weak self] in
192+
self?.updatesManager.startUpdater()
193+
}
191194
userNotificationManager.performSetup()
192195
}
193196

Ice/MenuBar/Appearance/MenuBarOverlayPanel.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,12 @@ final class MenuBarOverlayPanel: NSPanel {
328328
return
329329
}
330330

331+
// Validate before showing to ensure panel should be visible on this screen.
332+
let windows = WindowInfo.getOnScreenWindows()
333+
guard validate(for: .showing, with: windows) != nil else {
334+
return
335+
}
336+
331337
guard let menuBarHeight = owningScreen.getMenuBarHeight() else {
332338
return
333339
}

Ice/MenuBar/ControlItem/ControlItem.swift

Lines changed: 58 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -60,13 +60,46 @@ final class ControlItem {
6060
var window: NSWindow? {
6161
statusItem.button?.window
6262
}
63+
64+
/// The control item's button frame in screen coordinates.
65+
var buttonFrameInScreen: CGRect? {
66+
guard let button = statusItem.button, let window = button.window else {
67+
return nil
68+
}
69+
// The button frame is relative to its window
70+
// Use the window frame origin plus button bounds for screen coordinates
71+
let windowFrame = window.frame
72+
let buttonBounds = button.bounds
73+
// Convert button bounds to window coordinates
74+
let buttonFrameInWindow = button.convert(buttonBounds, to: nil)
75+
// Add window origin to get screen coordinates
76+
return CGRect(
77+
x: windowFrame.origin.x + buttonFrameInWindow.origin.x,
78+
y: windowFrame.origin.y + buttonFrameInWindow.origin.y,
79+
width: buttonFrameInWindow.width,
80+
height: buttonFrameInWindow.height
81+
)
82+
}
6383

84+
private static let logger = Logger(category: "ControlItem")
85+
6486
/// The identifier of the control item's window.
6587
var windowID: CGWindowID? {
6688
guard let window else {
6789
return nil
6890
}
69-
return CGWindowID(window.windowNumber)
91+
let windowNumber = window.windowNumber
92+
Self.logger.debug("windowNumber=\(windowNumber) for \(identifier.rawValue)")
93+
guard windowNumber > 0 else {
94+
return nil
95+
}
96+
// macOS 26+: windowNumber format changed - ID is in high 32 bits
97+
// Try high bits first, then low bits for backwards compatibility
98+
let highBits = CGWindowID(windowNumber >> 32)
99+
let lowBits = CGWindowID(truncatingIfNeeded: windowNumber)
100+
let resultID = highBits > 0 ? highBits : lowBits
101+
Self.logger.debug("windowID=\(resultID) (high=\(highBits), low=\(lowBits)) for \(identifier.rawValue)")
102+
return resultID > 0 ? resultID : nil
70103
}
71104

72105
/// A Boolean value that indicates whether the control item serves as
@@ -394,12 +427,17 @@ final class ControlItem {
394427
else {
395428
return
396429
}
430+
let modifiers = event.modifierFlags.intersection(.deviceIndependentFlagsMask)
431+
let showContextMenus = appState.settingsManager.advancedSettingsManager.showContextMenuOnRightClick
397432
switch event.type {
398433
case .leftMouseDown, .leftMouseUp:
399-
if NSEvent.modifierFlags == .control {
434+
if
435+
modifiers == .control,
436+
showContextMenus
437+
{
400438
statusItem.showMenu(createMenu(with: appState))
401439
} else if
402-
NSEvent.modifierFlags == .option,
440+
modifiers == .option,
403441
appState.settingsManager.advancedSettingsManager.canToggleAlwaysHiddenSection
404442
{
405443
if let alwaysHiddenSection = appState.menuBarManager.section(withName: .alwaysHidden) {
@@ -409,6 +447,9 @@ final class ControlItem {
409447
section?.toggle()
410448
}
411449
case .rightMouseUp:
450+
guard showContextMenus else {
451+
return
452+
}
412453
statusItem.showMenu(createMenu(with: appState))
413454
default:
414455
break
@@ -422,10 +463,10 @@ final class ControlItem {
422463
return hotkeySettingsManager.hotkey(withAction: action)
423464
}
424465

425-
let menu = NSMenu(title: "Ice")
466+
let menu = NSMenu(title: NSLocalizedString("Ice", comment: "Menu title"))
426467

427468
let settingsItem = NSMenuItem(
428-
title: "Ice Settings…",
469+
title: NSLocalizedString("Ice Settings…", comment: "Menu item"),
429470
action: #selector(AppDelegate.openSettingsWindow),
430471
keyEquivalent: ","
431472
)
@@ -435,7 +476,7 @@ final class ControlItem {
435476
menu.addItem(.separator())
436477

437478
let searchItem = NSMenuItem(
438-
title: "Search Menu Bar Items",
479+
title: NSLocalizedString("Search Menu Bar Items", comment: "Menu item"),
439480
action: #selector(showSearchPanel),
440481
keyEquivalent: ""
441482
)
@@ -462,7 +503,15 @@ final class ControlItem {
462503
continue
463504
}
464505
let item = NSMenuItem(
465-
title: "\(section.isHidden ? "Show" : "Hide") the \(name.displayString) Section",
506+
title: section.isHidden
507+
? String(
508+
format: NSLocalizedString("Show the %@ Section", comment: "Menu item"),
509+
name.displayString
510+
)
511+
: String(
512+
format: NSLocalizedString("Hide the %@ Section", comment: "Menu item"),
513+
name.displayString
514+
),
466515
action: #selector(toggleMenuBarSection),
467516
keyEquivalent: ""
468517
)
@@ -494,7 +543,7 @@ final class ControlItem {
494543
menu.addItem(.separator())
495544

496545
let checkForUpdatesItem = NSMenuItem(
497-
title: "Check for Updates…",
546+
title: NSLocalizedString("Check for Updates…", comment: "Menu item"),
498547
action: #selector(checkForUpdates),
499548
keyEquivalent: ""
500549
)
@@ -504,7 +553,7 @@ final class ControlItem {
504553
menu.addItem(.separator())
505554

506555
let quitItem = NSMenuItem(
507-
title: "Quit Ice",
556+
title: NSLocalizedString("Quit Ice", comment: "Menu item"),
508557
action: #selector(NSApp.terminate),
509558
keyEquivalent: "q"
510559
)

0 commit comments

Comments
 (0)