Opened 3 years ago

Closed 20 months ago

Last modified 19 months ago

#17459 closed defect (fixed)

PopupMenu does not work on dialogs under OSX

Reported by: 72deluxe Owned by: Stefan Csomor <csomor@…>
Priority: high Milestone: 3.1.1
Component: wxOSX Version: 3.1.0
Keywords: Popup, menu Cc: robertop2004@…, llemaitre@…, johnr@…
Blocked By: Blocking:
Patch: no

Description

Using wx3.1.0, if you create a dialog window under your main parent window, popupmenu shows a popup menu but all items are disabled.

This is also true if the popup menu has submenus; the submenus are available but their child items are disabled.

This can be seen using the menu sample using File > Show Dialog. The popup menu will be shown but all items will be disabled.

Change History (29)

comment:1 Changed 3 years ago by 72deluxe

I should add that this is under OSX 10.11.3 (15D21) and my build details for the menu sample are:

/Users/rich/wxWidgets-3.1.0/wx3.1.0-debug/bk-deps clang++ -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/ -mmacosx-version-min=10.8 -c -o menu_menu.o -DWXOSX_COCOA -I../../../samples/menu -DWXUSINGDLL -I../../../samples/menu/../../samples -Wall -Wundef -Wunused-parameter -Wno-ctor-dtor-privacy -Woverloaded-virtual -Wno-deprecated-declarations -D_FILE_OFFSET_BITS=64 -I/Users/rich/wxWidgets-3.1.0/wx3.1.0-debug/lib/wx/include/osx_cocoa-unicode-3.1 -I../../../include -DWX_PRECOMP -g -O0 -stdlib=libc++ -std=c++11 -fno-common -fvisibility=hidden -fvisibility-inlines-hidden ../../../samples/menu/menu.cpp

clang++ -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/ -mmacosx-version-min=10.8 -o menu menu_menu.o -L/Users/rich/wxWidgets-3.1.0/wx3.1.0-debug/lib -stdlib=libc++ -framework IOKit -framework Carbon -framework Cocoa -framework AudioToolbox -framework System -framework OpenGL -lwx_osx_cocoau_core-3.1 -lwx_baseu-3.1 -lwxtiff-3.1 -lwxjpeg-3.1 -lwxpng-3.1 -framework WebKit -lwxregexu-3.1 -stdlib=libc++ -framework IOKit -framework Carbon -framework Cocoa -framework AudioToolbox -framework System -framework OpenGL -lz -lpthread -liconv -llzma -lz -lpthread -liconv -llzma

So, built using OSX 10.11.sdk but with OSX minimum of 10.8 as I am using C++11.

comment:2 Changed 3 years ago by eran

I can confirm this as well.
It affects all type wxMenu created in a wxDialog

For example, I have this report on my project (wxWidgets 3.1 is used):
https://github.com/eranif/codelite/issues/1212

And also any toolbar items that may have drop down menus

comment:3 Changed 3 years ago by 72deluxe

Interestingly, another toolkit had the same problem.

I wonder if we could replace the code in PopUp in osx/cocoa/menu.mm from

[m_osxMenu popUpMenuPositioningItem:nil atLocation:NSMakePoint(x, y) inView:view];

to:

NSEvent *event = [NSEvent mouseEventWithType:NSRightMouseDown location:NSMakePoint(x,y) timestamp:0 modifierFlags:0 context:nil eventNumber:0 clickCount:1 pressure:1.0 windowNumber:view.window.windowNumber];
[NSMenu popUpContextMenu:m_osxMenu withEvent:event forView:view];

Can anyone see problems with that?

comment:4 Changed 3 years ago by paulclinger

@eran, I recompiled using the trunk version (as of few days ago; right after Scintilla 3.6.3 was merged), but don't see any issues with the toolbar dropdowns. I have several icons with SetToolDropDown registered for them (for wxAuiToolbar), but they don't show any issues with items being disabled. Or do you mean wxMenu created dynamically when clicked on a toolbar icon?

comment:5 Changed 3 years ago by 72deluxe

@paulclinger - this is specifically on secondary wxDialog windows. Are you using the wxAuiToolbar on a wxDialog or modal window or a main frame?

