From fe37afa8df7be20d933ba65191d045b7c7e87077 Mon Sep 17 00:00:00 2001 From: Marcelo Fernandez Date: Mon, 14 Aug 2017 09:53:05 -0300 Subject: [PATCH] Implemented borderless window functions on OS X --- platform/osx/os_osx.h | 6 +++ platform/osx/os_osx.mm | 85 ++++++++++++++++++++++++++++++++++++++---- 2 files changed, 84 insertions(+), 7 deletions(-) diff --git a/platform/osx/os_osx.h b/platform/osx/os_osx.h index 4b4cfefdd48..557b775fdf5 100644 --- a/platform/osx/os_osx.h +++ b/platform/osx/os_osx.h @@ -103,6 +103,7 @@ public: CursorShape cursor_shape; MouseMode mouse_mode; + String title; bool minimized; bool maximized; bool zoomed; @@ -117,6 +118,8 @@ public: return 1.0; } + void _update_window(); + float display_scale; protected: @@ -203,6 +206,9 @@ public: virtual void request_attention(); virtual String get_joy_guid(int p_device) const; + virtual void set_borderless_window(int p_borderless); + virtual bool get_borderless_window(); + void run(); void set_mouse_mode(MouseMode p_mode); diff --git a/platform/osx/os_osx.mm b/platform/osx/os_osx.mm index 67cc0939133..a3b29859325 100644 --- a/platform/osx/os_osx.mm +++ b/platform/osx/os_osx.mm @@ -86,6 +86,10 @@ // //======================================================================== +#if MAC_OS_X_VERSION_MAX_ALLOWED < 101200 +#define NSWindowStyleMaskBorderless NSBorderlessWindowMask +#endif + static NSRect convertRectToBacking(NSRect contentRect) { #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 @@ -880,7 +884,13 @@ void OS_OSX::initialize(const VideoMode &p_desired, int p_video_driver, int p_au // Don't use accumulation buffer support; it's not accelerated // Aux buffers probably aren't accelerated either - unsigned int styleMask = NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | (p_desired.resizable ? NSResizableWindowMask : 0); + unsigned int styleMask; + + if (p_desired.borderless_window) { + styleMask = NSWindowStyleMaskBorderless; + } else { + styleMask = NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | (p_desired.resizable ? NSResizableWindowMask : 0); + } window_object = [[GodotWindow alloc] initWithContentRect:NSMakeRect(0, 0, p_desired.width, p_desired.height) @@ -1220,6 +1230,7 @@ int OS_OSX::get_mouse_button_state() const { } void OS_OSX::set_window_title(const String &p_title) { + title = p_title; [window_object setTitle:[NSString stringWithUTF8String:p_title.utf8().get_data()]]; } @@ -1432,11 +1443,38 @@ Point2 OS_OSX::get_window_position() const { return wp; }; +void OS_OSX::_update_window() { + bool borderless_full = false; + + if (get_borderless_window()) { + NSRect frameRect = [window_object frame]; + NSRect screenRect = [[window_object screen] frame]; + + // Check if our window covers up the screen + if (frameRect.origin.x <= screenRect.origin.x && frameRect.origin.y <= frameRect.origin.y && + frameRect.size.width >= screenRect.size.width && frameRect.size.height >= screenRect.size.height) { + borderless_full = true; + } + } + + if (borderless_full) { + // If the window covers up the screen set the level to above the main menu and hide on deactivate + [window_object setLevel:NSMainMenuWindowLevel + 1]; + [window_object setHidesOnDeactivate:YES]; + } else { + // Reset these when our window is not a borderless window that covers up the screen + [window_object setLevel:NSNormalWindowLevel]; + [window_object setHidesOnDeactivate:NO]; + } +} + void OS_OSX::set_window_position(const Point2 &p_position) { Point2 size = p_position; size /= display_scale; [window_object setFrame:NSMakeRect(size.x, size.y, [window_object frame].size.width, [window_object frame].size.height) display:YES]; + + _update_window(); }; Size2 OS_OSX::get_window_size() const { @@ -1448,18 +1486,22 @@ void OS_OSX::set_window_size(const Size2 p_size) { Size2 size = p_size; - // NSRect used by setFrame includes the title bar, so add it to our size.y - CGFloat menuBarHeight = [[[NSApplication sharedApplication] mainMenu] menuBarHeight]; - if (menuBarHeight != 0.f) { - size.y += menuBarHeight; + if (get_borderless_window() == false) { + // NSRect used by setFrame includes the title bar, so add it to our size.y + CGFloat menuBarHeight = [[[NSApplication sharedApplication] mainMenu] menuBarHeight]; + if (menuBarHeight != 0.f) { + size.y += menuBarHeight; #if MAC_OS_X_VERSION_MAX_ALLOWED <= 101104 - } else { - size.y += [[NSStatusBar systemStatusBar] thickness]; + } else { + size.y += [[NSStatusBar systemStatusBar] thickness]; #endif + } } NSRect frame = [window_object frame]; [window_object setFrame:NSMakeRect(frame.origin.x, frame.origin.y, size.x, size.y) display:YES]; + + _update_window(); }; void OS_OSX::set_window_fullscreen(bool p_enabled) { @@ -1541,6 +1583,35 @@ void OS_OSX::request_attention() { [NSApp requestUserAttention:NSCriticalRequest]; } +void OS_OSX::set_borderless_window(int p_borderless) { + + // OrderOut prevents a lose focus bug with the window + [window_object orderOut:nil]; + + if (p_borderless) { + [window_object setStyleMask:NSWindowStyleMaskBorderless]; + } else { + [window_object setStyleMask:NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSResizableWindowMask]; + + // Force update of the window styles + NSRect frameRect = [window_object frame]; + [window_object setFrame:NSMakeRect(frameRect.origin.x, frameRect.origin.y, frameRect.size.width + 1, frameRect.size.height) display:NO]; + [window_object setFrame:frameRect display:NO]; + + // Restore the window title + [window_object setTitle:[NSString stringWithUTF8String:title.utf8().get_data()]]; + } + + _update_window(); + + [window_object makeKeyAndOrderFront:nil]; +} + +bool OS_OSX::get_borderless_window() { + + return [window_object styleMask] == NSWindowStyleMaskBorderless; +} + String OS_OSX::get_executable_path() const { int ret;