diff --git a/platform/macos/display_server_macos.h b/platform/macos/display_server_macos.h index 66c89d6cc55..f012292f84d 100644 --- a/platform/macos/display_server_macos.h +++ b/platform/macos/display_server_macos.h @@ -120,6 +120,7 @@ public: bool mpass = false; bool focused = false; bool is_visible = true; + bool extend_to_title = false; Rect2i parent_safe_rect; }; @@ -209,7 +210,6 @@ private: WindowID _create_window(WindowMode p_mode, VSyncMode p_vsync_mode, const Rect2i &p_rect); void _update_window_style(WindowData p_wd); - void _set_window_per_pixel_transparency_enabled(bool p_enabled, WindowID p_window); void _update_displays_arrangement(); Point2i _get_screens_origin() const; @@ -261,6 +261,7 @@ public: void window_destroy(WindowID p_window); void window_resize(WindowID p_window, int p_width, int p_height); void window_set_custom_window_buttons(WindowData &p_wd, bool p_enabled); + void set_window_per_pixel_transparency_enabled(bool p_enabled, WindowID p_window); virtual bool has_feature(Feature p_feature) const override; virtual String get_name() const override; diff --git a/platform/macos/display_server_macos.mm b/platform/macos/display_server_macos.mm index 20c1a5342f1..2a6f17cb5d5 100644 --- a/platform/macos/display_server_macos.mm +++ b/platform/macos/display_server_macos.mm @@ -270,53 +270,46 @@ void DisplayServerMacOS::_update_window_style(WindowData p_wd) { } } -void DisplayServerMacOS::_set_window_per_pixel_transparency_enabled(bool p_enabled, WindowID p_window) { +void DisplayServerMacOS::set_window_per_pixel_transparency_enabled(bool p_enabled, WindowID p_window) { ERR_FAIL_COND(!windows.has(p_window)); WindowData &wd = windows[p_window]; if (!OS::get_singleton()->is_layered_allowed()) { return; } - if (wd.layered_window != p_enabled) { - if (p_enabled) { - [wd.window_object setBackgroundColor:[NSColor clearColor]]; - [wd.window_object setOpaque:NO]; - [wd.window_object setHasShadow:NO]; - CALayer *layer = [(NSView *)wd.window_view layer]; - if (layer) { - [layer setBackgroundColor:[NSColor clearColor].CGColor]; - [layer setOpaque:NO]; - } -#if defined(GLES3_ENABLED) - if (gl_manager_legacy) { - gl_manager_legacy->window_set_per_pixel_transparency_enabled(p_window, true); - } -#endif - wd.layered_window = true; - } else { - NSColor *bg_color = [NSColor windowBackgroundColor]; - Color _bg_color; - if (_get_window_early_clear_override(_bg_color)) { - bg_color = [NSColor colorWithCalibratedRed:_bg_color.r green:_bg_color.g blue:_bg_color.b alpha:1.f]; - } - [wd.window_object setBackgroundColor:bg_color]; - [wd.window_object setOpaque:YES]; - [wd.window_object setHasShadow:YES]; - CALayer *layer = [(NSView *)wd.window_view layer]; - if (layer) { - [layer setBackgroundColor:bg_color.CGColor]; - [layer setOpaque:YES]; - } -#if defined(GLES3_ENABLED) - if (gl_manager_legacy) { - gl_manager_legacy->window_set_per_pixel_transparency_enabled(p_window, false); - } -#endif - wd.layered_window = false; + if (p_enabled) { + [wd.window_object setBackgroundColor:[NSColor clearColor]]; + [wd.window_object setOpaque:NO]; + [wd.window_object setHasShadow:NO]; + CALayer *layer = [(NSView *)wd.window_view layer]; + if (layer) { + [layer setBackgroundColor:[NSColor clearColor].CGColor]; + [layer setOpaque:NO]; } - NSRect frameRect = [wd.window_object frame]; - [wd.window_object setFrame:NSMakeRect(frameRect.origin.x, frameRect.origin.y, frameRect.size.width + 1, frameRect.size.height) display:YES]; - [wd.window_object setFrame:frameRect display:YES]; +#if defined(GLES3_ENABLED) + if (gl_manager_legacy) { + gl_manager_legacy->window_set_per_pixel_transparency_enabled(p_window, true); + } +#endif + } else { + NSColor *bg_color = [NSColor windowBackgroundColor]; + Color _bg_color; + if (_get_window_early_clear_override(_bg_color)) { + bg_color = [NSColor colorWithCalibratedRed:_bg_color.r green:_bg_color.g blue:_bg_color.b alpha:1.f]; + } + [wd.window_object setBackgroundColor:bg_color]; + [wd.window_object setOpaque:YES]; + [wd.window_object setHasShadow:YES]; + CALayer *layer = [(NSView *)wd.window_view layer]; + if (layer) { + [layer setBackgroundColor:bg_color.CGColor]; + [layer setOpaque:YES]; + } +#if defined(GLES3_ENABLED) + if (gl_manager_legacy) { + gl_manager_legacy->window_set_per_pixel_transparency_enabled(p_window, false); + } +#endif } } @@ -3295,7 +3288,6 @@ void DisplayServerMacOS::window_set_mode(WindowMode p_mode, WindowID p_window) { } [(NSWindow *)wd.window_object setLevel:NSNormalWindowLevel]; - _set_window_per_pixel_transparency_enabled(true, p_window); if (wd.resize_disabled) { // Restore resize disabled. [wd.window_object setStyleMask:[wd.window_object styleMask] & ~NSWindowStyleMaskResizable]; } @@ -3332,7 +3324,6 @@ void DisplayServerMacOS::window_set_mode(WindowMode p_mode, WindowID p_window) { } break; case WINDOW_MODE_EXCLUSIVE_FULLSCREEN: case WINDOW_MODE_FULLSCREEN: { - _set_window_per_pixel_transparency_enabled(false, p_window); if (wd.resize_disabled) { // Fullscreen window should be resizable to work. [wd.window_object setStyleMask:[wd.window_object styleMask] | NSWindowStyleMaskResizable]; } @@ -3489,6 +3480,7 @@ void DisplayServerMacOS::window_set_flag(WindowFlags p_flag, bool p_enabled, Win } break; case WINDOW_FLAG_EXTEND_TO_TITLE: { NSRect rect = [wd.window_object frame]; + wd.extend_to_title = p_enabled; if (p_enabled) { [wd.window_object setTitlebarAppearsTransparent:YES]; [wd.window_object setStyleMask:[wd.window_object styleMask] | NSWindowStyleMaskFullSizeContentView]; @@ -3508,6 +3500,9 @@ void DisplayServerMacOS::window_set_flag(WindowFlags p_flag, bool p_enabled, Win send_window_event(wd, DisplayServerMacOS::WINDOW_EVENT_TITLEBAR_CHANGE); } break; case WINDOW_FLAG_BORDERLESS: { + if (wd.fullscreen) { + return; + } // OrderOut prevents a lose focus bug with the window. bool was_visible = false; if ([wd.window_object isVisible]) { @@ -3518,8 +3513,11 @@ void DisplayServerMacOS::window_set_flag(WindowFlags p_flag, bool p_enabled, Win if (p_enabled) { [wd.window_object setStyleMask:NSWindowStyleMaskBorderless]; } else { - _set_window_per_pixel_transparency_enabled(false, p_window); - [wd.window_object setStyleMask:NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskMiniaturizable | (wd.resize_disabled ? 0 : NSWindowStyleMaskResizable)]; + if (wd.layered_window) { + wd.layered_window = false; + set_window_per_pixel_transparency_enabled(false, p_window); + } + [wd.window_object setStyleMask:NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskMiniaturizable | (wd.extend_to_title ? NSWindowStyleMaskFullSizeContentView : 0) | (wd.resize_disabled ? 0 : NSWindowStyleMaskResizable)]; // Force update of the window styles. NSRect frameRect = [wd.window_object frame]; [wd.window_object setFrame:NSMakeRect(frameRect.origin.x, frameRect.origin.y, frameRect.size.width + 1, frameRect.size.height) display:NO]; @@ -3548,12 +3546,20 @@ void DisplayServerMacOS::window_set_flag(WindowFlags p_flag, bool p_enabled, Win } } break; case WINDOW_FLAG_TRANSPARENT: { + if (wd.fullscreen) { + return; + } if (p_enabled) { [wd.window_object setStyleMask:NSWindowStyleMaskBorderless]; // Force borderless. } else if (!wd.borderless) { - [wd.window_object setStyleMask:NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskMiniaturizable | (wd.resize_disabled ? 0 : NSWindowStyleMaskResizable)]; + [wd.window_object setStyleMask:NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskMiniaturizable | (wd.extend_to_title ? NSWindowStyleMaskFullSizeContentView : 0) | (wd.resize_disabled ? 0 : NSWindowStyleMaskResizable)]; } - _set_window_per_pixel_transparency_enabled(p_enabled, p_window); + wd.layered_window = p_enabled; + set_window_per_pixel_transparency_enabled(p_enabled, p_window); + // Force update of the window styles. + NSRect frameRect = [wd.window_object frame]; + [wd.window_object setFrame:NSMakeRect(frameRect.origin.x, frameRect.origin.y, frameRect.size.width + 1, frameRect.size.height) display:NO]; + [wd.window_object setFrame:frameRect display:NO]; } break; case WINDOW_FLAG_NO_FOCUS: { wd.no_focus = p_enabled; diff --git a/platform/macos/godot_window_delegate.mm b/platform/macos/godot_window_delegate.mm index e359630d1da..93396b0e015 100644 --- a/platform/macos/godot_window_delegate.mm +++ b/platform/macos/godot_window_delegate.mm @@ -79,6 +79,14 @@ DisplayServerMacOS::WindowData &wd = ds->get_window(window_id); wd.fs_transition = true; + + // Temporary disable borderless and transparent state. + if ([wd.window_object styleMask] == NSWindowStyleMaskBorderless) { + [wd.window_object setStyleMask:NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskMiniaturizable | NSWindowStyleMaskResizable]; + } + if (wd.layered_window) { + ds->set_window_per_pixel_transparency_enabled(false, window_id); + } } - (void)windowDidFailToEnterFullScreen:(NSWindow *)window { @@ -175,9 +183,14 @@ [wd.window_object setContentMaxSize:NSMakeSize(size.x, size.y)]; } - // Restore resizability state. - if (wd.resize_disabled) { - [wd.window_object setStyleMask:[wd.window_object styleMask] & ~NSWindowStyleMaskResizable]; + // Restore borderless, transparent and resizability state. + if (wd.borderless || wd.layered_window) { + [wd.window_object setStyleMask:NSWindowStyleMaskBorderless]; + } else { + [wd.window_object setStyleMask:NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskMiniaturizable | (wd.extend_to_title ? NSWindowStyleMaskFullSizeContentView : 0) | (wd.resize_disabled ? 0 : NSWindowStyleMaskResizable)]; + } + if (wd.layered_window) { + ds->set_window_per_pixel_transparency_enabled(true, window_id); } // Restore on-top state.