From: Eli Zaretskii Date: Thu, 2 Mar 2017 15:46:25 +0000 (+0200) Subject: Fix display of mouse-highlight produced by overlapping overlays X-Git-Tag: emacs-26.0.90~668 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=d546be31a9320d94769cb322f008f49d08d852a8;p=emacs.git 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) --- diff --git a/src/xdisp.c b/src/xdisp.c index 1f8878408be..851a32b4f88 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 b5dbb53ca20..7fcaef4e41a 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;