Bug 59635 - Window.Toolbar cannot be set to null
Summary: Window.Toolbar cannot be set to null
Alias: None
Product: Xamarin.Mac
Classification: Desktop
Component: Library (Xamarin.Mac.dll) ()
Version: 3.8.0 (d15-4)
Hardware: PC Mac OS
: Normal normal
Target Milestone: 15.6
Assignee: Chris Hamons
Depends on:
Reported: 2017-09-21 08:48 UTC by Tim Uy
Modified: 2017-09-21 16:35 UTC (History)
3 users (show)

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

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 Tim Uy 2017-09-21 08:48:32 UTC
I should be able to set Window.Toolbar = null, but I cannot. When I do so I get:

                System.ArgumentNullException: Value cannot be null.
Parameter name: value
  at AppKit.NSWindow.set_Toolbar (AppKit.NSToolbar value) [0x00011] in /Users/builder/data/lanes/5143/416f778f/source/xamarin-macios/src/build/mac/mobile/AppKit/NSWindow.g.cs:10229
  at Kumquat.Mac.ToolbarWindow.MouseExited (AppKit.NSEvent theEvent) [0x0009c] in /Loqu8/Apps/kumquat/src/Kumquat.Mac/ToolbarWindow.cs:131
  at at (wrapper managed-to-native) AppKit.NSApplication:NSApplicationMain (int,string[])
  at AppKit.NSApplication.Main (System.String[] args) [0x00041] in /Users/builder/data/lanes/5143/416f778f/source/xamarin-macios/src/AppKit/NSApplication.cs:100
  at Kumquat.Mac.MainClass.Main (System.String[] args) [0x00007] in /Loqu8/Apps/kumquat/src/Kumquat.Mac/Main.cs:10

I need to do this because I will be toggling the border on the window

                Window.StyleMask = NSWindowStyle.Borderless;

If I do not set the Toolbar to null, I will get

2017-09-21 01:41:06.041 kumquat[36138:1780219] ERROR: Can't have a toolbar in a window with <NSNextStepFrame: 0x600000394ab0> as it's borderview

which does not toss me out of the app, but it does reset the views, the Window flashes white, ViewDidAppear gets called again, and well all sorts of initialization code that should happen once gets called again. I do see examples online of toolbar getting set to nil in XCode, I think it is possible. Can you help me?
Comment 1 Tim Uy 2017-09-21 08:49:21 UTC
A workaround would be acceptable too. I'm pretty sure this is possible because a new NSWindow actually starts with a (null) Toolbar.
Comment 2 Tim Uy 2017-09-21 09:12:09 UTC
I tried the following:

                Window.PerformSelector(new ObjCRuntime.Selector("setToolbar:"), NSNull.Null);

(not sure if I got the syntax right). It did seem to recognize "setToolbar:" (since I tried a bunch of different permutations). AFter doing so I got another error,

2017-09-21 02:00:19.770 kumquat[36326:1793630] -[NSNull _setToolbarViewWindow:]: unrecognized selector sent to instance 0x7fffc4b7f0e0
2017-09-21 02:00:19.771 kumquat[36326:1793630] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSNull _setToolbarViewWindow:]: unrecognized selector sent to instance 0x7fffc4b7f0e0'

That is called from NSToolbar, so perhaps it is starting to the right thing. I want to send nil to setToolbar:. Like in https://github.com/jmil/osirix/blob/master/osirix/ToolbarPanel.m

[self setToolbar: nil viewer: nil];
Comment 3 Tim Uy 2017-09-21 09:20:01 UTC
As an update, I tried

                Window.PerformSelector(new ObjCRuntime.Selector("setToolbar:"), null);
                var testToolbar = Window.Toolbar;
                Window.StyleMask = NSWindowStyle.Borderless;

and this time it worked. TestToolbar is null, and StyleMask does not throw the usual error although I still had ViewDidAppear called again. Maybe there is not a way of flipping the stylemask without forcing viewdidappear?
Comment 4 Tim Uy 2017-09-21 09:22:58 UTC
also a funny thing, each time viewdidappear gets called my window gets longer!
Comment 5 Tim Uy 2017-09-21 09:35:05 UTC
Scratch that window gets longer, it has to do with the toolbar being unified... I think that setToolbar: selector works just fine. Would suggest making it possible to Window.Toolbar = null
Comment 6 Manuel de la Peña [MSFT] 2017-09-21 13:35:37 UTC
Yes, this is indeed a bug in our side. We are doing a null check when we should not.
Comment 7 Manuel de la Peña [MSFT] 2017-09-21 13:35:54 UTC
As per Apple headers:

@property (nullable, strong) NSToolbar *toolbar;
Comment 8 Chris Hamons 2017-09-21 13:37:34 UTC
When this, and a majority of AppKit was originally bound, the header file did _not_ contain this information, and often neither did the documentation.

I'll PR a fix, as it's trivial (an additional [NullAllowed] attribute).

Calling PerformSelector to set the toolbar null is a reasonable work around.
Comment 9 Chris Hamons 2017-09-21 13:45:01 UTC