]> code.delx.au - gnu-emacs/blobdiff - src/xterm.c
(try_window_id) <all changes below window end>: Don't
[gnu-emacs] / src / xterm.c
index 056514d709646d3dc2c9b83fb8254c3f1a288d53..c7b8535c4808443c3ea891552fd8cb802328e56a 100644 (file)
@@ -399,6 +399,7 @@ enum draw_glyphs_face
   DRAW_IMAGE_SUNKEN
 };
 
+static int cursor_in_mouse_face_p P_ ((struct window *));
 static int clear_mouse_face P_ ((struct x_display_info *));
 static int x_alloc_nearest_color_1 P_ ((Display *, Colormap, XColor *));
 static void x_set_window_size_1 P_ ((struct frame *, int, int, int));
@@ -4384,14 +4385,23 @@ x_draw_stretch_glyph_string (s)
       /* Clear rest using the GC of the original non-cursor face.  */
       if (width < s->background_width)
        {
-         GC gc = s->face->gc;
          int x = s->x + width, y = s->y;
          int w = s->background_width - width, h = s->height;
          XRectangle r;
+         GC gc;
 
+         if (s->row->mouse_face_p
+             && cursor_in_mouse_face_p (s->w))
+           {
+             x_set_mouse_face_gc (s);
+             gc = s->gc;
+           }
+         else
+           gc = s->face->gc;
+  
          x_get_glyph_string_clip_rect (s, &r);
          XSetClipRectangles (s->display, gc, 0, 0, &r, 1, Unsorted);
-
+         
          if (s->face->stipple)
            {
              /* Fill background with a stipple pattern.  */
@@ -6949,10 +6959,6 @@ note_mouse_highlight (f, x, y)
          || (OVERLAYP (dpyinfo->mouse_face_overlay)
              && mouse_face_overlay_overlaps (dpyinfo->mouse_face_overlay)))
        {
-         /* Clear the display of the old active region, if any.  */
-         if (clear_mouse_face (dpyinfo))
-           cursor = None;
-
          /* Find the highest priority overlay that has a mouse-face
             property.  */
          overlay = Qnil;
@@ -6962,8 +6968,19 @@ note_mouse_highlight (f, x, y)
              if (!NILP (mouse_face))
                overlay = overlay_vec[i];
            }
-         dpyinfo->mouse_face_overlay = overlay;
+         
+         /* If we're actually highlighting the same overlay as
+            before, there's no need to do that again.  */
+         if (!NILP (overlay)
+             && EQ (overlay, dpyinfo->mouse_face_overlay))
+           goto check_help_echo;
            
+         dpyinfo->mouse_face_overlay = overlay;
+
+         /* Clear the display of the old active region, if any.  */
+         if (clear_mouse_face (dpyinfo))
+           cursor = None;
+
          /* If no overlay applies, get a text property.  */
          if (NILP (overlay))
            mouse_face = Fget_text_property (position, Qmouse_face, object);
@@ -6997,6 +7014,7 @@ note_mouse_highlight (f, x, y)
 
              /* Display it as active.  */
              show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
+             cursor = None;
            }
          /* Handle the text property case.  */
          else if (!NILP (mouse_face) && BUFFERP (object))
@@ -7038,6 +7056,7 @@ note_mouse_highlight (f, x, y)
 
              /* Display it as active.  */
              show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
+             cursor = None;
            }
          else if (!NILP (mouse_face) && STRINGP (object))
            {
@@ -7069,9 +7088,12 @@ note_mouse_highlight (f, x, y)
                = face_at_string_position (w, object, pos, 0, 0, 0, &ignore,
                                           glyph->face_id, 1);
              show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
+             cursor = None;
            }
        }
 
+    check_help_echo:
+
       /* Look for a `help-echo' property.  */
       {
        Lisp_Object help, overlay;
@@ -7674,6 +7696,7 @@ clear_mouse_face (dpyinfo)
   dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
   dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
   dpyinfo->mouse_face_window = Qnil;
+  dpyinfo->mouse_face_overlay = Qnil;
   return cleared;
 }
 
@@ -11198,6 +11221,35 @@ x_erase_phys_cursor (w)
 }
 
 
+/* Non-zero if physical cursor of window W is within mouse face.  */
+
+static int
+cursor_in_mouse_face_p (w)
+     struct window *w;
+{
+  struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (w->frame));
+  int in_mouse_face = 0;
+  
+  if (WINDOWP (dpyinfo->mouse_face_window)
+      && XWINDOW (dpyinfo->mouse_face_window) == w)
+    {
+      int hpos = w->phys_cursor.hpos;
+      int vpos = w->phys_cursor.vpos;
+
+      if (vpos >= dpyinfo->mouse_face_beg_row
+         && vpos <= dpyinfo->mouse_face_end_row
+         && (vpos > dpyinfo->mouse_face_beg_row
+             || hpos >= dpyinfo->mouse_face_beg_col)
+         && (vpos < dpyinfo->mouse_face_end_row
+             || hpos < dpyinfo->mouse_face_end_col
+             || dpyinfo->mouse_face_past_end))
+       in_mouse_face = 1;
+    }
+
+  return in_mouse_face;
+}
+
+
 /* Display or clear cursor of window W.  If ON is zero, clear the
    cursor.  If it is non-zero, display the cursor.  If ON is nonzero,
    where to put the cursor is specified by HPOS, VPOS, X and Y.  */
@@ -11980,7 +12032,7 @@ xim_open_dpy (dpyinfo, resource_name)
 #ifdef HAVE_X11R6
       destroy.callback = xim_destroy_callback;
       destroy.client_data = (XPointer)dpyinfo;
-      /* This isn't prptotyped in OSF 5.0.  */
+      /* This isn't prototyped in OSF 5.0.  */
       XSetIMValues (xim, XNDestroyCallback, &destroy, NULL);
 #endif
     }