macOS: Disable OS window shadows for transparent windows as they cause rendering artifacts due to Cocoa bugs

Fixes #6439
This commit is contained in:
Kovid Goyal 2023-07-22 11:20:37 +05:30
parent dcdc676719
commit 630101204b
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
5 changed files with 6 additions and 34 deletions

View File

@ -40,6 +40,8 @@ Detailed list of changes
- macOS: Fix a performance regression on M1 machines using outdated macOS versions (:iss:`6479`)
- macOS: Disable OS window shadows for transparent windows as they cause rendering artifacts due to Cocoa bugs (:iss:`6439`)
0.29.1 [2023-07-17]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -3029,6 +3029,9 @@ GLFWAPI void glfwCocoaSetWindowChrome(GLFWwindow *w, unsigned int color, bool us
has_shadow = true;
break;
}
// shadow causes burn-in/ghosting because cocoa doesnt invalidate it on OS window resize/minimize/restore.
// https://github.com/kovidgoyal/kitty/issues/6439
if (is_transparent) has_shadow = false;
bool hide_titlebar_buttons = !in_fullscreen && window->ns.titlebar_hidden;
[window->ns.object setTitlebarAppearsTransparent:titlebar_transparent];
[window->ns.object setHasShadow:has_shadow];

View File

@ -737,21 +737,6 @@ - (BOOL)openFileURLs:(NSPasteboard*)pasteboard
[window makeKeyWindow];
}
bool
cocoa_set_shadow(void *w, bool has_shadow) {
NSWindow *window = (NSWindow*)w;
bool current = window.hasShadow;
[window setHasShadow:has_shadow];
if (has_shadow) { // invalidate the shadow to clear the ghosting
[window invalidateShadow];
// invalidateShadow does not work with layer backed views, see http://www.openradar.me/34184270
// so do the frame resize dance to force AppKit to invalidate the shadow even with the layer
[window setFrame:NSMakeRect(NSMinX(window.frame), NSMinY(window.frame), NSWidth(window.frame)+1, NSHeight(window.frame)) display:NO animate:NO];
[window setFrame:NSMakeRect(NSMinX(window.frame), NSMinY(window.frame), NSWidth(window.frame)-1, NSHeight(window.frame)) display:NO animate:NO];
}
return current;
}
long
cocoa_window_number(void *w) {
NSWindow *window = (NSWindow*)w;

View File

@ -320,24 +320,6 @@ change_live_resize_state(OSWindow *w, bool in_progress) {
w->live_resize.num_of_resize_events = 0;
apply_swap_interval(in_progress ? 0 : -1);
#ifdef __APPLE__
extern bool cocoa_set_shadow(void*, bool);
if (w->is_semi_transparent && w->handle) {
// shadow with transparency during resize causes burn-in of window contents
// aka ghosting of the text after resize is completed. So avoid that by turning
// the shadow on and off.
if (in_progress) {
bool had_shadow = cocoa_set_shadow(glfwGetCocoaWindow(w->handle), false);
w->has_cocoa_shadow = had_shadow;
} else {
if (w->has_cocoa_shadow) {
// turning on the shadow will cause a resize event which will be delivered before cocoa_set_shadow returns
w->ignore_resize_events = true;
cocoa_set_shadow(glfwGetCocoaWindow(w->handle), true);
w->ignore_resize_events = false;
w->has_cocoa_shadow = false;
}
}
}
cocoa_out_of_sequence_render(w);
#endif
}

View File

@ -229,7 +229,7 @@ typedef struct {
bool viewport_size_dirty, viewport_updated_at_least_once;
monotonic_t viewport_resized_at;
LiveResizeInfo live_resize;
bool has_pending_resizes, is_semi_transparent, shown_once, is_damaged, has_cocoa_shadow, ignore_resize_events;
bool has_pending_resizes, is_semi_transparent, shown_once, is_damaged, ignore_resize_events;
unsigned int clear_count;
WindowChromeState last_window_chrome;
float background_opacity;