]> git.eshelyaron.com Git - emacs.git/commitdiff
Fix frame resize flicker on macOS (bug#30699)
authorAlan Third <alan@idiocy.org>
Mon, 19 Mar 2018 15:04:40 +0000 (15:04 +0000)
committerAndrew G Cohen <cohen@andy.bu.edu>
Tue, 11 Dec 2018 06:17:52 +0000 (14:17 +0800)
* src/nsterm.h (ns_enable_screen_updates): New function.
* src/nsterm.m (ns_enable_screen_updates):
(ns_disable_screen_updates): New functions.
(disable_screen_updates_count): Count of number of times we've called
NSDisableScreenUpdates.
(x_set_window_size): Disable screen updates when not in a live resize
loop.
* src/xdisp.c (redisplay_internal): Reenable screen updates when
redisplay doesn't complete due to a popup.
(unwind_redisplay): Reenable screen updates.

src/nsterm.h
src/nsterm.m
src/xdisp.c

index 8b985930ecb3791b9b508c0c9f8f0347f9a11ad6..df59a7dbd9aaf7360ad8e6c37de270d5cf66f139 100644 (file)
@@ -1160,6 +1160,9 @@ extern void ns_release_autorelease_pool (void *);
 extern const char *ns_get_defaults_value (const char *key);
 extern void ns_init_locale (void);
 
+#ifdef NS_IMPL_COCOA
+extern void ns_enable_screen_updates (void);
+#endif
 
 /* in nsmenu */
 extern void update_frame_tool_bar (struct frame *f);
index 75e0b837c6770d320d6394ac1dc20eb79c503358..f9107c43ce16fed41c79efa7120271f1ebfaf360 100644 (file)
@@ -288,6 +288,9 @@ static BOOL gsaved = NO;
 static BOOL ns_fake_keydown = NO;
 #ifdef NS_IMPL_COCOA
 static BOOL ns_menu_bar_is_hidden = NO;
+
+/* The number of times NSDisableScreenUpdates has been called.  */
+static int disable_screen_updates_count = 0;
 #endif
 /*static int debug_lock = 0; */
 
@@ -727,6 +730,40 @@ ns_release_autorelease_pool (void *pool)
 }
 
 
+#ifdef NS_IMPL_COCOA
+/* Disabling screen updates can be used to make several actions appear
+   "atomic" to the end user.  It seems some actions can still update
+   the display, though.
+
+   When we re-enable screen updates the number of calls to
+   NSEnableScreenUpdates should match the number to
+   NSDisableScreenUpdates.
+
+   We use these functions to prevent the user seeing a blank frame
+   after it has been resized.  x_set_window_size disables updates and
+   when redisplay completes unwind_redisplay enables them again
+   (bug#30699).  */
+
+static void
+ns_disable_screen_updates (void)
+{
+  NSDisableScreenUpdates ();
+  disable_screen_updates_count++;
+}
+
+void
+ns_enable_screen_updates (void)
+/* Re-enable screen updates.  Called from unwind_redisplay.  */
+{
+  while (disable_screen_updates_count > 0)
+    {
+      NSEnableScreenUpdates ();
+      disable_screen_updates_count--;
+    }
+}
+#endif
+
+
 static BOOL
 ns_menu_bar_should_be_hidden (void)
 /* True, if the menu bar should be hidden.  */
@@ -1877,6 +1914,15 @@ x_set_window_size (struct frame *f,
 
   block_input ();
 
+#ifdef NS_IMPL_COCOA
+  /* To prevent showing the user a blank frame, stop updates being
+     flushed to the screen until after redisplay has completed.  This
+     breaks live resize (resizing with a mouse), so don't do it if
+     we're in a live resize loop.  */
+  if (![view inLiveResize])
+    ns_disable_screen_updates ();
+#endif
+
   if (pixelwise)
     {
       pixelwidth = FRAME_TEXT_TO_PIXEL_WIDTH (f, width);
index a97d4db60705d9a51a9fbfa4c62a74c5b7e12964..4778f532cd40045b9c4acd1c84bcb7c3176f9afc 100644 (file)
@@ -13918,7 +13918,15 @@ redisplay_internal (void)
 
 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS)
   if (popup_activated ())
-    return;
+    {
+#ifdef NS_IMPL_COCOA
+      /* On macOS we may have disabled screen updates due to window
+         resizing.  We should re-enable them so the popup can be
+         displayed.  */
+      ns_enable_screen_updates ();
+#endif
+      return;
+    }
 #endif
 
   /* I don't think this happens but let's be paranoid.  */
@@ -14722,6 +14730,12 @@ unwind_redisplay (void)
 {
   redisplaying_p = false;
   unblock_buffer_flips ();
+#ifdef NS_IMPL_COCOA
+  /* On macOS we may have disabled screen updates due to window
+     resizing.  When redisplay completes we want to re-enable
+     them.  */
+  ns_enable_screen_updates ();
+#endif
 }