@@ -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