Bug 8498 - Context menu not closing when interacting with main menu
Summary: Context menu not closing when interacting with main menu
Alias: None
Product: Xamarin Studio
Classification: Desktop
Component: General ()
Version: 4.0
Hardware: PC Mac OS
: Low normal
Target Milestone: ---
Assignee: Cody Russell
: 10118 10167 15382 ()
Depends on:
Reported: 2012-11-19 07:48 UTC by Jérémie Laval
Modified: 2014-06-23 12:23 UTC (History)
7 users (show)

Tags: ui-refresh, gtk
Is this bug a regression?: ---
Last known good build:

patch that implements what is described above (7.68 KB, patch)
2013-03-30 07:40 UTC, Kristian Rietveld (inactive)

Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.

Please create a new report on Developer Community or GitHub with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:

Description Jérémie Laval 2012-11-19 07:48:13 UTC
http://screencast.com/t/Xis2rppBrX (not shown is when I go to "File > Close solution" at 0:06)

=== MonoDevelop ===

Version 4.0
Installation UUID: 4215efd4-6a56-4fcf-a2c4-f7b3d6cee9c7
	Mono 3.0.1 (master/301b6c6)
	GTK 2.24.13
	GTK# (
	Package version: 300010000

=== Apple Developer Tools ===

Xcode 4.5 (1839)
Build 4G182

=== Xamarin.iOS ===

Version: 6.1.0 (Unknown edition)

=== Xamarin.Android ===

Version: 4.5.80 (Starter edition)
Android SDK: /Users/jeremie/android-sdk-macosx
	Supported Android versions:
		1.6   (API level 4)
		2.1   (API level 7)
		2.2   (API level 8)
		2.3   (API level 10)
		3.1   (API level 12)
		3.2   (API level 13)
		4.0   (API level 14)
		4.0.3 (API level 15)
		4.1   (API level 16)
Java SDK: /usr

=== Build Information ===

Git revision: Release ID: 40000000
Build date: 2012-11-19 11:56:09+0000
Xamarin addins: e4572a8c05983141a477397615de2734fe71a683

=== Operating System ===

Mac OS X 10.7.5
Darwin Jeremies-iMac.local 11.4.2 Darwin Kernel Version 11.4.2
    Thu Aug 23 16:25:48 PDT 2012
    root:xnu-1699.32.7~1/RELEASE_X86_64 x86_64
Comment 1 Mikayla Hutchinson [MSFT] 2012-11-19 15:06:56 UTC
Looks like a GTK bug. It affects all context menus, I guess they aren't getting some leave event when the user clicks on the main menu?
Comment 2 Michael Natterer 2012-11-20 03:49:46 UTC
This is due to the lack of global grabs on OSX, but I think Kris thought
of a way to fix this. Kris?
Comment 3 Kristian Rietveld (inactive) 2012-11-20 04:20:34 UTC
The main menu is another process, so not contained in the process running an application. We don't really get proper leave events when the main menu is activated.

I once started looking into fixing this for GTK+ status icon menus, which is an even more complicated matter.  However, I do recall that I added a way to pop down all GTK+ menus once the main menu was clicked.  The patch should be in the status icon menu bug, otherwise I should have it somewhere.  Will have a look.
Comment 4 Michael Natterer 2013-02-08 05:49:54 UTC
See upstream bug https://bugzilla.gnome.org/show_bug.cgi?id=549153
Comment 5 Lluis Sanchez 2013-02-08 06:50:54 UTC
*** Bug 10118 has been marked as a duplicate of this bug. ***
Comment 6 Mikayla Hutchinson [MSFT] 2013-02-08 15:03:47 UTC
*** Bug 10167 has been marked as a duplicate of this bug. ***
Comment 7 Kristian Rietveld (inactive) 2013-03-26 03:52:51 UTC
I have been looking into the upstream bug again mentioned in comment 4. The patch there was written against GTK+ 3.x, so I ported it to GTK+ 2.x.

Then the trouble started ;) So, the patch works when you click on an empty part of the main menu bar, but not when you activate a menu in that main menu bar. This can be explained by the fact that while the menu is active, the GDK Quartz event loop code does not process pending events. Rather, it is waiting for the next matching NSEvent to come in. During this wait, the grab-broken event that has been generated by the detection of the click on the menu bar is still pending and is only processed after the main menu has been closed.

If you click on an empty part of the menu, I assume you do not end up in a modal loop and the grab-broken event comes through immediately.

When the grab-broken event is put into the event queue, the GMainLoop is woken up. This wake up code has changed between glib 2.32 and 2.28, so I reverted to glib 2.28 to double check this did not introduce a regression. The behavior is the same with both glib 2.32 and 2.28.

While the main menu is active, we still have some control over the run loop with the CFRunLoop observer callbacks which are still being called. I *think* that we should be checking within the run loop observer callbacks whether we should be waking up the GMainLoop. In such a case, we either run an iteration of the GMainLoop or we trigger some dummy NSEvent to break out of the wait for the next pending NSEvent. I got the impression that the latter does not work (likely due to the modality of the main menu handling). The former I still need to give a good try.

When re-reading the upstream bug, an alternative approach is to replace the use of NSTrackingRect with NSTrackingArea in GdkQuartzView. This would allow GDK to accurately detect when the mouse enters and exits GdkWindows. As a consequence, all code in the backend that is somehow dependent on this should be double checked and slightly reworked. So, such a patch would need some extensive QA. Because NSTrackingArea is only available in 10.5+, it might also not be upstreamed straightaway (unless we decide with the community to drop support for 10.4). On the upside, some hacks in the backend can possibly be removed and we do not need the event tap hack.
Comment 8 Mikayla Hutchinson [MSFT] 2013-03-28 13:58:03 UTC
FWIW, we get events when the menus open, so we could very easily call a "close all context menus" API if there were one.
Comment 9 Kristian Rietveld (inactive) 2013-03-30 07:38:25 UTC
Mitch suggested that we could also simply swallow the "global" button press event when a grab is active. So in order to reach the main menu bar with a GTK+ menu active, you need to click twice: once to break all grabs in GTK+ (which closes the GTK+) and then a click to activate the main menu bar.

I actually think this makes a lot of sense and upstream will likely accept this as well.
Comment 10 Kristian Rietveld (inactive) 2013-03-30 07:40:08 UTC
Created attachment 3720 [details]
patch that implements what is described above

Mitch: Could you test this with GIMP, especially with some custom widgets that perform pointer grabs?

I am not 100% confident we always catch all pointer ungrabs which should disable the event tap. (If we don't disable this event tap, the GTK+ application simply does not respond to mouse down events anymore).
Comment 11 Michael Natterer 2013-03-30 10:43:32 UTC
Yes please, and perhaps even deliver the button-press event to GDK, so
the quartz backend behaves more like other backend with global grab,
and stuff like "pick color anywhere from screen" becomes possible.
Comment 12 Michael Natterer 2013-03-30 10:48:51 UTC
Hmm, this code almost looks like it could be turned into a general global
event grab facility without much effort. Is there actually a problem
to forward the events that match the mask passed to gdk_pointer_grab()
to GDK?
Comment 13 Mikayla Hutchinson [MSFT] 2013-10-14 14:13:16 UTC
*** Bug 15382 has been marked as a duplicate of this bug. ***
Comment 14 Cody Russell 2014-06-23 12:23:51 UTC
With the new native context menus, this is no longer affecting us.