From 6ebbd6d38b65eafc19bfc178af216d3e96e29302 Mon Sep 17 00:00:00 2001 From: Alan Third Date: Sat, 22 May 2021 10:26:58 +0100 Subject: [PATCH] Fix "flickering" on NS * src/nsterm.m ([EmacsView initFrameFromEmacs:]): Add some settings that allow the frame to redraw properly while resizing. ([EmacsView viewWillDraw]): Call redisplay if we think expose_frame is going to refuse to draw anything. ([EmacsView drawRect:]): There's no point trying to draw anything if the frame is still garbaged. --- src/nsterm.m | 33 ++++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/src/nsterm.m b/src/nsterm.m index 26cc9486141..f6e16035ea5 100644 --- a/src/nsterm.m +++ b/src/nsterm.m @@ -7454,6 +7454,15 @@ not_in_argv (NSString *arg) [self initWithFrame: r]; [self setAutoresizingMask: NSViewWidthSizable | NSViewHeightSizable]; + /* These settings mean AppKit will retain the contents of the frame + on resize. Unfortunately it also means the frame will not be + automatically marked for display, but we can do that ourselves in + viewDidResize. */ + [self setWantsLayer:YES]; + [self setLayerContentsRedrawPolicy: + NSViewLayerContentsRedrawOnSetNeedsDisplay]; + [self setLayerContentsPlacement:NSViewLayerContentsPlacementTopLeft]; + FRAME_NS_VIEW (f) = self; emacsframe = f; #ifdef NS_IMPL_COCOA @@ -8254,10 +8263,23 @@ not_in_argv (NSString *arg) - (void)viewWillDraw { - /* If the frame has been garbaged there's no point in redrawing - anything. */ - if (FRAME_GARBAGED_P (emacsframe)) - [self setNeedsDisplay:NO]; + if (FRAME_GARBAGED_P (emacsframe) + && !redisplaying_p) + { + /* If there is IO going on when redisplay is run here Emacs + crashes. I think it's because this code will always be run + within the run loop and for whatever reason processing input + is dangerous. This technique was stolen wholesale from + nsmenu.m and seems to work. */ + bool owfi = waiting_for_input; + waiting_for_input = 0; + block_input (); + + redisplay (); + + unblock_input (); + waiting_for_input = owfi; + } } - (void)drawRect: (NSRect)rect @@ -8268,7 +8290,8 @@ not_in_argv (NSString *arg) NSTRACE ("[EmacsView drawRect:" NSTRACE_FMT_RECT "]", NSTRACE_ARG_RECT(rect)); - if (!emacsframe || !emacsframe->output_data.ns) + if (!emacsframe || !emacsframe->output_data.ns + || FRAME_GARBAGED_P (emacsframe)) return; block_input (); -- 2.39.2