Created
March 19, 2018 15:27
-
-
Save aaronjensen/8ab30a42abbdea18d64a1ea11ed9469e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
From 823298202face05009808d2f00e2faa711c3882f Mon Sep 17 00:00:00 2001 | |
From: Alan Third <[email protected]> | |
Date: Sat, 10 Mar 2018 00:09:09 +0000 | |
Subject: [PATCH v2] Fix frame resize flicker on macOS (bug#30699) | |
* 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 | 3 +++ | |
src/nsterm.m | 46 ++++++++++++++++++++++++++++++++++++++++++++++ | |
src/xdisp.c | 16 +++++++++++++++- | |
3 files changed, 64 insertions(+), 1 deletion(-) | |
diff --git a/src/nsterm.h b/src/nsterm.h | |
index 8b985930ec..df59a7dbd9 100644 | |
--- a/src/nsterm.h | |
+++ b/src/nsterm.h | |
@@ -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); | |
diff --git a/src/nsterm.m b/src/nsterm.m | |
index 75e0b837c6..45367dd36f 100644 | |
--- a/src/nsterm.m | |
+++ b/src/nsterm.m | |
@@ -288,6 +288,9 @@ - (NSColor *)colorUsingDefaultColorSpace | |
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 @@ Free a pool and temporary objects it refers to (callable from C) | |
} | |
+#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 this to prevent the user seeing a blank frame after it has | |
+ been resized. x_set_window_size disables updates and when | |
+ redisplay compeltes 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 @@ -(void)remove | |
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); | |
diff --git a/src/xdisp.c b/src/xdisp.c | |
index a97d4db607..4778f532cd 100644 | |
--- a/src/xdisp.c | |
+++ b/src/xdisp.c | |
@@ -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 | |
} | |
-- | |
2.16.1 | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment