When running the provided source, press [b] to toggle borderless fullscreen, [Enter] to toggle exclusive fullscreen, and [Escape] to close.
Build with:
clang main.m -framework Cocoa
static void ToggleBorderlessWindow () {
static struct {
NSWindowStyleMask style_mask;
NSRect frame;
NSApplicationPresentationOptions presentation_options;
} window_data;
if (IsBorderlessWindow()) {
[app setPresentationOptions:window_data.presentation_options];
[window setFrame: window_data.frame display: TRUE];
[window setStyleMask: window_data.style_mask];
}
else {
window_data.style_mask = [window styleMask];
window_data.frame = [window convertRectToScreen:[[window contentView] frame]];
window_data.presentation_options = [app presentationOptions];
[app setPresentationOptions: NSApplicationPresentationHideMenuBar | NSApplicationPresentationHideDock];
[window setStyleMask: NSWindowStyleMaskBorderless];
[window setFrame: [[window screen] frame] display: TRUE];
}
}
The three things we change when entering borderless fullscreen mode are: presentation options, style mask, and frame (window size/position). Any time we enter borderless fullscreen, we capture the current state of the window, then: set the menu bar and dock to hide, set the window style to borderless, and set the window frame to the frame of the screen which the window is most on.
To exit borderless fullscreen, we just set these three things back to what they were before we entered the mode.
PresentationOptions tell MacOS some things about how to present our application. They only apply to our program, so, if the user ⌘-tabs, they menu bar and dock will switch to their system settings.
These settings must be switch in the shown order to work correctly - try switch the order to see why!
You'll notice that switching into borderless fullscreen takes about half a second. This is caused by the call to setStyleMask, and I haven't found a way to speed it up. Let me know if you figure it out!
static bool IsBorderlessWindow () {
return [window styleMask] == NSWindowStyleMaskBorderless;
}
When checking if we're already borderless, I only check the window style. You might also check the presentation options and frame, but if the user has somehow overridden these with an external tool, I think treating the window as if it were still in borderless fullscreen is the best behaviour.
MacOS also has an exclusive fullscreen mode. I don't recommend you use this, but if you need it, it's very easy:
static bool IsFullscreen () {
return [NSApp currentSystemPresentationOptions] & NSApplicationPresentationFullScreen;
}
static void ToggleFullscreen () {
[window toggleFullScreen:nil];
}
For more information about these and related functions, check the Apple documentation linked in the references section.