summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Rudalics <rudalics@gmx.at>2017-04-12 18:22:44 +0200
committerMartin Rudalics <rudalics@gmx.at>2017-04-12 18:22:44 +0200
commitc25005eda1c5ad8dabb3ce815658bd3c637ae686 (patch)
treed4c7e6bd2d2a9fe8cdc3345a0f84d6d0aa6d4987
parent8720f601e715e5f1d41f7cf863a525a1cc1bc12c (diff)
downloademacs-c25005eda1c5ad8dabb3ce815658bd3c637ae686.tar.gz
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.
-rw-r--r--lisp/faces.el7
-rw-r--r--lisp/mwheel.el3
-rw-r--r--lisp/scroll-bar.el12
-rw-r--r--lisp/window.el2
-rw-r--r--src/dispextern.h1
-rw-r--r--src/frame.c10
-rw-r--r--src/frame.h2
-rw-r--r--src/gtkutil.c30
-rw-r--r--src/gtkutil.h1
-rw-r--r--src/nsfns.m2
-rw-r--r--src/w32fns.c30
-rw-r--r--src/w32term.c35
-rw-r--r--src/w32term.h2
-rw-r--r--src/window.c6
-rw-r--r--src/xdisp.c18
-rw-r--r--src/xfaces.c10
-rw-r--r--src/xfns.c12
-rw-r--r--src/xterm.c104
-rw-r--r--src/xterm.h1
19 files changed, 196 insertions, 92 deletions
diff --git a/lisp/faces.el b/lisp/faces.el
index e62561a63a5..a6ffd1ecd33 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 73fd2b7e115..1428e5f4d01 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 5290a7b3bee..58352740447 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 bea8383fcde..f4a834c0d8c 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 679820d5063..d1e4715c329 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 e5d80fa8257..fc7982d0d55 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 84f9a05d774..36af6e67804 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 227a062bff3..ad3590dfa66 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 244549fc54b..0abcb06bc71 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 e8f035f0e57..8a923dd3933 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 f7d3b722abf..62798f269ef 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 b50f0d39a48..1c3d243b62c 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 6896ef4f2c6..371cf9005bc 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 58c0c33cbb0..2d6f0e48faa 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 42a59d63b13..58b5ca2f018 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 7fcaef4e41a..4714b7b3cb8 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 3d667446e67..3257805cabb 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 4444a5c187a..8dc1067a688 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 a75257006fd..3122a2b208c 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