Subject: bug#35463: [PATCH] Refactor update_window_begin and update_window_end hooks

From: Alex Gramiak <[email-masked]>
Date: Sat, 27 Apr 2019 15:40:47 -0600

Ah, I forgot to update the patch to not use reset_mouse_highlight in the
generic version:

>From 380549267f0e83d284752ac90f2fdd1a8da99afb Mon Sep 17 00:00:00 2001
From: Alexander Gramiak <[email-masked]>
Date: Sat, 27 Apr 2019 15:00:13 -0600
Subject: [PATCH] Refactor update_window_begin and update_window_end hooks

* src/xdisp.c (gui_update_window_begin, gui_update_window_end): New
procedures implementing common functionality.

* src/nsterm.m: (ns_update_window_begin, ns_update_window_end): Remove
in favor of the generic version.

* src/w32term.c: (w32_update_window_begin, w32_update_window_end):
Use gui_update_window_begin and gui_update_window_end.

* src/xterm.c: (x_update_window_begin, x_update_window_end): Remove in
favor of the generic version.
---
 src/dispextern.h |  3 ++
 src/nsterm.m     | 78 +++-----------------------------------------
 src/w32term.c    | 40 ++---------------------
 src/xdisp.c      | 73 +++++++++++++++++++++++++++++++++++++++++
 src/xterm.c      | 84 +++---------------------------------------------
 5 files changed, 86 insertions(+), 192 deletions(-)

diff --git a/src/dispextern.h b/src/dispextern.h
index 4d6d0371d3..827eed86f1 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -3303,6 +3303,9 @@ extern void gui_update_cursor (struct frame *, bool);
 extern void gui_clear_cursor (struct window *);
 extern void gui_draw_vertical_border (struct window *w);
 extern void gui_draw_right_divider (struct window *w);
+extern void gui_update_window_begin (struct window *w);
+extern void gui_update_window_end (struct window *w, bool cursor_on_p,
+                                   bool mouse_face_overwritten_p);
 
 extern int get_glyph_string_clip_rects (struct glyph_string *,
                                         NativeRectangle *, int);
diff --git a/src/nsterm.m b/src/nsterm.m
index cdf1916e71..2a2b8cbaba 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -1106,7 +1106,7 @@ static NSRect constrain_frame_rect(NSRect frameRect, bool isFullscreen)
 ns_update_begin (struct frame *f)
 /* --------------------------------------------------------------------------
    Prepare for a grouped sequence of drawing calls
-   external (RIF) call; whole frame, called before update_window_begin
+   external (RIF) call; whole frame, called before gui_update_window_begin
    -------------------------------------------------------------------------- */
 {
 #ifdef NS_IMPL_COCOA
@@ -1128,81 +1128,11 @@ static NSRect constrain_frame_rect(NSRect frameRect, bool isFullscreen)
 }

-static void
-ns_update_window_begin (struct window *w)
-/* --------------------------------------------------------------------------
-   Prepare for a grouped sequence of drawing calls
-   external (RIF) call; for one window, called after update_begin
-   -------------------------------------------------------------------------- */
-{
-  struct frame *f = XFRAME (WINDOW_FRAME (w));
-  Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
-
-  NSTRACE_WHEN (NSTRACE_GROUP_UPDATES, "ns_update_window_begin");
-  w->output_cursor = w->cursor;
-
-  block_input ();
-
-  if (f == hlinfo->mouse_face_mouse_frame)
-    {
-      /* Don't do highlighting for mouse motion during the update.  */
-      hlinfo->mouse_face_defer = 1;
-
-        /* If the frame needs to be redrawn,
-           simply forget about any prior mouse highlighting.  */
-      if (FRAME_GARBAGED_P (f))
-        hlinfo->mouse_face_window = Qnil;
-
-      /* (further code for mouse faces ifdef'd out in other terms elided) */
-    }
-
-  unblock_input ();
-}
-
-
-static void
-ns_update_window_end (struct window *w, bool cursor_on_p,
-                      bool mouse_face_overwritten_p)
-/* --------------------------------------------------------------------------
-   Finished a grouped sequence of drawing calls
-   external (RIF) call; for one window called before update_end
-   -------------------------------------------------------------------------- */
-{
-  NSTRACE_WHEN (NSTRACE_GROUP_UPDATES, "ns_update_window_end");
-
-  /* note: this fn is nearly identical in all terms */
-  if (!w->pseudo_window_p)
-    {
-      block_input ();
-
-      if (cursor_on_p)
-	display_and_set_cursor (w, 1,
-				w->output_cursor.hpos, w->output_cursor.vpos,
-				w->output_cursor.x, w->output_cursor.y);
-
-      if (draw_window_fringes (w, 1))
-	{
-	  if (WINDOW_RIGHT_DIVIDER_WIDTH (w))
-	    gui_draw_right_divider (w);
-	  else
-	    gui_draw_vertical_border (w);
-	}
-
-      unblock_input ();
-    }
-
-  /* If a row with mouse-face was overwritten, arrange for
-     frame_up_to_date to redisplay the mouse highlight.  */
-  if (mouse_face_overwritten_p)
-    reset_mouse_highlight (MOUSE_HL_INFO (XFRAME (w->frame)));
-}
-
-
 static void
 ns_update_end (struct frame *f)
 /* --------------------------------------------------------------------------
    Finished a grouped sequence of drawing calls
-   external (RIF) call; for whole frame, called after update_window_end
+   external (RIF) call; for whole frame, called after gui_update_window_end
    -------------------------------------------------------------------------- */
 {
   NSTRACE_WHEN (NSTRACE_GROUP_UPDATES, "ns_update_end");
@@ -5166,8 +5096,8 @@ static Lisp_Object ns_string_to_lispmod (const char *s)
   gui_clear_end_of_line,
   ns_scroll_run,
   ns_after_update_window_line,
-  ns_update_window_begin,
-  ns_update_window_end,
+  gui_update_window_begin,
+  gui_update_window_end,
   0, /* flush_display */
   gui_clear_window_mouse_face,
   gui_get_glyph_overhangs,
diff --git a/src/w32term.c b/src/w32term.c
index 451dd54dd8..8d5f57836c 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -565,19 +565,12 @@ w32_update_window_begin (struct window *w)
 			  0, 6000, NULL);
     }
 
