ComboBox selection does not work if the menu is over the macOS menu bar. mainMenuTrackingBegan
is called which calls PopupMenu::dismissAllActiveMenus();
before the PopupMenu has time to handle the mouse click.
Code to reproduce:
Video:
One solution could be to give the PopupMenu a chance to close before dismissing. Or keep popup menus within the user area or the desktop.
--- a/modules/juce_gui_basics/native/juce_MainMenu_mac.mm
+++ b/modules/juce_gui_basics/native/juce_MainMenu_mac.mm
@@ -808,7 +808,7 @@ extern MenuTrackingChangedCallback menuTrackingChangedCallback;
static void mainMenuTrackingChanged (bool isTracking)
{
- PopupMenu::dismissAllActiveMenus();
+ juce::Timer::callAfterDelay (50, [] { PopupMenu::dismissAllActiveMenus(); });
if (auto* menuHandler = JuceMainMenuHandler::instance)
{
1 Like
I have a similar issue except the popup menu gets cut off by the notch on new MacBooks.
I second the idea of keeping it within the desktop area
Looks like the PopupMenu used to not cover the menu bar and was broken in this commit:
committed 10:31AM - 28 Sep 21 UTC
This change stops menus from displaying under notches/cutouts on mobile
platform… s.
I believe it should be correctly fixed as follows:
Rectangle<int> getParentArea (Point<int> targetPoint, Component* relativeTo = nullptr)
{
if (relativeTo != nullptr)
targetPoint = relativeTo->localPointToGlobal (targetPoint);
auto* display = Desktop::getInstance().getDisplays().getDisplayForPoint (targetPoint * scaleFactor);
#if JUCE_MAC
auto parentArea = display->userArea.getIntersection (display->safeAreaInsets.subtractedFrom (display->totalArea));
#else
auto parentArea = display->safeAreaInsets.subtractedFrom (display->totalArea);
#endif
if (auto* pc = options.getParentComponent())
{
return pc->getLocalArea (nullptr,
pc->getScreenBounds()
.reduced (getLookAndFeel().getPopupMenuBorderSizeWithOptions (options))
.getIntersection (parentArea));
}
return parentArea;
}
@evanberard looks like your issue is due to the fact safeAreaInsets
is not implemented on macOS
Can you try this and confirm if it fixes your issue:
static Displays::Display getDisplayFromScreen (NSScreen* s, CGFloat& mainScreenBottom, const float masterScale)
{
Displays::Display d;
d.isMain = (approximatelyEqual (mainScreenBottom, 0.0));
if (d.isMain)
mainScreenBottom = [s frame].size.height;
d.userArea = convertDisplayRect ([s visibleFrame], mainScreenBottom) / masterScale;
d.totalArea = convertDisplayRect ([s frame], mainScreenBottom) / masterScale;
d.scale = masterScale;
if (@available (macOS 12.0, *))
{
d.safeAreaInsets = {
int (std::ceil (s.safeAreaInsets.top / masterScale)),
int (std::ceil (s.safeAreaInsets.left / masterScale)),
int (std::ceil (s.safeAreaInsets.bottom / masterScale)),
int (std::ceil (s.safeAreaInsets.right / masterScale))
};
}
if ([s respondsToSelector: @selector (backingScaleFactor)])
d.scale *= s.backingScaleFactor;
NSSize dpi = [[[s deviceDescription] objectForKey: NSDeviceResolution] sizeValue];
d.dpi = (dpi.width + dpi.height) / 2.0;
return d;
}
1 Like
Yes nice! pasted that code block into JUCE and it’s keeping it in the desktop area nicely
reuk
October 19, 2023, 1:40pm
5
Thanks for reporting, we now respect the safe area insets on macOS:
committed 10:32AM - 19 Oct 23 UTC
1 Like
Still not working on non notch macs. See:
When I select ‘Default’ from the menu, the selection is ignored. My above change to getParentArea
is still required.