comment:6 Changed 3 years ago by eran

@paulclinger I will test this at home again. Don't have access to my Mac atm

comment:7 Changed 3 years ago by johnr

I see this on app modal dialogs only. Works ok on nonmodal and window modal dialogs so looks like an osx bug.

At a quick look, synthesizing an event and using popUpContextMenu as in comment 3 will work but has the downside of automatically inserting menu items from any contextual menu plug-ins that the user has installed. This may not be a problem but see last paragraph in the link:
https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/MenuList/Articles/DisplayContextMenu.html

The method suggested is what we did previously by creating an NSPopUpButtonCell object and attaching the menu. Unless anyone has a better suggestion it looks like we need to revert 33d8d4e57c14483f201da588129bfea9616da8d8 and for #15385 handle positioning better.

Positioning was not ideal previously and often resulted in highlighting the first item in the menu. Offsetting frame.origin.x and y by 10 fixes this on my screen but it needs something else if the mouse is clicked near the bottom of the screen.

comment:8 follow-up: Changed 3 years ago by 72deluxe

Would it be possible to use the allowsContextMenuPlugIns property on NSMenu to disable showing of menu plugins?

comment:9 Changed 3 years ago by paulclinger

@72deluxe, got it; my toolbar is indeed on the main frame.

comment:10 in reply to: ↑ 8 Changed 3 years ago by johnr

Replying to 72deluxe:

Would it be possible to use the allowsContextMenuPlugIns property on NSMenu to disable showing of menu plugins?

I can't see any reason why not and it might be advantageous to supply an API to enable or disable menu plugin services, osx only.

comment:11 Changed 3 years ago by eran

Can this bug get a higher priority? its really frustrating having all the menus shown from a wxDialog as disabled. This really cripples my application on OSX

comment:12 Changed 3 years ago by vadz

John, is the only possible solution still to revert 33d8d4e57c14483f201da588129bfea9616da8d8? If so, I can do it, of course...

comment:13 Changed 3 years ago by 72deluxe

For me, I had been doing the following:

osx/cocoa/menu.mm needs modifying to revert to http://trac.wxwidgets.org/changeset/33d8d4e57c14483f201da588129bfea9616da8d8/git-wxWidgets
Find

[m_osxMenu popUpMenuPositioningItem:nil atLocation:NSMakePoint(x, y) inView:view];

or

[m_osxMenu popUpMenuPositioningItem:nil atLocation:CGPointMake(x, y) inView:view];

in void PopUp( wxWindow *win, int x, int y ) wxOVERRIDE within menu.mm and replace with:

NSRect frame = [view frame];
frame.origin.x = x;
frame.origin.y = y;
frame.size.width = 1;
frame.size.height = 1;
NSPopUpButtonCell *popUpButtonCell = [[NSPopUpButtonCell alloc] initTextCell:@"" pullsDown:NO];
[popUpButtonCell setAutoenablesItems:NO];
[popUpButtonCell setAltersStateOfSelectedItem:NO];
[popUpButtonCell setMenu:m_osxMenu];
[popUpButtonCell selectItem:nil];
[popUpButtonCell performClickWithFrame:frame inView:view];
[popUpButtonCell release];

So for me reverting back to old behaviour was the only fix.

comment:14 Changed 3 years ago by johnr

  • Status changed from new to confirmed

Sad but we will have to revert and return the bug in #15385. That ticket should then be re-opened.

Using NSMenu popUpContextMenu:m_osxMenu withEvent:event forView:view as suggested in comment 3 does show the menu but its placement is also haphazard.

comment:15 Changed 20 months ago by roberto

  • Cc robertop2004@… added

comment:16 Changed 20 months ago by Stefan Csomor <csomor@…>

  • Owner set to Stefan Csomor <csomor@…>
  • Resolution set to fixed
  • Status changed from confirmed to closed

In 361d7b49/git-wxWidgets:

