2222#include " region.h"
2323#include " graphics.h"
2424#include " unicode.h"
25+ #include " globals.h"
2526
2627#include " platform.h"
2728#include " platform-internal.h"
@@ -1588,6 +1589,13 @@ - (void)drawRect: (NSRect)dirtyRect
15881589 // ////////
15891590
15901591 MCGRegionDestroy (t_update_region);
1592+
1593+ if (MCmajorosversion >= MCOSVersionMake (10 ,16 ,0 ))
1594+ {
1595+ // Send event to break wait in NSApp::nextEventMatchingMask in MCMacPlatformWindow::DoUpdate
1596+ t_window->DrawSync ();
1597+ MCMacPlatformSyncUpdateAfterDraw (self.window .windowNumber );
1598+ }
15911599}
15921600
15931601// ////////
@@ -1674,6 +1682,8 @@ - (void)setFrameSize: (NSSize)size
16741682 m_has_sheet = false ;
16751683 m_frame_locked = false ;
16761684
1685+ m_waiting_for_draw = false ;
1686+
16771687 m_parent = nil ;
16781688}
16791689
@@ -1693,6 +1703,7 @@ - (void)setFrameSize: (NSSize)size
16931703bool MCMacPlatformWindow::s_hiding = false ;
16941704MCMacPlatformWindow *MCMacPlatformWindow::s_hiding_focused = nil ;
16951705MCMacPlatformWindow *MCMacPlatformWindow::s_hiding_unfocused = nil ;
1706+ bool MCMacPlatformWindow::s_showing_sheet = false ;
16961707
16971708// //////////////////////////////////////////////////////////////////////////////
16981709
@@ -2122,6 +2133,7 @@ - (void)setFrameSize: (NSSize)size
21222133 m_parent -> Retain ();
21232134 ((MCMacPlatformWindow *)m_parent) -> m_has_sheet = true ;
21242135
2136+ s_showing_sheet = true ;
21252137 [NSApp beginSheet: m_window_handle modalForWindow: t_parent -> m_window_handle modalDelegate: m_delegate didEndSelector: @selector (didEndSheet:returnCode:contextInfo: ) contextInfo: nil ];
21262138}
21272139
@@ -2136,6 +2148,7 @@ - (void)setFrameSize: (NSSize)size
21362148 ((MCMacPlatformWindow *)m_parent) -> m_has_sheet = false ;
21372149 m_parent -> Release ();
21382150 m_parent = nil ;
2151+ s_showing_sheet = false ;
21392152 }
21402153 else if (m_style == kMCPlatformWindowStyleDialog )
21412154 {
@@ -2198,8 +2211,19 @@ bool MCMacDoUpdateRegionCallback(void *p_context, const MCRectangle &p_rect)
21982211
21992212 return true ;
22002213}
2214+
2215+ void MCMacPlatformHandleDrawSync (NSWindow *window)
2216+ {
2217+ /* NOOP */
2218+ }
2219+
2220+ void MCMacPlatformWindow::DrawSync ()
2221+ {
2222+ m_waiting_for_draw = false ;
2223+ }
2224+
22012225void MCMacPlatformWindow::DoUpdate (void )
2202- {
2226+ {
22032227 // If the shadow has changed (due to the mask changing) we must disable
22042228 // screen updates otherwise we get a flicker.
22052229 // IM-2015-02-23: [[ WidgetPopup ]] Assume shadow changes when redrawing a non-opaque widget
@@ -2214,10 +2238,32 @@ bool MCMacDoUpdateRegionCallback(void *p_context, const MCRectangle &p_rect)
22142238 s_rect_count = 0 ;
22152239 MCRegionForEachRect (m_dirty_region, MCMacDoUpdateRegionCallback, m_view);
22162240
2217- // Force a re-display, this will cause drawRect to be invoked on our view
2218- // which in term will result in a redraw window callback being sent.
2219- [m_view displayIfNeededInRect: [m_view mapMCRectangleToNSRect: MCRegionGetBoundingBox (m_dirty_region)]];
2220-
2241+ if (MCmajorosversion >= MCOSVersionMake (10 ,16 ,0 ))
2242+ {
2243+ // Frequent redraws with displayIfNeeded causes graphical glitches on Macos Big Sur, so instead
2244+ // we enter the runloop to trigger a redraw. This will cause drawRect to be invoked on our view
2245+ // which in turn will result in a redraw window callback being sent.
2246+ // The timeout value of 0.02ms is specified to avoid hitting the 60hz redraw limit.
2247+ if (!s_inside_focus_event && !s_showing_sheet && ![m_delegate inUserReshape ])
2248+ {
2249+ m_waiting_for_draw = true ;
2250+ while (m_waiting_for_draw)
2251+ {
2252+ NSEvent *t_event;
2253+ t_event = [NSApp nextEventMatchingMask: NSApplicationDefinedMask
2254+ untilDate: [NSDate dateWithTimeIntervalSinceNow: 0.02 ]
2255+ inMode: NSEventTrackingRunLoopMode
2256+ dequeue: NO ];
2257+ t_event = nil ;
2258+ }
2259+ }
2260+ }
2261+ else
2262+ {
2263+ // Use displayIfNeeded to trigger a redraw
2264+ [m_view displayIfNeeded ];
2265+ }
2266+
22212267 // Re-enable screen updates if needed.
22222268 if (t_shadow_changed)
22232269 {
0 commit comments