Skip to content

Commit

Permalink
[macOS] Fix transparent and borderless flags interaction with full-sc…
Browse files Browse the repository at this point in the history
…reen mode.
  • Loading branch information
bruvzg committed Nov 14, 2023
1 parent fee6df7 commit 6b25204
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 47 deletions.
3 changes: 2 additions & 1 deletion platform/macos/display_server_macos.h
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ class DisplayServerMacOS : public DisplayServer {
bool mpass = false;
bool focused = false;
bool is_visible = true;
bool extend_to_title = false;

Rect2i parent_safe_rect;
};
Expand Down Expand Up @@ -209,7 +210,6 @@ class DisplayServerMacOS : public DisplayServer {

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;
Expand Down Expand Up @@ -261,6 +261,7 @@ class DisplayServerMacOS : public DisplayServer {
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;
Expand Down
92 changes: 49 additions & 43 deletions platform/macos/display_server_macos.mm
Original file line number Diff line number Diff line change
Expand Up @@ -270,53 +270,46 @@
}
}

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 (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);
}
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];
}
} 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 (gl_manager_legacy) {
gl_manager_legacy->window_set_per_pixel_transparency_enabled(p_window, false);
}
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];
#endif
}
}

Expand Down Expand Up @@ -3295,7 +3288,6 @@ - (void)popupAction:(id)sender {
}

[(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];
}
Expand Down Expand Up @@ -3332,7 +3324,6 @@ - (void)popupAction:(id)sender {
} 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];
}
Expand Down Expand Up @@ -3489,6 +3480,7 @@ - (void)popupAction:(id)sender {
} 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];
Expand All @@ -3508,6 +3500,9 @@ - (void)popupAction:(id)sender {
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]) {
Expand All @@ -3518,8 +3513,11 @@ - (void)popupAction:(id)sender {
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];
Expand Down Expand Up @@ -3548,12 +3546,20 @@ - (void)popupAction:(id)sender {
}
} 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;
Expand Down
19 changes: 16 additions & 3 deletions platform/macos/godot_window_delegate.mm
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,14 @@ - (void)windowWillEnterFullScreen:(NSNotification *)notification {

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 {
Expand Down Expand Up @@ -175,9 +183,14 @@ - (void)windowDidExitFullScreen:(NSNotification *)notification {
[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.
Expand Down

0 comments on commit 6b25204

Please sign in to comment.