Fix popup menu items being always disabled in Mac OS X (#549)

Menus on Mac use automatic menu enabling, meaning that the system will enable
menu items only if the app responds to the menu item action. If I understand
correctly, the responder chain for menus in popup dialogs stop at the dialog
window, so the system thinks that the app does not handle the menu items.

This fix should not affect existing code since the wxWidgets user-facing API
dictates that apps specifically disable menu items.

Fix #17459

See Apple docs on automatic menu enabling at

https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/MenuList/Articles/EnablingMenuItems.html#//apple_ref/doc/uid/20000261-BAJBFGED

comment:17 Changed 20 months ago by moki19

  • Cc llemaitre@… added
  • Resolution fixed deleted
  • Status changed from closed to reopened

The fix works for menu items, but not for submenus items as I supposed before having tested (https://github.com/wxWidgets/wxWidgets/commit/361d7b493860c1b9aa7414bbf9bf4bd27d703744#commitcomment-24138534).

I encounter another issue which might be linked to : I can't get menu event functions called with modal dialog (while it works on MSW).

comment:18 Changed 20 months ago by csomor

what event functions are not called for you ? on osx in the menu sample when using File->ShowDialog and showing the contextual menu via right click, the individual menu lines are getting their
wxEVT_MENU_HIGHLIGHT

comment:20 Changed 20 months ago by moki19

  • Cc llemaitre@… removed

You are right, wxEVT_MENU_HIGHLIGHT events are called.

But if I bind a wxEVT_MENU to a menu item (as implemented for MyFrame), nothing happened when clicking the contextual menu on OSX while on MSW the event fonction is called as expected.

Maybe I do something wrong, but according to the documentation, even without any modification of the menu sample, clicking on an item of MyDialog contextual menu should have the same behaviour than in MyFrame (MyFrame is an ancestor of MyDialog) :
"Provide EVT_MENU handlers in the window which pops up the menu, or in an ancestor of that window (the simplest method);"

comment:21 Changed 20 months ago by csomor

OK, thanks, now I understand correctly, I'll look at it

comment:22 follow-up: Changed 20 months ago by csomor

In the end using NSMenu popUpContextMenu seems to produce a lot less problems when used from wxDialog, auto enabling works, and the events are sent as well.

@johnr could you provide us with examples for the haphazard positioning situations we might find another solution for these ...

Thanks a lot

comment:23 Changed 20 months ago by moki19

  • Cc llemaitre@… added

As suggested few month ago, I fix the problem by taking inspiration from previous implementation : https://trac.wxwidgets.org/changeset/33d8d4e57c14483f201da588129bfea9616da8d8/git-wxWidgets.

I have posted my code on wxWidgets forum : https://forums.wxwidgets.org/viewtopic.php?f=23&t=42095&p=179461#p179461

comment:24 Changed 20 months ago by csomor

yes, I know that code ;-) but as @JohnR reported it poses problems in some situations, and while I first implemented a fix along the autoEnable:NO I had to discover that events where not sent the same way as they should, therefore I've committed a different solution. Could you please test with the current state of master ? Thanks, Stefan

comment:25 Changed 20 months ago by moki19

  • Cc llemaitre@… removed

Sorry I wasn't aware of your last commit... And my post was mostly intended for users, in case of this annoying bug would not be fixed quickly...

So, thank you for your solution, I going to test it as soon as possible !

comment:26 Changed 20 months ago by csomor

No Problem, thanks in advance for testing, I hope it works, I'd prefer it as it would mean the least interference with the native event flow

comment:27 Changed 20 months ago by moki19

  • Cc llemaitre@… added
  • Resolution set to fixed
  • Status changed from reopened to closed

After some tests, everything seems to work as expected to me now.
Thanks again.

comment:28 in reply to: ↑ 22 Changed 19 months ago by johnr

  • Cc johnr@… added

Replying to csomor:

In the end using NSMenu popUpContextMenu seems to produce a lot less problems when used from wxDialog, auto enabling works, and the events are sent as well.

@johnr could you provide us with examples for the haphazard positioning situations we might find another solution for these ...

Sorry for the delayed reply. I have been away and unable to access internet. #15385 has a description or poor menu positioning but looking at comment 27 here the current solution appears to work.

comment:29 Changed 19 months ago by csomor

Thanks John

Note: See TracTickets for help on using tickets.