summaryrefslogtreecommitdiff
path: root/src/frame.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/frame.c')
-rw-r--r--src/frame.c902
1 files changed, 486 insertions, 416 deletions
diff --git a/src/frame.c b/src/frame.c
index 635fc945604..b105268d423 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -150,29 +150,6 @@ get_frame_param (struct frame *frame, Lisp_Object prop)
}
-void
-frame_size_history_add (struct frame *f, Lisp_Object fun_symbol,
- int width, int height, Lisp_Object rest)
-{
- Lisp_Object frame;
-
- XSETFRAME (frame, f);
- if (CONSP (frame_size_history)
- && FIXNUMP (XCAR (frame_size_history))
- && 0 < XFIXNUM (XCAR (frame_size_history)))
- frame_size_history =
- Fcons (make_fixnum (XFIXNUM (XCAR (frame_size_history)) - 1),
- Fcons (list4
- (frame, fun_symbol,
- ((width > 0)
- ? list4i (FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f),
- width, height)
- : Qnil),
- rest),
- XCDR (frame_size_history)));
-}
-
-
/* Return 1 if `frame-inhibit-implied-resize' is non-nil or fullscreen
state of frame F would be affected by a vertical (horizontal if
HORIZONTAL is true) resize. PARAMETER is the symbol of the frame
@@ -193,78 +170,54 @@ frame_inhibit_resize (struct frame *f, bool horizontal, Lisp_Object parameter)
|| FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f))
: ((horizontal && f->inhibit_horizontal_resize)
|| (!horizontal && f->inhibit_vertical_resize)));
- if (inhibit && !FRAME_TERMCAP_P (f) && !FRAME_MSDOS_P (f))
- frame_size_history_add
- (f, Qframe_inhibit_resize, 0, 0,
- list5 (horizontal ? Qt : Qnil, parameter,
- f->after_make_frame ? Qt : Qnil,
- frame_inhibit_implied_resize,
- fullscreen));
return inhibit;
}
+
+/** Set menu bar lines for a TTY frame. */
static void
set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
{
- int nlines;
int olines = FRAME_MENU_BAR_LINES (f);
+ int nlines = TYPE_RANGED_FIXNUMP (int, value) ? XFIXNUM (value) : 0;
/* Right now, menu bars don't work properly in minibuf-only frames;
most of the commands try to apply themselves to the minibuffer
frame itself, and get an error because you can't switch buffers
in or split the minibuffer window. */
- if (FRAME_MINIBUF_ONLY_P (f))
- return;
-
- if (TYPE_RANGED_FIXNUMP (int, value))
- nlines = XFIXNUM (value);
- else
- nlines = 0;
-
- if (nlines != olines)
+ if (!FRAME_MINIBUF_ONLY_P (f) && nlines != olines)
{
windows_or_buffers_changed = 14;
- FRAME_MENU_BAR_LINES (f) = nlines;
- FRAME_MENU_BAR_HEIGHT (f) = nlines * FRAME_LINE_HEIGHT (f);
- change_frame_size (f, FRAME_COLS (f),
- FRAME_LINES (f) + olines - nlines,
- 0, 1, 0, 0);
+ FRAME_MENU_BAR_LINES (f) = FRAME_MENU_BAR_HEIGHT (f) = nlines;
+ change_frame_size (f, FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f),
+ false, true, false);
}
}
+
+/** Set tab bar lines for a TTY frame. */
static void
set_tab_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
{
- int nlines;
int olines = FRAME_TAB_BAR_LINES (f);
+ int nlines = TYPE_RANGED_FIXNUMP (int, value) ? XFIXNUM (value) : 0;
/* Right now, tab bars don't work properly in minibuf-only frames;
most of the commands try to apply themselves to the minibuffer
frame itself, and get an error because you can't switch buffers
in or split the minibuffer window. */
- if (FRAME_MINIBUF_ONLY_P (f))
- return;
-
- if (TYPE_RANGED_FIXNUMP (int, value))
- nlines = XFIXNUM (value);
- else
- nlines = 0;
-
- if (nlines != olines)
+ if (!FRAME_MINIBUF_ONLY_P (f) && nlines != olines)
{
windows_or_buffers_changed = 14;
- FRAME_TAB_BAR_LINES (f) = nlines;
- FRAME_TAB_BAR_HEIGHT (f) = nlines * FRAME_LINE_HEIGHT (f);
- change_frame_size (f, FRAME_COLS (f),
- FRAME_LINES (f) + olines - nlines,
- 0, 1, 0, 0);
+ FRAME_TAB_BAR_LINES (f) = FRAME_TAB_BAR_HEIGHT (f) = nlines;
+ change_frame_size (f, FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f),
+ false, true, false);
}
}
Lisp_Object Vframe_list;
-
DEFUN ("framep", Fframep, Sframep, 1, 1, 0,
doc: /* Return non-nil if OBJECT is a frame.
Value is:
@@ -366,14 +319,15 @@ DEFUN ("frame-windows-min-size", Fframe_windows_min_size,
*
* If `frame-windows-min-size' is called, it will make sure that the
* return value accommodates all windows of FRAME respecting the values
- * of `window-min-height' (`window-min-width' if HORIZONTAL is non-nil).
- * With IGNORE non-nil the values of these variables are ignored.
+ * of `window-min-height' (`window-min-width' if HORIZONTAL is
+ * non-nil) and `window-safe-min-height' (`window-safe-min-width')
+ * according to IGNORE (see `window-min-size').
*
* In either case, never return a value less than 1. For TTY frames,
* additionally limit the minimum frame height to a value large enough
- * to support the menu bar, the mode line, and the echo area.
+ * to support menu bar, tab bar, mode line and echo area.
*/
-static int
+int
frame_windows_min_size (Lisp_Object frame, Lisp_Object horizontal,
Lisp_Object ignore, Lisp_Object pixelwise)
{
@@ -405,6 +359,7 @@ frame_windows_min_size (Lisp_Object frame, Lisp_Object horizontal,
else
retval = XFIXNUM (call4 (Qframe_windows_min_size, frame, horizontal,
ignore, pixelwise));
+
/* Don't allow too small height of text-mode frames, or else cm.c
might abort in cmcheckmagic. */
if ((FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f)) && NILP (horizontal))
@@ -413,6 +368,7 @@ frame_windows_min_size (Lisp_Object frame, Lisp_Object horizontal,
+ FRAME_TAB_BAR_LINES (f)
+ FRAME_WANTS_MODELINE_P (f)
+ 2); /* one text line and one echo-area line */
+
if (retval < min_height)
retval = min_height;
}
@@ -474,9 +430,10 @@ keep_ratio (struct frame *f, struct frame *p, int old_width, int old_height,
if (CONSP (keep_ratio)
&& (NILP (Fcar (keep_ratio))
|| EQ (Fcar (keep_ratio), Qheight_only))
- && p->pixel_width - f->pixel_width < pos_x)
+ && FRAME_PIXEL_WIDTH (p) - FRAME_PIXEL_WIDTH (f) < pos_x)
{
- int p_f_width = p->pixel_width - f->pixel_width;
+ int p_f_width
+ = FRAME_PIXEL_WIDTH (p) - FRAME_PIXEL_WIDTH (f);
if (p_f_width <= 0)
pos_x = 0;
@@ -496,14 +453,15 @@ keep_ratio (struct frame *f, struct frame *p, int old_width, int old_height,
if (CONSP (keep_ratio)
&& (NILP (Fcar (keep_ratio))
|| EQ (Fcar (keep_ratio), Qwidth_only))
- && p->pixel_height - f->pixel_height < pos_y)
+ && FRAME_PIXEL_HEIGHT (p) - FRAME_PIXEL_HEIGHT (f) < pos_y)
/* When positional adjustment was requested and the
width of F should remain unaltered, try to constrain
F to its parent. This means that when the parent
frame is enlarged later the child's original position
won't get restored. */
{
- int p_f_height = p->pixel_height - f->pixel_height;
+ int p_f_height
+ = FRAME_PIXEL_HEIGHT (p) - FRAME_PIXEL_HEIGHT (f);
if (p_f_height <= 0)
pos_y = 0;
@@ -523,211 +481,326 @@ keep_ratio (struct frame *f, struct frame *p, int old_width, int old_height,
if (CONSP (keep_ratio) && EQ (Fcar (keep_ratio), Qheight_only))
pixel_width = -1;
else
- {
- pixel_width = (int)(f->pixel_width * width_factor + 0.5);
- pixel_width = FRAME_PIXEL_TO_TEXT_WIDTH (f, pixel_width);
- }
+ pixel_width
+ = (int)(FRAME_PIXEL_WIDTH (f) * width_factor + 0.5);
if (CONSP (keep_ratio) && EQ (Fcar (keep_ratio), Qwidth_only))
pixel_height = -1;
else
- {
- pixel_height = (int)(f->pixel_height * height_factor + 0.5);
- pixel_height = FRAME_PIXEL_TO_TEXT_HEIGHT (f, pixel_height);
- }
+ pixel_height
+ = (int)(FRAME_PIXEL_HEIGHT (f) * height_factor + 0.5);
- adjust_frame_size (f, pixel_width, pixel_height, 1, 0,
- Qkeep_ratio);
+ adjust_frame_size (f, FRAME_PIXEL_TO_TEXT_WIDTH (f, pixel_width),
+ FRAME_PIXEL_TO_TEXT_HEIGHT (f, pixel_height), 1,
+ false, Qkeep_ratio);
}
}
}
#endif
+static void
+frame_size_history_adjust (struct frame *f, int inhibit, Lisp_Object parameter,
+ int old_text_width, int old_text_height,
+ int new_text_width, int new_text_height,
+ int old_text_cols, int old_text_lines,
+ int new_text_cols, int new_text_lines,
+ int old_native_width, int old_native_height,
+ int new_native_width, int new_native_height,
+ int old_inner_width, int old_inner_height,
+ int new_inner_width, int new_inner_height,
+ int min_inner_width, int min_inner_height,
+ bool inhibit_horizontal, bool inhibit_vertical)
+{
+ Lisp_Object frame;
+
+ XSETFRAME (frame, f);
+ if (CONSP (frame_size_history)
+ && FIXNUMP (XCAR (frame_size_history))
+ && 0 < XFIXNUM (XCAR (frame_size_history)))
+ frame_size_history =
+ Fcons (make_fixnum (XFIXNUM (XCAR (frame_size_history)) - 1),
+ Fcons (Fcons (list4 (frame, make_fixnum (5),
+ make_fixnum (inhibit), parameter),
+ list5 (list4i (old_text_width, old_text_height,
+ new_text_width, new_text_height),
+ list4i (old_text_cols, old_text_lines,
+ new_text_cols, new_text_lines),
+ list4i (old_native_width, old_native_height,
+ new_native_width, new_native_height),
+ list4i (old_inner_width, old_inner_height,
+ new_inner_width, new_inner_height),
+ list4 (make_fixnum (min_inner_width),
+ make_fixnum (min_inner_height),
+ inhibit_horizontal ? Qt : Qnil,
+ inhibit_vertical ? Qt : Qnil))),
+ XCDR (frame_size_history)));
+}
+
+
+void
+frame_size_history_plain (struct frame *f, Lisp_Object parameter)
+{
+ Lisp_Object frame;
+
+ XSETFRAME (frame, f);
+ if (CONSP (frame_size_history)
+ && FIXNUMP (XCAR (frame_size_history))
+ && 0 < XFIXNUM (XCAR (frame_size_history)))
+ frame_size_history =
+ Fcons (make_fixnum (XFIXNUM (XCAR (frame_size_history)) - 1),
+ Fcons (Fcons (list3 (frame, make_fixnum (1), parameter), Qt),
+ XCDR (frame_size_history)));
+}
+
+
+void
+frame_size_history_extra (struct frame *f, Lisp_Object parameter,
+ int pixel_width, int pixel_height,
+ int extra_width, int extra_height,
+ int delayed_width, int delayed_height)
+{
+ Lisp_Object frame;
+
+ XSETFRAME (frame, f);
+ if (CONSP (frame_size_history)
+ && FIXNUMP (XCAR (frame_size_history))
+ && 0 < XFIXNUM (XCAR (frame_size_history)))
+ frame_size_history =
+ Fcons (make_fixnum (XFIXNUM (XCAR (frame_size_history)) - 1),
+ Fcons (Fcons (list3 (frame, make_fixnum (2), parameter),
+ list2 (list4i (pixel_width, pixel_height,
+ extra_width, extra_height),
+ list2i (delayed_width, delayed_height))),
+ XCDR (frame_size_history)));
+}
+
+
/**
* adjust_frame_size:
*
- * Adjust size of frame F. NEW_WIDTH and NEW_HEIGHT specify the new
- * text size of F in pixels. A value of -1 means no change is requested
- * for that direction (but the frame may still have to be resized to
- * accommodate windows with their minimum sizes). This can either issue
- * a request to resize the frame externally (via set_window_size_hook), to
- * resize the frame internally (via resize_frame_windows) or do nothing
- * at all.
+ * Adjust size of frame F. NEW_TEXT_WIDTH and NEW_TEXT_HEIGHT specify
+ * the new text size of F in pixels. When INHIBIT equals 2, 3 or 4, a
+ * value of -1 means to leave the text size of F unchanged and adjust,
+ * if necessary and possible, F's native size accordingly. When INHIBIT
+ * equals 0, 1 or 5, a negative value means that the frame has been (or
+ * should be) made pathologically small which usually means that parts
+ * of the frame's windows may not be entirely visible.
+ *
+ * The effect of calling this function can be to either issue a request
+ * to resize the frame externally (via set_window_size_hook), to resize
+ * the frame internally (via resize_frame_windows) or to do nothing.
*
- * The argument INHIBIT can assume the following values:
+ * The argument INHIBIT controls whether set_window_size_hook may be
+ * called and can assume the following values:
*
* 0 means to unconditionally call set_window_size_hook even if sizes
* apparently do not change. Fx_create_frame uses this to pass the
* initial size to the window manager.
*
- * 1 means to call set_window_size_hook if the native frame size really
- * changes. Fset_frame_size, Fset_frame_height, ... use this.
+ * 1 means to call set_window_size_hook if the native frame size should
+ * change. Fset_frame_size and friends and width and height parameter
+ * changes use this.
*
* 2 means to call set_window_size_hook provided frame_inhibit_resize
- * allows it. The menu and tool bar code use this ("3" won't work
- * here in general because menu and tool bar are often not counted in
- * the frame's text height).
+ * allows it. The code updating external menu and tool bars uses this
+ * to keep the height of the native frame unaltered when one of these
+ * bars is added or removed. This means that Emacs has to work
+ * against the window manager which usually tries to keep the combined
+ * height (native frame plus bar) unaltered.
*
- * 3 means call set_window_size_hook if window minimum sizes must be
- * preserved or frame_inhibit_resize allows it.
- * gui_set_left_fringe, gui_set_scroll_bar_width, gui_new_font
- * ... use (or should use) this.
+ * 3 means to call set_window_size_hook if window minimum sizes must be
+ * preserved or frame_inhibit_resize allows it. This is the default
+ * for parameters accounted for in a frame's text size like fringes,
+ * scroll bars, internal border, tab bar, internal tool and menu bars.
+ * It's also used when the frame's default font changes.
*
- * 4 means call set_window_size_hook only if window minimum sizes must
- * be preserved. x_set_right_divider_width, x_set_border_width and
- * the code responsible for wrapping the tool bar use this.
+ * 4 means to call set_window_size_hook only if window minimum sizes
+ * must be preserved. The code for setting up window dividers and
+ * that responsible for wrapping the (internal) tool bar use this.
*
- * 5 means to never call set_window_size_hook. change_frame_size uses
- * this.
- *
- * Note that even when set_window_size_hook is not called, individual
- * windows may have to be resized (via `window--sanitize-window-sizes')
- * in order to support minimum size constraints.
+ * 5 means to never call set_window_size_hook. Usually this means to
+ * call resize_frame_windows. change_frame_size uses this.
*
* PRETEND is as for change_frame_size. PARAMETER, if non-nil, is the
* symbol of the parameter changed (like `menu-bar-lines', `font', ...).
* This is passed on to frame_inhibit_resize to let the latter decide on
- * a case-by-case basis whether the frame may be resized externally.
+ * a case-by-case basis whether set_window_size_hook should be called.
*/
void
-adjust_frame_size (struct frame *f, int new_width, int new_height, int inhibit,
- bool pretend, Lisp_Object parameter)
+adjust_frame_size (struct frame *f, int new_text_width, int new_text_height,
+ int inhibit, bool pretend, Lisp_Object parameter)
{
int unit_width = FRAME_COLUMN_WIDTH (f);
int unit_height = FRAME_LINE_HEIGHT (f);
- int old_pixel_width = FRAME_PIXEL_WIDTH (f);
- int old_pixel_height = FRAME_PIXEL_HEIGHT (f);
- int old_cols = FRAME_COLS (f);
- int old_lines = FRAME_LINES (f);
- int new_pixel_width, new_pixel_height;
- /* The following two values are calculated from the old frame pixel
- sizes and any "new" settings for tool bar, menu bar and internal
- borders. We do it this way to detect whether we have to call
- set_window_size_hook as consequence of the new settings. */
- int windows_width = FRAME_WINDOWS_WIDTH (f);
- int windows_height = FRAME_WINDOWS_HEIGHT (f);
- int min_windows_width, min_windows_height;
- /* These are a bit tedious, maybe we should use a macro. */
+ int old_native_width = FRAME_PIXEL_WIDTH (f);
+ int old_native_height = FRAME_PIXEL_HEIGHT (f);
+ int new_native_width, new_native_height;
+ /* The desired minimum inner width and height of the frame calculated
+ via 'frame-windows-min-size'. */
+ int min_inner_width, min_inner_height;
+ /* Get the "old" inner width, height and position of F via its root
+ window and the minibuffer window. We cannot use FRAME_INNER_WIDTH
+ and FRAME_INNER_HEIGHT here since the internal border and the top
+ margin may have been already set to new values. */
struct window *r = XWINDOW (FRAME_ROOT_WINDOW (f));
- int old_windows_width = WINDOW_PIXEL_WIDTH (r);
- int old_windows_height
+ int old_inner_width = WINDOW_PIXEL_WIDTH (r);
+ int old_inner_height
= (WINDOW_PIXEL_HEIGHT (r)
+ ((FRAME_HAS_MINIBUF_P (f) && !FRAME_MINIBUF_ONLY_P (f))
? WINDOW_PIXEL_HEIGHT (XWINDOW (FRAME_MINIBUF_WINDOW (f)))
: 0));
- int new_windows_width, new_windows_height;
+ int new_inner_width, new_inner_height;
+ int old_text_cols = FRAME_COLS (f);
+ int old_text_lines = FRAME_LINES (f);
+ int new_text_cols, new_text_lines;
int old_text_width = FRAME_TEXT_WIDTH (f);
int old_text_height = FRAME_TEXT_HEIGHT (f);
- /* If a size is < 0 use the old value. */
- int new_text_width = (new_width >= 0) ? new_width : old_text_width;
- int new_text_height = (new_height >= 0) ? new_height : old_text_height;
- int new_cols, new_lines;
bool inhibit_horizontal, inhibit_vertical;
Lisp_Object frame;
XSETFRAME (frame, f);
- frame_size_history_add
- (f, Qadjust_frame_size_1, new_text_width, new_text_height,
- list2 (parameter, make_fixnum (inhibit)));
-
- /* The following two values are calculated from the old window body
- sizes and any "new" settings for scroll bars, dividers, fringes and
- margins (though the latter should have been processed already). */
- min_windows_width
- = frame_windows_min_size (frame, Qt, (inhibit == 5) ? Qt : Qnil, Qt);
- min_windows_height
- = frame_windows_min_size (frame, Qnil, (inhibit == 5) ? Qt : Qnil, Qt);
+ min_inner_width
+ = frame_windows_min_size (frame, Qt, (inhibit == 5) ? Qsafe : Qnil, Qt);
+ min_inner_height
+ = frame_windows_min_size (frame, Qnil, (inhibit == 5) ? Qsafe : Qnil, Qt);
if (inhibit >= 2 && inhibit <= 4)
/* When INHIBIT is in [2..4] inhibit if the "old" window sizes stay
within the limits and either resizing is inhibited or INHIBIT
equals 4. */
{
- inhibit_horizontal = (windows_width >= min_windows_width
+ if (new_text_width == -1)
+ new_text_width = FRAME_TEXT_WIDTH (f);
+ if (new_text_height == -1)
+ new_text_height = FRAME_TEXT_HEIGHT (f);
+
+ inhibit_horizontal = (FRAME_INNER_WIDTH (f) >= min_inner_width
&& (inhibit == 4
|| frame_inhibit_resize (f, true, parameter)));
- inhibit_vertical = (windows_height >= min_windows_height
+ inhibit_vertical = (FRAME_INNER_HEIGHT (f) >= min_inner_height
&& (inhibit == 4
|| frame_inhibit_resize (f, false, parameter)));
}
else
- /* Otherwise inhibit if INHIBIT equals 5. */
+ /* Otherwise inhibit if INHIBIT equals 5. If we wanted to overrule
+ the WM do that here (could lead to some sort of eternal fight
+ with the WM). */
inhibit_horizontal = inhibit_vertical = inhibit == 5;
- new_pixel_width = ((inhibit_horizontal && (inhibit < 5))
- ? old_pixel_width
- : max (FRAME_TEXT_TO_PIXEL_WIDTH (f, new_text_width),
- min_windows_width
- + 2 * FRAME_INTERNAL_BORDER_WIDTH (f)));
- new_windows_width = new_pixel_width - 2 * FRAME_INTERNAL_BORDER_WIDTH (f);
- new_text_width = FRAME_PIXEL_TO_TEXT_WIDTH (f, new_pixel_width);
- new_cols = new_text_width / unit_width;
-
- new_pixel_height = ((inhibit_vertical && (inhibit < 5))
- ? old_pixel_height
- : max (FRAME_TEXT_TO_PIXEL_HEIGHT (f, new_text_height),
- min_windows_height
- + FRAME_TOP_MARGIN_HEIGHT (f)
+ new_native_width = ((inhibit_horizontal && inhibit < 5)
+ ? old_native_width
+ : max (FRAME_TEXT_TO_PIXEL_WIDTH (f, new_text_width),
+ min_inner_width
+ 2 * FRAME_INTERNAL_BORDER_WIDTH (f)));
- new_windows_height = (new_pixel_height
- - FRAME_TOP_MARGIN_HEIGHT (f)
- - 2 * FRAME_INTERNAL_BORDER_WIDTH (f));
- new_text_height = FRAME_PIXEL_TO_TEXT_HEIGHT (f, new_pixel_height);
- new_lines = new_text_height / unit_height;
+ new_inner_width = new_native_width - 2 * FRAME_INTERNAL_BORDER_WIDTH (f);
+ new_text_width = FRAME_PIXEL_TO_TEXT_WIDTH (f, new_native_width);
+ new_text_cols = new_text_width / unit_width;
+
+ new_native_height = ((inhibit_vertical && inhibit < 5)
+ ? old_native_height
+ : max (FRAME_TEXT_TO_PIXEL_HEIGHT (f, new_text_height),
+ min_inner_height
+ + FRAME_TOP_MARGIN_HEIGHT (f)
+ + 2 * FRAME_INTERNAL_BORDER_WIDTH (f)));
+ new_inner_height = (new_native_height
+ - FRAME_TOP_MARGIN_HEIGHT (f)
+ - 2 * FRAME_INTERNAL_BORDER_WIDTH (f));
+ new_text_height = FRAME_PIXEL_TO_TEXT_HEIGHT (f, new_native_height);
+ new_text_lines = new_text_height / unit_height;
-#ifdef HAVE_WINDOW_SYSTEM
if (FRAME_WINDOW_P (f)
&& f->can_set_window_size
+ /* For inhibit == 1 call the window_size_hook only if a native
+ size changes. For inhibit == 0 or inhibit == 2 always call
+ it. */
&& ((!inhibit_horizontal
- && (new_pixel_width != old_pixel_width
+ && (new_native_width != old_native_width
|| inhibit == 0 || inhibit == 2))
|| (!inhibit_vertical
- && (new_pixel_height != old_pixel_height
+ && (new_native_height != old_native_height
|| inhibit == 0 || inhibit == 2))))
- /* We are either allowed to change the frame size or the minimum
- sizes request such a change. Do not care for fixing minimum
- sizes here, we do that eventually when we're called from
- change_frame_size. */
{
- /* Make sure we respect fullheight and fullwidth. */
- if (inhibit_horizontal)
- new_text_width = old_text_width;
- else if (inhibit_vertical)
- new_text_height = old_text_height;
+ if (inhibit == 2
+#ifdef USE_MOTIF
+ && !EQ (parameter, Qmenu_bar_lines)
+#endif
+ && (f->new_width >= 0 || f->new_height >= 0))
+ /* For implied resizes with inhibit 2 (external menu and tool
+ bar) pick up any new sizes the display engine has not
+ processed yet. Otherwsie, we would request the old sizes
+ which will make this request appear as a request to set new
+ sizes and have the WM react accordingly which is not TRT.
+
+ We don't that for the external menu bar on Motif.
+ Otherwise, switching off the menu bar will shrink the frame
+ and switching it on will not enlarge it. */
+ {
+ if (f->new_width >= 0)
+ new_native_width = f->new_width;
+ if (f->new_height >= 0)
+ new_native_height = f->new_height;
+ }
- frame_size_history_add
- (f, Qadjust_frame_size_2, new_text_width, new_text_height,
- list2 (inhibit_horizontal ? Qt : Qnil,
- inhibit_vertical ? Qt : Qnil));
+ if (CONSP (frame_size_history))
+ frame_size_history_adjust (f, inhibit, parameter,
+ old_text_width, old_text_height,
+ new_text_width, new_text_height,
+ old_text_cols, old_text_lines,
+ new_text_cols, new_text_lines,
+ old_native_width, old_native_height,
+ new_native_width, new_native_height,
+ old_inner_width, old_inner_height,
+ new_inner_width, new_inner_height,
+ min_inner_width, min_inner_height,
+ inhibit_horizontal, inhibit_vertical);
+
+ if (inhibit == 0 || inhibit == 1)
+ {
+ f->new_width = new_native_width;
+ f->new_height = new_native_height;
+ /* Resetting f->new_size_p is controversial: It might cause
+ do_pending_window_change drop a previous request and we are
+ in troubles when the window manager does not honor the
+ request we issue here. */
+ f->new_size_p = false;
+ }
if (FRAME_TERMINAL (f)->set_window_size_hook)
FRAME_TERMINAL (f)->set_window_size_hook
- (f, 0, new_text_width, new_text_height, 1);
+ (f, 0, new_native_width, new_native_height);
f->resized_p = true;
return;
}
-#endif
+
+ if (CONSP (frame_size_history))
+ frame_size_history_adjust (f, inhibit, parameter,
+ old_text_width, old_text_height,
+ new_text_width, new_text_height,
+ old_text_cols, old_text_lines,
+ new_text_cols, new_text_lines,
+ old_native_width, old_native_height,
+ new_native_width, new_native_height,
+ old_inner_width, old_inner_height,
+ new_inner_width, new_inner_height,
+ min_inner_width, min_inner_height,
+ inhibit_horizontal, inhibit_vertical);
if ((XWINDOW (FRAME_ROOT_WINDOW (f))->pixel_top
== FRAME_TOP_MARGIN_HEIGHT (f))
&& new_text_width == old_text_width
&& new_text_height == old_text_height
- && new_windows_width == old_windows_width
- && new_windows_height == old_windows_height
- && new_pixel_width == old_pixel_width
- && new_pixel_height == old_pixel_height
- && new_cols == old_cols
- && new_lines == old_lines)
- /* No change. Sanitize window sizes and return. */
- {
- sanitize_window_sizes (Qt);
- sanitize_window_sizes (Qnil);
-
- return;
- }
+ && new_inner_width == old_inner_width
+ && new_inner_height == old_inner_height
+ /* We might be able to drop these but some doubts remain. */
+ && new_native_width == old_native_width
+ && new_native_height == old_native_height
+ && new_text_cols == old_text_cols
+ && new_text_lines == old_text_lines)
+ /* No change. */
+ return;
block_input ();
@@ -736,69 +809,67 @@ adjust_frame_size (struct frame *f, int new_width, int new_height, int inhibit,
our video hardware. Try to find the smallest size greater or
equal to the requested dimensions, while accounting for the fact
that the menu-bar lines are not counted in the frame height. */
- int dos_new_lines = new_lines + FRAME_TOP_MARGIN (f);
- dos_set_window_size (&dos_new_lines, &new_cols);
- new_lines = dos_new_lines - FRAME_TOP_MARGIN (f);
+ int dos_new_text_lines = new_text_lines + FRAME_TOP_MARGIN (f);
+
+ dos_set_window_size (&dos_new_text_lines, &new_text_cols);
+ new_text_lines = dos_new_text_lines - FRAME_TOP_MARGIN (f);
#endif
- if (new_windows_width != old_windows_width)
+ if (new_inner_width != old_inner_width)
{
- resize_frame_windows (f, new_windows_width, true);
+ resize_frame_windows (f, new_inner_width, true);
/* MSDOS frames cannot PRETEND, as they change frame size by
manipulating video hardware. */
if ((FRAME_TERMCAP_P (f) && !pretend) || FRAME_MSDOS_P (f))
- FrameCols (FRAME_TTY (f)) = new_cols;
+ FrameCols (FRAME_TTY (f)) = new_text_cols;
#if defined (HAVE_WINDOW_SYSTEM)
if (WINDOWP (f->tab_bar_window))
{
- XWINDOW (f->tab_bar_window)->pixel_width = new_windows_width;
+ XWINDOW (f->tab_bar_window)->pixel_width = new_inner_width;
XWINDOW (f->tab_bar_window)->total_cols
- = new_windows_width / unit_width;
+ = new_inner_width / unit_width;
}
#endif
#if defined (HAVE_WINDOW_SYSTEM) && ! defined (HAVE_EXT_TOOL_BAR)
if (WINDOWP (f->tool_bar_window))
{
- XWINDOW (f->tool_bar_window)->pixel_width = new_windows_width;
+ XWINDOW (f->tool_bar_window)->pixel_width = new_inner_width;
XWINDOW (f->tool_bar_window)->total_cols
- = new_windows_width / unit_width;
+ = new_inner_width / unit_width;
}
#endif
}
- else if (new_cols != old_cols)
+ else if (new_text_cols != old_text_cols)
call2 (Qwindow__pixel_to_total, frame, Qt);
- if (new_windows_height != old_windows_height
+ if (new_inner_height != old_inner_height
/* When the top margin has changed we have to recalculate the top
edges of all windows. No such calculation is necessary for the
left edges. */
|| WINDOW_TOP_PIXEL_EDGE (r) != FRAME_TOP_MARGIN_HEIGHT (f))
{
- resize_frame_windows (f, new_windows_height, false);
+ resize_frame_windows (f, new_inner_height, false);
/* MSDOS frames cannot PRETEND, as they change frame size by
manipulating video hardware. */
if ((FRAME_TERMCAP_P (f) && !pretend) || FRAME_MSDOS_P (f))
- FrameRows (FRAME_TTY (f)) = new_lines + FRAME_TOP_MARGIN (f);
+ FrameRows (FRAME_TTY (f)) = new_text_lines + FRAME_TOP_MARGIN (f);
}
- else if (new_lines != old_lines)
+ else if (new_text_lines != old_text_lines)
call2 (Qwindow__pixel_to_total, frame, Qnil);
- frame_size_history_add
- (f, Qadjust_frame_size_3, new_text_width, new_text_height,
- list4i (old_pixel_width, old_pixel_height,
- new_pixel_width, new_pixel_height));
-
/* Assign new sizes. */
+ FRAME_COLS (f) = new_text_cols;
+ FRAME_LINES (f) = new_text_lines;
FRAME_TEXT_WIDTH (f) = new_text_width;
FRAME_TEXT_HEIGHT (f) = new_text_height;
- FRAME_PIXEL_WIDTH (f) = new_pixel_width;
- FRAME_PIXEL_HEIGHT (f) = new_pixel_height;
- SET_FRAME_COLS (f, new_cols);
- SET_FRAME_LINES (f, new_lines);
+ FRAME_PIXEL_WIDTH (f) = new_native_width;
+ FRAME_PIXEL_HEIGHT (f) = new_native_height;
+ FRAME_TOTAL_COLS (f) = FRAME_PIXEL_WIDTH (f) / FRAME_COLUMN_WIDTH (f);
+ FRAME_TOTAL_LINES (f) = FRAME_PIXEL_HEIGHT (f) / FRAME_LINE_HEIGHT (f);
{
struct window *w = XWINDOW (FRAME_SELECTED_WINDOW (f));
@@ -812,18 +883,18 @@ adjust_frame_size (struct frame *f, int new_width, int new_height, int inhibit,
w->cursor.vpos = w->cursor.y = 0;
}
- /* Sanitize window sizes. */
- sanitize_window_sizes (Qt);
- sanitize_window_sizes (Qnil);
-
adjust_frame_glyphs (f);
calculate_costs (f);
SET_FRAME_GARBAGED (f);
+ /* We now say here that F was resized instead of using the old
+ condition below. Some resizing must have taken place and if it was
+ only shifting the root window's position (paranoia?). */
+ f->resized_p = true;
- /* A frame was "resized" if one of its pixelsizes changed, even if its
- X window wasn't resized at all. */
- f->resized_p = (new_pixel_width != old_pixel_width
- || new_pixel_height != old_pixel_height);
+/** /\* A frame was "resized" if its native size changed, even if its X **/
+/** window wasn't resized at all. *\/ **/
+/** f->resized_p = (new_native_width != old_native_width **/
+/** || new_native_height != old_native_height); **/
unblock_input ();
@@ -834,8 +905,8 @@ adjust_frame_size (struct frame *f, int new_width, int new_height, int inhibit,
FOR_EACH_FRAME (frames, frame1)
if (FRAME_PARENT_FRAME (XFRAME (frame1)) == f)
- keep_ratio (XFRAME (frame1), f, old_pixel_width, old_pixel_height,
- new_pixel_width, new_pixel_height);
+ keep_ratio (XFRAME (frame1), f, old_native_width, old_native_height,
+ new_native_width, new_native_height);
}
#endif
}
@@ -884,6 +955,8 @@ make_frame (bool mini_p)
f->tool_bar_resized = false;
f->column_width = 1; /* !FRAME_WINDOW_P value. */
f->line_height = 1; /* !FRAME_WINDOW_P value. */
+ f->new_width = -1;
+ f->new_height = -1;
#ifdef HAVE_WINDOW_SYSTEM
f->vertical_scroll_bar_type = vertical_scroll_bar_none;
f->horizontal_scroll_bars = false;
@@ -898,6 +971,7 @@ make_frame (bool mini_p)
f->no_accept_focus = false;
f->z_group = z_group_none;
f->tooltip = false;
+ f->was_invisible = false;
f->child_frame_border_width = -1;
f->last_tab_bar_item = -1;
#ifndef HAVE_EXT_TOOL_BAR
@@ -908,6 +982,7 @@ make_frame (bool mini_p)
f->ns_transparent_titlebar = false;
#endif
#endif
+ f->select_mini_window_flag = false;
/* This one should never be zero. */
f->change_stamp = 1;
root_window = make_window ();
@@ -932,20 +1007,21 @@ make_frame (bool mini_p)
wset_frame (rw, frame);
- /* 80/25 is arbitrary,
- just so that there is "something there."
+ /* 80/25 is arbitrary, just so that there is "something there."
Correct size will be set up later with adjust_frame_size. */
+ FRAME_COLS (f) = FRAME_TOTAL_COLS (f) = rw->total_cols = 80;
+ FRAME_TEXT_WIDTH (f) = FRAME_PIXEL_WIDTH (f) = rw->pixel_width
+ = 80 * FRAME_COLUMN_WIDTH (f);
+ FRAME_LINES (f) = FRAME_TOTAL_LINES (f) = 25;
+ FRAME_TEXT_HEIGHT (f) = FRAME_PIXEL_HEIGHT (f) = 25 * FRAME_LINE_HEIGHT (f);
- SET_FRAME_COLS (f, 80);
- SET_FRAME_LINES (f, 25);
- SET_FRAME_WIDTH (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f));
- SET_FRAME_HEIGHT (f, FRAME_LINES (f) * FRAME_LINE_HEIGHT (f));
-
- rw->total_cols = FRAME_COLS (f);
- rw->pixel_width = rw->total_cols * FRAME_COLUMN_WIDTH (f);
rw->total_lines = FRAME_LINES (f) - (mini_p ? 1 : 0);
rw->pixel_height = rw->total_lines * FRAME_LINE_HEIGHT (f);
+ fset_face_hash_table
+ (f, make_hash_table (hashtest_eq, DEFAULT_HASH_SIZE, DEFAULT_REHASH_SIZE,
+ DEFAULT_REHASH_THRESHOLD, Qnil, false));
+
if (mini_p)
{
mw->top_line = rw->total_lines;
@@ -1254,7 +1330,7 @@ affects all frames on the same terminal device. */)
{
struct frame *f;
struct terminal *t = NULL;
- Lisp_Object frame, tem;
+ Lisp_Object frame;
struct frame *sf = SELECTED_FRAME ();
#ifdef MSDOS
@@ -1316,8 +1392,8 @@ affects all frames on the same terminal device. */)
{
int width, height;
get_tty_size (fileno (FRAME_TTY (f)->input), &width, &height);
- adjust_frame_size (f, width, height - FRAME_MENU_BAR_LINES (f)
- - FRAME_TAB_BAR_LINES (f),
+ /* With INHIBIT 5 pass correct text height to adjust_frame_size. */
+ adjust_frame_size (f, width, height - FRAME_TOP_MARGIN (f),
5, 0, Qterminal_frame);
}
@@ -1336,14 +1412,16 @@ affects all frames on the same terminal device. */)
store_in_alist (&parms, Qminibuffer, Qt);
Fmodify_frame_parameters (frame, parms);
- /* Make the frame face alist be frame-specific, so that each
+ /* Make the frame face hash be frame-specific, so that each
frame could change its face definitions independently. */
- fset_face_alist (f, Fcopy_alist (sf->face_alist));
- /* Simple Fcopy_alist isn't enough, because we need the contents of
- the vectors which are the CDRs of associations in face_alist to
+ fset_face_hash_table (f, Fcopy_hash_table (sf->face_hash_table));
+ /* Simple copy_hash_table isn't enough, because we need the contents of
+ the vectors which are the values in face_hash_table to
be copied as well. */
- for (tem = f->face_alist; CONSP (tem); tem = XCDR (tem))
- XSETCDR (XCAR (tem), Fcopy_sequence (XCDR (XCAR (tem))));
+ ptrdiff_t idx = 0;
+ struct Lisp_Hash_Table *table = XHASH_TABLE (f->face_hash_table);
+ for (idx = 0; idx < table->count; ++idx)
+ set_hash_value_slot (table, idx, Fcopy_sequence (HASH_VALUE (table, idx)));
f->can_set_window_size = true;
f->after_make_frame = true;
@@ -1384,7 +1462,8 @@ do_switch_frame (Lisp_Object frame, int track, int for_deletion, Lisp_Object nor
especially when deleting the initial frame during startup. */
CHECK_FRAME (frame);
f = XFRAME (frame);
- if (!FRAME_LIVE_P (f))
+ /* Silently ignore dead and tooltip frames (Bug#47207). */
+ if (!FRAME_LIVE_P (f) || FRAME_TOOLTIP_P (f))
return Qnil;
else if (f == sf)
return frame;
@@ -1470,7 +1549,17 @@ do_switch_frame (Lisp_Object frame, int track, int for_deletion, Lisp_Object nor
tty->top_frame = frame;
}
+ sf->select_mini_window_flag = MINI_WINDOW_P (XWINDOW (sf->selected_window));
+
selected_frame = frame;
+
+ move_minibuffers_onto_frame (sf, for_deletion);
+
+ if (f->select_mini_window_flag
+ && !NILP (Fminibufferp (XWINDOW (f->minibuffer_window)->contents, Qt)))
+ f->selected_window = f->minibuffer_window;
+ f->select_mini_window_flag = false;
+
if (! FRAME_MINIBUF_ONLY_P (XFRAME (selected_frame)))
last_nonminibuf_frame = XFRAME (selected_frame);
@@ -1487,7 +1576,6 @@ do_switch_frame (Lisp_Object frame, int track, int for_deletion, Lisp_Object nor
#endif
internal_last_event_frame = Qnil;
- move_minibuffer_onto_frame ();
return frame;
}
@@ -1508,7 +1596,16 @@ redisplay will display FRAME.
This function returns FRAME, or nil if FRAME has been deleted. */)
(Lisp_Object frame, Lisp_Object norecord)
{
- return do_switch_frame (frame, 1, 0, norecord);
+ struct frame *f;
+
+ CHECK_LIVE_FRAME (frame);
+ f = XFRAME (frame);
+
+ if (FRAME_TOOLTIP_P (f))
+ /* Do not select a tooltip frame (Bug#47207). */
+ error ("Cannot select a tooltip frame");
+ else
+ return do_switch_frame (frame, 1, 0, norecord);
}
DEFUN ("handle-switch-frame", Fhandle_switch_frame,
@@ -1523,6 +1620,7 @@ necessarily represent user-visible input focus. */)
/* Preserve prefix arg that the command loop just cleared. */
kset_prefix_arg (current_kboard, Vcurrent_prefix_arg);
run_hook (Qmouse_leave_buffer_hook);
+
return do_switch_frame (event, 0, 0, Qnil);
}
@@ -1848,52 +1946,6 @@ other_frames (struct frame *f, bool invisible, bool force)
return false;
}
-/* Make sure that minibuf_window doesn't refer to FRAME's minibuffer
- window. Preferably use the selected frame's minibuffer window
- instead. If the selected frame doesn't have one, get some other
- frame's minibuffer window. SELECT non-zero means select the new
- minibuffer window. */
-static void
-check_minibuf_window (Lisp_Object frame, int select)
-{
- struct frame *f = decode_live_frame (frame);
-
- XSETFRAME (frame, f);
-
- if (WINDOWP (minibuf_window) && EQ (f->minibuffer_window, minibuf_window))
- {
- Lisp_Object frames, this, window = make_fixnum (0);
-
- if (!EQ (frame, selected_frame)
- && FRAME_HAS_MINIBUF_P (XFRAME (selected_frame)))
- window = FRAME_MINIBUF_WINDOW (XFRAME (selected_frame));
- else
- FOR_EACH_FRAME (frames, this)
- {
- if (!EQ (this, frame) && FRAME_HAS_MINIBUF_P (XFRAME (this)))
- {
- window = FRAME_MINIBUF_WINDOW (XFRAME (this));
- break;
- }
- }
-
- /* Don't abort if no window was found (Bug#15247). */
- if (WINDOWP (window))
- {
- /* Use set_window_buffer instead of Fset_window_buffer (see
- discussion of bug#11984, bug#12025, bug#12026). */
- set_window_buffer (window, XWINDOW (minibuf_window)->contents, 0, 0);
- minibuf_window = window;
-
- /* SELECT non-zero usually means that FRAME's minibuffer
- window was selected; select the new one. */
- if (select)
- Fselect_window (minibuf_window, Qnil);
- }
- }
-}
-
-
/**
* delete_frame:
*
@@ -1908,7 +1960,7 @@ delete_frame (Lisp_Object frame, Lisp_Object force)
struct frame *sf;
struct kboard *kb;
Lisp_Object frames, frame1;
- int minibuffer_selected, is_tooltip_frame;
+ int is_tooltip_frame;
bool nochild = !FRAME_PARENT_FRAME (f);
Lisp_Object minibuffer_child_frame = Qnil;
@@ -2016,7 +2068,6 @@ delete_frame (Lisp_Object frame, Lisp_Object force)
/* At this point, we are committed to deleting the frame.
There is no more chance for errors to prevent it. */
- minibuffer_selected = EQ (minibuf_window, selected_window);
sf = SELECTED_FRAME ();
/* Don't let the frame remain selected. */
if (f == sf)
@@ -2074,9 +2125,10 @@ delete_frame (Lisp_Object frame, Lisp_Object force)
do_switch_frame (frame1, 0, 1, Qnil);
sf = SELECTED_FRAME ();
}
-
- /* Don't allow minibuf_window to remain on a deleted frame. */
- check_minibuf_window (frame, minibuffer_selected);
+ else
+ /* Ensure any minibuffers on FRAME are moved onto the selected
+ frame. */
+ move_minibuffers_onto_frame (f, true);
/* Don't let echo_area_window to remain on a deleted frame. */
if (EQ (f->minibuffer_window, echo_area_window))
@@ -2707,9 +2759,6 @@ displayed in the terminal. */)
if (NILP (force) && !other_frames (f, true, false))
error ("Attempt to make invisible the sole visible or iconified frame");
- /* Don't allow minibuf_window to remain on an invisible frame. */
- check_minibuf_window (frame, EQ (minibuf_window, selected_window));
-
if (FRAME_WINDOW_P (f) && FRAME_TERMINAL (f)->frame_visible_invisible_hook)
FRAME_TERMINAL (f)->frame_visible_invisible_hook (f, false);
@@ -2752,9 +2801,6 @@ for how to proceed. */)
}
#endif /* HAVE_WINDOW_SYSTEM */
- /* Don't allow minibuf_window to remain on an iconified frame. */
- check_minibuf_window (frame, EQ (minibuf_window, selected_window));
-
if (FRAME_WINDOW_P (f) && FRAME_TERMINAL (f)->iconify_frame_hook)
FRAME_TERMINAL (f)->iconify_frame_hook (f);
@@ -3209,21 +3255,26 @@ If FRAME is omitted or nil, return information on the currently selected frame.
: FRAME_W32_P (f) ? "w32term"
:"tty"));
}
+
store_in_alist (&alist, Qname, f->name);
- height = (f->new_height
- ? (f->new_pixelwise
- ? (f->new_height / FRAME_LINE_HEIGHT (f))
- : f->new_height)
+ /* It's questionable whether here we should report the value of
+ f->new_height (and f->new_width below) but we've done that in the
+ past, so let's keep it. Note that a value of -1 for either of
+ these means that no new size was requested.
+
+ But check f->new_size before to make sure that f->new_height and
+ f->new_width are not ones requested by adjust_frame_size. */
+ height = ((f->new_size_p && f->new_height >= 0)
+ ? f->new_height / FRAME_LINE_HEIGHT (f)
: FRAME_LINES (f));
store_in_alist (&alist, Qheight, make_fixnum (height));
- width = (f->new_width
- ? (f->new_pixelwise
- ? (f->new_width / FRAME_COLUMN_WIDTH (f))
- : f->new_width)
- : FRAME_COLS (f));
+ width = ((f->new_size_p && f->new_width >= 0)
+ ? f->new_width / FRAME_COLUMN_WIDTH (f)
+ : FRAME_COLS(f));
store_in_alist (&alist, Qwidth, make_fixnum (width));
- store_in_alist (&alist, Qmodeline, (FRAME_WANTS_MODELINE_P (f) ? Qt : Qnil));
- store_in_alist (&alist, Qunsplittable, (FRAME_NO_SPLIT_P (f) ? Qt : Qnil));
+
+ store_in_alist (&alist, Qmodeline, FRAME_WANTS_MODELINE_P (f) ? Qt : Qnil);
+ store_in_alist (&alist, Qunsplittable, FRAME_NO_SPLIT_P (f) ? Qt : Qnil);
store_in_alist (&alist, Qbuffer_list, f->buffer_list);
store_in_alist (&alist, Qburied_buffer_list, f->buried_buffer_list);
@@ -3236,6 +3287,7 @@ If FRAME is omitted or nil, return information on the currently selected frame.
{
/* This ought to be correct in f->param_alist for an X frame. */
Lisp_Object lines;
+
XSETFASTINT (lines, FRAME_MENU_BAR_LINES (f));
store_in_alist (&alist, Qmenu_bar_lines, lines);
XSETFASTINT (lines, FRAME_TAB_BAR_LINES (f));
@@ -3582,20 +3634,23 @@ DEFUN ("frame-bottom-divider-width", Fbottom_divider_width, Sbottom_divider_widt
static int
check_frame_pixels (Lisp_Object size, Lisp_Object pixelwise, int item_size)
{
+ intmax_t sz;
+ int pixel_size; /* size * item_size */
+
CHECK_INTEGER (size);
if (!NILP (pixelwise))
item_size = 1;
- intmax_t sz;
- int pixel_size; /* size * item_size */
- if (! integer_to_intmax (size, &sz)
+
+ if (!integer_to_intmax (size, &sz)
|| INT_MULTIPLY_WRAPV (sz, item_size, &pixel_size))
args_out_of_range_3 (size, make_int (INT_MIN / item_size),
make_int (INT_MAX / item_size));
+
return pixel_size;
}
DEFUN ("set-frame-height", Fset_frame_height, Sset_frame_height, 2, 4,
- "(list (selected-frame) (prefix-numeric-value current-prefix-arg))",
+ "(set-frame-property--interactive \"Frame height: \" (frame-height))",
doc: /* Set text height of frame FRAME to HEIGHT lines.
Optional third arg PRETEND non-nil means that redisplay should use
HEIGHT lines but that the idea of the actual height of the frame should
@@ -3613,14 +3668,18 @@ If FRAME is nil, it defaults to the selected frame. */)
(Lisp_Object frame, Lisp_Object height, Lisp_Object pretend, Lisp_Object pixelwise)
{
struct frame *f = decode_live_frame (frame);
- int pixel_height = check_frame_pixels (height, pixelwise,
- FRAME_LINE_HEIGHT (f));
- adjust_frame_size (f, -1, pixel_height, 1, !NILP (pretend), Qheight);
+ int text_height
+ = check_frame_pixels (height, pixelwise, FRAME_LINE_HEIGHT (f));
+
+ /* With INHIBIT 1 pass correct text width to adjust_frame_size. */
+ adjust_frame_size
+ (f, FRAME_TEXT_WIDTH (f), text_height, 1, !NILP (pretend), Qheight);
+
return Qnil;
}
DEFUN ("set-frame-width", Fset_frame_width, Sset_frame_width, 2, 4,
- "(list (selected-frame) (prefix-numeric-value current-prefix-arg))",
+ "(set-frame-property--interactive \"Frame width: \" (frame-width))",
doc: /* Set text width of frame FRAME to WIDTH columns.
Optional third arg PRETEND non-nil means that redisplay should use WIDTH
columns but that the idea of the actual width of the frame should not
@@ -3638,9 +3697,13 @@ If FRAME is nil, it defaults to the selected frame. */)
(Lisp_Object frame, Lisp_Object width, Lisp_Object pretend, Lisp_Object pixelwise)
{
struct frame *f = decode_live_frame (frame);
- int pixel_width = check_frame_pixels (width, pixelwise,
- FRAME_COLUMN_WIDTH (f));
- adjust_frame_size (f, pixel_width, -1, 1, !NILP (pretend), Qwidth);
+ int text_width
+ = check_frame_pixels (width, pixelwise, FRAME_COLUMN_WIDTH (f));
+
+ /* With INHIBIT 1 pass correct text height to adjust_frame_size. */
+ adjust_frame_size
+ (f, text_width, FRAME_TEXT_HEIGHT (f), 1, !NILP (pretend), Qwidth);
+
return Qnil;
}
@@ -3656,11 +3719,14 @@ If FRAME is nil, it defaults to the selected frame. */)
(Lisp_Object frame, Lisp_Object width, Lisp_Object height, Lisp_Object pixelwise)
{
struct frame *f = decode_live_frame (frame);
- int pixel_width = check_frame_pixels (width, pixelwise,
- FRAME_COLUMN_WIDTH (f));
- int pixel_height = check_frame_pixels (height, pixelwise,
- FRAME_LINE_HEIGHT (f));
- adjust_frame_size (f, pixel_width, pixel_height, 1, 0, Qsize);
+ int text_width
+ = check_frame_pixels (width, pixelwise, FRAME_COLUMN_WIDTH (f));
+ int text_height
+ = check_frame_pixels (height, pixelwise, FRAME_LINE_HEIGHT (f));
+
+ /* PRETEND is always false here. */
+ adjust_frame_size (f, text_width, text_height, 1, false, Qsize);
+
return Qnil;
}
@@ -3744,6 +3810,18 @@ window state change flag is reset. */)
return (FRAME_WINDOW_STATE_CHANGE (f) = !NILP (arg)) ? Qt : Qnil;
}
+DEFUN ("frame-scale-factor", Fframe_scale_factor, Sframe_scale_factor,
+ 0, 1, 0,
+ doc: /* Return FRAMEs scale factor.
+If FRAME is omitted or nil, the selected frame is used.
+The scale factor is the amount by which a logical pixel size must be
+multiplied to find the real number of pixels. */)
+ (Lisp_Object frame)
+{
+ struct frame *f = decode_live_frame (frame);
+
+ return (make_float (f ? FRAME_SCALE_FACTOR (f) : 1));
+}
/***********************************************************************
Frame Parameters
@@ -3890,7 +3968,7 @@ frame_float (struct frame *f, Lisp_Object val, enum frame_float_type what,
Lisp_Object frame;
XSETFRAME (frame, f);
- monitor_attributes = Fcar (call1 (Qdisplay_monitor_attributes_list, frame));
+ monitor_attributes = call1 (Qframe_monitor_attributes, frame);
if (NILP (monitor_attributes))
{
/* No monitor attributes available. */
@@ -4012,11 +4090,9 @@ gui_set_frame_parameters (struct frame *f, Lisp_Object alist)
{
Lisp_Object tail, frame;
-
- /* If both of these parameters are present, it's more efficient to
- set them both at once. So we wait until we've looked at the
- entire list before we set them. */
- int width = -1, height = -1; /* -1 denotes they were not changed. */
+ /* Neither of these values should be used. */
+ int width = -1, height = -1;
+ bool width_change = false, height_change = false;
/* Same here. */
Lisp_Object left, top;
@@ -4094,6 +4170,8 @@ gui_set_frame_parameters (struct frame *f, Lisp_Object alist)
if (EQ (prop, Qwidth))
{
+ width_change = true;
+
if (RANGED_FIXNUMP (0, val, INT_MAX))
width = XFIXNAT (val) * FRAME_COLUMN_WIDTH (f) ;
else if (CONSP (val) && EQ (XCAR (val), Qtext_pixels)
@@ -4102,9 +4180,13 @@ gui_set_frame_parameters (struct frame *f, Lisp_Object alist)
else if (FLOATP (val))
width = frame_float (f, val, FRAME_FLOAT_WIDTH, &parent_done,
&outer_done, -1);
+ else
+ width_change = false;
}
else if (EQ (prop, Qheight))
{
+ height_change = true;
+
if (RANGED_FIXNUMP (0, val, INT_MAX))
height = XFIXNAT (val) * FRAME_LINE_HEIGHT (f);
else if (CONSP (val) && EQ (XCAR (val), Qtext_pixels)
@@ -4113,6 +4195,8 @@ gui_set_frame_parameters (struct frame *f, Lisp_Object alist)
else if (FLOATP (val))
height = frame_float (f, val, FRAME_FLOAT_HEIGHT, &parent_done,
&outer_done, -1);
+ else
+ height_change = false;
}
else if (EQ (prop, Qtop))
top = val;
@@ -4181,23 +4265,28 @@ gui_set_frame_parameters (struct frame *f, Lisp_Object alist)
XSETINT (icon_top, 0);
}
- /* Don't set these parameters unless they've been explicitly
- specified. The window might be mapped or resized while we're in
- this function, and we don't want to override that unless the lisp
- code has asked for it.
-
- Don't set these parameters unless they actually differ from the
- window's current parameters; the window may not actually exist
- yet. */
- if ((width != -1 && width != FRAME_TEXT_WIDTH (f))
- || (height != -1 && height != FRAME_TEXT_HEIGHT (f)))
- /* We could consider checking f->after_make_frame here, but I
- don't have the faintest idea why the following is needed at
- all. With the old setting it can get a Heisenbug when
- EmacsFrameResize intermittently provokes a delayed
- change_frame_size in the middle of adjust_frame_size. */
- /** || (f->can_set_window_size && (f->new_height || f->new_width))) **/
- adjust_frame_size (f, width, height, 1, 0, Qx_set_frame_parameters);
+ if (width_change || height_change)
+ {
+ Lisp_Object parameter;
+
+ if (width_change)
+ {
+ if (height_change)
+ parameter = Qsize;
+ else
+ {
+ height = FRAME_TEXT_HEIGHT (f);
+ parameter = Qwidth;
+ }
+ }
+ else
+ {
+ width = FRAME_TEXT_WIDTH (f);
+ parameter = Qheight;
+ }
+
+ adjust_frame_size (f, width, height, 1, 0, parameter);
+ }
if ((!NILP (left) || !NILP (top))
&& ! (left_no_change && top_no_change)
@@ -4270,9 +4359,6 @@ gui_set_frame_parameters (struct frame *f, Lisp_Object alist)
{
Lisp_Object old_value = get_frame_param (f, Qfullscreen);
- frame_size_history_add
- (f, Qx_set_fullscreen, 0, 0, list2 (old_value, fullscreen));
-
store_frame_param (f, Qfullscreen, fullscreen);
if (!EQ (fullscreen, old_value))
gui_set_fullscreen (f, fullscreen, old_value);
@@ -5481,25 +5567,16 @@ On Nextstep, this just calls `ns-parse-geometry'. */)
This function does not make the coordinates positive. */
-#define DEFAULT_ROWS 36
-#define DEFAULT_COLS 80
-
long
gui_figure_window_size (struct frame *f, Lisp_Object parms, bool tabbar_p,
- bool toolbar_p, int *x_width, int *x_height)
+ bool toolbar_p)
{
Lisp_Object height, width, user_size, top, left, user_position;
long window_prompting = 0;
Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f);
int parent_done = -1, outer_done = -1;
-
- /* Default values if we fall through.
- Actually, if that happens we should get
- window manager prompting. */
- SET_FRAME_WIDTH (f, DEFAULT_COLS * FRAME_COLUMN_WIDTH (f));
- SET_FRAME_COLS (f, DEFAULT_COLS);
- SET_FRAME_HEIGHT (f, DEFAULT_ROWS * FRAME_LINE_HEIGHT (f));
- SET_FRAME_LINES (f, DEFAULT_ROWS);
+ int text_width = 80 * FRAME_COLUMN_WIDTH (f);
+ int text_height = 36 * FRAME_LINE_HEIGHT (f);
/* Window managers expect that if program-specified
positions are not (0,0), they're intentional, not defaults. */
@@ -5514,8 +5591,12 @@ gui_figure_window_size (struct frame *f, Lisp_Object parms, bool tabbar_p,
if (tabbar_p && FRAME_TAB_BAR_LINES (f))
{
if (frame_default_tab_bar_height)
+ /* A default tab bar height was already set by the display code
+ for some other frame, use that. */
FRAME_TAB_BAR_HEIGHT (f) = frame_default_tab_bar_height;
else
+ /* Calculate the height from various other settings. For some
+ reason, these are usually off by 2 hence of no use. */
{
int margin, relief;
@@ -5568,7 +5649,7 @@ gui_figure_window_size (struct frame *f, Lisp_Object parms, bool tabbar_p,
/* Ensure that earlier new_width and new_height settings won't
override what we specify below. */
- f->new_width = f->new_height = 0;
+ f->new_width = f->new_height = -1;
height = gui_display_get_arg (dpyinfo, parms, Qheight, 0, 0, RES_TYPE_NUMBER);
width = gui_display_get_arg (dpyinfo, parms, Qwidth, 0, 0, RES_TYPE_NUMBER);
@@ -5582,9 +5663,8 @@ gui_figure_window_size (struct frame *f, Lisp_Object parms, bool tabbar_p,
if ((XFIXNUM (XCDR (width)) < 0 || XFIXNUM (XCDR (width)) > INT_MAX))
xsignal1 (Qargs_out_of_range, XCDR (width));
- SET_FRAME_WIDTH (f, XFIXNUM (XCDR (width)));
+ text_width = XFIXNUM (XCDR (width));
f->inhibit_horizontal_resize = true;
- *x_width = XFIXNUM (XCDR (width));
}
else if (FLOATP (width))
{
@@ -5598,7 +5678,7 @@ gui_figure_window_size (struct frame *f, Lisp_Object parms, bool tabbar_p,
&parent_done, &outer_done, -1);
if (new_width > -1)
- SET_FRAME_WIDTH (f, new_width);
+ text_width = new_width;
}
}
else
@@ -5607,7 +5687,7 @@ gui_figure_window_size (struct frame *f, Lisp_Object parms, bool tabbar_p,
if ((XFIXNUM (width) < 0 || XFIXNUM (width) > INT_MAX))
xsignal1 (Qargs_out_of_range, width);
- SET_FRAME_WIDTH (f, XFIXNUM (width) * FRAME_COLUMN_WIDTH (f));
+ text_width = XFIXNUM (width) * FRAME_COLUMN_WIDTH (f);
}
}
@@ -5619,9 +5699,8 @@ gui_figure_window_size (struct frame *f, Lisp_Object parms, bool tabbar_p,
if ((XFIXNUM (XCDR (height)) < 0 || XFIXNUM (XCDR (height)) > INT_MAX))
xsignal1 (Qargs_out_of_range, XCDR (height));
- SET_FRAME_HEIGHT (f, XFIXNUM (XCDR (height)));
+ text_height = XFIXNUM (XCDR (height));
f->inhibit_vertical_resize = true;
- *x_height = XFIXNUM (XCDR (height));
}
else if (FLOATP (height))
{
@@ -5635,7 +5714,7 @@ gui_figure_window_size (struct frame *f, Lisp_Object parms, bool tabbar_p,
&parent_done, &outer_done, -1);
if (new_height > -1)
- SET_FRAME_HEIGHT (f, new_height);
+ text_height = new_height;
}
}
else
@@ -5644,7 +5723,7 @@ gui_figure_window_size (struct frame *f, Lisp_Object parms, bool tabbar_p,
if ((XFIXNUM (height) < 0) || (XFIXNUM (height) > INT_MAX))
xsignal1 (Qargs_out_of_range, height);
- SET_FRAME_HEIGHT (f, XFIXNUM (height) * FRAME_LINE_HEIGHT (f));
+ text_height = XFIXNUM (height) * FRAME_LINE_HEIGHT (f);
}
}
@@ -5656,6 +5735,9 @@ gui_figure_window_size (struct frame *f, Lisp_Object parms, bool tabbar_p,
window_prompting |= PSize;
}
+ adjust_frame_size (f, text_width, text_height, 5, false,
+ Qgui_figure_window_size);
+
top = gui_display_get_arg (dpyinfo, parms, Qtop, 0, 0, RES_TYPE_NUMBER);
left = gui_display_get_arg (dpyinfo, parms, Qleft, 0, 0, RES_TYPE_NUMBER);
user_position = gui_display_get_arg (dpyinfo, parms, Quser_position, 0, 0,
@@ -5790,7 +5872,18 @@ selected frame. This is useful when `make-pointer-invisible' is set. */)
return decode_any_frame (frame)->pointer_invisible ? Qnil : Qt;
}
+DEFUN ("frame--set-was-invisible", Fframe__set_was_invisible,
+ Sframe__set_was_invisible, 2, 2, 0,
+ doc: /* Set FRAME's was-invisible flag if WAS-INVISIBLE is non-nil.
+This function is for internal use only. */)
+ (Lisp_Object frame, Lisp_Object was_invisible)
+{
+ struct frame *f = decode_live_frame (frame);
+
+ f->was_invisible = !NILP (was_invisible);
+ return f->was_invisible ? Qt : Qnil;
+}
/***********************************************************************
Multimonitor data
@@ -5890,7 +5983,7 @@ syms_of_frame (void)
DEFSYM (Qframep, "framep");
DEFSYM (Qframe_live_p, "frame-live-p");
DEFSYM (Qframe_windows_min_size, "frame-windows-min-size");
- DEFSYM (Qdisplay_monitor_attributes_list, "display-monitor-attributes-list");
+ DEFSYM (Qframe_monitor_attributes, "frame-monitor-attributes");
DEFSYM (Qwindow__pixel_to_total, "window--pixel-to-total");
DEFSYM (Qexplicit_name, "explicit-name");
DEFSYM (Qheight, "height");
@@ -5963,39 +6056,17 @@ syms_of_frame (void)
DEFSYM (Qtab_bar_size, "tab-bar-size");
DEFSYM (Qtool_bar_external, "tool-bar-external");
DEFSYM (Qtool_bar_size, "tool-bar-size");
- /* The following are used for frame_size_history. */
- DEFSYM (Qadjust_frame_size_1, "adjust-frame-size-1");
- DEFSYM (Qadjust_frame_size_2, "adjust-frame-size-2");
- DEFSYM (Qadjust_frame_size_3, "adjust-frame-size-3");
- DEFSYM (Qx_set_frame_parameters, "x-set-frame-parameters");
- DEFSYM (QEmacsFrameResize, "EmacsFrameResize");
- DEFSYM (Qset_frame_size, "set-frame-size");
- DEFSYM (Qframe_inhibit_resize, "frame-inhibit-resize");
- DEFSYM (Qx_set_fullscreen, "x-set-fullscreen");
- DEFSYM (Qx_check_fullscreen, "x-check-fullscreen");
- DEFSYM (Qxg_frame_resized, "xg-frame-resized");
- DEFSYM (Qxg_frame_set_char_size_1, "xg-frame-set-char-size-1");
- DEFSYM (Qxg_frame_set_char_size_2, "xg-frame-set-char-size-2");
- DEFSYM (Qxg_frame_set_char_size_3, "xg-frame-set-char-size-3");
- DEFSYM (Qxg_frame_set_char_size_4, "xg-frame-set-char-size-4");
- DEFSYM (Qx_set_window_size_1, "x-set-window-size-1");
- DEFSYM (Qx_set_window_size_2, "x-set-window-size-2");
- DEFSYM (Qx_set_window_size_3, "x-set-window-size-3");
- DEFSYM (Qxg_change_toolbar_position, "xg-change-toolbar-position");
- DEFSYM (Qx_net_wm_state, "x-net-wm-state");
- DEFSYM (Qx_handle_net_wm_state, "x-handle-net-wm-state");
- DEFSYM (Qtb_size_cb, "tb-size-cb");
- DEFSYM (Qupdate_frame_tab_bar, "update-frame-tab-bar");
- DEFSYM (Qupdate_frame_tool_bar, "update-frame-tool-bar");
- DEFSYM (Qfree_frame_tab_bar, "free-frame-tab-bar");
- DEFSYM (Qfree_frame_tool_bar, "free-frame-tool-bar");
- DEFSYM (Qx_set_menu_bar_lines, "x-set-menu-bar-lines");
- DEFSYM (Qchange_frame_size, "change-frame-size");
- DEFSYM (Qxg_frame_set_char_size, "xg-frame-set-char-size");
- DEFSYM (Qset_window_configuration, "set-window-configuration");
- DEFSYM (Qx_create_frame_1, "x-create-frame-1");
- DEFSYM (Qx_create_frame_2, "x-create-frame-2");
- DEFSYM (Qterminal_frame, "terminal-frame");
+ /* The following are passed to adjust_frame_size. */
+ DEFSYM (Qx_set_menu_bar_lines, "x_set_menu_bar_lines");
+ DEFSYM (Qchange_frame_size, "change_frame_size");
+ DEFSYM (Qxg_frame_set_char_size, "xg_frame_set_char_size");
+ DEFSYM (Qx_set_window_size_1, "x_set_window_size_1");
+ DEFSYM (Qset_window_configuration, "set_window_configuration");
+ DEFSYM (Qx_create_frame_1, "x_create_frame_1");
+ DEFSYM (Qx_create_frame_2, "x_create_frame_2");
+ DEFSYM (Qgui_figure_window_size, "gui_figure_window_size");
+ DEFSYM (Qtip_frame, "tip_frame");
+ DEFSYM (Qterminal_frame, "terminal_frame");
#ifdef HAVE_NS
DEFSYM (Qns_parse_geometry, "ns-parse-geometry");
@@ -6024,9 +6095,7 @@ syms_of_frame (void)
DEFSYM (Qleft_fringe, "left-fringe");
DEFSYM (Qline_spacing, "line-spacing");
DEFSYM (Qmenu_bar_lines, "menu-bar-lines");
- DEFSYM (Qupdate_frame_menubar, "update-frame-menubar");
- DEFSYM (Qfree_frame_menubar_1, "free-frame-menubar-1");
- DEFSYM (Qfree_frame_menubar_2, "free-frame-menubar-2");
+ DEFSYM (Qtab_bar_lines, "tab-bar-lines");
DEFSYM (Qmouse_color, "mouse-color");
DEFSYM (Qname, "name");
DEFSYM (Qright_divider_width, "right-divider-width");
@@ -6038,7 +6107,6 @@ syms_of_frame (void)
DEFSYM (Qscroll_bar_width, "scroll-bar-width");
DEFSYM (Qsticky, "sticky");
DEFSYM (Qtitle, "title");
- DEFSYM (Qtab_bar_lines, "tab-bar-lines");
DEFSYM (Qtool_bar_lines, "tool-bar-lines");
DEFSYM (Qtool_bar_position, "tool-bar-position");
DEFSYM (Qunsplittable, "unsplittable");
@@ -6455,8 +6523,10 @@ iconify the top level frame instead. */);
defsubr (&Sframe_position);
defsubr (&Sset_frame_position);
defsubr (&Sframe_pointer_visible_p);
+ defsubr (&Sframe__set_was_invisible);
defsubr (&Sframe_window_state_change);
defsubr (&Sset_frame_window_state_change);
+ defsubr (&Sframe_scale_factor);
#ifdef HAVE_WINDOW_SYSTEM
defsubr (&Sx_get_resource);