Bug 10256 - Mac window manipulation tools get confused by Xamarin Studio
Summary: Mac window manipulation tools get confused by Xamarin Studio
Alias: None
Product: Xamarin Studio
Classification: Desktop
Component: General ()
Version: 4.0
Hardware: PC Mac OS
: --- normal
Target Milestone: ---
Assignee: Bugzilla
: 10473 10745 ()
Depends on:
Reported: 2013-02-12 17:14 UTC by Mikayla Hutchinson [MSFT]
Modified: 2013-04-04 13:28 UTC (History)
5 users (show)

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

[PATCH] Call NSApp finishLaunching before polling the first event from Cocoa (1.54 KB, patch)
2013-02-23 08:00 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 Mikayla Hutchinson [MSFT] 2013-02-12 17:14:29 UTC
From http://forums.xamarin.com/discussion/1276/better-touch-tool-btt-and-xamarin-studio-window-snapping#latest:

I use Better Touch Tool (http://blog.boastr.net/) on OS X Mountain Lion to get Win7 Aero Snap behavior for windows.

For some reason MonoDevelop and Xamarin Studio don't aero snap. All other windows / apps I have used work. Not sure if this is a BTT problem or something that is being done in MonoDevelop that makes the window different from a normal window?

Another possible clue... I use Witch (http://manytricks.com/witch/) to get proper Alt-Tab behavior in OS X and the MonoDevelop / Xamarin Studio window always shows up as if it is minimized or missing a "main window".
Comment 1 Mikayla Hutchinson [MSFT] 2013-02-12 17:27:07 UTC
The problem here is likely because Xamarin Studio uses the GTK+ UI toolkit instead of using Cocoa. Although GTK+ is built on top of Cocoa primitives such as NSWindow, it sounds like these tools are making additional assumptions about these windows that do not hold for GTK+'s usage of them.

We might be able to work around this this in XS but it'd be difficult to debug it without knowing how those tools work. Ideally the authors of some of these tools could debug it and either fix it in those tools or tell us what they need us to do.
Comment 2 Mikayla Hutchinson [MSFT] 2013-02-20 19:50:41 UTC
From further discussion, it sounds like the problem is XS not showing up in accessibility inspector.
Comment 3 Mikayla Hutchinson [MSFT] 2013-02-20 20:49:32 UTC
I was able to get the Xamarin Studio window to show up in Accessibility Inspector by making sure NSApplication was properly initialized by calling NSApplicationLoad () before Gtk.Application.Init(). However, this breaks clicking on the window to focus it.

Kris, any ideas?
Comment 4 Kristian Rietveld (inactive) 2013-02-21 03:42:26 UTC
It could be that NSApplicationLoad() does some initialization additional to [NSApplication sharedApplication] (which GDK also calls), which messes something up. The documentation says the function sets up event handlers necessary for Cocoa, perhaps one of these is the problem.

I think the right way to fix the bug is to figure out how to enable the accessibility framework (if this is indeed not part of sharedApplication) and do this at the point where GDK sets up the shared application (which is in gdk_display_open).

I will put it on my list to experiment with it.
Comment 5 Kristian Rietveld (inactive) 2013-02-22 19:49:01 UTC
The function to enable accessibility, _NSAccessibilityInit() is a private symbol, so we can't call that. [NSApp finishLaunching] does call the function. If I put this at the end of gdk_display_open() (can't figure a better place), then accessibility is indeed enabled. However, all kinds of stuff in MonoDevelop break, such as the global menu bar. So this does not seem the way to go.

If we call NSApplicationLoad() in gdk_display_open(), before [NSApplication sharedApplication], a11y is also enabled successfully, but we get the window focus bug as Michael has described.

At this point, the safest bet seems to go with NSApplicationLoad() in gdk_display_open() and try to fix the window focus bug. However, I cannot say if this introduces any more breakage caused by the additional event handlers that are installed by NSApplicationLoad().
Comment 6 Kristian Rietveld (inactive) 2013-02-23 07:59:13 UTC
Okay, I have changed my mind again ;)