-  w->output_cursor = w->cursor;
+  gui_update_window_begin (w);
 
   block_input ();
 
   if (f == hlinfo->mouse_face_mouse_frame)
     {
-      /* Don't do highlighting for mouse motion during the update.  */
-      hlinfo->mouse_face_defer = true;
-
-      /* If F needs to be redrawn, simply forget about any prior mouse
-	 highlighting.  */
-      if (FRAME_GARBAGED_P (f))
-	hlinfo->mouse_face_window = Qnil;
 
 #if 0 /* Rows in a current matrix containing glyphs in mouse-face have
 	 their mouse_face_p flag set, which means that they are always
@@ -696,36 +689,7 @@ static void
 w32_update_window_end (struct window *w, bool cursor_on_p,
 		     bool mouse_face_overwritten_p)
 {
-  if (!w->pseudo_window_p)
-    {
-      block_input ();
-
-      if (cursor_on_p)
-	display_and_set_cursor (w, true,
-				w->output_cursor.hpos, w->output_cursor.vpos,
-				w->output_cursor.x, w->output_cursor.y);
-
-      if (draw_window_fringes (w, true))
-	{
-	  if (WINDOW_RIGHT_DIVIDER_WIDTH (w))
-	    gui_draw_right_divider (w);
-	  else
-	    gui_draw_vertical_border (w);
-	}
-
-      unblock_input ();
-    }
-
-  /* If a row with mouse-face was overwritten, arrange for
-     XTframe_up_to_date to redisplay the mouse highlight.  */
-  if (mouse_face_overwritten_p)
-    {
-      Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame));
-
-      hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
-      hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
-      hlinfo->mouse_face_window = Qnil;
-    }
+  gui_update_window_end (w, cursor_on_p, mouse_face_overwritten_p);
 
   /* Unhide the caret.  This won't actually show the cursor, unless it
      was visible before the corresponding call to HideCaret in
diff --git a/src/xdisp.c b/src/xdisp.c
index d52d1333a0..a3dddfa8a5 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -32223,6 +32223,79 @@ gui_draw_bottom_divider (struct window *w)
     }
 }
 
+/* EXPORT:
+   Start update of window W.  */
+
+void
+gui_update_window_begin (struct window *w)
+{
+  struct frame *f = XFRAME (WINDOW_FRAME (w));
+  Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
+
+  w->output_cursor = w->cursor;
+
+  block_input ();
+
+  if (f == hlinfo->mouse_face_mouse_frame)
+    {
+      /* Don't do highlighting for mouse motion during the update.  */
+      hlinfo->mouse_face_defer = true;
+
+      /* If the frame needs to be redrawn, simply forget about any
+	 prior mouse highlighting.  */
+      if (FRAME_GARBAGED_P (f))
+	hlinfo->mouse_face_window = Qnil;
+    }
+
+  unblock_input ();
+}
+
+/* EXPORT:
+   End update of window W.
+
+   Draw vertical borders between horizontally adjacent windows, and
+   display W's cursor if CURSOR_ON_P is non-zero.
+
+   MOUSE_FACE_OVERWRITTEN_P non-zero means that some row containing
+   glyphs in mouse-face were overwritten.  In that case we have to
+   make sure that the mouse-highlight is properly redrawn.  */
+void
+gui_update_window_end (struct window *w, bool cursor_on_p,
+                       bool mouse_face_overwritten_p)
+{
+  /* 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,
+				w->output_cursor.hpos, w->output_cursor.vpos,
+				w->output_cursor.x, w->output_cursor.y);
+
+      if (draw_window_fringes (w, true))
+	{
+	  if (WINDOW_RIGHT_DIVIDER_WIDTH (w))
+	    gui_draw_right_divider (w);
+	  else
+	    gui_draw_vertical_border (w);
+	}
+
+      unblock_input ();
+    }
+
+  /* If a row with mouse-face was overwritten, arrange for
+     frame_up_to_date_hook to redisplay the mouse highlight.  */
+  if (mouse_face_overwritten_p)
+    {
+      Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame));
+
+      hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
+      hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
+      hlinfo->mouse_face_window = Qnil;
+    }
+}
+
 /* Redraw the part of window W intersection rectangle FR.  Pixel
    coordinates in FR are frame-relative.  Call this function with
    input blocked.  Value is true if the exposure overwrites
diff --git a/src/xterm.c b/src/xterm.c
index dd19b8bde1..b08f5f6a62 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -989,7 +989,7 @@ x_set_frame_alpha (struct frame *f)
 
 /* Start an update of frame F.  This function is installed as a hook
    for update_begin, i.e. it is called when update_begin is called.
-   This function is called prior to calls to x_update_window_begin for
+   This function is called prior to calls to gui_update_window_begin for
    each window being updated.  Currently, there is nothing to do here
    because all interesting stuff is done on a window basis.  */
 
