From 4fbdf0d68060e7da0af3868294756c55c702dd72 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Thu, 21 Nov 2024 14:07:20 -0700 Subject: [PATCH] macOS: catch spurious full redraw calls to NSView:drawRect and act appropriately --- libs/tk/ydk/quartz/GdkQuartzView.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/libs/tk/ydk/quartz/GdkQuartzView.c b/libs/tk/ydk/quartz/GdkQuartzView.c index de6b9b868a..fcf4af8084 100644 --- a/libs/tk/ydk/quartz/GdkQuartzView.c +++ b/libs/tk/ydk/quartz/GdkQuartzView.c @@ -696,6 +696,7 @@ NSInteger count; int i; GdkRegion *region; + gboolean full_draw; if (GDK_WINDOW_DESTROYED (gdk_window)) return; @@ -706,6 +707,22 @@ if (NSEqualRects (rect, NSZeroRect)) return; + + /* Quartz/CoreGraphics/something on macOS causes occasional/periodic drawRect + * calls with a "dirty" rect that covers the entire NSView. As of 11/2024, + * this seems to be caused by how much of the NSView is redrawn in a given + * interval. The lower layers really do invalidate the contents of any + * backing store, so if we do not obey the drawRect call, portions of the + * window will remain undrawn. + */ + + if (NSContainsRect (rect, [self bounds])) { + full_draw = TRUE; + printf ("full draw seen!\n"); + } else { + full_draw = FALSE; + } + if (!GDK_WINDOW_IS_MAPPED (gdk_window) && ((gdk_quartz_osx_version() >= GDK_OSX_LEOPARD) && [self wantsLayer])) { /* If the window is not yet mapped, clip_region_with_children @@ -732,7 +749,7 @@ return; } - if (!impl->needs_display_region || gdk_quartz_get_use_cocoa_invalidation()) { + if (!impl->needs_display_region || gdk_quartz_get_use_cocoa_invalidation() || full_draw) { [self getRectsBeingDrawn: &drawn_rects count: &count]; region = gdk_region_new ();