]> git.eshelyaron.com Git - emacs.git/commitdiff
New internal-border face and args for select-window and x-focus-frame
authorMartin Rudalics <rudalics@gmx.at>
Wed, 12 Apr 2017 16:22:44 +0000 (18:22 +0200)
committerMartin Rudalics <rudalics@gmx.at>
Wed, 12 Apr 2017 16:22:44 +0000 (18:22 +0200)
Add `internal-border' face and handle it whenever clearing the
internal border.  If NORECORD equals the symbol
'mark-for-redisplay', `select-window' will not record the window
but still mark it for redisplay.  The new argument NOACTIVATE
for `x-focus-frame' tries to not activate FRAME when set.

* lisp/faces.el (internal-border): New face.
* lisp/mwheel.el (mwheel-scroll): Select window to scroll with
`mark-for-redisplay'.
* lisp/scroll-bar.el (scroll-bar-drag)
(scroll-bar-horizontal-drag, scroll-bar-scroll-down)
(scroll-bar-scroll-up, scroll-bar-toolkit-scroll)
(scroll-bar-toolkit-horizontal-scroll): Select window to scroll
with `mark-for-redisplay'.
* lisp/window.el (handle-select-window): When
`focus-follows-mouse' is not 'auto-raise' try to not activate
FRAME.
* src/dispextern.h (face_id): Add INTERNAL_BORDER_FACE_ID.
* src/frame.c (Fx_focus_frame): New argument NOACTIVATE.
* src/frame.h (x_focus_frame): Update extern declaration.
* src/gtkutil.c (xg_clear_under_internal_border): Remove
function.
(xg_frame_resized, xg_frame_set_char_size): Call
x_clear_under_internal_border.
(xg_tool_bar_callback): Adapt x_focus_frame call.
* src/gtkutil.h (xg_clear_under_internal_border): Remove
declaration.
* src/nsfns.m (x_focus_frame): Add argument NOACTIVATE.
* src/w32fns.c (x_clear_under_internal_border): Fill border
with internal-border background if specified.
* src/w32term.h (x_clear_under_internal_border): Add extern
declaration.
* src/w32term.c (x_after_update_window_line): Fill border
with internal-border background if specified.
(w32_set_vertical_scroll_bar, w32_set_horizontal_scroll_bar)
(x_scroll_bar_clear, w32_read_socket): Call
x_clear_under_internal_border.
(x_focus_frame): New argument NOACTIVATE.
* src/window.c (select_window): Mark WINDOW for redisplay when
NORECORD equals 'mark-for-redisplay'.
(Fselect_window): Update doc-string.
(syms_of_window): Define Qmark_for_redisplay.
* src/xdisp.c (clear_garbaged_frames, echo_area_display)
(redisplay_internal): Call x_clear_under_internal_border.
* src/xfaces.c (lookup_basic_face): Handle `window-divider'
and `internal-border' faces.
(realize_basic_faces): Realize `internal-border' face.
(syms_of_xfaces): Define Qinternal_border.
* src/xfns.c (x_set_internal_border_width): Remove call for
xg_clear_under_internal_border.
(x_focus_frame): New argument NOACTIVATE.  When non-nil try to not
activate frame.
* src/xterm.c (x_fill_rectangle): No more static.
(x_clear_under_internal_border, x_after_update_window_line):
Fill border with internal-border background if specified.
(xt_horizontal_action_hook): Rewrite.
(handle_one_xevent): Call x_clear_under_internal_border.
* src/xterm.h (x_fill_rectangle): Add extern declaration.

19 files changed:
lisp/faces.el
lisp/mwheel.el
lisp/scroll-bar.el
lisp/window.el
src/dispextern.h
src/frame.c
src/frame.h
src/gtkutil.c
src/gtkutil.h
src/nsfns.m
src/w32fns.c
src/w32term.c
src/w32term.h
src/window.c
src/xdisp.c
src/xfaces.c
src/xfns.c
src/xterm.c
src/xterm.h

index e62561a63a5e8e6fc61a4853f98f6525d7f49c7c..a6ffd1ecd3357f8771981aefc0966a119dd37ea9 100644 (file)
@@ -2629,6 +2629,13 @@ the same as `window-divider' face."
   :group 'window-divider
   :group 'basic-faces)
 
