diff options
author | Martin Rudalics <rudalics@gmx.at> | 2017-04-12 18:22:44 +0200 |
---|---|---|
committer | Martin Rudalics <rudalics@gmx.at> | 2017-04-12 18:22:44 +0200 |
commit | c25005eda1c5ad8dabb3ce815658bd3c637ae686 (patch) | |
tree | d4c7e6bd2d2a9fe8cdc3345a0f84d6d0aa6d4987 | |
parent | 8720f601e715e5f1d41f7cf863a525a1cc1bc12c (diff) | |
download | emacs-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.el | 7 | ||||
-rw-r--r-- | lisp/mwheel.el | 3 | ||||
-rw-r--r-- | lisp/scroll-bar.el | 12 | ||||
-rw-r--r-- | lisp/window.el | 2 | ||||
-rw-r--r-- | src/dispextern.h | 1 | ||||
-rw-r--r-- | src/frame.c | 10 | ||||
-rw-r--r-- | src/frame.h | 2 | ||||
-rw-r--r-- | src/gtkutil.c | 30 | ||||
-rw-r--r-- | src/gtkutil.h | 1 | ||||
-rw-r--r-- | src/nsfns.m | 2 | ||||
-rw-r--r-- | src/w32fns.c | 30 | ||||
-rw-r--r-- | src/w32term.c | 35 | ||||
-rw-r--r-- | src/w32term.h | 2 | ||||
-rw-r--r-- | src/window.c | 6 | ||||
-rw-r--r-- | src/xdisp.c | 18 | ||||
-rw-r--r-- | src/xfaces.c | 10 | ||||
-rw-r--r-- | src/xfns.c | 12 | ||||
-rw-r--r-- | src/xterm.c | 104 | ||||
-rw-r--r-- | src/xterm.h | 1 |
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 |