: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
(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))
(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)
(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)
(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
(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
(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)
(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)
(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.
WINDOW_DIVIDER_FACE_ID,
WINDOW_DIVIDER_FIRST_PIXEL_FACE_ID,
WINDOW_DIVIDER_LAST_PIXEL_FACE_ID,
+ INTERNAL_BORDER_FACE_ID,
BASIC_FACE_ID_SENTINEL
};
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;
}
#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
}
}
-/* 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)
{
|| 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);
&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))
{
/* 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 *
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);
}
void
-x_focus_frame (struct frame *f)
+x_focus_frame (struct frame *f, bool noactivate)
{
struct ns_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
#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);
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 ();
}
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 ();
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. */
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. */
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);
msg.rect.top,
msg.rect.right - msg.rect.left,
msg.rect.bottom - msg.rect.top);
+ x_clear_under_internal_border (f);
}
}
break;
}
#endif
+ if (f = x_window_to_frame (dpyinfo, msg.msg.hwnd))
+ x_clear_under_internal_border (f);
+
check_visibility = 1;
break;
}
\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;
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
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));
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
DEFSYM (Qclone_of, "clone-of");
DEFSYM (Qfloor, "floor");
DEFSYM (Qceiling, "ceiling");
+ DEFSYM (Qmark_for_redisplay, "mark-for-redisplay");
staticpro (&Vwindow_list);
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;
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
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. */
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 */
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)
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");
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
}
}
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);
{
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 ();
#endif
}
-static void
+void
x_fill_rectangle (struct frame *f, GC gc, int x, int y, int width, int height)
{
#ifdef USE_CAIRO
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)
{
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
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 ();
}
}
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);
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 */
event->xexpose.x, event->xexpose.y,
event->xexpose.width, event->xexpose.height,
0);
+ x_clear_under_internal_border (f);
#endif
}
#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))
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
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