From 57447f5ce0a723f698d1515485860ca17ce93960 Mon Sep 17 00:00:00 2001 From: Po Lu Date: Sat, 30 Apr 2022 18:54:34 +0800 Subject: [PATCH] Fix display updating inside the minibuffer on MS Windows * src/minibuf.c (read_minibuf): Call `w32_flip_buffers_if_dirty' after changing the cursor position and redisplaying instead of `flush_frame'. (bug#55193) * src/w32term.c (w32_flip_buffers_if_dirty): New function. * src/w32term.h: Update prototypes. --- src/minibuf.c | 14 ++++++++++++++ src/w32term.c | 13 +++++++++++++ src/w32term.h | 1 + 3 files changed, 28 insertions(+) diff --git a/src/minibuf.c b/src/minibuf.c index dacfd1255ba..df82bcb121a 100644 --- a/src/minibuf.c +++ b/src/minibuf.c @@ -34,6 +34,10 @@ along with GNU Emacs. If not, see . */ #include "systty.h" #include "pdumper.h" +#ifdef HAVE_NTGUI +#include "w32term.h" +#endif + /* List of buffers for use as minibuffers. The first element of the list is used for the outermost minibuffer invocation, the next element is used for a recursive minibuffer @@ -916,7 +920,17 @@ read_minibuf (Lisp_Object map, Lisp_Object initial, Lisp_Object prompt, XWINDOW (minibuf_window)->cursor.x = 0; XWINDOW (minibuf_window)->must_be_updated_p = true; update_frame (XFRAME (selected_frame), true, true); +#ifndef HAVE_NTGUI flush_frame (XFRAME (XWINDOW (minibuf_window)->frame)); +#else + /* The reason this function isn't `flush_display' in the RIF is + that `flush_frame' is also called in many other circumstances + when some code wants X requests to be sent to the X server, + but there is no corresponding "flush" concept on MS Windows, + and flipping buffers every time `flush_frame' is called + causes flicker. */ + w32_flip_buffers_if_dirty (XFRAME (XWINDOW (minibuf_window)->frame)); +#endif } /* Make minibuffer contents into a string. */ diff --git a/src/w32term.c b/src/w32term.c index 0c16dc1eef4..11675085fcc 100644 --- a/src/w32term.c +++ b/src/w32term.c @@ -774,6 +774,19 @@ w32_buffer_flipping_unblocked_hook (struct frame *f) w32_show_back_buffer (f); } +/* Flip buffers on F if drawing has happened. This function is not + called to flush the display connection of a frame (which doesn't + exist on MS Windows), but also called in some situations in + minibuf.c to make the contents of the back buffer visible. */ +void +w32_flip_buffers_if_dirty (struct frame *f) +{ + if (FRAME_OUTPUT_DATA (f)->paint_buffer + && FRAME_OUTPUT_DATA (f)->paint_buffer_dirty + && !f->garbaged && !buffer_flipping_blocked_p ()) + w32_show_back_buffer (f); +} + /* Draw truncation mark bitmaps, continuation mark bitmaps, overlay arrow bitmaps, or clear the fringes if no bitmaps are required before DESIRED_ROW is made current. This function is called from diff --git a/src/w32term.h b/src/w32term.h index 2dcc43fc59f..88b7ec22bd1 100644 --- a/src/w32term.h +++ b/src/w32term.h @@ -898,6 +898,7 @@ typedef char guichar_t; extern Lisp_Object w32_popup_dialog (struct frame *, Lisp_Object, Lisp_Object); extern void w32_arrow_cursor (void); extern void w32_release_paint_buffer (struct frame *); +extern void w32_flip_buffers_if_dirty (struct frame *); extern void syms_of_w32term (void); extern void syms_of_w32menu (void); -- 2.39.2