Bug 5832 - Events and Properties calling EnsureNSWindowDelegate() can break NSOpenPanel.BeginSheet, Zoom, possibly other problems
Summary: Events and Properties calling EnsureNSWindowDelegate() can break NSOpenPanel....
Alias: None
Product: MonoMac
Classification: Desktop
Component: Bindings ()
Version: unspecified
Hardware: Macintosh Mac OS
: --- normal
Target Milestone: ---
Assignee: Rolf Bjarne Kvinge [MSFT]
Depends on:
Reported: 2012-06-22 18:44 UTC by steven.orth
Modified: 2012-08-08 22:02 UTC (History)
3 users (show)

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

App to reproduce problem with NSOpenPanel.BeginSheet() (19.38 KB, application/zip)
2012-08-03 15:38 UTC, steven.orth

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 steven.orth 2012-06-22 18:44:24 UTC
If any code calls either of these properties (have not tested all others), and you later zoom the window, it moves off the bottom of the screen and is shrunk to small height. I believe there are other causes as well, since our larger app accesses neither of these properties, yet produces the same behavior.

In a default project, here is code to reproduce:

        public override void FinishedLaunching(NSObject notification)
            mainWindowController = new MainWindowController();
            NSWindowFramePredicate p = mainWindowController.Window.ShouldZoom;

When running, simply click the zoom button to observe.
Comment 1 steven.orth 2012-06-22 18:50:22 UTC
More generally, it seems accessing something that uses this.EnsureNSWindowDelegate() causes the problem.
Comment 2 steven.orth 2012-06-22 19:01:22 UTC
It certainly appears that most usages of EnsureNSWindowDelegate() are intended for implementing C# events. Have not tested using the events that call this function, but every property on NSWindow that calls this method as its implementation illustrates the bad behavior. This has been verified with the following properties:

Comment 3 steven.orth 2012-08-03 15:28:47 UTC
Just spent a couple days rediscovering this bug, though with a different manifestation.

Something in the update must have altered the behavior of EnsureNSWindowDelegate(). Accessing the aforementioned properties, as well as adding an event handler for events on NSWindow, causes problems with NSOpenPanel.BeginSheet().

Specifically, the window passed to BeginSheet() moves to a lower location on the screen, and the sheet does not appear. You can use the Escape key to exit the condition, but it does render NSOpenPanel.BeginSheet() useless. Have not tested other similar operations -- but it does appear to be a problem that is caused by EnsureNSWindowDelegate().
Comment 4 steven.orth 2012-08-03 15:38:49 UTC
Created attachment 2296 [details]
App to reproduce problem with NSOpenPanel.BeginSheet()

To disable the bug, comment out the event handler installation in the MainWindow.cs file's Initialize() method.
Comment 5 Miguel de Icaza [MSFT] 2012-08-07 00:44:19 UTC
As a workaround, do not use the NSWindow events, and instead manually set the Delegate to a subclass of NSWindowDelegate that only implements the methods that you are interested in.

It looks like a marshalling bug, the WillPositionSheet method is getting a corrupted value:

Comment 6 Miguel de Icaza [MSFT] 2012-08-07 00:53:55 UTC
Actually, it might not be a marshaling bug, but a requirement from the API that we must return a height = 0 for the panel.

Adding this fixes the problem:

			this.WillPositionSheet = (w, s, r) => {
				r.Height = 0;
				return r;

The 2.436731E+36 turns out to be 0x8000000000000000, which could be a sentinel for height not being set.   From the docs:

" It is recommended that you specify zero for the size.height value as this field may have additional meaning in a future release."

So we need to extend the binding tool to let us run code snippets to set the default returned value for events in the meantime.
Comment 7 steven.orth 2012-08-07 17:36:46 UTC
Thank you! Noticed that commend in the docs, too. Great catch.
Comment 8 Rolf Bjarne Kvinge [MSFT] 2012-08-07 18:42:26 UTC
This looks like a marshalling bug, I get different value for Height every time I run it.
Comment 9 Rolf Bjarne Kvinge [MSFT] 2012-08-08 13:17:33 UTC
It was a marshalling bug.

Fixed in 7c89590f7af846cbd5c57f44398bac303e0c0a84.

The workaround in comment #6 is correct - just return a new RectangleF with Height=0 (which you should do anyway according to Apple's documentation).
Comment 10 Rolf Bjarne Kvinge [MSFT] 2012-08-08 22:02:40 UTC
Just for the record: my initial fix was wrong (and has been reverted). The proper fix is in 4ea4701318814f77e2a571edb4a40615f65d2a4c.