Merge from emacs--rel--22
[bpt/emacs.git] / src / xterm.c
index 512fff3..a5bb506 100644 (file)
@@ -720,8 +720,10 @@ x_draw_fringe_bitmap (w, row, p)
   else
     x_clip_to_row (w, row, -1, gc);
 
-  if (p->bx >= 0 && !p->overlay_p)
+  if (!p->overlay_p)
     {
+      int bx = p->bx, by = p->by, nx = p->nx, ny = p->ny;
+
       /* In case the same realized face is used for fringes and
         for something displayed in the text (e.g. face `region' on
         mono-displays, the fill style may have been changed to
@@ -731,8 +733,55 @@ x_draw_fringe_bitmap (w, row, p)
       else
        XSetForeground (display, face->gc, face->background);
 
-      XFillRectangle (display, window, face->gc,
-                     p->bx, p->by, p->nx, p->ny);
+#ifdef USE_TOOLKIT_SCROLL_BARS
+      /* If the fringe is adjacent to the left (right) scroll bar of a
+        leftmost (rightmost, respectively) window, then extend its
+        background to the gap between the fringe and the bar.  */
+      if ((WINDOW_LEFTMOST_P (w)
+          && WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
+         || (WINDOW_RIGHTMOST_P (w)
+             && WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w)))
+       {
+         int sb_width = WINDOW_CONFIG_SCROLL_BAR_WIDTH (w);
+
+         if (sb_width > 0)
+           {
+             int left = WINDOW_SCROLL_BAR_AREA_X (w);
+             int width = (WINDOW_CONFIG_SCROLL_BAR_COLS (w)
+                          * FRAME_COLUMN_WIDTH (f));
+
+             if (bx < 0)
+               {
+                 /* Bitmap fills the fringe.  */
+                 if (left + width == p->x)
+                   bx = left + sb_width;
+                 else if (p->x + p->wd == left)
+                   bx = left;
+                 if (bx >= 0)
+                   {
+                     int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
+
+                     nx = width - sb_width;
+                     by = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height,
+                                                           row->y));
+                     ny = row->visible_height;
+                   }
+               }
+             else
+               {
+                 if (left + width == bx)
+                   {
+                     bx = left + sb_width;
+                     nx += width - sb_width;
+                   }
+                 else if (bx + nx == left)
+                   nx += width - sb_width;
+               }
+           }
+       }
+#endif
+      if (bx >= 0 && nx > 0)
+       XFillRectangle (display, window, face->gc, bx, by, nx, ny);
 
       if (!face->stipple)
        XSetForeground (display, face->gc, face->foreground);
@@ -4789,6 +4838,9 @@ x_scroll_bar_create (w, top, left, width, height)
   XSETINT (bar->start, 0);
   XSETINT (bar->end, 0);
   bar->dragging = Qnil;
+#ifdef USE_TOOLKIT_SCROLL_BARS
+  bar->fringe_extended_p = Qnil;
+#endif
 
   /* Add bar to its frame's list of scroll bars.  */
   bar->next = FRAME_SCROLL_BARS (f);
@@ -4981,6 +5033,9 @@ XTset_vertical_scroll_bar (w, portion, whole, position)
   struct scroll_bar *bar;
   int top, height, left, sb_left, width, sb_width;
   int window_y, window_height;
+#ifdef USE_TOOLKIT_SCROLL_BARS
+  int fringe_extended_p;
+#endif
 
   /* Get window dimensions.  */
   window_box (w, -1, 0, &window_y, 0, &window_height);
@@ -5001,15 +5056,9 @@ XTset_vertical_scroll_bar (w, portion, whole, position)
   /* Compute the left edge of the scroll bar.  */
 #ifdef USE_TOOLKIT_SCROLL_BARS
   if (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w))
-    sb_left = (left +
-              (WINDOW_RIGHTMOST_P (w)
-               ? width - sb_width - (width - sb_width) / 2
-               : 0));
+    sb_left = left + (WINDOW_RIGHTMOST_P (w) ? width - sb_width : 0);
   else
-    sb_left = (left +
-              (WINDOW_LEFTMOST_P (w)
-               ? (width - sb_width) / 2
-               : width - sb_width));
+    sb_left = left + (WINDOW_LEFTMOST_P (w) ? 0 : width - sb_width);
 #else
   if (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w))
     sb_left = left + width - sb_width;
@@ -5017,14 +5066,33 @@ XTset_vertical_scroll_bar (w, portion, whole, position)
     sb_left = left;
 #endif
 
+#ifdef USE_TOOLKIT_SCROLL_BARS
+  if (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
+    fringe_extended_p = (WINDOW_LEFTMOST_P (w)
+                        && WINDOW_LEFT_FRINGE_WIDTH (w)
+                        && (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
+                            || WINDOW_LEFT_MARGIN_COLS (w) == 0));
+  else
+    fringe_extended_p = (WINDOW_RIGHTMOST_P (w)
+                        && WINDOW_RIGHT_FRINGE_WIDTH (w)
+                        && (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
+                            || WINDOW_RIGHT_MARGIN_COLS (w) == 0));
+#endif
+
   /* Does the scroll bar exist yet?  */
   if (NILP (w->vertical_scroll_bar))
     {
       if (width > 0 && height > 0)
        {
          BLOCK_INPUT;
-         x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
-                       left, top, width, height, False);
+#ifdef USE_TOOLKIT_SCROLL_BARS
+         if (fringe_extended_p)
+           x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
+                         sb_left, top, sb_width, height, False);
+         else
+#endif
+           x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
+                         left, top, width, height, False);
          UNBLOCK_INPUT;
        }
 