@@ -1033,33 +1033,6 @@ x_update_begin (struct frame *f)
 #endif /* USE_CAIRO */
 }
 
-/* Start update of window W.  */
-
-static void
-x_update_window_begin (struct window *w)
-{
-  struct frame *f = XFRAME (WINDOW_FRAME (w));
-  Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
-
-  w->output_cursor = w->cursor;
-
-  block_input ();
-
-  if (f == hlinfo->mouse_face_mouse_frame)
-    {
-      /* Don't do highlighting for mouse motion during the update.  */
-      hlinfo->mouse_face_defer = true;
-
-      /* If F needs to be redrawn, simply forget about any prior mouse
-	 highlighting.  */
-      if (FRAME_GARBAGED_P (f))
-	hlinfo->mouse_face_window = Qnil;
-    }
-
-  unblock_input ();
-}
-
-
 /* Draw a vertical window border from (x,y0) to (x,y1)  */
 
 static void
@@ -1139,55 +1112,6 @@ x_draw_window_divider (struct window *w, int x0, int x1, int y0, int y1)
     }
 }
 
-/* End update of window W.
-
-   Draw vertical borders between horizontally adjacent windows, and
-   display W's cursor if CURSOR_ON_P is non-zero.
-
-   MOUSE_FACE_OVERWRITTEN_P non-zero means that some row containing
-   glyphs in mouse-face were overwritten.  In that case we have to
-   make sure that the mouse-highlight is properly redrawn.
-
-   W may be a menu bar pseudo-window in case we don't have X toolkit
-   support.  Such windows don't have a cursor, so don't display it
-   here.  */
-
-static void
-x_update_window_end (struct window *w, bool cursor_on_p,
-		     bool mouse_face_overwritten_p)
-{
-  if (!w->pseudo_window_p)
-    {
-      block_input ();
-
-      if (cursor_on_p)
-	display_and_set_cursor (w, true,
-				w->output_cursor.hpos, w->output_cursor.vpos,
-				w->output_cursor.x, w->output_cursor.y);
-
-      if (draw_window_fringes (w, true))
-	{
-	  if (WINDOW_RIGHT_DIVIDER_WIDTH (w))
-	    gui_draw_right_divider (w);
-	  else
-	    gui_draw_vertical_border (w);
-	}
-
-      unblock_input ();
-    }
-
-  /* If a row with mouse-face was overwritten, arrange for
-     XTframe_up_to_date to redisplay the mouse highlight.  */
-  if (mouse_face_overwritten_p)
-    {
-      Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame));
-
-      hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
-      hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
-      hlinfo->mouse_face_window = Qnil;
-    }
-}
-
 /* Show the frame back buffer.  If frame is double-buffered,
    atomically publish to the user's screen graphics updates made since
    the last call to show_back_buffer.  */
@@ -4306,7 +4230,7 @@ x_scroll_run (struct window *w, struct run *run)
 
   block_input ();
 
-  /* Cursor off.  Will be switched on again in x_update_window_end.  */
+  /* Cursor off.  Will be switched on again in gui_update_window_end.  */
   gui_clear_cursor (w);
 
 #ifdef USE_CAIRO
@@ -13145,8 +13069,8 @@ static struct redisplay_interface x_redisplay_interface =
     gui_clear_end_of_line,
     x_scroll_run,
     x_after_update_window_line,
-    x_update_window_begin,
-    x_update_window_end,
+    gui_update_window_begin,
+    gui_update_window_end,
     x_flip_and_flush,
     gui_clear_window_mouse_face,
     gui_get_glyph_overhangs,
-- 
2.21.0