emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] master c25005e: New internal-border face and args for sele


From: Martin Rudalics
Subject: [Emacs-diffs] master c25005e: New internal-border face and args for select-window and x-focus-frame
Date: Wed, 12 Apr 2017 12:24:59 -0400 (EDT)

branch: master
commit c25005eda1c5ad8dabb3ce815658bd3c637ae686
Author: Martin Rudalics <address@hidden>
Commit: Martin Rudalics <address@hidden>

    New internal-border face and args for select-window and x-focus-frame
    
    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.
---
 lisp/faces.el      |   7 ++++
 lisp/mwheel.el     |   3 ++
 lisp/scroll-bar.el |  12 +++----
 lisp/window.el     |   2 +-
 src/dispextern.h   |   1 +
 src/frame.c        |  10 +++---
 src/frame.h        |   2 +-
 src/gtkutil.c      |  30 ++--------------
 src/gtkutil.h      |   1 -
 src/nsfns.m        |   2 +-
 src/w32fns.c       |  30 +++++++++++++---
 src/w32term.c      |  35 +++++++++++++++---
 src/w32term.h      |   2 +-
 src/window.c       |   6 ++--
 src/xdisp.c        |  18 +++++++++-
 src/xfaces.c       |  10 ++++--
 src/xfns.c         |  12 +++----
 src/xterm.c        | 104 +++++++++++++++++++++++++++++++++++++++--------------
 src/xterm.h        |   1 +
 19 files changed, 196 insertions(+), 92 deletions(-)

diff --git a/lisp/faces.el b/lisp/faces.el
index e62561a..a6ffd1e 100644
--- a/lisp/faces.el
+++ b/lisp/faces.el
@@ -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
diff --git a/lisp/mwheel.el b/lisp/mwheel.el
index 73fd2b7..1428e5f 100644
--- a/lisp/mwheel.el
+++ b/lisp/mwheel.el
@@ -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))
diff --git a/lisp/scroll-bar.el b/lisp/scroll-bar.el
index 5290a7b..5835274 100644
--- a/lisp/scroll-bar.el
+++ b/lisp/scroll-bar.el
@@ -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)
diff --git a/lisp/window.el b/lisp/window.el
index bea8383..f4a834c 100644
--- a/lisp/window.el
+++ b/lisp/window.el
@@ -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.
diff --git a/src/dispextern.h b/src/dispextern.h
index 679820d..d1e4715 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -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
 };
 
diff --git a/src/frame.c b/src/frame.c
index e5d80fa..fc7982d 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -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;
 }
diff --git a/src/frame.h b/src/frame.h
index 84f9a05..36af6e6 100644
--- a/src/frame.h
+++ b/src/frame.h
@@ -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
 
diff --git a/src/gtkutil.c b/src/gtkutil.c
index 227a062..ad3590d 100644
--- a/src/gtkutil.c
+++ b/src/gtkutil.c
@@ -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 *
diff --git a/src/gtkutil.h b/src/gtkutil.h
index 244549f..0abcb06 100644
--- a/src/gtkutil.h
+++ b/src/gtkutil.h
@@ -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);
diff --git a/src/nsfns.m b/src/nsfns.m
index e8f035f..8a923dd 100644
--- a/src/nsfns.m
+++ b/src/nsfns.m
@@ -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);
 
diff --git a/src/w32fns.c b/src/w32fns.c
index f7d3b72..62798f2 100644
--- a/src/w32fns.c
+++ b/src/w32fns.c
@@ -1634,7 +1634,13 @@ x_set_icon_name (struct frame *f, Lisp_Object arg, 
Lisp_Object oldval)
 #endif
 }
 
-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 ();
     }
diff --git a/src/w32term.c b/src/w32term.c
index b50f0d3..1c3d243 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -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)
 }
 
 
-/* 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;
diff --git a/src/w32term.h b/src/w32term.h
index 6896ef4..371cf90 100644
--- a/src/w32term.h
+++ b/src/w32term.h
@@ -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
diff --git a/src/window.c b/src/window.c
index 58c0c33..2d6f0e4 100644
--- a/src/window.c
+++ b/src/window.c
@@ -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);
 
diff --git a/src/xdisp.c b/src/xdisp.c
index 42a59d6..58b5ca2 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -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.  */
diff --git a/src/xfaces.c b/src/xfaces.c
index 7fcaef4..4714b7b 100644
--- a/src/xfaces.c
+++ b/src/xfaces.c
@@ -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");
diff --git a/src/xfns.c b/src/xfns.c
index 3d66744..3257805 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -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 ();
diff --git a/src/xterm.c b/src/xterm.c
index 4444a5c..8dc1067 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -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
diff --git a/src/xterm.h b/src/xterm.h
index a752570..3122a2b 100644
--- a/src/xterm.h
+++ b/src/xterm.h
@@ -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



reply via email to

[Prev in Thread] Current Thread [Next in Thread]