@@ -5051,13 +5119,19 @@ XTset_vertical_scroll_bar (w, portion, whole, position)
 #ifdef USE_TOOLKIT_SCROLL_BARS
 
       /* Move/size the scroll bar widget.  */
-      if (mask)
+      if (mask || !NILP (bar->fringe_extended_p) != fringe_extended_p)
        {
          /* Since toolkit scroll bars are smaller than the space reserved
             for them on the frame, we have to clear "under" them.  */
          if (width > 0 && height > 0)
-           x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
-                          left, top, width, height, False);
+           {
+             if (fringe_extended_p)
+               x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
+                             sb_left, top, sb_width, height, False);
+             else
+               x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
+                             left, top, width, height, False);
+           }
 #ifdef USE_GTK
           xg_update_scrollbar_pos (f,
                                    SCROLL_BAR_X_WINDOW (bar),
@@ -5132,6 +5206,8 @@ XTset_vertical_scroll_bar (w, portion, whole, position)
     }
 
 #ifdef USE_TOOLKIT_SCROLL_BARS
+  bar->fringe_extended_p = fringe_extended_p ? Qt : Qnil;
+
   x_set_toolkit_scroll_bar_thumb (bar, portion, position, whole);
 #else /* not USE_TOOLKIT_SCROLL_BARS */
   /* Set the scroll bar's current state, unless we're currently being
@@ -8359,7 +8435,7 @@ wm_supports (f, atomname)
                            prop_atom, 0, max_len, False, target_type,
                            &actual_type, &actual_format, &actual_size,
                            &bytes_remaining, &tmp_data);
-  
+
   if (rc != Success || actual_type != XA_WINDOW || x_had_errors_p (dpy))
     {
       if (tmp_data) XFree (tmp_data);
@@ -8414,7 +8490,7 @@ wm_supports (f, atomname)
   rc = 0;
   want_atom = XInternAtom (dpy, atomname, False);
 
-  for (i = 0; rc == 0 && i < dpyinfo->nr_net_supported_atoms; ++i) 
+  for (i = 0; rc == 0 && i < dpyinfo->nr_net_supported_atoms; ++i)
     rc = dpyinfo->net_supported_atoms[i] == want_atom;
 
   x_uncatch_errors ();
@@ -8855,38 +8931,36 @@ x_lower_frame (f)
     }
 }
 
+/* Activate frame with Extended Window Manager Hints */
+
+void
+x_ewmh_activate_frame (f)
+     FRAME_PTR f;
+{
+  /* See Window Manager Specification/Extended Window Manager Hints at
+     http://freedesktop.org/wiki/Standards_2fwm_2dspec  */
+
+  const char *atom = "_NET_ACTIVE_WINDOW";
+  if (f->async_visible && wm_supports (f, atom))
+    {
+      Lisp_Object frame;
+      XSETFRAME (frame, f);
+      Fx_send_client_event (frame, make_number (0), frame,
+                            make_unibyte_string (atom, strlen (atom)),
+                            make_number (32),
+                            Fcons (make_number (1),
+                                   Fcons (make_number (last_user_time),
+                                          Qnil)));
+    }
+}
+
 static void
 XTframe_raise_lower (f, raise_flag)
      FRAME_PTR f;
      int raise_flag;
 {
   if (raise_flag)
-    {
-      /* The following code is needed for `raise-frame' to work on
-        some versions of metacity; see Window Manager
-        Specification/Extended Window Manager Hints at
-        http://freedesktop.org/wiki/Standards_2fwm_2dspec  */
-
-#if 0
-      /* However, on other versions (metacity 2.17.2-1.fc7), it
-        reportedly causes hangs when resizing frames.  */
-
-      const char *atom = "_NET_ACTIVE_WINDOW";
-      if (f->async_visible && wm_supports (f, atom))
-        {
-          Lisp_Object frame;
-          XSETFRAME (frame, f);
-          Fx_send_client_event (frame, make_number (0), frame,
-                                make_unibyte_string (atom, strlen (atom)),
-                                make_number (32),
-                                Fcons (make_number (1),
-                                       Fcons (make_number (last_user_time),
-                                              Qnil)));
-        }
-      else
-#endif
-        x_raise_frame (f);
-    }
+    x_raise_frame (f);
   else
     x_lower_frame (f);
 }
@@ -10651,7 +10725,7 @@ x_term_init (display_name, xrm_option, resource_name)
            UNBLOCK_INPUT;
            dpyinfo->kboard->Vsystem_key_alist
              = call1 (Qvendor_specific_keysyms,
-                      build_string (vendor ? vendor : ""));
+                      vendor ? build_string (vendor) : empty_unibyte_string);
            BLOCK_INPUT;
          }