aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Rudalics2014-11-07 11:49:22 +0100
committerMartin Rudalics2014-11-07 11:49:22 +0100
commit1c50b3adb636addc4244942e8f0e33b1e557ec07 (patch)
treefc452db1b888d5833e915778ad795c9d86f06678
parenta067ef9a5ddc9812e35734e8c027684e01d684ef (diff)
downloademacs-1c50b3adb636addc4244942e8f0e33b1e557ec07.tar.gz
emacs-1c50b3adb636addc4244942e8f0e33b1e557ec07.zip
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.
-rw-r--r--doc/lispref/ChangeLog5
-rw-r--r--doc/lispref/frames.texi50
-rw-r--r--lisp/ChangeLog5
-rw-r--r--lisp/cus-start.el8
-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
18 files changed, 578 insertions, 134 deletions
diff --git a/doc/lispref/ChangeLog b/doc/lispref/ChangeLog
index 356560f2576..9a7a6c8c8a6 100644
--- a/doc/lispref/ChangeLog
+++ b/doc/lispref/ChangeLog
@@ -1,3 +1,8 @@
12014-11-07 Martin Rudalics <rudalics@gmx.at>
2
3 * frames.texi (Size and Position): Rewrite description of
4 `frame-inhibit-implied-resize'.
5
12014-10-22 Martin Rudalics <rudalics@gmx.at> 62014-10-22 Martin Rudalics <rudalics@gmx.at>
2 7
3 * frames.texi (Size Parameters): Replace "frame contents" by 8 * frames.texi (Size Parameters): Replace "frame contents" by
diff --git a/doc/lispref/frames.texi b/doc/lispref/frames.texi
index 146170a967c..0bded22eade 100644
--- a/doc/lispref/frames.texi
+++ b/doc/lispref/frames.texi
@@ -1350,10 +1350,9 @@ frame's text area unaltered when, for example, adding or removing a menu
1350bar, changing the default font or setting the width of the frame's 1350bar, changing the default font or setting the width of the frame's
1351scroll bars. This means, however, that in such case Emacs must ask the 1351scroll bars. This means, however, that in such case Emacs must ask the
1352window manager to resize the display area of the frame in order to 1352window manager to resize the display area of the frame in order to
1353accommodate the size change. (Note that with the exception of GTK+ 1353accommodate the size change. Note that wrapping a menu or tool bar
1354builds, adding, removing or wrapping the tool bar usually do not resize 1354usually does not resize the frame's display area, hence this will alter
1355the frame's display area, hence these may alter the number of displayed 1355the number of displayed lines.
1356lines.)
1357 1356
1358 Occasionally, such implied resizing of the display area may be 1357 Occasionally, such implied resizing of the display area may be
1359unwanted, for example, when the frame is maximized or made fullscreen 1358unwanted, for example, when the frame is maximized or made fullscreen
@@ -1361,15 +1360,40 @@ where it's turned off by default. In other cases you can disable
1361implied resizing with the following option: 1360implied resizing with the following option:
1362 1361
1363@defopt frame-inhibit-implied-resize 1362@defopt frame-inhibit-implied-resize
1364If this option is @code{nil}, changing default font, menu bar mode, 1363If this option is @code{nil}, changing font, menu bar, tool bar,
1365fringe width, or scroll bars of a specific frame may resize the frame's 1364internal borders, fringes or scroll bars of a specific frame may
1366display area in order to preserve the number of columns or lines the 1365implicitly resize the frame's display area in order to preserve the
1367frame displays. If this option is non-@code{nil}, no such resizing is 1366number of columns or lines the frame displays. If this option is
1368done. 1367non-@code{nil}, no implied resizing is done.
1369 1368
1370When you add a tool bar or scroll bar to a frame that is not large 1369The value of this option can be also be a list of frame parameters. In
1371enough to accommodate one, Emacs will try to enlarge the frame even if 1370that case, implied resizing is inhibited when changing a parameter that
1372this option is non-@code{nil}. 1371appears in this list. The frame parameters currently handled by this
1372option are: @code{font}, @code{font-backend},
1373@code{internal-border-width}, @code{menu-bar-lines} and
1374@code{tool-bar-lines}.
1375
1376Changing any of the @code{scroll-bar-width}, @code{scroll-bar-height},
1377@code{vertical-scroll-bars}, @code{horizontal-scroll-bars},
1378@code{left-fringe} and @code{right-fringe} frame parameters is handled
1379as if the frame contained just one live window. This means, for
1380example, that removing vertical scroll bars on a frame containing
1381several side by side windows will shrink the frame width by the width of
1382one scroll bar provided this option is @code{nil} and keep it unchanged
1383if this option is either @code{t} or a list containing
1384@code{vertical-scroll-bars}.
1385
1386The default value is @code{'(tool-bar-lines)} for Lucid, Motif and
1387Windows (which means that adding/removing a tool bar there does not
1388change the frame height), @code{nil} on all other window systems
1389including GTK+ (which means that changing any of the parameters listed
1390above may change the size of the frame), and @code{t} otherwise (which
1391means the frame size never changes implicitly when there's no window
1392system support).
1393
1394Note that when a frame is not large enough to accommodate a change of
1395any of the parameters listed above, Emacs may try to enlarge the frame
1396even if this option is non-@code{nil}.
1373@end defopt 1397@end defopt
1374 1398
1375@c FIXME? Belongs more in Emacs manual than here? 1399@c FIXME? Belongs more in Emacs manual than here?
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index e3b453edc09..f242386215a 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,8 @@
12014-11-07 Martin Rudalics <rudalics@gmx.at>
2
3 * cus-start.el (frame-resize-pixelwise): Fix group.
4 (frame-inhibit-implied-resize): Add entry.
5
12014-11-07 Daiki Ueno <ueno@gnu.org> 62014-11-07 Daiki Ueno <ueno@gnu.org>
2 7
3 * epa.el (epa-pinentry-mode): New user option. 8 * epa.el (epa-pinentry-mode): New user option.
diff --git a/lisp/cus-start.el b/lisp/cus-start.el
index e0c1b73a465..3b8885a8717 100644
--- a/lisp/cus-start.el
+++ b/lisp/cus-start.el
@@ -274,7 +274,13 @@ Leaving \"Default\" unchecked is equivalent with specifying a default of
274 (tool-bar-mode (frames mouse) boolean nil 274 (tool-bar-mode (frames mouse) boolean nil
275; :initialize custom-initialize-default 275; :initialize custom-initialize-default
276 :set custom-set-minor-mode) 276 :set custom-set-minor-mode)
277 (frame-resize-pixelwise windows boolean "24.4") 277 (frame-resize-pixelwise frames boolean "24.4")
278 (frame-inhibit-implied-resize frames
279 (choice
280 (const :tag "Never" nil)
281 (const :tag "Always" t)
282 (repeat (symbol :tag "Parameter")))
283 "25.1")
278 ;; fringe.c 284 ;; fringe.c
279 (overflow-newline-into-fringe fringe boolean) 285 (overflow-newline-into-fringe fringe boolean)
280 ;; image.c 286 ;; image.c
diff --git a/src/ChangeLog b/src/ChangeLog
index 6b62a60f7b0..c46d23dd82e 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,62 @@
12014-11-07 Martin Rudalics <rudalics@gmx.at>
2
3 * dispnew.c (change_frame_size_1): Fix call of
4 adjust_frame_size.
5 * frame.c (Qsize, Qframe_position, Qframe_outer_size)
6 (Qframe_inner_size, Qexternal_border_size, Qtitle_height)
7 (Qmenu_bar_external, Qmenu_bar_size, Qtool_bar_external)
8 (Qtool_bar_size): New constants.
9 (frame_inhibit_resize, adjust_frame_size): New argument to
10 handle case where frame_inhibit_implied_resize is a list.
11 (Fmake_terminal_frame, Fset_frame_height, Fset_frame_width)
12 (Fset_frame_size, x_set_left_fringe, x_set_right_fringe)
13 (x_set_right_divider_width, x_set_bottom_divider_width)
14 (x_set_vertical_scroll_bars, x_set_horizontal_scroll_bars)
15 (x_set_scroll_bar_width, x_set_scroll_bar_height): Update
16 callers.
17 (frame-inhibit-implied-resize): Rewrite doc-string.
18 * frame.h (frame_inhibit_resize, adjust_frame_size): Fix
19 external declarations.
20 (Qframe_position, Qframe_outer_size)
21 (Qframe_inner_size, Qexternal_border_size, Qtitle_height)
22 (Qmenu_bar_external, Qmenu_bar_size, Qtool_bar_external)
23 (Qtool_bar_size): Extern them.
24 * gtkutil.c (FRAME_TOTAL_PIXEL_HEIGHT, FRAME_TOTAL_PIXEL_WIDTH)
25 (xg_height_or_width_changed): Remove.
26 (xg_frame_set_char_size): Adjust adjust_frame_size calls.
27 (menubar_map_cb, xg_update_frame_menubar, free_frame_menubar)
28 (tb_size_cb, update_frame_tool_bar, free_frame_tool_bar)
29 (xg_change_toolbar_position): Call adjust_frame_size directly.
30 * nsfns.m (x_set_internal_border_width, Fx_create_frame): Fix
31 calls of adjust_frame_size.
32 * w32fns.c (x_set_internal_border_width, x_set_menu_bar_lines)
33 (Fx_create_frame, x_create_tip_frame): Adjust adjust_frame_size
34 calls.
35 (x_set_tool_bar_lines, x_change_tool_bar_height): Make sure that
36 frame can get resized when tool-bar-lines parameter changes from
37 or to zero.
38 (Fw32_frame_menu_bar_size): Return fourth value.
39 (Fw32_frame_rect): Block input around system calls
40 (Fx_frame_geometry): New function.
41 * w32menu.c (set_frame_menubar): Adjust adjust_frame_size call.
42 * w32term.c (x_new_font): Adjust adjust_frame_size call.
43 * widget.c (EmacsFrameSetCharSize): Adjust frame_inhibit_resize
44 call.
45 * window.c (Fset_window_configuration): Adjust adjust_frame_size
46 call.
47 * xfns.c (x_set_menu_bar_lines, x_set_internal_border_width)
48 (Fx_create_frame): Adjust adjust_frame_size calls.
49 (x_set_tool_bar_lines, x_change_tool_bar_height): Make sure that
50 frame can get resized when tool-bar-lines parameter changes from
51 or to zero.
52 (Fx_frame_geometry): New function.
53 * xmenu.c (update_frame_menubar): On Lucid call
54 adjust_frame_size with one pixel less height to avoid that
55 repeatedly adding/removing the menu bar grows the frame.
56 (free_frame_menubar): On Motif arrange to optionally preserve
57 the old frame height when removing the menu bar.
58 * xterm.c (x_new_font): Adjust adjust_frame_size call.
59
12014-11-03 Eli Zaretskii <eliz@gnu.org> 602014-11-03 Eli Zaretskii <eliz@gnu.org>
2 61
3 * xdisp.c (Fdump_glyph_matrix, Fdump_frame_glyph_matrix): Doc fix. 62 * 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,
5528 5528
5529 /* Adjust frame size but make sure x_set_window_size does not 5529 /* Adjust frame size but make sure x_set_window_size does not
5530 get called. */ 5530 get called. */
5531 adjust_frame_size (f, new_width, new_height, 5, pretend); 5531 adjust_frame_size (f, new_width, new_height, 5, pretend, Qnil);
5532 } 5532 }
5533} 5533}
5534 5534
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;
77Lisp_Object Qauto_raise, Qauto_lower; 77Lisp_Object Qauto_raise, Qauto_lower;
78Lisp_Object Qborder_color, Qborder_width; 78Lisp_Object Qborder_color, Qborder_width;
79Lisp_Object Qcursor_color, Qcursor_type; 79Lisp_Object Qcursor_color, Qcursor_type;
80Lisp_Object Qheight, Qwidth; 80Lisp_Object Qheight, Qwidth, Qsize;
81Lisp_Object Qicon_left, Qicon_top, Qicon_type, Qicon_name; 81Lisp_Object Qicon_left, Qicon_top, Qicon_type, Qicon_name;
82Lisp_Object Qtooltip; 82Lisp_Object Qtooltip;
83Lisp_Object Qinternal_border_width; 83Lisp_Object Qinternal_border_width;
@@ -120,6 +120,11 @@ static Lisp_Object Qdelete_frame_functions;
120static Lisp_Object Qframe_windows_min_size; 120static Lisp_Object Qframe_windows_min_size;
121static Lisp_Object Qgeometry, Qworkarea, Qmm_size, Qframes, Qsource; 121static Lisp_Object Qgeometry, Qworkarea, Qmm_size, Qframes, Qsource;
122 122
123Lisp_Object Qframe_position, Qframe_outer_size, Qframe_inner_size;
124Lisp_Object Qexternal_border_size, Qtitle_height;
125Lisp_Object Qmenu_bar_external, Qmenu_bar_size;
126Lisp_Object Qtool_bar_external, Qtool_bar_size;
127
123/* The currently selected frame. */ 128/* The currently selected frame. */
124 129
125Lisp_Object selected_frame; 130Lisp_Object selected_frame;
@@ -209,12 +214,14 @@ get_frame_param (register struct frame *frame, Lisp_Object prop)
209 214
210/* Return 1 if `frame-inhibit-implied-resize' is non-nil or fullscreen 215/* Return 1 if `frame-inhibit-implied-resize' is non-nil or fullscreen
211 state of frame F would be affected by a vertical (horizontal if 216 state of frame F would be affected by a vertical (horizontal if
212 HORIZONTAL is true) resize. */ 217 HORIZONTAL is true) resize. PARAMETER is the symbol of the frame
218 parameter that is changed. */
213bool 219bool
214frame_inhibit_resize (struct frame *f, bool horizontal) 220frame_inhibit_resize (struct frame *f, bool horizontal, Lisp_Object parameter)
215{ 221{
216 222 return (EQ (frame_inhibit_implied_resize, Qt)
217 return (frame_inhibit_implied_resize 223 || (CONSP (frame_inhibit_implied_resize)
224 && !NILP (Fmemq (parameter, frame_inhibit_implied_resize)))
218 || !NILP (get_frame_param (f, Qfullscreen)) 225 || !NILP (get_frame_param (f, Qfullscreen))
219 || FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f)); 226 || FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f));
220} 227}
@@ -337,40 +344,46 @@ frame_windows_min_size (Lisp_Object frame, Lisp_Object horizontal, Lisp_Object p
337/* Make sure windows sizes of frame F are OK. new_width and new_height 344/* Make sure windows sizes of frame F are OK. new_width and new_height
338 are in pixels. A value of -1 means no change is requested for that 345 are in pixels. A value of -1 means no change is requested for that
339 size (but the frame may still have to be resized to accommodate 346 size (but the frame may still have to be resized to accommodate
340 windows with their minimum sizes. 347 windows with their minimum sizes). This can either issue a request
348 to resize the frame externally (via x_set_window_size), to resize the
349 frame internally (via resize_frame_windows) or do nothing at all.
341 350
342 The argument INHIBIT can assume the following values: 351 The argument INHIBIT can assume the following values:
343 352
344 0 means to unconditionally call x_set_window_size even if sizes 353 0 means to unconditionally call x_set_window_size even if sizes
345 apparently do not change. Fx_create_frame uses this to pass the 354 apparently do not change. Fx_create_frame uses this to pass the
346 initial size to the window manager. 355 initial size to the window manager.
347 356
348 1 means to call x_set_window_size iff the pixel size really changes. 357 1 means to call x_set_window_size if the outer frame size really
349 Fset_frame_size, Fset_frame_height, ... use this. 358 changes. Fset_frame_size, Fset_frame_height, ... use this.
350 359
351 2 means to unconditionally call x_set_window_size provided 360 2 means to call x_set_window_size provided frame_inhibit_resize
352 frame_inhibit_resize allows it. The menu bar code uses this. 361 allows it. The menu and tool bar code use this ("3" won't work
362 here in general because menu and tool bar are often not counted in
363 the frame's text height).
353 364
354 3 means call x_set_window_size iff window minimum sizes must be 365 3 means call x_set_window_size if window minimum sizes must be
355 preserved or frame_inhibit_resize allows it, x_set_left_fringe, 366 preserved or frame_inhibit_resize allows it. x_set_left_fringe,
356 x_set_scroll_bar_width, ... use this. 367 x_set_scroll_bar_width, x_new_font ... use (or should use) this.
357 368
358 4 means call x_set_window_size iff window minimum sizes must be 369 4 means call x_set_window_size only if window minimum sizes must be
359 preserved. x_set_tool_bar_lines, x_set_right_divider_width, ... use 370 preserved. x_set_right_divider_width, x_set_border_width and the
360 this. BUT maybe the toolbar code shouldn't .... 371 code responsible for wrapping the tool bar use this.
361 372
362 5 means to never call x_set_window_size. change_frame_size uses 373 5 means to never call x_set_window_size. change_frame_size uses
363 this. 374 this.
364 375
365 For 2 and 3 note that if frame_inhibit_resize inhibits resizing and 376 Note that even when x_set_window_size is not called, individual
366 minimum sizes are not violated no internal resizing takes place 377 windows may have to be resized (via `window--sanitize-window-sizes')
367 either. For 2, 3, 4 and 5 note that even if no x_set_window_size 378 in order to support minimum size constraints.
368 call is issued, window sizes may have to be adjusted in order to
369 support minimum size constraints for the frame's windows.
370 379
371 PRETEND is as for change_frame_size. */ 380 PRETEND is as for change_frame_size. PARAMETER, if non-nil, is the
381 symbol of the parameter changed (like `menu-bar-lines', `font', ...).
382 This is passed on to frame_inhibit_resize to let the latter decide on
383 a case-by-case basis whether the frame may be resized externally. */
372void 384void
373adjust_frame_size (struct frame *f, int new_width, int new_height, int inhibit, bool pretend) 385adjust_frame_size (struct frame *f, int new_width, int new_height, int inhibit,
386 bool pretend, Lisp_Object parameter)
374{ 387{
375 int unit_width = FRAME_COLUMN_WIDTH (f); 388 int unit_width = FRAME_COLUMN_WIDTH (f);
376 int unit_height = FRAME_LINE_HEIGHT (f); 389 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,
415 so or INHIBIT equals 4. */ 428 so or INHIBIT equals 4. */
416 { 429 {
417 inhibit_horizontal = ((windows_width >= min_windows_width 430 inhibit_horizontal = ((windows_width >= min_windows_width
418 && (inhibit == 4 || frame_inhibit_resize (f, true))) 431 && (inhibit == 4
432 || frame_inhibit_resize (f, true, parameter)))
419 ? true : false); 433 ? true : false);
420 inhibit_vertical = ((windows_height >= min_windows_height 434 inhibit_vertical = ((windows_height >= min_windows_height
421 && (inhibit == 4 || frame_inhibit_resize (f, false))) 435 && (inhibit == 4
436 || frame_inhibit_resize (f, false, parameter)))
422 ? true : false); 437 ? true : false);
423 } 438 }
424 else 439 else
@@ -1004,7 +1019,7 @@ affects all frames on the same terminal device. */)
1004 { 1019 {
1005 int width, height; 1020 int width, height;
1006 get_tty_size (fileno (FRAME_TTY (f)->input), &width, &height); 1021 get_tty_size (fileno (FRAME_TTY (f)->input), &width, &height);
1007 adjust_frame_size (f, width, height - FRAME_MENU_BAR_LINES (f), 5, 0); 1022 adjust_frame_size (f, width, height - FRAME_MENU_BAR_LINES (f), 5, 0, Qnil);
1008 } 1023 }
1009 1024
1010 adjust_frame_glyphs (f); 1025 adjust_frame_glyphs (f);
@@ -2848,7 +2863,7 @@ multiple of the default frame font height. */)
2848 ? XINT (height) 2863 ? XINT (height)
2849 : XINT (height) * FRAME_LINE_HEIGHT (f)); 2864 : XINT (height) * FRAME_LINE_HEIGHT (f));
2850 if (pixel_height != FRAME_TEXT_HEIGHT (f)) 2865 if (pixel_height != FRAME_TEXT_HEIGHT (f))
2851 adjust_frame_size (f, -1, pixel_height, 1, !NILP (pretend)); 2866 adjust_frame_size (f, -1, pixel_height, 1, !NILP (pretend), Qheight);
2852 2867
2853 return Qnil; 2868 return Qnil;
2854} 2869}
@@ -2874,7 +2889,7 @@ multiple of the default frame font width. */)
2874 ? XINT (width) 2889 ? XINT (width)
2875 : XINT (width) * FRAME_COLUMN_WIDTH (f)); 2890 : XINT (width) * FRAME_COLUMN_WIDTH (f));
2876 if (pixel_width != FRAME_TEXT_WIDTH (f)) 2891 if (pixel_width != FRAME_TEXT_WIDTH (f))
2877 adjust_frame_size (f, pixel_width, -1, 1, !NILP (pretend)); 2892 adjust_frame_size (f, pixel_width, -1, 1, !NILP (pretend), Qwidth);
2878 2893
2879 return Qnil; 2894 return Qnil;
2880} 2895}
@@ -2903,7 +2918,7 @@ font height. */)
2903 2918
2904 if (pixel_width != FRAME_TEXT_WIDTH (f) 2919 if (pixel_width != FRAME_TEXT_WIDTH (f)
2905 || pixel_height != FRAME_TEXT_HEIGHT (f)) 2920 || pixel_height != FRAME_TEXT_HEIGHT (f))
2906 adjust_frame_size (f, pixel_width, pixel_height, 1, 0); 2921 adjust_frame_size (f, pixel_width, pixel_height, 1, 0, Qsize);
2907 2922
2908 return Qnil; 2923 return Qnil;
2909} 2924}
@@ -3627,7 +3642,7 @@ x_set_left_fringe (struct frame *f, Lisp_Object new_value, Lisp_Object old_value
3627 = (new_width + FRAME_RIGHT_FRINGE_WIDTH (f) + unit - 1) / unit; 3642 = (new_width + FRAME_RIGHT_FRINGE_WIDTH (f) + unit - 1) / unit;
3628 3643
3629 if (FRAME_X_WINDOW (f) != 0) 3644 if (FRAME_X_WINDOW (f) != 0)
3630 adjust_frame_size (f, -1, -1, 3, 0); 3645 adjust_frame_size (f, -1, -1, 3, 0, Qleft_fringe);
3631 3646
3632 SET_FRAME_GARBAGED (f); 3647 SET_FRAME_GARBAGED (f);
3633 } 3648 }
@@ -3651,7 +3666,7 @@ x_set_right_fringe (struct frame *f, Lisp_Object new_value, Lisp_Object old_valu
3651 = (new_width + FRAME_LEFT_FRINGE_WIDTH (f) + unit - 1) / unit; 3666 = (new_width + FRAME_LEFT_FRINGE_WIDTH (f) + unit - 1) / unit;
3652 3667
3653 if (FRAME_X_WINDOW (f) != 0) 3668 if (FRAME_X_WINDOW (f) != 0)
3654 adjust_frame_size (f, -1, -1, 3, 0); 3669 adjust_frame_size (f, -1, -1, 3, 0, Qright_fringe);
3655 3670
3656 SET_FRAME_GARBAGED (f); 3671 SET_FRAME_GARBAGED (f);
3657 } 3672 }
@@ -3683,7 +3698,7 @@ x_set_right_divider_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
3683 FRAME_RIGHT_DIVIDER_WIDTH (f) = 0; 3698 FRAME_RIGHT_DIVIDER_WIDTH (f) = 0;
3684 if (FRAME_RIGHT_DIVIDER_WIDTH (f) != old) 3699 if (FRAME_RIGHT_DIVIDER_WIDTH (f) != old)
3685 { 3700 {
3686 adjust_frame_size (f, -1, -1, 4, 0); 3701 adjust_frame_size (f, -1, -1, 4, 0, Qright_divider_width);
3687 adjust_frame_glyphs (f); 3702 adjust_frame_glyphs (f);
3688 SET_FRAME_GARBAGED (f); 3703 SET_FRAME_GARBAGED (f);
3689 } 3704 }
@@ -3701,7 +3716,7 @@ x_set_bottom_divider_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval
3701 FRAME_BOTTOM_DIVIDER_WIDTH (f) = 0; 3716 FRAME_BOTTOM_DIVIDER_WIDTH (f) = 0;
3702 if (FRAME_BOTTOM_DIVIDER_WIDTH (f) != old) 3717 if (FRAME_BOTTOM_DIVIDER_WIDTH (f) != old)
3703 { 3718 {
3704 adjust_frame_size (f, -1, -1, 4, 0); 3719 adjust_frame_size (f, -1, -1, 4, 0, Qbottom_divider_width);
3705 adjust_frame_glyphs (f); 3720 adjust_frame_glyphs (f);
3706 SET_FRAME_GARBAGED (f); 3721 SET_FRAME_GARBAGED (f);
3707 } 3722 }
@@ -3765,7 +3780,7 @@ x_set_vertical_scroll_bars (struct frame *f, Lisp_Object arg, Lisp_Object oldval
3765 However, if the window hasn't been created yet, we shouldn't 3780 However, if the window hasn't been created yet, we shouldn't
3766 call x_set_window_size. */ 3781 call x_set_window_size. */
3767 if (FRAME_X_WINDOW (f)) 3782 if (FRAME_X_WINDOW (f))
3768 adjust_frame_size (f, -1, -1, 3, 0); 3783 adjust_frame_size (f, -1, -1, 3, 0, Qvertical_scroll_bars);
3769 3784
3770 SET_FRAME_GARBAGED (f); 3785 SET_FRAME_GARBAGED (f);
3771 } 3786 }
@@ -3785,7 +3800,7 @@ x_set_horizontal_scroll_bars (struct frame *f, Lisp_Object arg, Lisp_Object oldv
3785 However, if the window hasn't been created yet, we shouldn't 3800 However, if the window hasn't been created yet, we shouldn't
3786 call x_set_window_size. */ 3801 call x_set_window_size. */
3787 if (FRAME_X_WINDOW (f)) 3802 if (FRAME_X_WINDOW (f))
3788 adjust_frame_size (f, -1, -1, 3, 0); 3803 adjust_frame_size (f, -1, -1, 3, 0, Qhorizontal_scroll_bars);
3789 3804
3790 SET_FRAME_GARBAGED (f); 3805 SET_FRAME_GARBAGED (f);
3791 } 3806 }
@@ -3802,7 +3817,7 @@ x_set_scroll_bar_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
3802 x_set_scroll_bar_default_width (f); 3817 x_set_scroll_bar_default_width (f);
3803 3818
3804 if (FRAME_X_WINDOW (f)) 3819 if (FRAME_X_WINDOW (f))
3805 adjust_frame_size (f, -1, -1, 3, 0); 3820 adjust_frame_size (f, -1, -1, 3, 0, Qscroll_bar_width);
3806 3821
3807 SET_FRAME_GARBAGED (f); 3822 SET_FRAME_GARBAGED (f);
3808 } 3823 }
@@ -3812,7 +3827,7 @@ x_set_scroll_bar_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
3812 FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = XFASTINT (arg); 3827 FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = XFASTINT (arg);
3813 FRAME_CONFIG_SCROLL_BAR_COLS (f) = (XFASTINT (arg) + unit - 1) / unit; 3828 FRAME_CONFIG_SCROLL_BAR_COLS (f) = (XFASTINT (arg) + unit - 1) / unit;
3814 if (FRAME_X_WINDOW (f)) 3829 if (FRAME_X_WINDOW (f))
3815 adjust_frame_size (f, -1, -1, 3, 0); 3830 adjust_frame_size (f, -1, -1, 3, 0, Qscroll_bar_width);
3816 3831
3817 SET_FRAME_GARBAGED (f); 3832 SET_FRAME_GARBAGED (f);
3818 } 3833 }
@@ -3832,7 +3847,7 @@ x_set_scroll_bar_height (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
3832 x_set_scroll_bar_default_height (f); 3847 x_set_scroll_bar_default_height (f);
3833 3848
3834 if (FRAME_X_WINDOW (f)) 3849 if (FRAME_X_WINDOW (f))
3835 adjust_frame_size (f, -1, -1, 3, 0); 3850 adjust_frame_size (f, -1, -1, 3, 0, Qscroll_bar_height);
3836 3851
3837 SET_FRAME_GARBAGED (f); 3852 SET_FRAME_GARBAGED (f);
3838 } 3853 }
@@ -3842,7 +3857,7 @@ x_set_scroll_bar_height (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
3842 FRAME_CONFIG_SCROLL_BAR_HEIGHT (f) = XFASTINT (arg); 3857 FRAME_CONFIG_SCROLL_BAR_HEIGHT (f) = XFASTINT (arg);
3843 FRAME_CONFIG_SCROLL_BAR_LINES (f) = (XFASTINT (arg) + unit - 1) / unit; 3858 FRAME_CONFIG_SCROLL_BAR_LINES (f) = (XFASTINT (arg) + unit - 1) / unit;
3844 if (FRAME_X_WINDOW (f)) 3859 if (FRAME_X_WINDOW (f))
3845 adjust_frame_size (f, -1, -1, 3, 0); 3860 adjust_frame_size (f, -1, -1, 3, 0, Qscroll_bar_height);
3846 3861
3847 SET_FRAME_GARBAGED (f); 3862 SET_FRAME_GARBAGED (f);
3848 } 3863 }
@@ -4785,12 +4800,21 @@ syms_of_frame (void)
4785 4800
4786 DEFSYM (Qterminal, "terminal"); 4801 DEFSYM (Qterminal, "terminal");
4787 4802
4788 DEFSYM (Qgeometry, "geometry");
4789 DEFSYM (Qworkarea, "workarea"); 4803 DEFSYM (Qworkarea, "workarea");
4790 DEFSYM (Qmm_size, "mm-size"); 4804 DEFSYM (Qmm_size, "mm-size");
4791 DEFSYM (Qframes, "frames"); 4805 DEFSYM (Qframes, "frames");
4792 DEFSYM (Qsource, "source"); 4806 DEFSYM (Qsource, "source");
4793 4807
4808 DEFSYM (Qframe_position, "frame-position");
4809 DEFSYM (Qframe_outer_size, "frame-outer-size");
4810 DEFSYM (Qexternal_border_size, "external-border-size");
4811 DEFSYM (Qtitle_height, "title-height");
4812 DEFSYM (Qmenu_bar_external, "menu-bar-external");
4813 DEFSYM (Qmenu_bar_size, "menu-bar-size");
4814 DEFSYM (Qtool_bar_external, "tool-bar-external");
4815 DEFSYM (Qtool_bar_size, "tool-bar-size");
4816 DEFSYM (Qframe_inner_size, "frame-inner-size");
4817
4794#ifdef HAVE_NS 4818#ifdef HAVE_NS
4795 DEFSYM (Qns_parse_geometry, "ns-parse-geometry"); 4819 DEFSYM (Qns_parse_geometry, "ns-parse-geometry");
4796#endif 4820#endif
@@ -4985,13 +5009,49 @@ fullscreen. To resize your initial frame pixelwise, set this option to
4985a non-nil value in your init file. */); 5009a non-nil value in your init file. */);
4986 frame_resize_pixelwise = 0; 5010 frame_resize_pixelwise = 0;
4987 5011
4988 DEFVAR_BOOL ("frame-inhibit-implied-resize", frame_inhibit_implied_resize, 5012 DEFVAR_LISP ("frame-inhibit-implied-resize", frame_inhibit_implied_resize,
4989 doc: /* Non-nil means do not resize frames implicitly. 5013 doc: /* Whether frames should be resized implicitly.
4990If this option is nil, setting default font, menubar mode, fringe width, 5014If this option is nil, setting font, menu bar, tool bar, internal
4991or scroll bar mode of a specific frame may resize the frame in order to 5015borders, fringes or scroll bars of a specific frame may resize the frame
4992preserve the number of columns or lines it displays. If this option is 5016in order to preserve the number of columns or lines it displays. If
4993non-nil, no such resizing is done. */); 5017this option is `t', no such resizing is done. Note that the size of
4994 frame_inhibit_implied_resize = 0; 5018fullscreen and maximized frames, the height of fullheight frames and the
5019width of fullwidth frames never change implicitly.
5020
5021The value of this option can be also be a list of frame parameters. In
5022this case, resizing is inhibited when changing a parameter that appears
5023in that list. The parameters currently handled by this option include
5024`font', `font-backend', `internal-border-width', `menu-bar-lines' and
5025`tool-bar-lines'.
5026
5027Changing any of the parameters `scroll-bar-width', `scroll-bar-height',
5028`vertical-scroll-bars', `horizontal-scroll-bars', `left-fringe' and
5029`right-fringe' is handled as if the frame contained just one live
5030window. This means, for example, that removing vertical scroll bars on
5031a frame containing several side by side windows will shrink the frame
5032width by the width of one scroll bar provided this option is nil and
5033keep it unchanged if this option is either `t' or a list containing
5034`vertical-scroll-bars'.
5035
5036The default value is '(tool-bar-lines) on Lucid, Motif and Windows
5037(which means that adding/removing a tool bar does not change the frame
5038height), nil on all other window systems including GTK+ (which means
5039that changing any of the parameters listed above may change the size of
5040the frame), and `t' otherwise (which means the frame size never changes
5041implicitly when there's no window system support).
5042
5043Note that when a frame is not large enough to accommodate a change of
5044any of the parameters listed above, Emacs may try to enlarge the frame
5045even if this option is non-nil. */);
5046#if defined (HAVE_WINDOW_SYSTEM)
5047#if defined (USE_LUCID) || defined (USE_MOTIF) || defined (HAVE_NTGUI)
5048 frame_inhibit_implied_resize = list1 (Qtool_bar_lines);
5049#else
5050 frame_inhibit_implied_resize = Qnil;
5051#endif
5052#else
5053 frame_inhibit_implied_resize = Qt;
5054#endif
4995 5055
4996 staticpro (&Vframe_list); 5056 staticpro (&Vframe_list);
4997 5057
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 *);
1117extern void frame_make_pointer_invisible (struct frame *); 1117extern void frame_make_pointer_invisible (struct frame *);
1118extern void frame_make_pointer_visible (struct frame *); 1118extern void frame_make_pointer_visible (struct frame *);
1119extern Lisp_Object delete_frame (Lisp_Object, Lisp_Object); 1119extern Lisp_Object delete_frame (Lisp_Object, Lisp_Object);
1120extern bool frame_inhibit_resize (struct frame *, bool); 1120extern bool frame_inhibit_resize (struct frame *, bool, Lisp_Object);
1121extern void adjust_frame_size (struct frame *, int, int, int, bool); 1121extern void adjust_frame_size (struct frame *, int, int, int, bool, Lisp_Object);
1122 1122
1123extern Lisp_Object Vframe_list; 1123extern Lisp_Object Vframe_list;
1124 1124
@@ -1380,6 +1380,11 @@ extern Lisp_Object Qx_resource_name;
1380extern Lisp_Object Qtop, Qbox, Qbottom; 1380extern Lisp_Object Qtop, Qbox, Qbottom;
1381extern Lisp_Object Qdisplay; 1381extern Lisp_Object Qdisplay;
1382 1382
1383extern Lisp_Object Qframe_position, Qframe_outer_size, Qframe_inner_size;
1384extern Lisp_Object Qexternal_border_size, Qtitle_height;
1385extern Lisp_Object Qmenu_bar_external, Qmenu_bar_size;
1386extern Lisp_Object Qtool_bar_external, Qtool_bar_size;
1387
1383extern Lisp_Object Qrun_hook_with_args; 1388extern Lisp_Object Qrun_hook_with_args;
1384 1389
1385#ifdef HAVE_WINDOW_SYSTEM 1390#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/>. */
50#include "emacsgtkfixed.h" 50#include "emacsgtkfixed.h"
51#endif 51#endif
52 52
53#define FRAME_TOTAL_PIXEL_HEIGHT(f) \ 53/** #define FRAME_TOTAL_PIXEL_HEIGHT(f) \ **/
54 (FRAME_PIXEL_HEIGHT (f) + FRAME_MENUBAR_HEIGHT (f) + FRAME_TOOLBAR_HEIGHT (f)) 54/** (FRAME_PIXEL_HEIGHT (f) + FRAME_MENUBAR_HEIGHT (f) + FRAME_TOOLBAR_HEIGHT (f)) **/
55 55
56#define FRAME_TOTAL_PIXEL_WIDTH(f) \ 56/** #define FRAME_TOTAL_PIXEL_WIDTH(f) \ **/
57 (FRAME_PIXEL_WIDTH (f) + FRAME_TOOLBAR_WIDTH (f)) 57/** (FRAME_PIXEL_WIDTH (f) + FRAME_TOOLBAR_WIDTH (f)) **/
58 58
59#ifndef HAVE_GTK_WIDGET_SET_HAS_WINDOW 59#ifndef HAVE_GTK_WIDGET_SET_HAS_WINDOW
60#define gtk_widget_set_has_window(w, b) \ 60#define gtk_widget_set_has_window(w, b) \
@@ -940,12 +940,13 @@ xg_frame_set_char_size (struct frame *f, int width, int height)
940 x_wait_for_event (f, ConfigureNotify); 940 x_wait_for_event (f, ConfigureNotify);
941 } 941 }
942 else 942 else
943 adjust_frame_size (f, -1, -1, 5, 0); 943 adjust_frame_size (f, -1, -1, 5, 0, Qnil);
944} 944}
945 945
946/* Handle height/width changes (i.e. add/remove/move menu/toolbar). 946/* Handle height/width changes (i.e. add/remove/move menu/toolbar).
947 The policy is to keep the number of editable lines. */ 947 The policy is to keep the number of editable lines. */
948 948
949#if 0
949static void 950static void
950xg_height_or_width_changed (struct frame *f) 951xg_height_or_width_changed (struct frame *f)
951{ 952{
@@ -955,6 +956,7 @@ xg_height_or_width_changed (struct frame *f)
955 f->output_data.x->hint_flags = 0; 956 f->output_data.x->hint_flags = 0;
956 x_wm_set_size_hint (f, 0, 0); 957 x_wm_set_size_hint (f, 0, 0);
957} 958}
959#endif
958 960
959/* Convert an X Window WSESC on display DPY to its corresponding GtkWidget. 961/* Convert an X Window WSESC on display DPY to its corresponding GtkWidget.
960 Must be done like this, because GtkWidget:s can have "hidden" 962 Must be done like this, because GtkWidget:s can have "hidden"
@@ -3241,7 +3243,7 @@ menubar_map_cb (GtkWidget *w, gpointer user_data)
3241 if (FRAME_MENUBAR_HEIGHT (f) != req.height) 3243 if (FRAME_MENUBAR_HEIGHT (f) != req.height)
3242 { 3244 {
3243 FRAME_MENUBAR_HEIGHT (f) = req.height; 3245 FRAME_MENUBAR_HEIGHT (f) = req.height;
3244 xg_height_or_width_changed (f); 3246 adjust_frame_size (f, -1, -1, 2, 0, Qmenu_bar_lines);
3245 } 3247 }
3246} 3248}
3247 3249
@@ -3273,7 +3275,7 @@ xg_update_frame_menubar (struct frame *f)
3273 if (FRAME_MENUBAR_HEIGHT (f) != req.height) 3275 if (FRAME_MENUBAR_HEIGHT (f) != req.height)
3274 { 3276 {
3275 FRAME_MENUBAR_HEIGHT (f) = req.height; 3277 FRAME_MENUBAR_HEIGHT (f) = req.height;
3276 xg_height_or_width_changed (f); 3278 adjust_frame_size (f, -1, -1, 2, 0, Qmenu_bar_lines);
3277 } 3279 }
3278 unblock_input (); 3280 unblock_input ();
3279} 3281}
@@ -3295,7 +3297,7 @@ free_frame_menubar (struct frame *f)
3295 the container. */ 3297 the container. */
3296 x->menubar_widget = 0; 3298 x->menubar_widget = 0;
3297 FRAME_MENUBAR_HEIGHT (f) = 0; 3299 FRAME_MENUBAR_HEIGHT (f) = 0;
3298 xg_height_or_width_changed (f); 3300 adjust_frame_size (f, -1, -1, 2, 0, Qmenu_bar_lines);
3299 unblock_input (); 3301 unblock_input ();
3300 } 3302 }
3301} 3303}
@@ -4219,7 +4221,7 @@ tb_size_cb (GtkWidget *widget,
4219 size hints if tool bar size changes. Seen on Fedora 18 at least. */ 4221 size hints if tool bar size changes. Seen on Fedora 18 at least. */
4220 struct frame *f = user_data; 4222 struct frame *f = user_data;
4221 if (xg_update_tool_bar_sizes (f)) 4223 if (xg_update_tool_bar_sizes (f))
4222 xg_height_or_width_changed (f); 4224 adjust_frame_size (f, -1, -1, 2, 0, Qtool_bar_lines);
4223} 4225}
4224 4226
4225/* Create a tool bar for frame F. */ 4227/* Create a tool bar for frame F. */
@@ -4819,7 +4821,7 @@ update_frame_tool_bar (struct frame *f)
4819 xg_pack_tool_bar (f, FRAME_TOOL_BAR_POSITION (f)); 4821 xg_pack_tool_bar (f, FRAME_TOOL_BAR_POSITION (f));
4820 gtk_widget_show_all (x->toolbar_widget); 4822 gtk_widget_show_all (x->toolbar_widget);
4821 if (xg_update_tool_bar_sizes (f)) 4823 if (xg_update_tool_bar_sizes (f))
4822 xg_height_or_width_changed (f); 4824 adjust_frame_size (f, -1, -1, 2, 0, Qtool_bar_lines);
4823 } 4825 }
4824 4826
4825 unblock_input (); 4827 unblock_input ();
@@ -4867,7 +4869,7 @@ free_frame_tool_bar (struct frame *f)
4867 NULL); 4869 NULL);
4868 } 4870 }
4869 4871
4870 xg_height_or_width_changed (f); 4872 adjust_frame_size (f, -1, -1, 2, 0, Qtool_bar_lines);
4871 4873
4872 unblock_input (); 4874 unblock_input ();
4873 } 4875 }
@@ -4897,7 +4899,7 @@ xg_change_toolbar_position (struct frame *f, Lisp_Object pos)
4897 xg_pack_tool_bar (f, pos); 4899 xg_pack_tool_bar (f, pos);
4898 g_object_unref (top_widget); 4900 g_object_unref (top_widget);
4899 if (xg_update_tool_bar_sizes (f)) 4901 if (xg_update_tool_bar_sizes (f))
4900 xg_height_or_width_changed (f); 4902 adjust_frame_size (f, -1, -1, 2, 0, Qtool_bar_lines);
4901 4903
4902 unblock_input (); 4904 unblock_input ();
4903} 4905}
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
731 return; 731 return;
732 732
733 if (FRAME_X_WINDOW (f) != 0) 733 if (FRAME_X_WINDOW (f) != 0)
734 adjust_frame_size (f, -1, -1, 3, 0); 734 adjust_frame_size (f, -1, -1, 3, 0, Qinternal_border_width);
735 735
736 SET_FRAME_GARBAGED (f); 736 SET_FRAME_GARBAGED (f);
737} 737}
@@ -1275,7 +1275,7 @@ This function is an internal primitive--use `make-frame' instead. */)
1275 1275
1276 /* Read comment about this code in corresponding place in xfns.c. */ 1276 /* Read comment about this code in corresponding place in xfns.c. */
1277 adjust_frame_size (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f), 1277 adjust_frame_size (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f),
1278 FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 5, 1); 1278 FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 5, 1, Qnil);
1279 1279
1280 /* The resources controlling the menu-bar and tool-bar are 1280 /* The resources controlling the menu-bar and tool-bar are
1281 processed specially at startup, and reflected in the mode 1281 processed specially at startup, and reflected in the mode
@@ -1349,7 +1349,7 @@ This function is an internal primitive--use `make-frame' instead. */)
1349 /* Consider frame official, now. */ 1349 /* Consider frame official, now. */
1350 f->official = true; 1350 f->official = true;
1351 1351
1352 adjust_frame_size (f, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f), 0, 1); 1352 adjust_frame_size (f, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f), 0, 1, Qnil);
1353 1353
1354 if (! f->output_data.ns->explicit_parent) 1354 if (! f->output_data.ns->explicit_parent)
1355 { 1355 {
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
1645 1645
1646 if (FRAME_X_WINDOW (f) != 0) 1646 if (FRAME_X_WINDOW (f) != 0)
1647 { 1647 {
1648 adjust_frame_size (f, -1, -1, 3, 0); 1648 adjust_frame_size (f, -1, -1, 3, 0, Qinternal_border_width);
1649 1649
1650 if (FRAME_VISIBLE_P (f)) 1650 if (FRAME_VISIBLE_P (f))
1651 x_clear_under_internal_border (f); 1651 x_clear_under_internal_border (f);
@@ -1691,7 +1691,7 @@ x_set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
1691 of the outer rectangle (including decorations) unchanged, and a 1691 of the outer rectangle (including decorations) unchanged, and a
1692 second time because we want to keep the height of the inner 1692 second time because we want to keep the height of the inner
1693 rectangle (without the decorations unchanged). */ 1693 rectangle (without the decorations unchanged). */
1694 adjust_frame_size (f, -1, -1, 2, 1); 1694 adjust_frame_size (f, -1, -1, 2, 1, Qmenu_bar_lines);
1695 1695
1696 /* Not sure whether this is needed. */ 1696 /* Not sure whether this is needed. */
1697 x_clear_under_internal_border (f); 1697 x_clear_under_internal_border (f);
@@ -1721,7 +1721,15 @@ x_set_tool_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
1721 else 1721 else
1722 nlines = 0; 1722 nlines = 0;
1723 1723
1724 x_change_tool_bar_height (f, nlines * FRAME_LINE_HEIGHT (f)); 1724 if (nlines == 0)
1725 x_change_tool_bar_height (f, nlines * FRAME_LINE_HEIGHT (f));
1726 else
1727 {
1728 f->n_tool_bar_rows = 0;
1729 FRAME_TOOL_BAR_LINES (f) = nlines;
1730 adjust_frame_glyphs (f);
1731 SET_FRAME_GARBAGED (f);
1732 }
1725} 1733}
1726 1734
1727 1735
@@ -1741,10 +1749,10 @@ x_change_tool_bar_height (struct frame *f, int height)
1741 /* Recalculate tool bar and frame text sizes. */ 1749 /* Recalculate tool bar and frame text sizes. */
1742 FRAME_TOOL_BAR_HEIGHT (f) = height; 1750 FRAME_TOOL_BAR_HEIGHT (f) = height;
1743 FRAME_TOOL_BAR_LINES (f) = lines; 1751 FRAME_TOOL_BAR_LINES (f) = lines;
1744 FRAME_TEXT_HEIGHT (f) 1752/** FRAME_TEXT_HEIGHT (f) **/
1745 = FRAME_PIXEL_TO_TEXT_HEIGHT (f, FRAME_PIXEL_HEIGHT (f)); 1753/** = FRAME_PIXEL_TO_TEXT_HEIGHT (f, FRAME_PIXEL_HEIGHT (f)); **/
1746 FRAME_LINES (f) 1754/** FRAME_LINES (f) **/
1747 = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, FRAME_PIXEL_HEIGHT (f)); 1755/** = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, FRAME_PIXEL_HEIGHT (f)); **/
1748 /* Store the `tool-bar-lines' and `height' frame parameters. */ 1756 /* Store the `tool-bar-lines' and `height' frame parameters. */
1749 store_frame_param (f, Qtool_bar_lines, make_number (lines)); 1757 store_frame_param (f, Qtool_bar_lines, make_number (lines));
1750 store_frame_param (f, Qheight, make_number (FRAME_LINES (f))); 1758 store_frame_param (f, Qheight, make_number (FRAME_LINES (f)));
@@ -1761,7 +1769,8 @@ x_change_tool_bar_height (struct frame *f, int height)
1761 /* Recalculate toolbar height. */ 1769 /* Recalculate toolbar height. */
1762 f->n_tool_bar_rows = 0; 1770 f->n_tool_bar_rows = 0;
1763 1771
1764 adjust_frame_size (f, -1, -1, 4, 0); 1772 adjust_frame_size (f, -1, -1, (old_height == 0 || height == 0) ? 2 : 4, 0,
1773 Qtool_bar_lines);
1765 1774
1766 if (FRAME_X_WINDOW (f)) 1775 if (FRAME_X_WINDOW (f))
1767 x_clear_under_internal_border (f); 1776 x_clear_under_internal_border (f);
@@ -4629,7 +4638,7 @@ This function is an internal primitive--use `make-frame' instead. */)
4629 had one frame line vs one toolbar line which left us with a zero 4638 had one frame line vs one toolbar line which left us with a zero
4630 root window height which was obviously wrong as well ... */ 4639 root window height which was obviously wrong as well ... */
4631 adjust_frame_size (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f), 4640 adjust_frame_size (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f),
4632 FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 5, 1); 4641 FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 5, 1, Qnil);
4633 4642
4634 /* The X resources controlling the menu-bar and tool-bar are 4643 /* The X resources controlling the menu-bar and tool-bar are
4635 processed specially at startup, and reflected in the mode 4644 processed specially at startup, and reflected in the mode
@@ -4697,7 +4706,7 @@ This function is an internal primitive--use `make-frame' instead. */)
4697 /* Consider frame official, now. */ 4706 /* Consider frame official, now. */
4698 f->official = true; 4707 f->official = true;
4699 4708
4700 adjust_frame_size (f, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f), 0, 1); 4709 adjust_frame_size (f, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f), 0, 1, Qnil);
4701 4710
4702 /* Tell the server what size and position, etc, we want, and how 4711 /* Tell the server what size and position, etc, we want, and how
4703 badly we want them. This should be done after we have the menu 4712 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,
5797 SET_FRAME_COLS (f, 0); 5806 SET_FRAME_COLS (f, 0);
5798 SET_FRAME_LINES (f, 0); 5807 SET_FRAME_LINES (f, 0);
5799 adjust_frame_size (f, width * FRAME_COLUMN_WIDTH (f), 5808 adjust_frame_size (f, width * FRAME_COLUMN_WIDTH (f),
5800 height * FRAME_LINE_HEIGHT (f), 0, 1); 5809 height * FRAME_LINE_HEIGHT (f), 0, 1, Qnil);
5801 5810
5802 /* Add `tooltip' frame parameter's default value. */ 5811 /* Add `tooltip' frame parameter's default value. */
5803 if (NILP (Fframe_parameter (frame, Qtooltip))) 5812 if (NILP (Fframe_parameter (frame, Qtooltip)))
@@ -7368,30 +7377,33 @@ This is a direct interface to the Windows API FindWindow function. */)
7368 7377
7369DEFUN ("w32-frame-menu-bar-size", Fw32_frame_menu_bar_size, Sw32_frame_menu_bar_size, 0, 1, 0, 7378DEFUN ("w32-frame-menu-bar-size", Fw32_frame_menu_bar_size, Sw32_frame_menu_bar_size, 0, 1, 0,
7370 doc: /* Return sizes of menu bar on frame FRAME. 7379 doc: /* Return sizes of menu bar on frame FRAME.
7371The return value is a list of three elements: The current width and 7380The return value is a list of four elements: The current width and
7372height of FRAME's menu bar in pixels and the default height of the menu 7381height of FRAME's menu bar in pixels, the height of one menu bar line in
7373bar in pixels. If FRAME is omitted or nil, the selected frame is 7382a wrapped menu bar in pixels, and the height of a single line menu bar
7374used. */) 7383in pixels.
7384
7385If FRAME is omitted or nil, the selected frame is used. */)
7375 (Lisp_Object frame) 7386 (Lisp_Object frame)
7376{ 7387{
7377 struct frame *f = decode_any_frame (frame); 7388 struct frame *f = decode_any_frame (frame);
7378 MENUBARINFO info; 7389 MENUBARINFO menu_bar;
7379 int width, height, default_height; 7390 int width, height, single_height, wrapped_height;
7380 7391
7381 block_input (); 7392 block_input ();
7382 7393
7383 default_height = GetSystemMetrics (SM_CYMENUSIZE); 7394 single_height = GetSystemMetrics (SM_CYMENU);
7384 info.cbSize = sizeof (info); 7395 wrapped_height = GetSystemMetrics (SM_CYMENUSIZE);
7385 info.rcBar.right = info.rcBar.left = 0; 7396 menu_bar.cbSize = sizeof (menu_bar);
7386 info.rcBar.top = info.rcBar.bottom = 0; 7397 menu_bar.rcBar.right = menu_bar.rcBar.left = 0;
7387 GetMenuBarInfo (FRAME_W32_WINDOW (f), 0xFFFFFFFD, 0, &info); 7398 menu_bar.rcBar.top = menu_bar.rcBar.bottom = 0;
7388 width = info.rcBar.right - info.rcBar.left; 7399 GetMenuBarInfo (FRAME_W32_WINDOW (f), 0xFFFFFFFD, 0, &menu_bar);
7389 height = info.rcBar.bottom - info.rcBar.top; 7400 width = menu_bar.rcBar.right - menu_bar.rcBar.left;
7401 height = menu_bar.rcBar.bottom - menu_bar.rcBar.top;
7390 7402
7391 unblock_input (); 7403 unblock_input ();
7392 7404
7393 return list3 (make_number (width), make_number (height), 7405 return list4 (make_number (width), make_number (height),
7394 make_number (default_height)); 7406 make_number (wrapped_height), make_number (single_height));
7395} 7407}
7396 7408
7397DEFUN ("w32-frame-rect", Fw32_frame_rect, Sw32_frame_rect, 0, 2, 0, 7409DEFUN ("w32-frame-rect", Fw32_frame_rect, Sw32_frame_rect, 0, 2, 0,
@@ -7408,15 +7420,131 @@ title bar and decorations. */)
7408 struct frame *f = decode_live_frame (frame); 7420 struct frame *f = decode_live_frame (frame);
7409 RECT rect; 7421 RECT rect;
7410 7422
7423 block_input ();
7424
7411 if (!NILP (client)) 7425 if (!NILP (client))
7412 GetClientRect (FRAME_W32_WINDOW (f), &rect); 7426 GetClientRect (FRAME_W32_WINDOW (f), &rect);
7413 else 7427 else
7414 GetWindowRect (FRAME_W32_WINDOW (f), &rect); 7428 GetWindowRect (FRAME_W32_WINDOW (f), &rect);
7415 7429
7430 unblock_input ();
7431
7416 return list4 (make_number (rect.left), make_number (rect.top), 7432 return list4 (make_number (rect.left), make_number (rect.top),
7417 make_number (rect.right), make_number (rect.bottom)); 7433 make_number (rect.right), make_number (rect.bottom));
7418} 7434}
7419 7435
7436DEFUN ("x-frame-geometry", Fx_frame_geometry, Sx_frame_geometry, 0, 1, 0,
7437 doc: /* Return geometric atributes of frame FRAME.
7438FRAME must be a live frame and defaults to the selected one.
7439
7440The return value is an association list containing the following
7441elements (all size values are in pixels).
7442
7443- `frame-outer-size' is a cons of the outer width and height of FRAME.
7444 The outer size includes the title bar and the external borders as well
7445 as any menu and/or tool bar of frame.
7446
7447- `border' is a cons of the horizontal and vertical width of FRAME's
7448 external borders.
7449
7450- `title-bar-height' is the height of the title bar of FRAME.
7451
7452- `menu-bar-external' if `t' means the menu bar is by default external
7453 (not included in the inner size of FRAME).
7454
7455- `menu-bar-size' is a cons of the width and height of the menu bar of
7456 FRAME.
7457
7458- `tool-bar-external' if `t' means the tool bar is by default external
7459 (not included in the inner size of FRAME).
7460
7461- `tool-bar-side' tells tells on which side the tool bar on FRAME is by
7462 default and can be one of `left', `top', `right' or `bottom'.
7463
7464- `tool-bar-size' is a cons of the width and height of the tool bar of
7465 FRAME.
7466
7467- `frame-inner-size' is a cons of the inner width and height of FRAME.
7468 This excludes FRAME's title bar and external border as well as any
7469 external menu and/or tool bar. */)
7470 (Lisp_Object frame)
7471{
7472 struct frame *f = decode_live_frame (frame);
7473 Lisp_Object geometry = Qnil;
7474 RECT frame_outer_edges, frame_inner_edges;
7475 MENUBARINFO menu_bar;
7476 int border_width, border_height, title_height;
7477 int single_bar_height, wrapped_bar_height, menu_bar_height;
7478 Lisp_Object fullscreen = Fframe_parameter (frame, Qfullscreen);
7479
7480 block_input ();
7481
7482 /* Outer frame rectangle, including outer borders and title bar. */
7483 GetWindowRect (FRAME_W32_WINDOW (f), &frame_outer_edges);
7484 /* Inner frame rectangle, excluding borders and title bar. */
7485 GetClientRect (FRAME_W32_WINDOW (f), &frame_inner_edges);
7486 /* Outer border. */
7487 border_width = GetSystemMetrics (SM_CXFRAME);
7488 border_height = GetSystemMetrics (SM_CYFRAME);
7489 /* Title bar. */
7490 title_height = GetSystemMetrics (SM_CYCAPTION);
7491 /* Menu bar. */
7492 menu_bar.cbSize = sizeof (menu_bar);
7493 menu_bar.rcBar.right = menu_bar.rcBar.left = 0;
7494 menu_bar.rcBar.top = menu_bar.rcBar.bottom = 0;
7495 GetMenuBarInfo (FRAME_W32_WINDOW (f), 0xFFFFFFFD, 0, &menu_bar);
7496 single_bar_height = GetSystemMetrics (SM_CYMENU);
7497 wrapped_bar_height = GetSystemMetrics (SM_CYMENUSIZE);
7498 unblock_input ();
7499
7500 menu_bar_height = menu_bar.rcBar.bottom - menu_bar.rcBar.top;
7501 /* Fix menu bar height reported by GetMenuBarInfo. */
7502 if (menu_bar_height > single_bar_height)
7503 /* A wrapped menu bar. */
7504 menu_bar_height += single_bar_height - wrapped_bar_height;
7505 else if (menu_bar_height > 0)
7506 /* A single line menu bar. */
7507 menu_bar_height = single_bar_height;
7508
7509 return
7510 listn (CONSTYPE_PURE, 10,
7511 Fcons (Qframe_position,
7512 Fcons (make_number (frame_outer_edges.left),
7513 make_number (frame_outer_edges.top))),
7514 Fcons (Qframe_outer_size,
7515 Fcons (make_number
7516 (frame_outer_edges.right - frame_outer_edges.left),
7517 make_number
7518 (frame_outer_edges.bottom - frame_outer_edges.top))),
7519 Fcons (Qexternal_border_size,
7520 ((EQ (fullscreen, Qfullboth) || EQ (fullscreen, Qfullscreen))
7521 ? Fcons (make_number (0), make_number (0))
7522 : Fcons (make_number (border_width),
7523 make_number (border_height)))),
7524 Fcons (Qtitle_height,
7525 ((EQ (fullscreen, Qfullboth) || EQ (fullscreen, Qfullscreen))
7526 ? make_number (0)
7527 : make_number (title_height))),
7528 Fcons (Qmenu_bar_external, Qt),
7529 Fcons (Qmenu_bar_size,
7530 Fcons (make_number
7531 (menu_bar.rcBar.right - menu_bar.rcBar.left),
7532 make_number (menu_bar_height))),
7533 Fcons (Qtool_bar_external, Qnil),
7534 Fcons (Qtool_bar_position, Qtop),
7535 Fcons (Qtool_bar_size,
7536 Fcons (make_number (FRAME_TOOL_BAR_LINES (f)
7537 ? (FRAME_PIXEL_WIDTH (f)
7538 - 2 * FRAME_INTERNAL_BORDER_WIDTH (f))
7539 : 0),
7540 make_number (FRAME_TOOL_BAR_HEIGHT (f)))),
7541 Fcons (Qframe_inner_size,
7542 Fcons (make_number
7543 (frame_inner_edges.right - frame_inner_edges.left),
7544 make_number
7545 (frame_inner_edges.bottom - frame_inner_edges.top))));
7546}
7547
7420DEFUN ("w32-battery-status", Fw32_battery_status, Sw32_battery_status, 0, 0, 0, 7548DEFUN ("w32-battery-status", Fw32_battery_status, Sw32_battery_status, 0, 0, 0,
7421 doc: /* Get power status information from Windows system. 7549 doc: /* Get power status information from Windows system.
7422 7550
@@ -8411,6 +8539,7 @@ only be necessary if the default setting causes problems. */);
8411 defsubr (&Sx_open_connection); 8539 defsubr (&Sx_open_connection);
8412 defsubr (&Sx_close_connection); 8540 defsubr (&Sx_close_connection);
8413 defsubr (&Sx_display_list); 8541 defsubr (&Sx_display_list);
8542 defsubr (&Sx_frame_geometry);
8414 defsubr (&Sx_synchronize); 8543 defsubr (&Sx_synchronize);
8415 8544
8416 /* W32 specific functions */ 8545 /* 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)
504 area remains the same, if menubar has just been created. */ 504 area remains the same, if menubar has just been created. */
505 if (old_widget == NULL) 505 if (old_widget == NULL)
506 adjust_frame_size (f, FRAME_TEXT_WIDTH (f), 506 adjust_frame_size (f, FRAME_TEXT_WIDTH (f),
507 FRAME_TEXT_HEIGHT (f), 2, 0); 507 FRAME_TEXT_HEIGHT (f), 2, 0, Qmenu_bar_lines);
508 } 508 }
509 509
510 unblock_input (); 510 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)
5843 problems because the tip frame has no widget. */ 5843 problems because the tip frame has no widget. */
5844 if (NILP (tip_frame) || XFRAME (tip_frame) != f) 5844 if (NILP (tip_frame) || XFRAME (tip_frame) != f)
5845 adjust_frame_size (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f), 5845 adjust_frame_size (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f),
5846 FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 3, 0); 5846 FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 3, 0, Qfont);
5847 } 5847 }
5848 5848
5849 /* X version sets font of input methods here also. */ 5849 /* 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)
644 EmacsFrame ew = (EmacsFrame) widget; 644 EmacsFrame ew = (EmacsFrame) widget;
645 struct frame *f = ew->emacs_frame.frame; 645 struct frame *f = ew->emacs_frame.frame;
646 646
647 if (!frame_inhibit_resize (f, 0) && !frame_inhibit_resize (f, 1)) 647 if (!frame_inhibit_resize (f, 0, Qfont)
648 && !frame_inhibit_resize (f, 1, Qfont))
648 x_set_window_size (f, 0, columns, rows, 0); 649 x_set_window_size (f, 0, columns, rows, 0);
649} 650}
650 651
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. */)
6417 /* Make frame official again and apply frame size changes if 6417 /* Make frame official again and apply frame size changes if
6418 needed. */ 6418 needed. */
6419 f->official = true; 6419 f->official = true;
6420 adjust_frame_size (f, -1, -1, 1, 0); 6420 adjust_frame_size (f, -1, -1, 1, 0, Qnil);
6421 6421
6422 adjust_frame_glyphs (f); 6422 adjust_frame_glyphs (f);
6423 unblock_input (); 6423 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)
1009#else /* not USE_X_TOOLKIT && not USE_GTK */ 1009#else /* not USE_X_TOOLKIT && not USE_GTK */
1010 FRAME_MENU_BAR_LINES (f) = nlines; 1010 FRAME_MENU_BAR_LINES (f) = nlines;
1011 FRAME_MENU_BAR_HEIGHT (f) = nlines * FRAME_LINE_HEIGHT (f); 1011 FRAME_MENU_BAR_HEIGHT (f) = nlines * FRAME_LINE_HEIGHT (f);
1012 adjust_frame_size (f, -1, -1, 2, 1); 1012 adjust_frame_size (f, -1, -1, 2, 1, Qmenu_bar_lines);
1013 if (FRAME_X_WINDOW (f)) 1013 if (FRAME_X_WINDOW (f))
1014 x_clear_under_internal_border (f); 1014 x_clear_under_internal_border (f);
1015 1015
@@ -1075,7 +1075,19 @@ x_set_tool_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
1075 else 1075 else
1076 nlines = 0; 1076 nlines = 0;
1077 1077
1078#ifdef USE_GTK
1078 x_change_tool_bar_height (f, nlines * FRAME_LINE_HEIGHT (f)); 1079 x_change_tool_bar_height (f, nlines * FRAME_LINE_HEIGHT (f));
1080#else /* !USE_GTK */
1081 if (nlines == 0)
1082 x_change_tool_bar_height (f, nlines * FRAME_LINE_HEIGHT (f));
1083 else
1084 {
1085 f->n_tool_bar_rows = 0;
1086 FRAME_TOOL_BAR_LINES (f) = nlines;
1087 adjust_frame_glyphs (f);
1088 SET_FRAME_GARBAGED (f);
1089 }
1090#endif /* USE_GTK */
1079} 1091}
1080 1092
1081 1093
@@ -1112,10 +1124,10 @@ x_change_tool_bar_height (struct frame *f, int height)
1112 /* Recalculate tool bar and frame text sizes. */ 1124 /* Recalculate tool bar and frame text sizes. */
1113 FRAME_TOOL_BAR_HEIGHT (f) = height; 1125 FRAME_TOOL_BAR_HEIGHT (f) = height;
1114 FRAME_TOOL_BAR_LINES (f) = lines; 1126 FRAME_TOOL_BAR_LINES (f) = lines;
1115 FRAME_TEXT_HEIGHT (f) 1127/** FRAME_TEXT_HEIGHT (f) **/
1116 = FRAME_PIXEL_TO_TEXT_HEIGHT (f, FRAME_PIXEL_HEIGHT (f)); 1128/** = FRAME_PIXEL_TO_TEXT_HEIGHT (f, FRAME_PIXEL_HEIGHT (f)); **/
1117 FRAME_LINES (f) 1129/** FRAME_LINES (f) **/
1118 = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, FRAME_PIXEL_HEIGHT (f)); 1130/** = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, FRAME_PIXEL_HEIGHT (f)); **/
1119 /* Store the `tool-bar-lines' and `height' frame parameters. */ 1131 /* Store the `tool-bar-lines' and `height' frame parameters. */
1120 store_frame_param (f, Qtool_bar_lines, make_number (lines)); 1132 store_frame_param (f, Qtool_bar_lines, make_number (lines));
1121 store_frame_param (f, Qheight, make_number (FRAME_LINES (f))); 1133 store_frame_param (f, Qheight, make_number (FRAME_LINES (f)));
@@ -1138,7 +1150,8 @@ x_change_tool_bar_height (struct frame *f, int height)
1138 /* Recalculate toolbar height. */ 1150 /* Recalculate toolbar height. */
1139 f->n_tool_bar_rows = 0; 1151 f->n_tool_bar_rows = 0;
1140 1152
1141 adjust_frame_size (f, -1, -1, 4, 0); 1153 adjust_frame_size (f, -1, -1, (old_height == 0 || height == 0) ? 2 : 4, 0,
1154 Qtool_bar_lines);
1142 1155
1143 if (FRAME_X_WINDOW (f)) 1156 if (FRAME_X_WINDOW (f))
1144 x_clear_under_internal_border (f); 1157 x_clear_under_internal_border (f);
@@ -1166,7 +1179,7 @@ x_set_internal_border_width (struct frame *f, Lisp_Object arg, Lisp_Object oldva
1166 1179
1167 if (FRAME_X_WINDOW (f) != 0) 1180 if (FRAME_X_WINDOW (f) != 0)
1168 { 1181 {
1169 adjust_frame_size (f, -1, -1, 3, 0); 1182 adjust_frame_size (f, -1, -1, 3, 0, Qinternal_border_width);
1170 1183
1171#ifdef USE_GTK 1184#ifdef USE_GTK
1172 xg_clear_under_internal_border (f); 1185 xg_clear_under_internal_border (f);
@@ -3163,7 +3176,7 @@ This function is an internal primitive--use `make-frame' instead. */)
3163 had one frame line vs one toolbar line which left us with a zero 3176 had one frame line vs one toolbar line which left us with a zero
3164 root window height which was obviously wrong as well ... */ 3177 root window height which was obviously wrong as well ... */
3165 adjust_frame_size (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f), 3178 adjust_frame_size (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f),
3166 FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 5, 1); 3179 FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 5, 1, Qnil);
3167 3180
3168 /* Set the menu-bar-lines and tool-bar-lines parameters. We don't 3181 /* Set the menu-bar-lines and tool-bar-lines parameters. We don't
3169 look up the X resources controlling the menu-bar and tool-bar 3182 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. */)
3237 /* Consider frame official, now. */ 3250 /* Consider frame official, now. */
3238 f->official = true; 3251 f->official = true;
3239 3252
3240 adjust_frame_size (f, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f), 0, 1); 3253 adjust_frame_size (f, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f), 0, 1, Qnil);
3241 3254
3242#if defined (USE_X_TOOLKIT) || defined (USE_GTK) 3255#if defined (USE_X_TOOLKIT) || defined (USE_GTK)
3243 /* Create the menu bar. */ 3256 /* Create the menu bar. */
@@ -4221,6 +4234,124 @@ Internal use only, use `display-monitor-attributes-list' instead. */)
4221 return attributes_list; 4234 return attributes_list;
4222} 4235}
4223 4236
4237DEFUN ("x-frame-geometry", Fx_frame_geometry, Sx_frame_geometry, 0, 1, 0,
4238 doc: /* Return geometric atributes of frame FRAME.
4239
4240FRAME must be a live frame and defaults to the selected one.
4241
4242The return value is an association list containing the following
4243elements (all size values are in pixels).
4244
4245- `frame-outer-size' is a cons of the outer width and height of FRAME.
4246 The outer size include the title bar and the external borders as well
4247 as any menu and/or tool bar of frame.
4248
4249- `border' is a cons of the horizontal and vertical width of FRAME's
4250 external borders.
4251
4252- `title-bar-height' is the height of the title bar of FRAME.
4253
4254- `menu-bar-external' if `t' means the menu bar is external (not
4255 included in the inner edges of FRAME).
4256
4257- `menu-bar-size' is a cons of the width and height of the menu bar of
4258 FRAME.
4259
4260- `tool-bar-external' if `t' means the tool bar is external (not
4261 included in the inner edges of FRAME).
4262
4263- `tool-bar-side' tells tells on which side the tool bar on FRAME is and
4264 can be one of `left', `top', `right' or `bottom'.
4265
4266- `tool-bar-size' is a cons of the width and height of the tool bar of
4267 FRAME.
4268
4269- `frame-inner-size' is a cons of the inner width and height of FRAME.
4270 This excludes FRAME's title bar and external border as well as any
4271 external menu and/or tool bar. */)
4272 (Lisp_Object frame)
4273{
4274 struct frame *f = decode_live_frame (frame);
4275 int inner_width = FRAME_PIXEL_WIDTH (f);
4276 int inner_height = FRAME_PIXEL_HEIGHT (f);
4277 int outer_width, outer_height, border, title;
4278 Lisp_Object fullscreen = Fframe_parameter (frame, Qfullscreen);
4279 int menu_bar_height, menu_bar_width, tool_bar_height, tool_bar_width;
4280
4281 border = FRAME_OUTER_TO_INNER_DIFF_X (f);
4282 title = FRAME_X_OUTPUT (f)->y_pixels_outer_diff - border;
4283
4284 outer_width = FRAME_PIXEL_WIDTH (f) + 2 * border;
4285 outer_height = (FRAME_PIXEL_HEIGHT (f)
4286 + FRAME_OUTER_TO_INNER_DIFF_Y (f)
4287 + FRAME_OUTER_TO_INNER_DIFF_X (f));
4288
4289#if defined (USE_GTK)
4290 {
4291 bool tool_bar_left_right = (EQ (FRAME_TOOL_BAR_POSITION (f), Qleft)
4292 || EQ (FRAME_TOOL_BAR_POSITION (f), Qright));
4293
4294 tool_bar_width = (tool_bar_left_right
4295 ? FRAME_TOOLBAR_WIDTH (f)
4296 : FRAME_PIXEL_WIDTH (f));
4297 tool_bar_height = (tool_bar_left_right
4298 ? FRAME_PIXEL_HEIGHT (f)
4299 : FRAME_TOOLBAR_HEIGHT (f));
4300 if (tool_bar_left_right)
4301 /* For some reason FRAME_OUTER_TO_INNER_DIFF_X does not count the
4302 width of a tool bar. */
4303 outer_width += FRAME_TOOLBAR_WIDTH (f);
4304 }
4305#else
4306 tool_bar_height = FRAME_TOOL_BAR_HEIGHT (f);
4307 tool_bar_width = ((tool_bar_height > 0)
4308 ? outer_width - 2 * FRAME_INTERNAL_BORDER_WIDTH (f)
4309 : 0);
4310#endif
4311
4312#if defined (USE_X_TOOLKIT) || defined (USE_GTK)
4313 menu_bar_height = FRAME_MENUBAR_HEIGHT (f);
4314#else
4315 menu_bar_height = FRAME_MENU_BAR_HEIGHT (f);
4316#endif
4317
4318 menu_bar_width = ((menu_bar_height > 0)
4319 ? outer_width - 2 * border
4320 : 0);
4321
4322 if (!FRAME_EXTERNAL_MENU_BAR (f))
4323 inner_height -= menu_bar_height;
4324 if (!FRAME_EXTERNAL_TOOL_BAR (f))
4325 inner_height -= tool_bar_height;
4326
4327 return
4328 listn (CONSTYPE_PURE, 10,
4329 Fcons (Qframe_position,
4330 Fcons (make_number (f->left_pos), make_number (f->top_pos))),
4331 Fcons (Qframe_outer_size,
4332 Fcons (make_number (outer_width), make_number (outer_height))),
4333 Fcons (Qexternal_border_size,
4334 ((EQ (fullscreen, Qfullboth) || EQ (fullscreen, Qfullscreen))
4335 ? Fcons (make_number (0), make_number (0))
4336 : Fcons (make_number (border), make_number (border)))),
4337 Fcons (Qtitle_height,
4338 ((EQ (fullscreen, Qfullboth) || EQ (fullscreen, Qfullscreen))
4339 ? make_number (0)
4340 : make_number (title))),
4341 Fcons (Qmenu_bar_external, FRAME_EXTERNAL_MENU_BAR (f) ? Qt : Qnil),
4342 Fcons (Qmenu_bar_size,
4343 Fcons (make_number (menu_bar_width),
4344 make_number (menu_bar_height))),
4345 Fcons (Qtool_bar_external, FRAME_EXTERNAL_TOOL_BAR (f) ? Qt : Qnil),
4346 Fcons (Qtool_bar_position, FRAME_TOOL_BAR_POSITION (f)),
4347 Fcons (Qtool_bar_size,
4348 Fcons (make_number (tool_bar_width),
4349 make_number (tool_bar_height))),
4350 Fcons (Qframe_inner_size,
4351 Fcons (make_number (inner_width),
4352 make_number (inner_height))));
4353}
4354
4224/************************************************************************ 4355/************************************************************************
4225 X Displays 4356 X Displays
4226 ************************************************************************/ 4357 ************************************************************************/
@@ -6224,6 +6355,7 @@ When using Gtk+ tooltips, the tooltip face is not used. */);
6224 defsubr (&Sx_display_backing_store); 6355 defsubr (&Sx_display_backing_store);
6225 defsubr (&Sx_display_save_under); 6356 defsubr (&Sx_display_save_under);
6226 defsubr (&Sx_display_monitor_attributes_list); 6357 defsubr (&Sx_display_monitor_attributes_list);
6358 defsubr (&Sx_frame_geometry);
6227 defsubr (&Sx_wm_set_size_hint); 6359 defsubr (&Sx_wm_set_size_hint);
6228 defsubr (&Sx_create_frame); 6360 defsubr (&Sx_create_frame);
6229 defsubr (&Sx_open_connection); 6361 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)
657 lw_refigure_widget (x->column_widget, True); 657 lw_refigure_widget (x->column_widget, True);
658 658
659 /* Force the pane widget to resize itself. */ 659 /* Force the pane widget to resize itself. */
660 adjust_frame_size (f, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f), 2, 0); 660#ifdef USE_LUCID
661 /* For reasons I don't know Lucid wants to add one pixel to the frame
662 height when adding the menu bar. Compensate that here. */
663 adjust_frame_size (f, -1, FRAME_TEXT_HEIGHT (f) - 1, 2, 0, Qmenu_bar_lines);
664#else
665 adjust_frame_size (f, -1, -1, 2, 0, Qmenu_bar_lines);
666#endif /* USE_LUCID */
661 unblock_input (); 667 unblock_input ();
662#endif 668#endif /* USE_GTK */
663} 669}
664 670
665#ifdef USE_LUCID 671#ifdef USE_LUCID
@@ -1050,6 +1056,12 @@ void
1050free_frame_menubar (struct frame *f) 1056free_frame_menubar (struct frame *f)
1051{ 1057{
1052 Widget menubar_widget; 1058 Widget menubar_widget;
1059#ifdef USE_MOTIF
1060 /* Motif automatically shrinks the frame in lw_destroy_all_widgets.
1061 If we want to preserve the old height, calculate it now so we can
1062 restore it below. */
1063 int old_height = FRAME_TEXT_HEIGHT (f) + FRAME_MENUBAR_HEIGHT (f);
1064#endif
1053 1065
1054 eassert (FRAME_X_P (f)); 1066 eassert (FRAME_X_P (f));
1055 1067
@@ -1087,17 +1099,20 @@ free_frame_menubar (struct frame *f)
1087 XtVaGetValues (f->output_data.x->widget, XtNx, &x1, XtNy, &y1, NULL); 1099 XtVaGetValues (f->output_data.x->widget, XtNx, &x1, XtNy, &y1, NULL);
1088 if (x1 == 0 && y1 == 0) 1100 if (x1 == 0 && y1 == 0)
1089 XtVaSetValues (f->output_data.x->widget, XtNx, x0, XtNy, y0, NULL); 1101 XtVaSetValues (f->output_data.x->widget, XtNx, x0, XtNy, y0, NULL);
1090#endif 1102 if (frame_inhibit_resize (f, 0, Qmenu_bar_lines))
1091 adjust_frame_size (f, FRAME_TEXT_WIDTH (f), 1103 adjust_frame_size (f, -1, old_height, 1, 0, Qmenu_bar_lines);
1092 FRAME_TEXT_HEIGHT (f), 2, 0);
1093 /*
1094 if (frame_inhibit_resize (f, 0))
1095 change_frame_size (f, 0, 0, 0, 0, 0, 1);
1096 else 1104 else
1097 x_set_window_size (f, 0, FRAME_TEXT_WIDTH (f), 1105#endif /* USE_MOTIF */
1098 FRAME_TEXT_HEIGHT (f), 1); 1106 adjust_frame_size (f, -1, -1, 2, 0, Qmenu_bar_lines);
1099 */
1100 } 1107 }
1108 else
1109 {
1110#ifdef USE_MOTIF
1111 if (frame_inhibit_resize (f, 0, Qmenu_bar_lines))
1112 adjust_frame_size (f, -1, old_height, 1, 0, Qmenu_bar_lines);
1113#endif
1114 }
1115
1101 unblock_input (); 1116 unblock_input ();
1102 } 1117 }
1103} 1118}
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)
8662 doing it because it's done in Fx_show_tip, and it leads to 8662 doing it because it's done in Fx_show_tip, and it leads to
8663 problems because the tip frame has no widget. */ 8663 problems because the tip frame has no widget. */
8664 if (NILP (tip_frame) || XFRAME (tip_frame) != f) 8664 if (NILP (tip_frame) || XFRAME (tip_frame) != f)
8665 x_set_window_size (f, 0, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f), 8665 adjust_frame_size (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f),
8666 FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 1); 8666 FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 3,
8667 0, Qfont);
8667 } 8668 }
8668 8669
8669#ifdef HAVE_X_I18N 8670#ifdef HAVE_X_I18N