Avoid leaving artifacts when the system caret is used on w32

* src/xdisp.c (try_window_reusing_current_matrix, try_window_id):
* src/dispnew.c (scrolling_window) [HAVE_NTGUI]: If
w32-use-visible-system-caret is non-nil, disallow scrolling the
display are in scroll_run_hook.  This avoids copying traces of the
caret, about which Emacs knows nothing, and thus considers those
pixels show the default background.  (Bug#39188)
(gui_update_window_end): Block input only around part of the code,
as we did before this code was extracted from backend-specific
implementations.

* src/w32term.c (w32_update_window_begin, w32_update_window_end):
Only hide/show the caret when redisplaying the window where the
caret is shown.
This commit is contained in:
Eli Zaretskii 2020-01-21 18:23:32 +02:00
parent 5abd8d73b0
commit 4aec94da37
3 changed files with 31 additions and 5 deletions

View file

@ -3743,11 +3743,10 @@ gui_update_window_end (struct window *w, bool cursor_on_p,
{
struct frame *f = XFRAME (WINDOW_FRAME (w));
block_input ();
/* Pseudo windows don't have cursors, so don't display them here. */
if (!w->pseudo_window_p)
{
block_input ();
if (cursor_on_p)
display_and_set_cursor (w, true,
@ -3761,6 +3760,7 @@ gui_update_window_end (struct window *w, bool cursor_on_p,
else
gui_draw_vertical_border (w);
}
unblock_input ();
}
/* If a row with mouse-face was overwritten, arrange for
@ -3778,7 +3778,6 @@ gui_update_window_end (struct window *w, bool cursor_on_p,
FRAME_RIF (f)->update_window_end_hook (w,
cursor_on_p,
mouse_face_overwritten_p);
unblock_input ();
}
#endif /* HAVE_WINDOW_SYSTEM */
@ -4360,6 +4359,14 @@ scrolling_window (struct window *w, int tab_line_p)
return 0;
#endif
/* Can't scroll the display of w32 GUI frames when position of point
is indicated by the system caret, because scrolling the display
will then "copy" the pixles used by the caret. */
#ifdef HAVE_NTGUI
if (w32_use_visible_system_caret)
return 0;
#endif
/* Give up if some rows in the desired matrix are not enabled. */
if (! MATRIX_ROW_ENABLED_P (desired_matrix, i))
return -1;

View file

@ -560,7 +560,8 @@ static void
w32_update_window_begin (struct window *w)
{
/* Hide the system caret during an update. */
if (w32_use_visible_system_caret && w32_system_caret_hwnd)
if (w32_use_visible_system_caret && w32_system_caret_hwnd
&& w == w32_system_caret_window)
{
SendMessageTimeout (w32_system_caret_hwnd, WM_EMACS_HIDE_CARET, 0, 0,
0, 6000, NULL);
@ -657,7 +658,8 @@ w32_update_window_end (struct window *w, bool cursor_on_p,
/* Unhide the caret. This won't actually show the cursor, unless it
was visible before the corresponding call to HideCaret in
w32_update_window_begin. */
if (w32_use_visible_system_caret && w32_system_caret_hwnd)
if (w32_use_visible_system_caret && w32_system_caret_hwnd
&& w == w32_system_caret_window)
{
SendMessageTimeout (w32_system_caret_hwnd, WM_EMACS_SHOW_CARET, 0, 0,
0, 6000, NULL);

View file

@ -19191,6 +19191,14 @@ try_window_reusing_current_matrix (struct window *w)
if (!NILP (Vdisplay_line_numbers))
return false;
/* Can't scroll the display of w32 GUI frames when position of point
is indicated by the system caret, because scrolling the display
will then "copy" the pixles used by the caret. */
#ifdef HAVE_NTGUI
if (w32_use_visible_system_caret)
return false;
#endif
/* The variable new_start now holds the new window start. The old
start `start' can be determined from the current matrix. */
SET_TEXT_POS_FROM_MARKER (new_start, w->start);
@ -20175,6 +20183,15 @@ try_window_id (struct window *w)
if (MATRIX_ROW_START_CHARPOS (row) == MATRIX_ROW_END_CHARPOS (row))
GIVE_UP (20);
/* Can't let scroll_run_hook below run on w32 GUI frames when
position of point is indicated by the system caret, because
scrolling the display will then "copy" the pixles used by the
caret. */
#ifdef HAVE_NTGUI
if (FRAME_W32_P (f) && w32_use_visible_system_caret)
GIVE_UP (25);
#endif
/* Compute the position at which we have to start displaying new
lines. Some of the lines at the top of the window might be
reusable because they are not displaying changed text. Find the