The window focus bug is caused due to notifications, that indicate when a window has become key, main, etc., that no longer arrive at the delegate. According to Apple documentation, NSApplicationLoad() should be called when running Cocoa code from a Carbon application. Possibly this messes up the notifications (and other things we can't oversee?). At least, GTK+ aims to be a proper Cocoa application.

So, with the help of a debugger I have looked how normal Cocoa applications call NSAccessibilityInit. The backtrace is the following:

[NSApplication finishLaunching]
[NSApplication run]

It appears that the run method calls finishLaunching before starting the main loop. A parallel for this in GTK+ would be to call finishLaunching before starting the event loop. Of course, we rather want this in GDK than GTK+, so I decided to place this in the poll function right before the we poll for an event from Cocoa for the very first time. See the patch that will be attached.

I tested this with MonoDevelop and it appears to work just fine. The global menu bar is installed as usual and the windows are visible in the accessibility inspector.

However, the GIMP global menu bar is not fully installed (it looks like everything is installed apart from the app menu). Before we can upstream the patch, we need to look into this.
Comment 7 Kristian Rietveld (inactive) 2013-02-23 08:00:42 UTC
Created attachment 3465 [details]
[PATCH] Call NSApp finishLaunching before polling the first event from Cocoa

The patch seems to work fine for me with MonoDevelop. HOWEVER, before including this patch with a release, I would do some more testing to see if calling finishLaunching does not have any other unwanted side effects ...

I will briefly investigate the problem with the menu bar in GIMP, if we can resolve that, we can likely upstream this patch.
Comment 8 Kristian Rietveld (inactive) 2013-02-23 09:30:53 UTC
A different way would be to call finishLaunching from gdk_notify_startup_complete(), which is normally called from gtk_window_map(). I am not sure about this, maybe finishLaunching is then called too early and maybe it is wise to stick to the Cocoa behavior of calling finishLaunching just before the run loop is started.
Comment 9 Mikayla Hutchinson [MSFT] 2013-02-28 00:33:14 UTC
*** Bug 10745 has been marked as a duplicate of this bug. ***
Comment 10 Alex Regueiro 2013-02-28 00:45:17 UTC
Glad to hear. I'm looking forward to the fix being included in the next release if possible.
Comment 11 Mikayla Hutchinson [MSFT] 2013-03-01 17:18:11 UTC
Thanks, I've integrated the patch into bockbuild and will give it a spin. If it doesn't cause any issues it'll be in the next Mono release.
Comment 12 Mikayla Hutchinson [MSFT] 2013-03-08 16:34:04 UTC
I've been using this without any problems so it can stay in our GTK+ patchset :)

Should go out in the next Mono release.
Comment 13 Kristian Rietveld (inactive) 2013-03-09 11:01:23 UTC
Great that this works for MonoDevelop without problems!

I have briefly investigated what is causing trouble with GIMP. A side effect of this patch is that the "application menu" now appears empty, where before this menu was filled with a few default items (Services, two hide items and a quit item). The menu code used by GIMP relies on the hide menu item to be present, to be able to find the application menu. Besides this, I don't see the default menu items to have any use, the Services and Quit items do not even work.

Because the menu code used in GIMP is used by other GTK+/OS X applications as well, I don't think we should upstream the patch at this stage. It might be possible to work around the problem temporarily by having the GTK+ backend insert a hide item using Cocoa API ....   The real fix would be for all GTK+/OS X applications to switch to Cocoa API for handling menus instead of Carbon.
Comment 14 Mikayla Hutchinson [MSFT] 2013-03-09 15:46:16 UTC
Weird, we use Carbon for menus and that stuff works in XS.
Comment 15 Kristian Rietveld (inactive) 2013-03-10 16:27:24 UTC
Indeed the same methodology is used: looking for the hide menu item. The difference is that MonoDevelop does this before calling the main loop for the first time, GIMP runs the main loop first (to show the splash screen) and later sets up the global menu.
Comment 16 Mikayla Hutchinson [MSFT] 2013-04-04 13:28:03 UTC
*** Bug 10473 has been marked as a duplicate of this bug. ***