Hello,
in System Preferences > General there is the option to “Automatically hide and show the Menu Bar”.
Suppose I hide the MenuBar and push a window up to the screen-top.
When I make the MenuBar again visible, the MenuBar overlaps the top of the window.
macOSlib has got a function that tells whether the MenuBar is visible or not, but how can I make my app aware that the MenuBar mode has changed and consequently push the window below? I would avoid a timer solution polling MenubarVisible.
OS X sends a distributed notification when the menu bar is hidden or shown.
To get this notification you have to use something like MBS plugins and listen for a notification named
AppleInterfaceMenuBarHidingChangedNotification
this is done using NSDistributedNotificationCenter in Cocoa.
Maybe macosLib has something for this too.
I looked into macosLib, but as usual I find myself lost.
In the open event of a window I tried a variety of
cocoa.NSDistributedNotificationCenter.NSNotificationDeliverImmediately
but debugging (obviously) show an error at this line.
Could you put together a snippet? Thanks.
@Michel: yes, with macoslib installed, the following snippet in the activate and deactivate event handlers does the job:
if Cocoa.NSMenu.MenuBarVisible then
if top < 45 then top = 45
end if
But I was after a “notification” solution that is beyond my expertise.
Indeed this is not documented, I discovered it simply subscribing for all notifications and going to system preferences and turning on and off the setting for the menu bar.
[quote=262705:@Carlo Rubini]@Michel: yes, with macoslib installed, the following snippet in the activate and deactivate event handlers does the job:
if Cocoa.NSMenu.MenuBarVisible then
if top < 45 then top = 45
end if
But I was after a “notification” solution that is beyond my expertise.[/quote]
A simple multiple timer monitoring the property every half a second or so are to do it. I would rather go that route than relying on undocumented features that may break each time a new version of OS X appears.
Well, it’s true this notification is not (yet) documented from Apple. I have to say I used this mechanism very often in past and never had problems with undocumented notifications. The worst thing can happen is the notification name change and the application doesn’t detect anymore the change. The timer solution should be the last resource IMHO.
I modified my module for getting window fullscreen notifications to listen for all from the distributed center and get a different notification name, here’s the ones collected so far
Don’t know why my names are different. Also I couldn’t find in the system preferences and option to hide the menubar. Toggling things in preferences yields notifications like AppleInterfaceThemeChangedNotification but using Xojo to hide the menubar yields com.apple.HIToolbox.hideMenuBarShown.
Anyways here’s my code. http://trochoid.weebly.com/uploads/6/2/6/4/62644133/distnot.zip
It’s fairly simple, for declares, but I don’t know how much help it will be.
It only handles one listener. Call distNot.setup(receiver) to start. receiver must implement the iNotify interface whose single method is called each time a notification comes in. Call distNot.destroy before receiver is done with.
[quote=262760:@Will Shank]
Don’t know why my names are different. Also I couldn’t find in the system preferences and option to hide the menubar. [/quote]
You see the notification is there.
I’m talking about the System Preferences setting in the General panel for Yosemite+
Btw, I got the same with the MBS methods.
@Carlo Rubini you can use the code from Will then, and get notified for both the System Preferences setting and the menu on/off switch from Xojo or other applications.
OK, thanks Massimo, I see it now. The notification for this new El Capitan feature is AppleInterfaceMenuBarHidingChangedNotification. The other notification I pointed out is just an app hiding it’s own menubar.
Just for the record: this snippet either in a timer or in activation/deactivation events won’t do:
if Cocoa.NSMenu.MenuBarVisible then
if top < 45 then top = 45
end if
In fact, if in System Preferences > General the option is set to hide the menubar and a window is positioned at top < 45, then moving the mouse over the hidden menubar, the menubar shows up and the window.top shifts to top = 45.
Experimenting with Safari etc., it seems this is NOT the expected behavior; i.e. the window should remain at top < 45. Only at resetting the Preferences option to “Show” the window should move to top = 45.
Therefore, it seems that “notification” (like Will’s, MBS or other) is indeed needed.
Again, thanks to all who contributed to this topic.
static previousmenubarvisible as boolean
dim ismenuvisible as boolean = Cocoa.NSMenu.MenuBarVisible
if ismenuVisible <> previousmenubarvisible then
// Do what is needed on MenuBarChanged
system.DebugLog str(ismenuVisible)
end if
previousmenubarvisible = ismenuVisible
It triggers the debuglog like clockworks when the bar is hidden/reinstated.
The issue must be with the window top values. Simply hiding the window bar with the menu takes a value of 22, not 45. You can also go by Self.Bounds.Top = 0 which indicates the top of the window bar is at position 0.