summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMartin Rudalics <rudalics@gmx.at>2014-11-07 11:49:22 +0100
committerMartin Rudalics <rudalics@gmx.at>2014-11-07 11:49:22 +0100
commit1c50b3adb636addc4244942e8f0e33b1e557ec07 (patch)
treefc452db1b888d5833e915778ad795c9d86f06678 /src
parenta067ef9a5ddc9812e35734e8c027684e01d684ef (diff)
downloademacs-1c50b3adb636addc4244942e8f0e33b1e557ec07.tar.gz
Improve inhibiting of implied frame resizes.
* frames.texi (Size and Position): Rewrite description of `frame-inhibit-implied-resize'. * cus-start.el (frame-resize-pixelwise): Fix group. (frame-inhibit-implied-resize): Add entry. * dispnew.c (change_frame_size_1): Fix call of adjust_frame_size. * frame.c (Qsize, Qframe_position, Qframe_outer_size) (Qframe_inner_size, Qexternal_border_size, Qtitle_height) (Qmenu_bar_external, Qmenu_bar_size, Qtool_bar_external) (Qtool_bar_size): New constants. (frame_inhibit_resize, adjust_frame_size): New argument to handle case where frame_inhibit_implied_resize is a list. (Fmake_terminal_frame, Fset_frame_height, Fset_frame_width) (Fset_frame_size, x_set_left_fringe, x_set_right_fringe) (x_set_right_divider_width, x_set_bottom_divider_width) (x_set_vertical_scroll_bars, x_set_horizontal_scroll_bars) (x_set_scroll_bar_width, x_set_scroll_bar_height): Update callers. (frame-inhibit-implied-resize): Rewrite doc-string. * frame.h (frame_inhibit_resize, adjust_frame_size): Fix external declarations. (Qframe_position, Qframe_outer_size) (Qframe_inner_size, Qexternal_border_size, Qtitle_height) (Qmenu_bar_external, Qmenu_bar_size, Qtool_bar_external) (Qtool_bar_size): Extern them. * gtkutil.c (FRAME_TOTAL_PIXEL_HEIGHT, FRAME_TOTAL_PIXEL_WIDTH) (xg_height_or_width_changed): Remove. (xg_frame_set_char_size): Adjust adjust_frame_size calls. (menubar_map_cb, xg_update_frame_menubar, free_frame_menubar) (tb_size_cb, update_frame_tool_bar, free_frame_tool_bar) (xg_change_toolbar_position): Call adjust_frame_size directly. * nsfns.m (x_set_internal_border_width, Fx_create_frame): Fix calls of adjust_frame_size. * w32fns.c (x_set_internal_border_width, x_set_menu_bar_lines) (Fx_create_frame, x_create_tip_frame): Adjust adjust_frame_size calls. (x_set_tool_bar_lines, x_change_tool_bar_height): Make sure that frame can get resized when tool-bar-lines parameter changes from or to zero. (Fw32_frame_menu_bar_size): Return fourth value. (Fw32_frame_rect): Block input around system calls (Fx_frame_geometry): New function. * w32menu.c (set_frame_menubar): Adjust adjust_frame_size call. * w32term.c (x_new_font): Adjust adjust_frame_size call. * widget.c (EmacsFrameSetCharSize): Adjust frame_inhibit_resize call. * window.c (Fset_window_configuration): Adjust adjust_frame_size call. * xfns.c (x_set_menu_bar_lines, x_set_internal_border_width) (Fx_create_frame): Adjust adjust_frame_size calls. (x_set_tool_bar_lines, x_change_tool_bar_height): Make sure that frame can get resized when tool-bar-lines parameter changes from or to zero. (Fx_frame_geometry): New function. * xmenu.c (update_frame_menubar): On Lucid call adjust_frame_size with one pixel less height to avoid that repeatedly adding/removing the menu bar grows the frame. (free_frame_menubar): On Motif arrange to optionally preserve the old frame height when removing the menu bar. * xterm.c (x_new_font): Adjust adjust_frame_size call.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog59
-rw-r--r--src/dispnew.c2
-rw-r--r--src/frame.c160
-rw-r--r--src/frame.h9
-rw-r--r--src/gtkutil.c26
-rw-r--r--src/nsfns.m6
-rw-r--r--src/w32fns.c181
-rw-r--r--src/w32menu.c2
-rw-r--r--src/w32term.c2
-rw-r--r--src/widget.c3
-rw-r--r--src/window.c2
-rw-r--r--src/xfns.c150
-rw-r--r--src/xmenu.c37
-rw-r--r--src/xterm.c5
14 files changed, 524 insertions, 120 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 6b62a60f7b0..c46d23dd82e 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,62 @@
+2014-11-07 Martin Rudalics <rudalics@gmx.at>
+
+ * dispnew.c (change_frame_size_1): Fix call of
+ adjust_frame_size.
+ * frame.c (Qsize, Qframe_position, Qframe_outer_size)
+ (Qframe_inner_size, Qexternal_border_size, Qtitle_height)
+ (Qmenu_bar_external, Qmenu_bar_size, Qtool_bar_external)
+ (Qtool_bar_size): New constants.
+ (frame_inhibit_resize, adjust_frame_size): New argument to
+ handle case where frame_inhibit_implied_resize is a list.
+ (Fmake_terminal_frame, Fset_frame_height, Fset_frame_width)
+ (Fset_frame_size, x_set_left_fringe, x_set_right_fringe)
+ (x_set_right_divider_width, x_set_bottom_divider_width)
+ (x_set_vertical_scroll_bars, x_set_horizontal_scroll_bars)
+ (x_set_scroll_bar_width, x_set_scroll_bar_height): Update
+ callers.
+ (frame-inhibit-implied-resize): Rewrite doc-string.
+ * frame.h (frame_inhibit_resize, adjust_frame_size): Fix
+ external declarations.
+ (Qframe_position, Qframe_outer_size)
+ (Qframe_inner_size, Qexternal_border_size, Qtitle_height)
+ (Qmenu_bar_external, Qmenu_bar_size, Qtool_bar_external)
+ (Qtool_bar_size): Extern them.
+ * gtkutil.c (FRAME_TOTAL_PIXEL_HEIGHT, FRAME_TOTAL_PIXEL_WIDTH)
+ (xg_height_or_width_changed): Remove.
+ (xg_frame_set_char_size): Adjust adjust_frame_size calls.
+ (menubar_map_cb, xg_update_frame_menubar, free_frame_menubar)
+ (tb_size_cb, update_frame_tool_bar, free_frame_tool_bar)
+ (xg_change_toolbar_position): Call adjust_frame_size directly.
+ * nsfns.m (x_set_internal_border_width, Fx_create_frame): Fix
+ calls of adjust_frame_size.
+ * w32fns.c (x_set_internal_border_width, x_set_menu_bar_lines)
+ (Fx_create_frame, x_create_tip_frame): Adjust adjust_frame_size
+ calls.
+ (x_set_tool_bar_lines, x_change_tool_bar_height): Make sure that
+ frame can get resized when tool-bar-lines parameter changes from
+ or to zero.
+ (Fw32_frame_menu_bar_size): Return fourth value.
+ (Fw32_frame_rect): Block input around system calls
+ (Fx_frame_geometry): New function.
+ * w32menu.c (set_frame_menubar): Adjust adjust_frame_size call.
+ * w32term.c (x_new_font): Adjust adjust_frame_size call.
+ * widget.c (EmacsFrameSetCharSize): Adjust frame_inhibit_resize
+ call.
+ * window.c (Fset_window_configuration): Adjust adjust_frame_size
+ call.
+ * xfns.c (x_set_menu_bar_lines, x_set_internal_border_width)
+ (Fx_create_frame): Adjust adjust_frame_size calls.
+ (x_set_tool_bar_lines, x_change_tool_bar_height): Make sure that
+ frame can get resized when tool-bar-lines parameter changes from
+ or to zero.
+ (Fx_frame_geometry): New function.
+ * xmenu.c (update_frame_menubar): On Lucid call
+ adjust_frame_size with one pixel less height to avoid that
+ repeatedly adding/removing the menu bar grows the frame.
+ (free_frame_menubar): On Motif arrange to optionally preserve
+ the old frame height when removing the menu bar.
+ * xterm.c (x_new_font): Adjust adjust_frame_size call.
+
2014-11-03 Eli Zaretskii <eliz@gnu.org>
* xdisp.c (Fdump_glyph_matrix, Fdump_frame_glyph_matrix): Doc fix.
diff --git a/src/dispnew.c b/src/dispnew.c
index 900912d9d97..d50d06f2d47 100644
--- a/src/dispnew.c
+++ b/src/dispnew.c
@@ -5528,7 +5528,7 @@ change_frame_size_1 (struct frame *f, int new_width, int new_height,
/* Adjust frame size but make sure x_set_window_size does not
get called. */
- adjust_frame_size (f, new_width, new_height, 5, pretend);
+ adjust_frame_size (f, new_width, new_height, 5, pretend, Qnil);
}
}
diff --git a/src/frame.c b/src/frame.c
index d1acb73b926..5bb2c831c20 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -77,7 +77,7 @@ Lisp_Object Qterminal;
Lisp_Object Qauto_raise, Qauto_lower;
Lisp_Object Qborder_color, Qborder_width;
Lisp_Object Qcursor_color, Qcursor_type;
-Lisp_Object Qheight, Qwidth;
+Lisp_Object Qheight, Qwidth, Qsize;
Lisp_Object Qicon_left, Qicon_top, Qicon_type, Qicon_name;
Lisp_Object Qtooltip;
Lisp_Object Qinternal_border_width;
@@ -120,6 +120,11 @@ static Lisp_Object Qdelete_frame_functions;
static Lisp_Object Qframe_windows_min_size;
static Lisp_Object Qgeometry, Qworkarea, Qmm_size, Qframes, Qsource;
+Lisp_Object Qframe_position, Qframe_outer_size, Qframe_inner_size;
+Lisp_Object Qexternal_border_size, Qtitle_height;
+Lisp_Object Qmenu_bar_external, Qmenu_bar_size;
+Lisp_Object Qtool_bar_external, Qtool_bar_size;
+
/* The currently selected frame. */
Lisp_Object selected_frame;
@@ -209,12 +214,14 @@ get_frame_param (register struct frame *frame, Lisp_Object prop)
/* 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. */
+ HORIZONTAL is true) resize. PARAMETER is the symbol of the frame
+ parameter that is changed. */
bool
-frame_inhibit_resize (struct frame *f, bool horizontal)
+frame_inhibit_resize (struct frame *f, bool horizontal, Lisp_Object parameter)
{
-
- return (frame_inhibit_implied_resize
+ return (EQ (frame_inhibit_implied_resize, Qt)
+ || (CONSP (frame_inhibit_implied_resize)
+ && !NILP (Fmemq (parameter, frame_inhibit_implied_resize)))
|| !NILP (get_frame_param (f, Qfullscreen))
|| FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f));
}
@@ -337,40 +344,46 @@ frame_windows_min_size (Lisp_Object frame, Lisp_Object horizontal, Lisp_Object p
/* Make sure windows sizes of frame F are OK. new_width and new_height
are in pixels. A value of -1 means no change is requested for that
size (but the frame may still have to be resized to accommodate
- windows with their minimum sizes.
+ windows with their minimum sizes). This can either issue a request
+ to resize the frame externally (via x_set_window_size), to resize the
+ frame internally (via resize_frame_windows) or do nothing at all.
The argument INHIBIT can assume the following values:
0 means to unconditionally call x_set_window_size even if sizes
- apparently do not change. Fx_create_frame uses this to pass the
- initial size to the window manager.
+ apparently do not change. Fx_create_frame uses this to pass the
+ initial size to the window manager.
- 1 means to call x_set_window_size iff the pixel size really changes.
- Fset_frame_size, Fset_frame_height, ... use this.
+ 1 means to call x_set_window_size if the outer frame size really
+ changes. Fset_frame_size, Fset_frame_height, ... use this.
- 2 means to unconditionally call x_set_window_size provided
- frame_inhibit_resize allows it. The menu bar code uses this.
+ 2 means to call x_set_window_size 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).
- 3 means call x_set_window_size iff window minimum sizes must be
- preserved or frame_inhibit_resize allows it, x_set_left_fringe,
- x_set_scroll_bar_width, ... use this.
+ 3 means call x_set_window_size if window minimum sizes must be
+ preserved or frame_inhibit_resize allows it. x_set_left_fringe,
+ x_set_scroll_bar_width, x_new_font ... use (or should use) this.
- 4 means call x_set_window_size iff window minimum sizes must be
- preserved. x_set_tool_bar_lines, x_set_right_divider_width, ... use
- this. BUT maybe the toolbar code shouldn't ....
+ 4 means call x_set_window_size 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.
5 means to never call x_set_window_size. change_frame_size uses
- this.
+ this.
- For 2 and 3 note that if frame_inhibit_resize inhibits resizing and
- minimum sizes are not violated no internal resizing takes place
- either. For 2, 3, 4 and 5 note that even if no x_set_window_size
- call is issued, window sizes may have to be adjusted in order to
- support minimum size constraints for the frame's windows.
+ Note that even when x_set_window_size is not called, individual
+ windows may have to be resized (via `window--sanitize-window-sizes')
+ in order to support minimum size constraints.
- PRETEND is as for change_frame_size. */
+ 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. */
void
-adjust_frame_size (struct frame *f, int new_width, int new_height, int inhibit, bool pretend)
+adjust_frame_size (struct frame *f, int new_width, int new_height, int inhibit,
+ bool pretend, Lisp_Object parameter)
{
int unit_width = FRAME_COLUMN_WIDTH (f);
int unit_height = FRAME_LINE_HEIGHT (f);
@@ -415,10 +428,12 @@ adjust_frame_size (struct frame *f, int new_width, int new_height, int inhibit,
so or INHIBIT equals 4. */
{
inhibit_horizontal = ((windows_width >= min_windows_width
- && (inhibit == 4 || frame_inhibit_resize (f, true)))
+ && (inhibit == 4
+ || frame_inhibit_resize (f, true, parameter)))
? true : false);
inhibit_vertical = ((windows_height >= min_windows_height
- && (inhibit == 4 || frame_inhibit_resize (f, false)))
+ && (inhibit == 4
+ || frame_inhibit_resize (f, false, parameter)))
? true : false);
}
else
@@ -1004,7 +1019,7 @@ 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), 5, 0);
+ adjust_frame_size (f, width, height - FRAME_MENU_BAR_LINES (f), 5, 0, Qnil);
}
adjust_frame_glyphs (f);
@@ -2848,7 +2863,7 @@ multiple of the default frame font height. */)
? XINT (height)
: XINT (height) * FRAME_LINE_HEIGHT (f));
if (pixel_height != FRAME_TEXT_HEIGHT (f))
- adjust_frame_size (f, -1, pixel_height, 1, !NILP (pretend));
+ adjust_frame_size (f, -1, pixel_height, 1, !NILP (pretend), Qheight);
return Qnil;
}
@@ -2874,7 +2889,7 @@ multiple of the default frame font width. */)
? XINT (width)
: XINT (width) * FRAME_COLUMN_WIDTH (f));
if (pixel_width != FRAME_TEXT_WIDTH (f))
- adjust_frame_size (f, pixel_width, -1, 1, !NILP (pretend));
+ adjust_frame_size (f, pixel_width, -1, 1, !NILP (pretend), Qwidth);
return Qnil;
}
@@ -2903,7 +2918,7 @@ font height. */)
if (pixel_width != FRAME_TEXT_WIDTH (f)
|| pixel_height != FRAME_TEXT_HEIGHT (f))
- adjust_frame_size (f, pixel_width, pixel_height, 1, 0);
+ adjust_frame_size (f, pixel_width, pixel_height, 1, 0, Qsize);
return Qnil;
}
@@ -3627,7 +3642,7 @@ x_set_left_fringe (struct frame *f, Lisp_Object new_value, Lisp_Object old_value
= (new_width + FRAME_RIGHT_FRINGE_WIDTH (f) + unit - 1) / unit;
if (FRAME_X_WINDOW (f) != 0)
- adjust_frame_size (f, -1, -1, 3, 0);
+ adjust_frame_size (f, -1, -1, 3, 0, Qleft_fringe);
SET_FRAME_GARBAGED (f);
}
@@ -3651,7 +3666,7 @@ x_set_right_fringe (struct frame *f, Lisp_Object new_value, Lisp_Object old_valu
= (new_width + FRAME_LEFT_FRINGE_WIDTH (f) + unit - 1) / unit;
if (FRAME_X_WINDOW (f) != 0)
- adjust_frame_size (f, -1, -1, 3, 0);
+ adjust_frame_size (f, -1, -1, 3, 0, Qright_fringe);
SET_FRAME_GARBAGED (f);
}
@@ -3683,7 +3698,7 @@ x_set_right_divider_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
FRAME_RIGHT_DIVIDER_WIDTH (f) = 0;
if (FRAME_RIGHT_DIVIDER_WIDTH (f) != old)
{
- adjust_frame_size (f, -1, -1, 4, 0);
+ adjust_frame_size (f, -1, -1, 4, 0, Qright_divider_width);
adjust_frame_glyphs (f);
SET_FRAME_GARBAGED (f);
}
@@ -3701,7 +3716,7 @@ x_set_bottom_divider_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval
FRAME_BOTTOM_DIVIDER_WIDTH (f) = 0;
if (FRAME_BOTTOM_DIVIDER_WIDTH (f) != old)
{
- adjust_frame_size (f, -1, -1, 4, 0);
+ adjust_frame_size (f, -1, -1, 4, 0, Qbottom_divider_width);
adjust_frame_glyphs (f);
SET_FRAME_GARBAGED (f);
}
@@ -3765,7 +3780,7 @@ x_set_vertical_scroll_bars (struct frame *f, Lisp_Object arg, Lisp_Object oldval
However, if the window hasn't been created yet, we shouldn't
call x_set_window_size. */
if (FRAME_X_WINDOW (f))
- adjust_frame_size (f, -1, -1, 3, 0);
+ adjust_frame_size (f, -1, -1, 3, 0, Qvertical_scroll_bars);
SET_FRAME_GARBAGED (f);
}
@@ -3785,7 +3800,7 @@ x_set_horizontal_scroll_bars (struct frame *f, Lisp_Object arg, Lisp_Object oldv
However, if the window hasn't been created yet, we shouldn't
call x_set_window_size. */
if (FRAME_X_WINDOW (f))
- adjust_frame_size (f, -1, -1, 3, 0);
+ adjust_frame_size (f, -1, -1, 3, 0, Qhorizontal_scroll_bars);
SET_FRAME_GARBAGED (f);
}
@@ -3802,7 +3817,7 @@ x_set_scroll_bar_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
x_set_scroll_bar_default_width (f);
if (FRAME_X_WINDOW (f))
- adjust_frame_size (f, -1, -1, 3, 0);
+ adjust_frame_size (f, -1, -1, 3, 0, Qscroll_bar_width);
SET_FRAME_GARBAGED (f);
}
@@ -3812,7 +3827,7 @@ x_set_scroll_bar_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = XFASTINT (arg);
FRAME_CONFIG_SCROLL_BAR_COLS (f) = (XFASTINT (arg) + unit - 1) / unit;
if (FRAME_X_WINDOW (f))
- adjust_frame_size (f, -1, -1, 3, 0);
+ adjust_frame_size (f, -1, -1, 3, 0, Qscroll_bar_width);
SET_FRAME_GARBAGED (f);
}
@@ -3832,7 +3847,7 @@ x_set_scroll_bar_height (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
x_set_scroll_bar_default_height (f);
if (FRAME_X_WINDOW (f))
- adjust_frame_size (f, -1, -1, 3, 0);
+ adjust_frame_size (f, -1, -1, 3, 0, Qscroll_bar_height);
SET_FRAME_GARBAGED (f);
}
@@ -3842,7 +3857,7 @@ x_set_scroll_bar_height (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
FRAME_CONFIG_SCROLL_BAR_HEIGHT (f) = XFASTINT (arg);
FRAME_CONFIG_SCROLL_BAR_LINES (f) = (XFASTINT (arg) + unit - 1) / unit;
if (FRAME_X_WINDOW (f))
- adjust_frame_size (f, -1, -1, 3, 0);
+ adjust_frame_size (f, -1, -1, 3, 0, Qscroll_bar_height);
SET_FRAME_GARBAGED (f);
}
@@ -4785,12 +4800,21 @@ syms_of_frame (void)
DEFSYM (Qterminal, "terminal");
- DEFSYM (Qgeometry, "geometry");
DEFSYM (Qworkarea, "workarea");
DEFSYM (Qmm_size, "mm-size");
DEFSYM (Qframes, "frames");
DEFSYM (Qsource, "source");
+ DEFSYM (Qframe_position, "frame-position");
+ DEFSYM (Qframe_outer_size, "frame-outer-size");
+ DEFSYM (Qexternal_border_size, "external-border-size");
+ DEFSYM (Qtitle_height, "title-height");
+ DEFSYM (Qmenu_bar_external, "menu-bar-external");
+ DEFSYM (Qmenu_bar_size, "menu-bar-size");
+ DEFSYM (Qtool_bar_external, "tool-bar-external");
+ DEFSYM (Qtool_bar_size, "tool-bar-size");
+ DEFSYM (Qframe_inner_size, "frame-inner-size");
+
#ifdef HAVE_NS
DEFSYM (Qns_parse_geometry, "ns-parse-geometry");
#endif
@@ -4985,13 +5009,49 @@ fullscreen. To resize your initial frame pixelwise, set this option to
a non-nil value in your init file. */);
frame_resize_pixelwise = 0;
- DEFVAR_BOOL ("frame-inhibit-implied-resize", frame_inhibit_implied_resize,
- doc: /* Non-nil means do not resize frames implicitly.
-If this option is nil, setting default font, menubar mode, fringe width,
-or scroll bar mode of a specific frame may resize the frame in order to
-preserve the number of columns or lines it displays. If this option is
-non-nil, no such resizing is done. */);
- frame_inhibit_implied_resize = 0;
+ DEFVAR_LISP ("frame-inhibit-implied-resize", frame_inhibit_implied_resize,
+ doc: /* Whether frames should be resized implicitly.
+If this option is nil, setting font, menu bar, tool bar, internal
+borders, fringes or scroll bars of a specific frame may resize the frame
+in order to preserve the number of columns or lines it displays. If
+this option is `t', no such resizing is done. Note that the size of
+fullscreen and maximized frames, the height of fullheight frames and the
+width of fullwidth frames never change implicitly.
+
+The value of this option can be also be a list of frame parameters. In
+this case, resizing is inhibited when changing a parameter that appears
+in that list. The parameters currently handled by this option include
+`font', `font-backend', `internal-border-width', `menu-bar-lines' and
+`tool-bar-lines'.
+
+Changing any of the parameters `scroll-bar-width', `scroll-bar-height',
+`vertical-scroll-bars', `horizontal-scroll-bars', `left-fringe' and
+`right-fringe' is handled as if the frame contained just one live
+window. This means, for example, that removing vertical scroll bars on
+a frame containing several side by side windows will shrink the frame
+width by the width of one scroll bar provided this option is nil and
+keep it unchanged if this option is either `t' or a list containing
+`vertical-scroll-bars'.
+
+The default value is '(tool-bar-lines) on Lucid, Motif and Windows
+(which means that adding/removing a tool bar does not change the frame
+height), nil on all other window systems including GTK+ (which means
+that changing any of the parameters listed above may change the size of
+the frame), and `t' otherwise (which means the frame size never changes
+implicitly when there's no window system support).
+
+Note that when a frame is not large enough to accommodate a change of
+any of the parameters listed above, Emacs may try to enlarge the frame
+even if this option is non-nil. */);
+#if defined (HAVE_WINDOW_SYSTEM)
+#if defined (USE_LUCID) || defined (USE_MOTIF) || defined (HAVE_NTGUI)
+ frame_inhibit_implied_resize = list1 (Qtool_bar_lines);
+#else
+ frame_inhibit_implied_resize = Qnil;
+#endif
+#else
+ frame_inhibit_implied_resize = Qt;
+#endif
staticpro (&Vframe_list);
diff --git a/src/frame.h b/src/frame.h
index 22f2fa7a24c..b5d3bbb5b11 100644
--- a/src/frame.h
+++ b/src/frame.h
@@ -1117,8 +1117,8 @@ extern void check_window_system (struct frame *);
extern void frame_make_pointer_invisible (struct frame *);
extern void frame_make_pointer_visible (struct frame *);
extern Lisp_Object delete_frame (Lisp_Object, Lisp_Object);
-extern bool frame_inhibit_resize (struct frame *, bool);
-extern void adjust_frame_size (struct frame *, int, int, int, bool);
+extern bool frame_inhibit_resize (struct frame *, bool, Lisp_Object);
+extern void adjust_frame_size (struct frame *, int, int, int, bool, Lisp_Object);
extern Lisp_Object Vframe_list;
@@ -1380,6 +1380,11 @@ extern Lisp_Object Qx_resource_name;
extern Lisp_Object Qtop, Qbox, Qbottom;
extern Lisp_Object Qdisplay;
+extern Lisp_Object Qframe_position, Qframe_outer_size, Qframe_inner_size;
+extern Lisp_Object Qexternal_border_size, Qtitle_height;
+extern Lisp_Object Qmenu_bar_external, Qmenu_bar_size;
+extern Lisp_Object Qtool_bar_external, Qtool_bar_size;
+
extern Lisp_Object Qrun_hook_with_args;
#ifdef HAVE_WINDOW_SYSTEM
diff --git a/src/gtkutil.c b/src/gtkutil.c
index 01360244c2e..6db8858923d 100644
--- a/src/gtkutil.c
+++ b/src/gtkutil.c
@@ -50,11 +50,11 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include "emacsgtkfixed.h"
#endif
-#define FRAME_TOTAL_PIXEL_HEIGHT(f) \
- (FRAME_PIXEL_HEIGHT (f) + FRAME_MENUBAR_HEIGHT (f) + FRAME_TOOLBAR_HEIGHT (f))
+/** #define FRAME_TOTAL_PIXEL_HEIGHT(f) \ **/
+/** (FRAME_PIXEL_HEIGHT (f) + FRAME_MENUBAR_HEIGHT (f) + FRAME_TOOLBAR_HEIGHT (f)) **/
-#define FRAME_TOTAL_PIXEL_WIDTH(f) \
- (FRAME_PIXEL_WIDTH (f) + FRAME_TOOLBAR_WIDTH (f))
+/** #define FRAME_TOTAL_PIXEL_WIDTH(f) \ **/
+/** (FRAME_PIXEL_WIDTH (f) + FRAME_TOOLBAR_WIDTH (f)) **/
#ifndef HAVE_GTK_WIDGET_SET_HAS_WINDOW
#define gtk_widget_set_has_window(w, b) \
@@ -940,12 +940,13 @@ xg_frame_set_char_size (struct frame *f, int width, int height)
x_wait_for_event (f, ConfigureNotify);
}
else
- adjust_frame_size (f, -1, -1, 5, 0);
+ adjust_frame_size (f, -1, -1, 5, 0, Qnil);
}
/* Handle height/width changes (i.e. add/remove/move menu/toolbar).
The policy is to keep the number of editable lines. */
+#if 0
static void
xg_height_or_width_changed (struct frame *f)
{
@@ -955,6 +956,7 @@ xg_height_or_width_changed (struct frame *f)
f->output_data.x->hint_flags = 0;
x_wm_set_size_hint (f, 0, 0);
}
+#endif
/* Convert an X Window WSESC on display DPY to its corresponding GtkWidget.
Must be done like this, because GtkWidget:s can have "hidden"
@@ -3241,7 +3243,7 @@ menubar_map_cb (GtkWidget *w, gpointer user_data)
if (FRAME_MENUBAR_HEIGHT (f) != req.height)
{
FRAME_MENUBAR_HEIGHT (f) = req.height;
- xg_height_or_width_changed (f);
+ adjust_frame_size (f, -1, -1, 2, 0, Qmenu_bar_lines);
}
}
@@ -3273,7 +3275,7 @@ xg_update_frame_menubar (struct frame *f)
if (FRAME_MENUBAR_HEIGHT (f) != req.height)
{
FRAME_MENUBAR_HEIGHT (f) = req.height;
- xg_height_or_width_changed (f);
+ adjust_frame_size (f, -1, -1, 2, 0, Qmenu_bar_lines);
}
unblock_input ();
}
@@ -3295,7 +3297,7 @@ free_frame_menubar (struct frame *f)
the container. */
x->menubar_widget = 0;
FRAME_MENUBAR_HEIGHT (f) = 0;
- xg_height_or_width_changed (f);
+ adjust_frame_size (f, -1, -1, 2, 0, Qmenu_bar_lines);
unblock_input ();
}
}
@@ -4219,7 +4221,7 @@ tb_size_cb (GtkWidget *widget,
size hints if tool bar size changes. Seen on Fedora 18 at least. */
struct frame *f = user_data;
if (xg_update_tool_bar_sizes (f))
- xg_height_or_width_changed (f);
+ adjust_frame_size (f, -1, -1, 2, 0, Qtool_bar_lines);
}
/* Create a tool bar for frame F. */
@@ -4819,7 +4821,7 @@ update_frame_tool_bar (struct frame *f)
xg_pack_tool_bar (f, FRAME_TOOL_BAR_POSITION (f));
gtk_widget_show_all (x->toolbar_widget);
if (xg_update_tool_bar_sizes (f))
- xg_height_or_width_changed (f);
+ adjust_frame_size (f, -1, -1, 2, 0, Qtool_bar_lines);
}
unblock_input ();
@@ -4867,7 +4869,7 @@ free_frame_tool_bar (struct frame *f)
NULL);
}
- xg_height_or_width_changed (f);
+ adjust_frame_size (f, -1, -1, 2, 0, Qtool_bar_lines);
unblock_input ();
}
@@ -4897,7 +4899,7 @@ xg_change_toolbar_position (struct frame *f, Lisp_Object pos)
xg_pack_tool_bar (f, pos);
g_object_unref (top_widget);
if (xg_update_tool_bar_sizes (f))
- xg_height_or_width_changed (f);
+ adjust_frame_size (f, -1, -1, 2, 0, Qtool_bar_lines);
unblock_input ();
}
diff --git a/src/nsfns.m b/src/nsfns.m
index 1537adbc56d..16f4ba3b579 100644
--- a/src/nsfns.m
+++ b/src/nsfns.m
@@ -731,7 +731,7 @@ x_set_internal_border_width (struct frame *f, Lisp_Object arg, Lisp_Object oldva
return;
if (FRAME_X_WINDOW (f) != 0)
- adjust_frame_size (f, -1, -1, 3, 0);
+ adjust_frame_size (f, -1, -1, 3, 0, Qinternal_border_width);
SET_FRAME_GARBAGED (f);
}
@@ -1275,7 +1275,7 @@ This function is an internal primitive--use `make-frame' instead. */)
/* Read comment about this code in corresponding place in xfns.c. */
adjust_frame_size (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f),
- FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 5, 1);
+ FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 5, 1, Qnil);
/* The resources controlling the menu-bar and tool-bar are
processed specially at startup, and reflected in the mode
@@ -1349,7 +1349,7 @@ This function is an internal primitive--use `make-frame' instead. */)
/* Consider frame official, now. */
f->official = true;
- adjust_frame_size (f, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f), 0, 1);
+ adjust_frame_size (f, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f), 0, 1, Qnil);
if (! f->output_data.ns->explicit_parent)
{
diff --git a/src/w32fns.c b/src/w32fns.c
index 829347b2c6c..95821df6c61 100644
--- a/src/w32fns.c
+++ b/src/w32fns.c
@@ -1645,7 +1645,7 @@ x_set_internal_border_width (struct frame *f, Lisp_Object arg, Lisp_Object oldva
if (FRAME_X_WINDOW (f) != 0)
{
- adjust_frame_size (f, -1, -1, 3, 0);
+ adjust_frame_size (f, -1, -1, 3, 0, Qinternal_border_width);
if (FRAME_VISIBLE_P (f))
x_clear_under_internal_border (f);
@@ -1691,7 +1691,7 @@ x_set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
of the outer rectangle (including decorations) unchanged, and a
second time because we want to keep the height of the inner
rectangle (without the decorations unchanged). */
- adjust_frame_size (f, -1, -1, 2, 1);
+ adjust_frame_size (f, -1, -1, 2, 1, Qmenu_bar_lines);
/* Not sure whether this is needed. */
x_clear_under_internal_border (f);
@@ -1721,7 +1721,15 @@ x_set_tool_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
else
nlines = 0;
- x_change_tool_bar_height (f, nlines * FRAME_LINE_HEIGHT (f));
+ if (nlines == 0)
+ x_change_tool_bar_height (f, nlines * FRAME_LINE_HEIGHT (f));
+ else
+ {
+ f->n_tool_bar_rows = 0;
+ FRAME_TOOL_BAR_LINES (f) = nlines;
+ adjust_frame_glyphs (f);
+ SET_FRAME_GARBAGED (f);
+ }
}
@@ -1741,10 +1749,10 @@ x_change_tool_bar_height (struct frame *f, int height)
/* Recalculate tool bar and frame text sizes. */
FRAME_TOOL_BAR_HEIGHT (f) = height;
FRAME_TOOL_BAR_LINES (f) = lines;
- FRAME_TEXT_HEIGHT (f)
- = FRAME_PIXEL_TO_TEXT_HEIGHT (f, FRAME_PIXEL_HEIGHT (f));
- FRAME_LINES (f)
- = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, FRAME_PIXEL_HEIGHT (f));
+/** FRAME_TEXT_HEIGHT (f) **/
+/** = FRAME_PIXEL_TO_TEXT_HEIGHT (f, FRAME_PIXEL_HEIGHT (f)); **/
+/** FRAME_LINES (f) **/
+/** = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, FRAME_PIXEL_HEIGHT (f)); **/
/* Store the `tool-bar-lines' and `height' frame parameters. */
store_frame_param (f, Qtool_bar_lines, make_number (lines));
store_frame_param (f, Qheight, make_number (FRAME_LINES (f)));
@@ -1761,7 +1769,8 @@ x_change_tool_bar_height (struct frame *f, int height)
/* Recalculate toolbar height. */
f->n_tool_bar_rows = 0;
- adjust_frame_size (f, -1, -1, 4, 0);
+ adjust_frame_size (f, -1, -1, (old_height == 0 || height == 0) ? 2 : 4, 0,
+ Qtool_bar_lines);
if (FRAME_X_WINDOW (f))
x_clear_under_internal_border (f);
@@ -4629,7 +4638,7 @@ This function is an internal primitive--use `make-frame' instead. */)
had one frame line vs one toolbar line which left us with a zero
root window height which was obviously wrong as well ... */
adjust_frame_size (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f),
- FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 5, 1);
+ FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 5, 1, Qnil);
/* The X resources controlling the menu-bar and tool-bar are
processed specially at startup, and reflected in the mode
@@ -4697,7 +4706,7 @@ This function is an internal primitive--use `make-frame' instead. */)
/* Consider frame official, now. */
f->official = true;
- adjust_frame_size (f, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f), 0, 1);
+ adjust_frame_size (f, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f), 0, 1, Qnil);
/* Tell the server what size and position, etc, we want, and how
badly we want them. This should be done after we have the menu
@@ -5797,7 +5806,7 @@ x_create_tip_frame (struct w32_display_info *dpyinfo,
SET_FRAME_COLS (f, 0);
SET_FRAME_LINES (f, 0);
adjust_frame_size (f, width * FRAME_COLUMN_WIDTH (f),
- height * FRAME_LINE_HEIGHT (f), 0, 1);
+ height * FRAME_LINE_HEIGHT (f), 0, 1, Qnil);
/* Add `tooltip' frame parameter's default value. */
if (NILP (Fframe_parameter (frame, Qtooltip)))
@@ -7368,30 +7377,33 @@ This is a direct interface to the Windows API FindWindow function. */)
DEFUN ("w32-frame-menu-bar-size", Fw32_frame_menu_bar_size, Sw32_frame_menu_bar_size, 0, 1, 0,
doc: /* Return sizes of menu bar on frame FRAME.
-The return value is a list of three elements: The current width and
-height of FRAME's menu bar in pixels and the default height of the menu
-bar in pixels. If FRAME is omitted or nil, the selected frame is
-used. */)
+The return value is a list of four elements: The current width and
+height of FRAME's menu bar in pixels, the height of one menu bar line in
+a wrapped menu bar in pixels, and the height of a single line menu bar
+in pixels.
+
+If FRAME is omitted or nil, the selected frame is used. */)
(Lisp_Object frame)
{
struct frame *f = decode_any_frame (frame);
- MENUBARINFO info;
- int width, height, default_height;
+ MENUBARINFO menu_bar;
+ int width, height, single_height, wrapped_height;
block_input ();
- default_height = GetSystemMetrics (SM_CYMENUSIZE);
- info.cbSize = sizeof (info);
- info.rcBar.right = info.rcBar.left = 0;
- info.rcBar.top = info.rcBar.bottom = 0;
- GetMenuBarInfo (FRAME_W32_WINDOW (f), 0xFFFFFFFD, 0, &info);
- width = info.rcBar.right - info.rcBar.left;
- height = info.rcBar.bottom - info.rcBar.top;
+ single_height = GetSystemMetrics (SM_CYMENU);
+ wrapped_height = GetSystemMetrics (SM_CYMENUSIZE);
+ menu_bar.cbSize = sizeof (menu_bar);
+ menu_bar.rcBar.right = menu_bar.rcBar.left = 0;
+ menu_bar.rcBar.top = menu_bar.rcBar.bottom = 0;
+ GetMenuBarInfo (FRAME_W32_WINDOW (f), 0xFFFFFFFD, 0, &menu_bar);
+ width = menu_bar.rcBar.right - menu_bar.rcBar.left;
+ height = menu_bar.rcBar.bottom - menu_bar.rcBar.top;
unblock_input ();
- return list3 (make_number (width), make_number (height),
- make_number (default_height));
+ return list4 (make_number (width), make_number (height),
+ make_number (wrapped_height), make_number (single_height));
}
DEFUN ("w32-frame-rect", Fw32_frame_rect, Sw32_frame_rect, 0, 2, 0,
@@ -7408,15 +7420,131 @@ title bar and decorations. */)
struct frame *f = decode_live_frame (frame);
RECT rect;
+ block_input ();
+
if (!NILP (client))
GetClientRect (FRAME_W32_WINDOW (f), &rect);
else
GetWindowRect (FRAME_W32_WINDOW (f), &rect);
+ unblock_input ();
+
return list4 (make_number (rect.left), make_number (rect.top),
make_number (rect.right), make_number (rect.bottom));
}
+DEFUN ("x-frame-geometry", Fx_frame_geometry, Sx_frame_geometry, 0, 1, 0,
+ doc: /* Return geometric atributes of frame FRAME.
+FRAME must be a live frame and defaults to the selected one.
+
+The return value is an association list containing the following
+elements (all size values are in pixels).
+
+- `frame-outer-size' is a cons of the outer width and height of FRAME.
+ The outer size includes the title bar and the external borders as well
+ as any menu and/or tool bar of frame.
+
+- `border' is a cons of the horizontal and vertical width of FRAME's
+ external borders.
+
+- `title-bar-height' is the height of the title bar of FRAME.
+
+- `menu-bar-external' if `t' means the menu bar is by default external
+ (not included in the inner size of FRAME).
+
+- `menu-bar-size' is a cons of the width and height of the menu bar of
+ FRAME.
+
+- `tool-bar-external' if `t' means the tool bar is by default external
+ (not included in the inner size of FRAME).
+
+- `tool-bar-side' tells tells on which side the tool bar on FRAME is by
+ default and can be one of `left', `top', `right' or `bottom'.
+
+- `tool-bar-size' is a cons of the width and height of the tool bar of
+ FRAME.
+
+- `frame-inner-size' is a cons of the inner width and height of FRAME.
+ This excludes FRAME's title bar and external border as well as any
+ external menu and/or tool bar. */)
+ (Lisp_Object frame)
+{
+ struct frame *f = decode_live_frame (frame);
+ Lisp_Object geometry = Qnil;
+ RECT frame_outer_edges, frame_inner_edges;
+ MENUBARINFO menu_bar;
+ int border_width, border_height, title_height;
+ int single_bar_height, wrapped_bar_height, menu_bar_height;
+ Lisp_Object fullscreen = Fframe_parameter (frame, Qfullscreen);
+
+ block_input ();
+
+ /* Outer frame rectangle, including outer borders and title bar. */
+ GetWindowRect (FRAME_W32_WINDOW (f), &frame_outer_edges);
+ /* Inner frame rectangle, excluding borders and title bar. */
+ GetClientRect (FRAME_W32_WINDOW (f), &frame_inner_edges);
+ /* Outer border. */
+ border_width = GetSystemMetrics (SM_CXFRAME);
+ border_height = GetSystemMetrics (SM_CYFRAME);
+ /* Title bar. */
+ title_height = GetSystemMetrics (SM_CYCAPTION);
+ /* Menu bar. */
+ menu_bar.cbSize = sizeof (menu_bar);
+ menu_bar.rcBar.right = menu_bar.rcBar.left = 0;
+ menu_bar.rcBar.top = menu_bar.rcBar.bottom = 0;
+ GetMenuBarInfo (FRAME_W32_WINDOW (f), 0xFFFFFFFD, 0, &menu_bar);
+ single_bar_height = GetSystemMetrics (SM_CYMENU);
+ wrapped_bar_height = GetSystemMetrics (SM_CYMENUSIZE);
+ unblock_input ();
+
+ menu_bar_height = menu_bar.rcBar.bottom - menu_bar.rcBar.top;
+ /* Fix menu bar height reported by GetMenuBarInfo. */
+ if (menu_bar_height > single_bar_height)
+ /* A wrapped menu bar. */
+ menu_bar_height += single_bar_height - wrapped_bar_height;
+ else if (menu_bar_height > 0)
+ /* A single line menu bar. */
+ menu_bar_height = single_bar_height;
+
+ return
+ listn (CONSTYPE_PURE, 10,
+ Fcons (Qframe_position,
+ Fcons (make_number (frame_outer_edges.left),
+ make_number (frame_outer_edges.top))),
+ Fcons (Qframe_outer_size,
+ Fcons (make_number
+ (frame_outer_edges.right - frame_outer_edges.left),
+ make_number
+ (frame_outer_edges.bottom - frame_outer_edges.top))),
+ Fcons (Qexternal_border_size,
+ ((EQ (fullscreen, Qfullboth) || EQ (fullscreen, Qfullscreen))
+ ? Fcons (make_number (0), make_number (0))
+ : Fcons (make_number (border_width),
+ make_number (border_height)))),
+ Fcons (Qtitle_height,
+ ((EQ (fullscreen, Qfullboth) || EQ (fullscreen, Qfullscreen))
+ ? make_number (0)
+ : make_number (title_height))),
+ Fcons (Qmenu_bar_external, Qt),
+ Fcons (Qmenu_bar_size,
+ Fcons (make_number
+ (menu_bar.rcBar.right - menu_bar.rcBar.left),
+ make_number (menu_bar_height))),
+ Fcons (Qtool_bar_external, Qnil),
+ Fcons (Qtool_bar_position, Qtop),
+ Fcons (Qtool_bar_size,
+ Fcons (make_number (FRAME_TOOL_BAR_LINES (f)
+ ? (FRAME_PIXEL_WIDTH (f)
+ - 2 * FRAME_INTERNAL_BORDER_WIDTH (f))
+ : 0),
+ make_number (FRAME_TOOL_BAR_HEIGHT (f)))),
+ Fcons (Qframe_inner_size,
+ Fcons (make_number
+ (frame_inner_edges.right - frame_inner_edges.left),
+ make_number
+ (frame_inner_edges.bottom - frame_inner_edges.top))));
+}
+
DEFUN ("w32-battery-status", Fw32_battery_status, Sw32_battery_status, 0, 0, 0,
doc: /* Get power status information from Windows system.
@@ -8411,6 +8539,7 @@ only be necessary if the default setting causes problems. */);
defsubr (&Sx_open_connection);
defsubr (&Sx_close_connection);
defsubr (&Sx_display_list);
+ defsubr (&Sx_frame_geometry);
defsubr (&Sx_synchronize);
/* W32 specific functions */
diff --git a/src/w32menu.c b/src/w32menu.c
index 9f777167bf0..6633ffddbcf 100644
--- a/src/w32menu.c
+++ b/src/w32menu.c
@@ -504,7 +504,7 @@ set_frame_menubar (struct frame *f, bool first_time, bool deep_p)
area remains the same, if menubar has just been created. */
if (old_widget == NULL)
adjust_frame_size (f, FRAME_TEXT_WIDTH (f),
- FRAME_TEXT_HEIGHT (f), 2, 0);
+ FRAME_TEXT_HEIGHT (f), 2, 0, Qmenu_bar_lines);
}
unblock_input ();
diff --git a/src/w32term.c b/src/w32term.c
index 4cffa3818ce..c2a37d078a8 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -5843,7 +5843,7 @@ x_new_font (struct frame *f, Lisp_Object font_object, int fontset)
problems because the tip frame has no widget. */
if (NILP (tip_frame) || XFRAME (tip_frame) != f)
adjust_frame_size (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f),
- FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 3, 0);
+ FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 3, 0, Qfont);
}
/* X version sets font of input methods here also. */
diff --git a/src/widget.c b/src/widget.c
index baa6a2ab917..ecf145199f2 100644
--- a/src/widget.c
+++ b/src/widget.c
@@ -644,7 +644,8 @@ EmacsFrameSetCharSize (Widget widget, int columns, int rows)
EmacsFrame ew = (EmacsFrame) widget;
struct frame *f = ew->emacs_frame.frame;
- if (!frame_inhibit_resize (f, 0) && !frame_inhibit_resize (f, 1))
+ if (!frame_inhibit_resize (f, 0, Qfont)
+ && !frame_inhibit_resize (f, 1, Qfont))
x_set_window_size (f, 0, columns, rows, 0);
}
diff --git a/src/window.c b/src/window.c
index 2c9292d5b02..168ef1e3b9d 100644
--- a/src/window.c
+++ b/src/window.c
@@ -6417,7 +6417,7 @@ the return value is nil. Otherwise the value is t. */)
/* Make frame official again and apply frame size changes if
needed. */
f->official = true;
- adjust_frame_size (f, -1, -1, 1, 0);
+ adjust_frame_size (f, -1, -1, 1, 0, Qnil);
adjust_frame_glyphs (f);
unblock_input ();
diff --git a/src/xfns.c b/src/xfns.c
index 8f5a06c0330..10eb3336fad 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -1009,7 +1009,7 @@ x_set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
#else /* not USE_X_TOOLKIT && not USE_GTK */
FRAME_MENU_BAR_LINES (f) = nlines;
FRAME_MENU_BAR_HEIGHT (f) = nlines * FRAME_LINE_HEIGHT (f);
- adjust_frame_size (f, -1, -1, 2, 1);
+ adjust_frame_size (f, -1, -1, 2, 1, Qmenu_bar_lines);
if (FRAME_X_WINDOW (f))
x_clear_under_internal_border (f);
@@ -1075,7 +1075,19 @@ x_set_tool_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
else
nlines = 0;
+#ifdef USE_GTK
x_change_tool_bar_height (f, nlines * FRAME_LINE_HEIGHT (f));
+#else /* !USE_GTK */
+ if (nlines == 0)
+ x_change_tool_bar_height (f, nlines * FRAME_LINE_HEIGHT (f));
+ else
+ {
+ f->n_tool_bar_rows = 0;
+ FRAME_TOOL_BAR_LINES (f) = nlines;
+ adjust_frame_glyphs (f);
+ SET_FRAME_GARBAGED (f);
+ }
+#endif /* USE_GTK */
}
@@ -1112,10 +1124,10 @@ x_change_tool_bar_height (struct frame *f, int height)
/* Recalculate tool bar and frame text sizes. */
FRAME_TOOL_BAR_HEIGHT (f) = height;
FRAME_TOOL_BAR_LINES (f) = lines;
- FRAME_TEXT_HEIGHT (f)
- = FRAME_PIXEL_TO_TEXT_HEIGHT (f, FRAME_PIXEL_HEIGHT (f));
- FRAME_LINES (f)
- = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, FRAME_PIXEL_HEIGHT (f));
+/** FRAME_TEXT_HEIGHT (f) **/
+/** = FRAME_PIXEL_TO_TEXT_HEIGHT (f, FRAME_PIXEL_HEIGHT (f)); **/
+/** FRAME_LINES (f) **/
+/** = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, FRAME_PIXEL_HEIGHT (f)); **/
/* Store the `tool-bar-lines' and `height' frame parameters. */
store_frame_param (f, Qtool_bar_lines, make_number (lines));
store_frame_param (f, Qheight, make_number (FRAME_LINES (f)));
@@ -1138,7 +1150,8 @@ x_change_tool_bar_height (struct frame *f, int height)
/* Recalculate toolbar height. */
f->n_tool_bar_rows = 0;
- adjust_frame_size (f, -1, -1, 4, 0);
+ adjust_frame_size (f, -1, -1, (old_height == 0 || height == 0) ? 2 : 4, 0,
+ Qtool_bar_lines);
if (FRAME_X_WINDOW (f))
x_clear_under_internal_border (f);
@@ -1166,7 +1179,7 @@ x_set_internal_border_width (struct frame *f, Lisp_Object arg, Lisp_Object oldva
if (FRAME_X_WINDOW (f) != 0)
{
- adjust_frame_size (f, -1, -1, 3, 0);
+ adjust_frame_size (f, -1, -1, 3, 0, Qinternal_border_width);
#ifdef USE_GTK
xg_clear_under_internal_border (f);
@@ -3163,7 +3176,7 @@ This function is an internal primitive--use `make-frame' instead. */)
had one frame line vs one toolbar line which left us with a zero
root window height which was obviously wrong as well ... */
adjust_frame_size (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f),
- FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 5, 1);
+ FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 5, 1, Qnil);
/* Set the menu-bar-lines and tool-bar-lines parameters. We don't
look up the X resources controlling the menu-bar and tool-bar
@@ -3237,7 +3250,7 @@ This function is an internal primitive--use `make-frame' instead. */)
/* Consider frame official, now. */
f->official = true;
- adjust_frame_size (f, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f), 0, 1);
+ adjust_frame_size (f, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f), 0, 1, Qnil);
#if defined (USE_X_TOOLKIT) || defined (USE_GTK)
/* Create the menu bar. */
@@ -4221,6 +4234,124 @@ Internal use only, use `display-monitor-attributes-list' instead. */)
return attributes_list;
}
+DEFUN ("x-frame-geometry", Fx_frame_geometry, Sx_frame_geometry, 0, 1, 0,
+ doc: /* Return geometric atributes of frame FRAME.
+
+FRAME must be a live frame and defaults to the selected one.
+
+The return value is an association list containing the following
+elements (all size values are in pixels).
+
+- `frame-outer-size' is a cons of the outer width and height of FRAME.
+ The outer size include the title bar and the external borders as well
+ as any menu and/or tool bar of frame.
+
+- `border' is a cons of the horizontal and vertical width of FRAME's
+ external borders.
+
+- `title-bar-height' is the height of the title bar of FRAME.
+
+- `menu-bar-external' if `t' means the menu bar is external (not
+ included in the inner edges of FRAME).
+
+- `menu-bar-size' is a cons of the width and height of the menu bar of
+ FRAME.
+
+- `tool-bar-external' if `t' means the tool bar is external (not
+ included in the inner edges of FRAME).
+
+- `tool-bar-side' tells tells on which side the tool bar on FRAME is and
+ can be one of `left', `top', `right' or `bottom'.
+
+- `tool-bar-size' is a cons of the width and height of the tool bar of
+ FRAME.
+
+- `frame-inner-size' is a cons of the inner width and height of FRAME.
+ This excludes FRAME's title bar and external border as well as any
+ external menu and/or tool bar. */)
+ (Lisp_Object frame)
+{
+ struct frame *f = decode_live_frame (frame);
+ int inner_width = FRAME_PIXEL_WIDTH (f);
+ int inner_height = FRAME_PIXEL_HEIGHT (f);
+ int outer_width, outer_height, border, title;
+ Lisp_Object fullscreen = Fframe_parameter (frame, Qfullscreen);
+ int menu_bar_height, menu_bar_width, tool_bar_height, tool_bar_width;
+
+ border = FRAME_OUTER_TO_INNER_DIFF_X (f);
+ title = FRAME_X_OUTPUT (f)->y_pixels_outer_diff - border;
+
+ outer_width = FRAME_PIXEL_WIDTH (f) + 2 * border;
+ outer_height = (FRAME_PIXEL_HEIGHT (f)
+ + FRAME_OUTER_TO_INNER_DIFF_Y (f)
+ + FRAME_OUTER_TO_INNER_DIFF_X (f));
+
+#if defined (USE_GTK)
+ {
+ bool tool_bar_left_right = (EQ (FRAME_TOOL_BAR_POSITION (f), Qleft)
+ || EQ (FRAME_TOOL_BAR_POSITION (f), Qright));
+
+ tool_bar_width = (tool_bar_left_right
+ ? FRAME_TOOLBAR_WIDTH (f)
+ : FRAME_PIXEL_WIDTH (f));
+ tool_bar_height = (tool_bar_left_right
+ ? FRAME_PIXEL_HEIGHT (f)
+ : FRAME_TOOLBAR_HEIGHT (f));
+ if (tool_bar_left_right)
+ /* For some reason FRAME_OUTER_TO_INNER_DIFF_X does not count the
+ width of a tool bar. */
+ outer_width += FRAME_TOOLBAR_WIDTH (f);
+ }
+#else
+ tool_bar_height = FRAME_TOOL_BAR_HEIGHT (f);
+ tool_bar_width = ((tool_bar_height > 0)
+ ? outer_width - 2 * FRAME_INTERNAL_BORDER_WIDTH (f)
+ : 0);
+#endif
+
+#if defined (USE_X_TOOLKIT) || defined (USE_GTK)
+ menu_bar_height = FRAME_MENUBAR_HEIGHT (f);
+#else
+ menu_bar_height = FRAME_MENU_BAR_HEIGHT (f);
+#endif
+
+ menu_bar_width = ((menu_bar_height > 0)
+ ? outer_width - 2 * border
+ : 0);
+
+ if (!FRAME_EXTERNAL_MENU_BAR (f))
+ inner_height -= menu_bar_height;
+ if (!FRAME_EXTERNAL_TOOL_BAR (f))
+ inner_height -= tool_bar_height;
+
+ return
+ listn (CONSTYPE_PURE, 10,
+ Fcons (Qframe_position,
+ Fcons (make_number (f->left_pos), make_number (f->top_pos))),
+ Fcons (Qframe_outer_size,
+ Fcons (make_number (outer_width), make_number (outer_height))),
+ Fcons (Qexternal_border_size,
+ ((EQ (fullscreen, Qfullboth) || EQ (fullscreen, Qfullscreen))
+ ? Fcons (make_number (0), make_number (0))
+ : Fcons (make_number (border), make_number (border)))),
+ Fcons (Qtitle_height,
+ ((EQ (fullscreen, Qfullboth) || EQ (fullscreen, Qfullscreen))
+ ? make_number (0)
+ : make_number (title))),
+ Fcons (Qmenu_bar_external, FRAME_EXTERNAL_MENU_BAR (f) ? Qt : Qnil),
+ Fcons (Qmenu_bar_size,
+ Fcons (make_number (menu_bar_width),
+ make_number (menu_bar_height))),
+ Fcons (Qtool_bar_external, FRAME_EXTERNAL_TOOL_BAR (f) ? Qt : Qnil),
+ Fcons (Qtool_bar_position, FRAME_TOOL_BAR_POSITION (f)),
+ Fcons (Qtool_bar_size,
+ Fcons (make_number (tool_bar_width),
+ make_number (tool_bar_height))),
+ Fcons (Qframe_inner_size,
+ Fcons (make_number (inner_width),
+ make_number (inner_height))));
+}
+
/************************************************************************
X Displays
************************************************************************/
@@ -6224,6 +6355,7 @@ When using Gtk+ tooltips, the tooltip face is not used. */);
defsubr (&Sx_display_backing_store);
defsubr (&Sx_display_save_under);
defsubr (&Sx_display_monitor_attributes_list);
+ defsubr (&Sx_frame_geometry);
defsubr (&Sx_wm_set_size_hint);
defsubr (&Sx_create_frame);
defsubr (&Sx_open_connection);
diff --git a/src/xmenu.c b/src/xmenu.c
index eb783fe5070..0f69ee28e84 100644
--- a/src/xmenu.c
+++ b/src/xmenu.c
@@ -657,9 +657,15 @@ update_frame_menubar (struct frame *f)
lw_refigure_widget (x->column_widget, True);
/* Force the pane widget to resize itself. */
- adjust_frame_size (f, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f), 2, 0);
+#ifdef USE_LUCID
+ /* For reasons I don't know Lucid wants to add one pixel to the frame
+ height when adding the menu bar. Compensate that here. */
+ adjust_frame_size (f, -1, FRAME_TEXT_HEIGHT (f) - 1, 2, 0, Qmenu_bar_lines);
+#else
+ adjust_frame_size (f, -1, -1, 2, 0, Qmenu_bar_lines);
+#endif /* USE_LUCID */
unblock_input ();
-#endif
+#endif /* USE_GTK */
}
#ifdef USE_LUCID
@@ -1050,6 +1056,12 @@ void
free_frame_menubar (struct frame *f)
{
Widget menubar_widget;
+#ifdef USE_MOTIF
+ /* Motif automatically shrinks the frame in lw_destroy_all_widgets.
+ If we want to preserve the old height, calculate it now so we can
+ restore it below. */
+ int old_height = FRAME_TEXT_HEIGHT (f) + FRAME_MENUBAR_HEIGHT (f);
+#endif
eassert (FRAME_X_P (f));
@@ -1087,17 +1099,20 @@ free_frame_menubar (struct frame *f)
XtVaGetValues (f->output_data.x->widget, XtNx, &x1, XtNy, &y1, NULL);
if (x1 == 0 && y1 == 0)
XtVaSetValues (f->output_data.x->widget, XtNx, x0, XtNy, y0, NULL);
-#endif
- adjust_frame_size (f, FRAME_TEXT_WIDTH (f),
- FRAME_TEXT_HEIGHT (f), 2, 0);
- /*
- if (frame_inhibit_resize (f, 0))
- change_frame_size (f, 0, 0, 0, 0, 0, 1);
+ if (frame_inhibit_resize (f, 0, Qmenu_bar_lines))
+ adjust_frame_size (f, -1, old_height, 1, 0, Qmenu_bar_lines);
else
- x_set_window_size (f, 0, FRAME_TEXT_WIDTH (f),
- FRAME_TEXT_HEIGHT (f), 1);
- */
+#endif /* USE_MOTIF */
+ adjust_frame_size (f, -1, -1, 2, 0, Qmenu_bar_lines);
}
+ else
+ {
+#ifdef USE_MOTIF
+ if (frame_inhibit_resize (f, 0, Qmenu_bar_lines))
+ adjust_frame_size (f, -1, old_height, 1, 0, Qmenu_bar_lines);
+#endif
+ }
+
unblock_input ();
}
}
diff --git a/src/xterm.c b/src/xterm.c
index 53eb7b3625d..98f2a27c1ce 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -8662,8 +8662,9 @@ x_new_font (struct frame *f, Lisp_Object font_object, int fontset)
doing it because it's done in Fx_show_tip, and it leads to
problems because the tip frame has no widget. */
if (NILP (tip_frame) || XFRAME (tip_frame) != f)
- x_set_window_size (f, 0, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f),
- FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 1);
+ adjust_frame_size (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f),
+ FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 3,
+ 0, Qfont);
}
#ifdef HAVE_X_I18N