소스 검색

Merge pull request #10335 from marcelofg55/2.1

Implemented borderless window functions on OS X
Rémi Verschelde 8 년 전
부모
커밋
29a8e1ac25
2개의 변경된 파일84개의 추가작업 그리고 7개의 파일을 삭제
  1. 6 0
      platform/osx/os_osx.h
  2. 78 7
      platform/osx/os_osx.mm

+ 6 - 0
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);

+ 78 - 7
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;