diff options
| author | Eli Zaretskii | 2017-03-02 17:46:25 +0200 |
|---|---|---|
| committer | Eli Zaretskii | 2017-03-02 17:46:25 +0200 |
| commit | d546be31a9320d94769cb322f008f49d08d852a8 (patch) | |
| tree | b51d96fe8a81f90e82530a43ad8db959cf671ff1 /src | |
| parent | 511a3c3ba27352fde26ae2371a9d4a64c6418122 (diff) | |
| download | emacs-d546be31a9320d94769cb322f008f49d08d852a8.tar.gz emacs-d546be31a9320d94769cb322f008f49d08d852a8.zip | |
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)
Diffstat (limited to 'src')
| -rw-r--r-- | src/xdisp.c | 4 | ||||
| -rw-r--r-- | src/xfaces.c | 53 |
2 files changed, 45 insertions, 12 deletions
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) | |||
| 30439 | no need to do that again. */ | 30439 | no need to do that again. */ |
| 30440 | if (!NILP (overlay) && EQ (overlay, hlinfo->mouse_face_overlay)) | 30440 | if (!NILP (overlay) && EQ (overlay, hlinfo->mouse_face_overlay)) |
| 30441 | goto check_help_echo; | 30441 | goto check_help_echo; |
| 30442 | hlinfo->mouse_face_overlay = overlay; | ||
| 30443 | 30442 | ||
| 30444 | /* Clear the display of the old active region, if any. */ | 30443 | /* Clear the display of the old active region, if any. */ |
| 30445 | if (clear_mouse_face (hlinfo)) | 30444 | if (clear_mouse_face (hlinfo)) |
| 30446 | cursor = No_Cursor; | 30445 | cursor = No_Cursor; |
| 30447 | 30446 | ||
| 30447 | /* Record the overlay, if any, to be highlighted. */ | ||
| 30448 | hlinfo->mouse_face_overlay = overlay; | ||
| 30449 | |||
| 30448 | /* If no overlay applies, get a text property. */ | 30450 | /* If no overlay applies, get a text property. */ |
| 30449 | if (NILP (overlay)) | 30451 | if (NILP (overlay)) |
| 30450 | mouse_face = Fget_text_property (position, Qmouse_face, object); | 30452 | 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) | |||
| 5869 | LIMIT is a position not to scan beyond. That is to limit the time | 5869 | LIMIT is a position not to scan beyond. That is to limit the time |
| 5870 | this function can take. | 5870 | this function can take. |
| 5871 | 5871 | ||
| 5872 | If MOUSE, use the character's mouse-face, not its face. | 5872 | If MOUSE, use the character's mouse-face, not its face, and only |
| 5873 | consider the highest-priority source of mouse-face at POS, | ||
| 5874 | i.e. don't merge different mouse-face values if more than one | ||
| 5875 | source specifies it. | ||
| 5873 | 5876 | ||
| 5874 | BASE_FACE_ID, if non-negative, specifies a base face id to use | 5877 | BASE_FACE_ID, if non-negative, specifies a base face id to use |
| 5875 | instead of DEFAULT_FACE_ID. | 5878 | instead of DEFAULT_FACE_ID. |
| @@ -5949,19 +5952,47 @@ face_at_buffer_position (struct window *w, ptrdiff_t pos, | |||
| 5949 | 5952 | ||
| 5950 | /* Now merge the overlay data. */ | 5953 | /* Now merge the overlay data. */ |
| 5951 | noverlays = sort_overlays (overlay_vec, noverlays, w); | 5954 | noverlays = sort_overlays (overlay_vec, noverlays, w); |
| 5952 | for (i = 0; i < noverlays; i++) | 5955 | /* For mouse-face, we need only the single highest-priority face |
| 5956 | from the overlays, if any. */ | ||
| 5957 | if (mouse) | ||
| 5953 | { | 5958 | { |
| 5954 | Lisp_Object oend; | 5959 | for (prop = Qnil, i = noverlays - 1; i >= 0 && NILP (prop); --i) |
| 5955 | ptrdiff_t oendpos; | 5960 | { |
| 5961 | Lisp_Object oend; | ||
| 5962 | ptrdiff_t oendpos; | ||
| 5956 | 5963 | ||
| 5957 | prop = Foverlay_get (overlay_vec[i], propname); | 5964 | prop = Foverlay_get (overlay_vec[i], propname); |
| 5958 | if (!NILP (prop)) | 5965 | if (!NILP (prop)) |
| 5959 | merge_face_ref (f, prop, attrs, true, 0); | 5966 | { |
| 5967 | /* Overlays always take priority over text properties, | ||
| 5968 | so discard the mouse-face text property, if any, and | ||
| 5969 | use the overlay property instead. */ | ||
| 5970 | memcpy (attrs, default_face->lface, sizeof attrs); | ||
| 5971 | merge_face_ref (f, prop, attrs, true, 0); | ||
| 5972 | } | ||
| 5960 | 5973 | ||
| 5961 | oend = OVERLAY_END (overlay_vec[i]); | 5974 | oend = OVERLAY_END (overlay_vec[i]); |
| 5962 | oendpos = OVERLAY_POSITION (oend); | 5975 | oendpos = OVERLAY_POSITION (oend); |
| 5963 | if (oendpos < endpos) | 5976 | if (oendpos < endpos) |
| 5964 | endpos = oendpos; | 5977 | endpos = oendpos; |
| 5978 | } | ||
| 5979 | } | ||
| 5980 | else | ||
| 5981 | { | ||
| 5982 | for (i = 0; i < noverlays; i++) | ||
| 5983 | { | ||
| 5984 | Lisp_Object oend; | ||
| 5985 | ptrdiff_t oendpos; | ||
| 5986 | |||
| 5987 | prop = Foverlay_get (overlay_vec[i], propname); | ||
| 5988 | if (!NILP (prop)) | ||
| 5989 | merge_face_ref (f, prop, attrs, true, 0); | ||
| 5990 | |||
| 5991 | oend = OVERLAY_END (overlay_vec[i]); | ||
| 5992 | oendpos = OVERLAY_POSITION (oend); | ||
| 5993 | if (oendpos < endpos) | ||
| 5994 | endpos = oendpos; | ||
| 5995 | } | ||
| 5965 | } | 5996 | } |
| 5966 | 5997 | ||
| 5967 | *endptr = endpos; | 5998 | *endptr = endpos; |