Disable maximise button on macOS?


#1

How does one disable the maximise/fullscreen behavior on macOS?

My main window ctor looks like:

MainWindow::MainWindow (String name)
:  DocumentWindow (name, Colours::grey, 0)
{
}

…but my title bar still has the maximis(z)e button active:

buttons

On Windows, things behave as I’d expect, but under macOS, I can’t find a way to disable this behavior – there are resize limits specified for the app that are being ignored here (I’m assuming because setBounds() is being called directly, which I know isn’t affected by resize limits).


Resizable DocumentWindow AND hide the Maximize Button?
#2

FWIW, I’ve been having the same problem and would also like to know.


#3

I might be mistaken, but I think you gotta set the flag directly on the Component Peer instance.


#4

Correct, the ComponentPeer::StyleFlags are defined for the ComponentPeer.

But you can set them, when you put your window to the desktop, when you called Component::addToDesktop (int windowStyleFlags, void* nativeWindowToAttachTo = nullptr)

Adding: if you use the DocumentWindow, there is another enum flag in the constructor specifically for which buttons to use:

requiredButtons
specifies which of the buttons (close, minimise, maximise) should be shown on the title bar. This value is a bitwise combination of values from the TitleBarButtons enum.
Note that it can be “allButtons” to get them all. You can change this later with the setTitleBarButtonsRequired() method, which can also specify where they are positioned.


#5

Right, that’s my puzzlement – I’m setting the style flags here to zero, which on Windows successfully disables all three buttons. On macOS, I’ve stepped down into the guts of the ComponentPeer code for macOS, and it looks like the maximise flag is completely ignored?

static unsigned int getNSWindowStyleMask (const int flags) noexcept
{
    unsigned int style = (flags & windowHasTitleBar) != 0 ? NSWindowStyleMaskTitled
                                                          : NSWindowStyleMaskBorderless;

    if ((flags & windowHasMinimiseButton) != 0)  style |= NSWindowStyleMaskMiniaturizable;
    if ((flags & windowHasCloseButton) != 0)     style |= NSWindowStyleMaskClosable;
    if ((flags & windowIsResizable) != 0)        style |= NSWindowStyleMaskResizable;
    return style;
}

…so we go more deeply into the component peer code to the point where we’re creating and initializing the NSWindow that our component uses, and looking up the valid values of NSWindowStyleMask on the Apple developer website, we note that there’s no style flag present to affect this fullscreen/maximize behavior, so not a JUCE problem, a macOS design that makes me harrumph.

Since my app is designed to have a maximum size, I guess that the approach to take here is:

  1. When we’re on the mac
  2. In my main component’s paint() method, look to see if the local bounds are larger than the current max size as set by the last call to setResizeLimits()
  3. If so, fill the bounds in a bg color, and then make sure that my component is actually drawn into a new rect at the maximum size, centered within the window bounds.

Better ideas (not including ‘redesign the UI to work at arbitrary sizes’), anyone?


#6

The buttons on the Window’s title bar are actually accessible through some Objective-c code. I have a routine which show/hides those buttons.
The void* view pointer is retrieved by calling getPeer()->getNativeHandle().

void OSXUIUtils::showHideWindowButtons(void* view, bool show, bool animate, float duration)
{
	NSView* nsView = (NSView*)view;
	NSWindow* nsWindow = [nsView window];
	
//[nsWindow setWindowController:(__kindof NSWindowController * _Nullable)

	CGFloat alpha = show ? 1.0 : 0.0;
	if (animate)
	{
		[NSAnimationContext beginGrouping];
		[[NSAnimationContext currentContext] setDuration:duration];
		[[[nsWindow standardWindowButton:NSWindowMiniaturizeButton] animator]  setAlphaValue:alpha];
		[[[nsWindow standardWindowButton:NSWindowZoomButton] animator]  setAlphaValue:alpha];
		[[[nsWindow standardWindowButton:NSWindowCloseButton] animator]  setAlphaValue:alpha];
		[NSAnimationContext endGrouping];
	} else {
		[[nsWindow standardWindowButton:NSWindowMiniaturizeButton] setAlphaValue:alpha];
		[[nsWindow standardWindowButton:NSWindowZoomButton] setAlphaValue:alpha];
		[[nsWindow standardWindowButton:NSWindowCloseButton] setAlphaValue:alpha];
	}
}

#7

Or something like this:

void OSXUIUtils::hideFullscreenButton(void* view)
{
	NSView* nsView = (NSView*)view;
	NSWindow* nsWindow = [nsView window];
	NSButton *button = [nsWindow standardWindowButton:NSWindowFullScreenButton];
	[button setHidden:YES];
	button.alphaValue = 0.0;
	[button setEnabled:NO];
	button.image = nil;
	button.alternateImage = nil;
}

#8

Wow, thanks. I’ll dig into this.


#9

I mean, shouldn’t this “just work” in JUCE without a native workaround? It sounds like a big bug or oversight for some of the desktop option flags to simply not work


#10

I’m doing something like this. Think it works.

 MainWindow::MainWindow() : DocumentWindow(name, Colours::grey, DocumentWindow::TitleBarButtons::closeButton | DocumentWindow::TitleBarButtons::minimiseButton)