+(defface internal-border
+    '((t nil))
+  "Basic face for the internal border."
+  :version "26.1"
+  :group 'frames
+  :group 'basic-faces)
+
 (defface minibuffer-prompt
   '((((background dark)) :foreground "cyan")
     ;; Don't use blue because many users of the MS-DOS port customize
index 73fd2b7e115c084fd0475cedead0ec305328cf23..1428e5f4d012d69f059ecb3e3298f6cc8d37ade6 100644 (file)
@@ -220,6 +220,9 @@ non-Windows systems."
          (mods
          (delq 'click (delq 'double (delq 'triple (event-modifiers event)))))
          (amt (assoc mods mouse-wheel-scroll-amount)))
+    (unless (eq scroll-window selected-window)
+      ;; Mark window to be scrolled for redisplay.
+      (select-window scroll-window 'mark-for-redisplay))
     ;; Extract the actual amount or find the element that has no modifiers.
     (if amt (setq amt (cdr amt))
       (let ((list-elt mouse-wheel-scroll-amount))
index 5290a7b3beefb6ee65ff1a15023c3cd698d263e3..58352740447a3207d0d04b65d31c2c4ad912e8bc 100644 (file)
@@ -281,7 +281,7 @@ If you click outside the slider, the window scrolls to bring the slider there."
     (with-current-buffer (window-buffer window)
       (setq before-scroll point-before-scroll))
     (save-selected-window
-      (select-window window)
+      (select-window window 'mark-for-redisplay)
       (setq before-scroll
            (or before-scroll (point))))
     (scroll-bar-drag-1 event)
@@ -326,7 +326,7 @@ If you click outside the slider, the window scrolls to bring the slider there."
     (with-current-buffer (window-buffer window)
       (setq before-scroll point-before-scroll))
     (save-selected-window
-      (select-window window)
+      (select-window window 'mark-for-redisplay)
       (setq before-scroll
            (or before-scroll (point))))
     (scroll-bar-horizontal-drag-1 event)
@@ -356,7 +356,7 @@ EVENT should be a scroll bar click."
     (unwind-protect
        (save-selected-window
          (let ((portion-whole (nth 2 end-position)))
-           (select-window window)
+           (select-window window 'mark-for-redisplay)
            (setq before-scroll
                  (or before-scroll (point)))
            (scroll-down
@@ -377,7 +377,7 @@ EVENT should be a scroll bar click."
     (unwind-protect
        (save-selected-window
          (let ((portion-whole (nth 2 end-position)))
-           (select-window window)
+           (select-window window 'mark-for-redisplay)
            (setq before-scroll
                  (or before-scroll (point)))
            (scroll-up
@@ -402,7 +402,7 @@ EVENT should be a scroll bar click."
       (with-current-buffer (window-buffer window)
        (setq before-scroll point-before-scroll))
       (save-selected-window
-       (select-window window)
+       (select-window window 'mark-for-redisplay)
        (setq before-scroll (or before-scroll (point)))
        (cond
         ((eq part 'above-handle)
@@ -449,7 +449,7 @@ EVENT should be a scroll bar click."
       (with-current-buffer (window-buffer window)
        (setq before-scroll point-before-scroll))
       (save-selected-window
-       (select-window window)
+       (select-window window 'mark-for-redisplay)
        (setq before-scroll (or before-scroll (point)))
        (cond
         ((eq part 'before-handle)
index bea8383fcded4ce9b1e8dba411e1e20e674a8fb9..f4a834c0d8c4adf9e2133805f4d9dd0cfbfdc2e1 100644 (file)
@@ -8855,7 +8855,7 @@ is active.  This function is run by `mouse-autoselect-window-timer'."
         (raise-frame frame))
        (t
         ;; Just focus frame.
-        (x-focus-frame frame))))))
+        (x-focus-frame frame t))))))
 
 (defun truncated-partial-width-window-p (&optional window)
   "Return non-nil if lines in WINDOW are specifically truncated due to its width.
index 679820d506323f29dfa5df83e636bcfb5f7ef66e..d1e4715c32975d4dc00a3cbbbfebaab39b1e4137 100644 (file)
@@ -1784,6 +1784,7 @@ enum face_id
   WINDOW_DIVIDER_FACE_ID,
   WINDOW_DIVIDER_FIRST_PIXEL_FACE_ID,
   WINDOW_DIVIDER_LAST_PIXEL_FACE_ID,
+  INTERNAL_BORDER_FACE_ID,
   BASIC_FACE_ID_SENTINEL
 };
 
index e5d80fa825747411830f3022a9d8f12b7e5d4d41..fc7982d0d55101e8ec9af31cffad531246bb7f28 100644 (file)
@@ -2450,14 +2450,16 @@ See `redirect-frame-focus'.  */)
   return FRAME_FOCUS_FRAME (decode_live_frame (frame));
 }
 
-DEFUN ("x-focus-frame", Fx_focus_frame, Sx_focus_frame, 1, 1, 0,
+DEFUN ("x-focus-frame", Fx_focus_frame, Sx_focus_frame, 1, 2, 0,
        doc: /* Set the input focus to FRAME.
-FRAME nil means use the selected frame.
+FRAME nil means use the selected frame.  Optional argument NOACTIVATE
+means do not activate FRAME.
+
 If there is no window system support, this function does nothing.  */)
-  (Lisp_Object frame)
+     (Lisp_Object frame, Lisp_Object noactivate)
 {
 #ifdef HAVE_WINDOW_SYSTEM
-  x_focus_frame (decode_window_system_frame (frame));
+  x_focus_frame (decode_window_system_frame (frame), !NILP (noactivate));
 #endif
   return Qnil;
 }
index 84f9a05d774623bd668489b9db9372aad8af6e51..36af6e6780413fed2f612244a98560ccd69c99de 100644 (file)
@@ -1531,7 +1531,7 @@ extern void x_sync (struct frame *);
 #endif /* HAVE_X_WINDOWS */
 
 extern void x_query_colors (struct frame *f, XColor *, int);
-extern void x_focus_frame (struct frame *);
+extern void x_focus_frame (struct frame *, bool);
 
 #ifndef HAVE_NS
 
index 227a062bff31abb22111abdcc38cd824eb447578..ad3590dfa664de5aacd050d51730059acdcb9aab 100644 (file)
@@ -835,30 +835,6 @@ xg_set_geometry (struct frame *f)
     }
 }
 
-/* Clear under internal border if any.  As we use a mix of Gtk+ and X calls
-   and use a GtkFixed widget, this doesn't happen automatically.  */
-
-void
-xg_clear_under_internal_border (struct frame *f)
-{
-  if (FRAME_INTERNAL_BORDER_WIDTH (f) > 0)
-    {
-      x_clear_area (f, 0, 0,
-                   FRAME_PIXEL_WIDTH (f), FRAME_INTERNAL_BORDER_WIDTH (f));
-
-      x_clear_area (f, 0, 0,
-                   FRAME_INTERNAL_BORDER_WIDTH (f), FRAME_PIXEL_HEIGHT (f));
-
-      x_clear_area (f, 0,
-                   FRAME_PIXEL_HEIGHT (f) - FRAME_INTERNAL_BORDER_WIDTH (f),
-                   FRAME_PIXEL_WIDTH (f), FRAME_INTERNAL_BORDER_WIDTH (f));
-
-      x_clear_area (f,
-                   FRAME_PIXEL_WIDTH (f) - FRAME_INTERNAL_BORDER_WIDTH (f),
-                   0, FRAME_INTERNAL_BORDER_WIDTH (f), FRAME_PIXEL_HEIGHT (f));
-    }
-}
-
 static int
 xg_get_gdk_scale (void)
 {
@@ -905,7 +881,7 @@ xg_frame_resized (struct frame *f, int pixelwidth, int pixelheight)
       || pixelwidth != FRAME_PIXEL_WIDTH (f)
       || pixelheight != FRAME_PIXEL_HEIGHT (f))
     {
-      xg_clear_under_internal_border (f);
+      x_clear_under_internal_border (f);
       change_frame_size (f, width, height, 0, 1, 0, 1);
       SET_FRAME_GARBAGED (f);
       cancel_mouse_face (f);
@@ -933,7 +909,7 @@ xg_frame_set_char_size (struct frame *f, int width, int height)
                       &gwidth, &gheight);
 
   /* Do this before resize, as we don't know yet if we will be resized.  */
-  xg_clear_under_internal_border (f);
+  x_clear_under_internal_border (f);
 
   if (FRAME_VISIBLE_P (f))
     {
@@ -4361,7 +4337,7 @@ xg_tool_bar_callback (GtkWidget *w, gpointer client_data)
 
   /* Return focus to the frame after we have clicked on a detached
      tool bar button. */
-  x_focus_frame (f);
+  x_focus_frame (f, false);
 }
 
 static GtkWidget *
index 244549fc54b5d1ee2d4bc2e7ba8649a9f38bbeb9..0abcb06bc71fc8f23749d25e2c79398a03bd6400 100644 (file)
@@ -150,7 +150,6 @@ extern void update_frame_tool_bar (struct frame *f);
 extern void free_frame_tool_bar (struct frame *f);
 extern void xg_change_toolbar_position (struct frame *f, Lisp_Object pos);
 
-extern void xg_clear_under_internal_border (struct frame *f);
 extern void xg_frame_resized (struct frame *f,
                               int pixelwidth,
                               int pixelheight);
index e8f035f0e5711317fb0a8ba14b1c5105aaacb470..8a923dd39333d33d10c5f1a613f8b72de6791f0b 100644 (file)
@@ -1391,7 +1391,7 @@ This function is an internal primitive--use `make-frame' instead.  */)
 }
 
 void
-x_focus_frame (struct frame *f)
+x_focus_frame (struct frame *f, bool noactivate)
 {
   struct ns_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
 
index f7d3b722abfde624b4818171af91812993cea6bf..62798f269ef11d2213ba51528a8b350481075dee 100644 (file)
@@ -1634,7 +1634,13 @@ x_set_icon_name (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
 #endif
 }
 \f
-static void
+/**
+ * x_clear_under_internal_border:
+ *
+ * Clear area of frame F's internal border.  If the internal border face
+ * of F has been specified (is not null), fill the area with that face.
+ */
+void
 x_clear_under_internal_border (struct frame *f)
 {
   int border = FRAME_INTERNAL_BORDER_WIDTH (f);
@@ -1645,12 +1651,26 @@ x_clear_under_internal_border (struct frame *f)
       HDC hdc = get_frame_dc (f);
       int width = FRAME_PIXEL_WIDTH (f);
       int height = FRAME_PIXEL_HEIGHT (f);
+      struct face *face = FACE_FROM_ID_OR_NULL (f, INTERNAL_BORDER_FACE_ID);
 
       block_input ();
-      w32_clear_area (f, hdc, 0, FRAME_TOP_MARGIN_HEIGHT (f), width, border);
-      w32_clear_area (f, hdc, 0, 0, border, height);
-      w32_clear_area (f, hdc, width - border, 0, border, height);
-      w32_clear_area (f, hdc, 0, height - border, width, border);
+      if (face)
+       {
+         /* Fill border with internal border face.  */
+         unsigned long color = face->background;
+
+         w32_fill_area (f, hdc, color, 0, FRAME_TOP_MARGIN_HEIGHT (f), width, border);
+         w32_fill_area (f, hdc, color, 0, 0, border, height);
+         w32_fill_area (f, hdc, color, width - border, 0, border, height);
+         w32_fill_area (f, hdc, color, 0, height - border, width, border);
+       }
+      else
+       {
+         w32_clear_area (f, hdc, 0, FRAME_TOP_MARGIN_HEIGHT (f), width, border);
+         w32_clear_area (f, hdc, 0, 0, border, height);
+         w32_clear_area (f, hdc, width - border, 0, border, height);
+         w32_clear_area (f, hdc, 0, height - border, width, border);
+       }
       release_frame_dc (f, hdc);
       unblock_input ();
     }
index b50f0d39a48f8d78d39e54d1b96d4b81f27b47f4..1c3d243b62cec934c280f581dd2be56f08fbbaa8 100644 (file)
@@ -782,9 +782,23 @@ x_after_update_window_line (struct window *w, struct glyph_row *desired_row)
       block_input ();
       {
        HDC hdc = get_frame_dc (f);
-       w32_clear_area (f, hdc, 0, y, width, height);
-       w32_clear_area (f, hdc, FRAME_PIXEL_WIDTH (f) - width,
-                       y, width, height);
+       struct face *face = FACE_FROM_ID_OR_NULL (f, INTERNAL_BORDER_FACE_ID);
+
+       if (face)
+         {
+           /* Fill border with internal border face.  */
+           unsigned long color = face->background;
+
+           w32_fill_area (f, hdc, color, 0, y, width, height);
+           w32_fill_area (f, hdc, color, FRAME_PIXEL_WIDTH (f) - width,
+                          y, width, height);
+         }
+       else
+         {
+           w32_clear_area (f, hdc, 0, y, width, height);
+           w32_clear_area (f, hdc, FRAME_PIXEL_WIDTH (f) - width,
+                           y, width, height);
+         }
        release_frame_dc (f, hdc);
       }
       unblock_input ();
@@ -3908,6 +3922,7 @@ w32_set_vertical_scroll_bar (struct window *w,
                 for them on the frame, we have to clear "under" them.  */
              w32_clear_area (f, hdc, left, top, width, height);
              release_frame_dc (f, hdc);
+             x_clear_under_internal_border (f);
            }
           /* Make sure scroll bar is "visible" before moving, to ensure the
              area of the parent window now exposed will be refreshed.  */
@@ -4009,6 +4024,7 @@ w32_set_horizontal_scroll_bar (struct window *w,
                 for them on the frame, we have to clear "under" them.  */
              w32_clear_area (f, hdc, clear_left, top, clear_width, height);
              release_frame_dc (f, hdc);
+             x_clear_under_internal_border (f);
            }
           /* Make sure scroll bar is "visible" before moving, to ensure the
              area of the parent window now exposed will be refreshed.  */
@@ -4553,6 +4569,7 @@ x_scroll_bar_clear (struct frame *f)
         GetClientRect (window, &rect);
         select_palette (f, hdc);
         w32_clear_rect (f, hdc, &rect);
+       x_clear_under_internal_border (f);
         deselect_palette (f, hdc);
 
         ReleaseDC (window, hdc);
@@ -4682,6 +4699,7 @@ w32_read_socket (struct terminal *terminal,
                                msg.rect.top,
                                msg.rect.right - msg.rect.left,
                                msg.rect.bottom - msg.rect.top);
+                 x_clear_under_internal_border (f);
                }
            }
          break;
@@ -5118,6 +5136,9 @@ w32_read_socket (struct terminal *terminal,
            }
 #endif
 
+         if (f = x_window_to_frame (dpyinfo, msg.msg.hwnd))
+           x_clear_under_internal_border (f);
+
          check_visibility = 1;
          break;
 
@@ -6392,10 +6413,14 @@ frame_set_mouse_pixel_position (struct frame *f, int pix_x, int pix_y)
 }
 
 \f
-/* focus shifting, raising and lowering.  */
+/* Focus shifting, raising and lowering.  */
+
+/* The NOACTIVATE argument has no effect on Windows.  According to the
+   Windows API: An application cannot activate an inactive window
+   without also bringing it to the top of the Z order.  */
 
 void
-x_focus_frame (struct frame *f)
+x_focus_frame (struct frame *f, bool noactivate)
 {
 #if 0
   struct w32_display_info *dpyinfo = &one_w32_display_info;
index 6896ef4f2c6f8ec318c67a51c09a1a7dfa96e6a0..371cf9005bc3aca012f0fbf34804a357f933143b 100644 (file)
@@ -707,7 +707,7 @@ extern BOOL parse_button (int, int, int *, int *);
 
 extern void w32_sys_ring_bell (struct frame *f);
 extern void x_delete_display (struct w32_display_info *dpyinfo);
-
+extern void x_clear_under_internal_border (struct frame *f);
 extern void x_query_color (struct frame *, XColor *);
 
 #define FILE_NOTIFICATIONS_SIZE 16384
index 58c0c33cbb077cdd97149c76babdcd19773e8d26..2d6f0e48faa37b0b04e251806872a19b1e5a3c79 100644 (file)
@@ -492,7 +492,7 @@ select_window (Lisp_Object window, Lisp_Object norecord,
        record_buffer before returning here.  */
     goto record_and_return;
 
-  if (NILP (norecord))
+  if (NILP (norecord) || EQ (norecord, Qmark_for_redisplay))
     { /* Mark the window for redisplay since the selected-window has
         a different mode-line.  */
       wset_redisplay (XWINDOW (selected_window));
@@ -571,7 +571,8 @@ Return WINDOW.
 
 Optional second arg NORECORD non-nil means do not put this buffer at the
 front of the buffer list and do not make this window the most recently
-selected one.
+selected one.  Also, do not mark WINDOW for redisplay unless NORECORD
+equals the special symbol `mark-for-redisplay'.
 
 Run `buffer-list-update-hook' unless NORECORD is non-nil.  Note that
 applications and internal routines often select a window temporarily for
@@ -7350,6 +7351,7 @@ syms_of_window (void)
   DEFSYM (Qclone_of, "clone-of");
   DEFSYM (Qfloor, "floor");
   DEFSYM (Qceiling, "ceiling");
+  DEFSYM (Qmark_for_redisplay, "mark-for-redisplay");
 
   staticpro (&Vwindow_list);
 
index 42a59d63b132fbe4d636462407d76fb6e553b5e2..58b5ca2f018d22475ee55966f144309b36459826 100644 (file)
@@ -11379,6 +11379,11 @@ clear_garbaged_frames (void)
                redraw_frame (f);
              else
                clear_current_matrices (f);
+
+#if defined (HAVE_WINDOW_SYSTEM) && !defined (HAVE_NS)
+             x_clear_under_internal_border (f);
+#endif /* HAVE_WINDOW_SYSTEM && !HAVE_NS */
+
              fset_redisplay (f);
              f->garbaged = false;
              f->resized_p = false;
@@ -11441,7 +11446,14 @@ echo_area_display (bool update_frame_p)
             been called, so that mode lines above the echo area are
             garbaged.  This looks odd, so we prevent it here.  */
          if (!display_completed)
-           n = redisplay_mode_lines (FRAME_ROOT_WINDOW (f), false);
+           {
+             n = redisplay_mode_lines (FRAME_ROOT_WINDOW (f), false);
+
+#if defined (HAVE_WINDOW_SYSTEM) && !defined (HAVE_NS)
+             x_clear_under_internal_border (f);
+#endif /* HAVE_WINDOW_SYSTEM && !HAVE_NS */
+
+           }
 
          if (window_height_changed_p
              /* Don't do this if Emacs is shutting down.  Redisplay
@@ -14151,6 +14163,10 @@ redisplay_internal (void)
                   if (FRAME_GARBAGED_P (f))
                     goto retry;
 
+#if defined (HAVE_WINDOW_SYSTEM) && !defined (HAVE_NS)
+                 x_clear_under_internal_border (f);
+#endif /* HAVE_WINDOW_SYSTEM && !HAVE_NS */
+
                  /* Prevent various kinds of signals during display
                     update.  stdio is not robust about handling
                     signals, which can cause an apparent I/O error.  */
index 7fcaef4e41a27ae620db52a7982b89de93172872..4714b7b3cb82ea2e59700167aaae323c86aed36d 100644 (file)
@@ -4474,6 +4474,10 @@ lookup_basic_face (struct frame *f, int face_id)
     case CURSOR_FACE_ID:               name = Qcursor;                 break;
     case MOUSE_FACE_ID:                        name = Qmouse;                  break;
     case MENU_FACE_ID:                 name = Qmenu;                   break;
+    case WINDOW_DIVIDER_FACE_ID:       name = Qwindow_divider;         break;
+    case WINDOW_DIVIDER_FIRST_PIXEL_FACE_ID:   name = Qwindow_divider_first_pixel;     break;
+    case WINDOW_DIVIDER_LAST_PIXEL_FACE_ID:    name = Qwindow_divider_last_pixel;      break;
+    case INTERNAL_BORDER_FACE_ID:      name = Qinternal_border;        break;
 
     default:
       emacs_abort (); /* the caller is supposed to pass us a basic face id */
@@ -5168,6 +5172,7 @@ realize_basic_faces (struct frame *f)
                          WINDOW_DIVIDER_FIRST_PIXEL_FACE_ID);
       realize_named_face (f, Qwindow_divider_last_pixel,
                          WINDOW_DIVIDER_LAST_PIXEL_FACE_ID);
+      realize_named_face (f, Qinternal_border, INTERNAL_BORDER_FACE_ID);
 
       /* Reflect changes in the `menu' face in menu bars.  */
       if (FRAME_FACE_CACHE (f)->menu_face_changed_p)
@@ -6420,11 +6425,12 @@ syms_of_xfaces (void)
   DEFSYM (Qmouse, "mouse");
   DEFSYM (Qmode_line_inactive, "mode-line-inactive");
   DEFSYM (Qvertical_border, "vertical-border");
-
-  /* TTY color-related functions (defined in tty-colors.el).  */
   DEFSYM (Qwindow_divider, "window-divider");
   DEFSYM (Qwindow_divider_first_pixel, "window-divider-first-pixel");
   DEFSYM (Qwindow_divider_last_pixel, "window-divider-last-pixel");
+  DEFSYM (Qinternal_border, "internal-border");
+
+  /* TTY color-related functions (defined in tty-colors.el).  */
   DEFSYM (Qtty_color_desc, "tty-color-desc");
   DEFSYM (Qtty_color_standard_values, "tty-color-standard-values");
   DEFSYM (Qtty_color_by_index, "tty-color-by-index");
index 3d667446e67c8b6a7f4b34dba4cc7998fe90f63a..3257805cabbee48e2dcd459121dc31384f55efd6 100644 (file)
@@ -1703,15 +1703,10 @@ x_set_internal_border_width (struct frame *f, Lisp_Object arg, Lisp_Object oldva
        widget_store_internal_border (FRAME_X_OUTPUT (f)->edit_widget);
 #endif
 
-      if (FRAME_X_WINDOW (f) != 0)
+      if (FRAME_X_WINDOW (f))
        {
          adjust_frame_size (f, -1, -1, 3, false, Qinternal_border_width);
-
-#ifdef USE_GTK
-         xg_clear_under_internal_border (f);
-#else
          x_clear_under_internal_border (f);
-#endif
        }
     }
 
@@ -4076,7 +4071,7 @@ x_get_focus_frame (struct frame *frame)
    following a user-command.  */
 
 void
-x_focus_frame (struct frame *f)
+x_focus_frame (struct frame *f, bool noactivate)
 {
   Display *dpy = FRAME_X_DISPLAY (f);
 
@@ -4094,7 +4089,8 @@ x_focus_frame (struct frame *f)
     {
       XSetInputFocus (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
                      RevertToParent, CurrentTime);
-      x_ewmh_activate_frame (f);
+      if (!noactivate)
+       x_ewmh_activate_frame (f);
     }
 
   x_uncatch_errors ();
index 4444a5c187aca0f6db192bbc1de5b99b6dfa95c7..8dc1067a688337e9618268bac4da298c438430e9 100644 (file)
@@ -714,7 +714,7 @@ x_reset_clip_rectangles (struct frame *f, GC gc)
 #endif
 }
 
-static void
+void
 x_fill_rectangle (struct frame *f, GC gc, int x, int y, int width, int height)
 {
 #ifdef USE_CAIRO
@@ -1295,8 +1295,12 @@ XTbuffer_flipping_unblocked_hook (struct frame *f)
     show_back_buffer (f);
 }
 
-/* Clear under internal border if any (GTK has its own version). */
-#ifndef USE_GTK
+/**
+ * x_clear_under_internal_border:
+ *
+ * Clear area of frame F's internal border.  If the internal border face
+ * of F has been specified (is not null), fill the area with that face.
+ */
 void
 x_clear_under_internal_border (struct frame *f)
 {
@@ -1305,17 +1309,39 @@ x_clear_under_internal_border (struct frame *f)
       int border = FRAME_INTERNAL_BORDER_WIDTH (f);
       int width = FRAME_PIXEL_WIDTH (f);
       int height = FRAME_PIXEL_HEIGHT (f);
+#ifdef USE_GTK
+      int margin = 0;
+#else
       int margin = FRAME_TOP_MARGIN_HEIGHT (f);
+#endif
+      struct face *face = FACE_FROM_ID_OR_NULL (f, INTERNAL_BORDER_FACE_ID);
 
       block_input ();
-      x_clear_area (f, 0, 0, border, height);
-      x_clear_area (f, 0, margin, width, border);
-      x_clear_area (f, width - border, 0, border, height);
-      x_clear_area (f, 0, height - border, width, border);
+
+      if (face)
+       {
+         unsigned long color = face->background;
+         Display *display = FRAME_X_DISPLAY (f);
+         GC gc = f->output_data.x->normal_gc;
+
+         XSetForeground (display, gc, color);
+         x_fill_rectangle (f, gc, 0, margin, width, border);
+         x_fill_rectangle (f, gc, 0, 0, border, height);
+         x_fill_rectangle (f, gc, width - border, 0, border, height);
+         x_fill_rectangle (f, gc, 0, height - border, width, border);
+         XSetForeground (display, gc, FRAME_FOREGROUND_PIXEL (f));
+       }
+      else
+       {
+         x_clear_area (f, 0, 0, border, height);
+         x_clear_area (f, 0, margin, width, border);
+         x_clear_area (f, width - border, 0, border, height);
+         x_clear_area (f, 0, height - border, width, border);
+       }
+
       unblock_input ();
     }
 }
-#endif
 
 /* Draw truncation mark bitmaps, continuation mark bitmaps, overlay
    arrow bitmaps, or clear the fringes if no bitmaps are required
@@ -1351,10 +1377,25 @@ x_after_update_window_line (struct window *w, struct glyph_row *desired_row)
            height > 0))
       {
        int y = WINDOW_TO_FRAME_PIXEL_Y (w, max (0, desired_row->y));
+       struct face *face = FACE_FROM_ID_OR_NULL (f, INTERNAL_BORDER_FACE_ID);
 
        block_input ();
-       x_clear_area (f, 0, y, width, height);
-       x_clear_area (f, FRAME_PIXEL_WIDTH (f) - width, y, width, height);
+       if (face)
+         {
+           unsigned long color = face->background;
+           Display *display = FRAME_X_DISPLAY (f);
+
+           XSetForeground (display, f->output_data.x->normal_gc, color);
+           x_fill_rectangle (f, f->output_data.x->normal_gc,
+                             0, y, width, height);
+           x_fill_rectangle (f, f->output_data.x->normal_gc,
+                             FRAME_PIXEL_WIDTH (f) - width, y, width, height);
+         }
+       else
+         {
+           x_clear_area (f, 0, y, width, height);
+           x_clear_area (f, FRAME_PIXEL_WIDTH (f) - width, y, width, height);
+         }
        unblock_input ();
       }
   }
@@ -3849,11 +3890,11 @@ x_clear_area (struct frame *f, int x, int y, int width, int height)
   cairo_fill (cr);
   x_end_cr_clip (f);
 #else
-    if (FRAME_X_DOUBLE_BUFFERED_P (f))
-      XFillRectangle (FRAME_X_DISPLAY (f),
-                      FRAME_X_DRAWABLE (f),
-                      f->output_data.x->reverse_gc,
-                      x, y, width, height);
+  if (FRAME_X_DOUBLE_BUFFERED_P (f))
+    XFillRectangle (FRAME_X_DISPLAY (f),
+                   FRAME_X_DRAWABLE (f),
+                   f->output_data.x->reverse_gc,
+                   x, y, width, height);
   else
     x_clear_area1 (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
                    x, y, width, height, False);
@@ -5307,20 +5348,22 @@ xt_horizontal_action_hook (Widget widget, XtPointer client_data, String action_n
       x_send_scroll_bar_event (window_being_scrolled,
                               scroll_bar_end_scroll, 0, 0, true);
       w = XWINDOW (window_being_scrolled);
-      bar = XSCROLL_BAR (w->horizontal_scroll_bar);
-
-      if (bar->dragging != -1)
+      if (!NILP (w->horizontal_scroll_bar))
        {
-         bar->dragging = -1;
-         /* The thumb size is incorrect while dragging: fix it.  */
-         set_horizontal_scroll_bar (w);
-       }
-      window_being_scrolled = Qnil;
+         bar = XSCROLL_BAR (w->horizontal_scroll_bar);
+         if (bar->dragging != -1)
+           {
+             bar->dragging = -1;
+             /* The thumb size is incorrect while dragging: fix it.  */
+             set_horizontal_scroll_bar (w);
+           }
+         window_being_scrolled = Qnil;
 #if defined (USE_LUCID)
-      bar->last_seen_part = scroll_bar_nowhere;
+         bar->last_seen_part = scroll_bar_nowhere;
 #endif
-      /* Xt timeouts no longer needed.  */
-      toolkit_scroll_bar_interaction = false;
+         /* Xt timeouts no longer needed.  */
+         toolkit_scroll_bar_interaction = false;
+       }
     }
 }
 #endif /* not USE_GTK */
@@ -7920,6 +7963,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
                 event->xexpose.x, event->xexpose.y,
                 event->xexpose.width, event->xexpose.height,
                 0);
+             x_clear_under_internal_border (f);
 #endif
             }
 
@@ -7935,6 +7979,9 @@ handle_one_xevent (struct x_display_info *dpyinfo,
 #endif
               expose_frame (f, event->xexpose.x, event->xexpose.y,
                            event->xexpose.width, event->xexpose.height);
+#ifdef USE_GTK
+             x_clear_under_internal_border (f);
+#endif
             }
 
           if (!FRAME_GARBAGED_P (f))
@@ -7983,7 +8030,10 @@ handle_one_xevent (struct x_display_info *dpyinfo,
                         event->xgraphicsexpose.y,
                         event->xgraphicsexpose.width,
                         event->xgraphicsexpose.height);
-          show_back_buffer (f);
+#ifdef USE_GTK
+         x_clear_under_internal_border (f);
+#endif
+         show_back_buffer (f);
         }
 #ifdef USE_X_TOOLKIT
       else
index a75257006fdaad4ed7f9b48f5777ed13c0b9dc90..3122a2b208ce991b37ff10ea3d56018a3a64e763 100644 (file)
@@ -1102,6 +1102,7 @@ extern bool x_alloc_lighter_color_for_widget (Widget, Display *, Colormap,
 extern bool x_alloc_nearest_color (struct frame *, Colormap, XColor *);
 extern void x_query_color (struct frame *f, XColor *);
 extern void x_clear_area (struct frame *f, int, int, int, int);
+extern void x_fill_rectangle (struct frame *f, GC, int, int, int, int);
 #if !defined USE_X_TOOLKIT && !defined USE_GTK
 extern void x_mouse_leave (struct x_display_info *);
 #endif