emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] master d546be3: Fix display of mouse-highlight produced by


From: Eli Zaretskii
Subject: [Emacs-diffs] master d546be3: Fix display of mouse-highlight produced by overlapping overlays
Date: Thu, 2 Mar 2017 10:47:34 -0500 (EST)

branch: master
commit d546be31a9320d94769cb322f008f49d08d852a8
Author: Eli Zaretskii <address@hidden>
Commit: Eli Zaretskii <address@hidden>

    Fix display of mouse-highlight produced by overlapping overlays
    
    * src/xfaces.c (face_at_buffer_position): If called to find the
    mouse-face, only consider the highest-priority source for that
    face, and ignore the rest.  Previously, all the mouse-face
    definitions at POS were merged in that case.
    * src/xdisp.c (note_mouse_highlight): Record the overlay that
    specifies mouse-face _after_ clearing the info about the previous
    overlay, so as not to clear the information about the just-recorded
    overlay.  (Bug#25906)
---
 src/xdisp.c  |  4 +++-
 src/xfaces.c | 53 ++++++++++++++++++++++++++++++++++++++++++-----------
 2 files changed, 45 insertions(+), 12 deletions(-)

diff --git a/src/xdisp.c b/src/xdisp.c
index 1f88784..851a32b 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -30439,12 +30439,14 @@ note_mouse_highlight (struct frame *f, int x, int y)
             no need to do that again.  */
          if (!NILP (overlay) && EQ (overlay, hlinfo->mouse_face_overlay))
            goto check_help_echo;
-         hlinfo->mouse_face_overlay = overlay;
 
          /* Clear the display of the old active region, if any.  */
          if (clear_mouse_face (hlinfo))
            cursor = No_Cursor;
 
+         /* Record the overlay, if any, to be highlighted.  */
+         hlinfo->mouse_face_overlay = overlay;
+
          /* If no overlay applies, get a text property.  */
          if (NILP (overlay))
            mouse_face = Fget_text_property (position, Qmouse_face, object);
diff --git a/src/xfaces.c b/src/xfaces.c
index b5dbb53..7fcaef4 100644
--- a/src/xfaces.c
+++ b/src/xfaces.c
@@ -5869,7 +5869,10 @@ compute_char_face (struct frame *f, int ch, Lisp_Object 
prop)
    LIMIT is a position not to scan beyond.  That is to limit the time
    this function can take.
 
-   If MOUSE, use the character's mouse-face, not its face.
+   If MOUSE, use the character's mouse-face, not its face, and only
+   consider the highest-priority source of mouse-face at POS,
+   i.e. don't merge different mouse-face values if more than one
+   source specifies it.
 
    BASE_FACE_ID, if non-negative, specifies a base face id to use
    instead of DEFAULT_FACE_ID.
@@ -5949,19 +5952,47 @@ face_at_buffer_position (struct window *w, ptrdiff_t 
pos,
 
   /* Now merge the overlay data.  */
   noverlays = sort_overlays (overlay_vec, noverlays, w);
-  for (i = 0; i < noverlays; i++)
+  /* For mouse-face, we need only the single highest-priority face
+     from the overlays, if any.  */
+  if (mouse)
     {
-      Lisp_Object oend;
-      ptrdiff_t oendpos;
+      for (prop = Qnil, i = noverlays - 1; i >= 0 && NILP (prop); --i)
+       {
+         Lisp_Object oend;
+         ptrdiff_t oendpos;
 
-      prop = Foverlay_get (overlay_vec[i], propname);
-      if (!NILP (prop))
-       merge_face_ref (f, prop, attrs, true, 0);
+         prop = Foverlay_get (overlay_vec[i], propname);
+         if (!NILP (prop))
+           {
+             /* Overlays always take priority over text properties,
+                so discard the mouse-face text property, if any, and
+                use the overlay property instead.  */
+             memcpy (attrs, default_face->lface, sizeof attrs);
+             merge_face_ref (f, prop, attrs, true, 0);
+           }
 
-      oend = OVERLAY_END (overlay_vec[i]);
-      oendpos = OVERLAY_POSITION (oend);
-      if (oendpos < endpos)
-       endpos = oendpos;
+         oend = OVERLAY_END (overlay_vec[i]);
+         oendpos = OVERLAY_POSITION (oend);
+         if (oendpos < endpos)
+           endpos = oendpos;
+       }
+    }
+  else
+    {
+      for (i = 0; i < noverlays; i++)
+       {
+         Lisp_Object oend;
+         ptrdiff_t oendpos;
+
+         prop = Foverlay_get (overlay_vec[i], propname);
+         if (!NILP (prop))
+           merge_face_ref (f, prop, attrs, true, 0);
+
+         oend = OVERLAY_END (overlay_vec[i]);
+         oendpos = OVERLAY_POSITION (oend);
+         if (oendpos < endpos)
+           endpos = oendpos;
+       }
     }
 
   *endptr = endpos;



reply via email to

[Prev in Thread] Current Thread [Next in Thread]