aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMartin Rudalics2015-10-13 12:11:43 +0200
committerMartin Rudalics2015-10-13 12:11:43 +0200
commitd4fe840df0b5fdb3aed538fae2ced143a471f60a (patch)
tree13ff9d7115616a99af7e0257277a1ca6edf31f72 /src
parente53e1a0426539aa3f2902632fdd8025da8f710f2 (diff)
downloademacs-d4fe840df0b5fdb3aed538fae2ced143a471f60a.tar.gz
emacs-d4fe840df0b5fdb3aed538fae2ced143a471f60a.zip
Allow setting frame pixel sizes from frame parameters (Bug#21415)
Also fix some misfeatures in frame (re-)sizing code, add more debugging information and remove some dead code. * lisp/frame.el (frame-notice-user-settings, make-frame): Change parameter names when setting `frame-size-history'. (frame--size-history): New function. * src/frame.c (frame_inhibit_resize): If frame has not been made yet, return t if inhibit_horizontal_resize or inhibit_vertical_resize bit have been set. (adjust_frame_size): Simplify. (make_frame): Initialize inhibit_horizontal_resize, inhibit_vertical_resize, tool_bar_redisplayed, tool_bar_resized. (Fframe_after_make_frame): Reset inhibit_horizontal_resize and inhibit_vertical_resize slots. (x_set_frame_parameters): Handle `text-pixels' specification for width and height parameters. Don't consider new_height or new_width changes. Call adjust_frame_size instead of Fset_frame_size. (x_figure_window_size): Two new arguments x_width and y_width returning frame's figures width and height. Calculate tool bar height before frame sizes so SET_FRAME_HEIGHT can pick it up. Handle `text-pixels' specification for width and height parameters. (Qtext_pixels, Qx_set_frame_parameters, Qset_frame_size) (Qx_set_window_size_1, Qx_set_window_size_2) (Qx_set_window_size_3, Qx_set_menu_bar_lines) (Qupdate_frame_menubar, Qfree_frame_menubar_1) (Qfree_frame_menubar_2): New symbols. * src/frame.h (structure frame): New booleans tool_bar_redisplayed, tool_bar_resized, inhibit_horizontal_resize, inhibit_vertical_resize. (x_figure_window_size): Update external declaration. * src/gtkutil.c (xg_frame_set_char_size): Set size hints before calling gtk_window_resize. (update_frame_tool_bar): Make inhibiting of frame resizing more discriminative. Set tool_bar_resized bit. * src/nsfns.m (x_set_tool_bar_lines): Make inhibiting of frame resizing more discriminative. Call adjust_frame_size instead of x_set_window_size. (Fx_create_frame): Handle x_width and x_height if set by x_figure_window_size. * src/nsterm.m (x_set_window_size): For GNUSTEP build don't subtract 3 from tool bar height. (x_set_window_size): Add frame_size_history_add call. (x_new_font): Call adjust_frame_size instead of x_set_window_size. * src/w32fns.c (x_change_tool_bar_height): Reset tool_bar_redisplayed and tool_bar_resized bits when adding tool bar. Make inhibiting of frame resizing more discriminative. (w32_wnd_proc): Remove dead code in WM_WINDOWPOSCHANGING case. (Fx_create_frame): Handle x_width and x_height if set by x_figure_window_size. Set size hints before adjusting frame size. (x_create_tip_frame): Adjust x_figure_window_size call. * src/w32term.c (x_set_window_size): Add frame_size_history_add call. * src/widget.c (set_frame_size): Remove dead code. Add frame_size_history_add call. When frame_resize_pixelwise is t use FRAME_PIXEL_WIDTH and FRAME_PIXEL_HEIGHT instead of pixel_width and pixel_height. (update_various_frame_slots): Remove dead code. (EmacsFrameResize): Add more information in frame_size_history_add call. (EmacsFrameQueryGeometry): Round only when frame_resize_pixelwise is not set. * src/xdisp.c (redisplay_tool_bar): Set tool_bar_redisplayed bits. * src/xfns.c (x_set_menu_bar_lines): Change argument name. (x_change_tool_bar_height): Reset tool_bar_redisplayed and tool_bar_resized bits when adding tool bar. Make inhibiting of frame resizing more discriminative. (Fx_create_frame): Handle x_width and x_height if set by x_figure_window_size. Set size hints before adjusting frame size. (x_create_tip_frame): Adjust x_figure_window_size call. * src/xmenu.c (update_frame_menubar): Don't handle Lucid specially. (set_frame_menubar): On Lucid never add core-border-width to avoid that adding XtNinternalBorderWidth adds it again. (free_frame_menubar): Handle frame_inhibit_resize true for Motif. * src/xterm.c (x_new_font): In non-toolkit case handle size change of menu bar. (x_set_window_size_1): Fix calls to frame_size_history_add. (x_wm_set_size_hint): Remove dead code. Set size_hints.min_width and size_hints.min_height to base_width and base_height.
Diffstat (limited to 'src')
-rw-r--r--src/frame.c221
-rw-r--r--src/frame.h10
-rw-r--r--src/gtkutil.c40
-rw-r--r--src/nsfns.m26
-rw-r--r--src/nsterm.m16
-rw-r--r--src/w32fns.c121
-rw-r--r--src/w32term.c7
-rw-r--r--src/widget.c196
-rw-r--r--src/xdisp.c1
-rw-r--r--src/xfns.c39
-rw-r--r--src/xmenu.c34
-rw-r--r--src/xterm.c52
12 files changed, 340 insertions, 423 deletions
diff --git a/src/frame.c b/src/frame.c
index 77ead082ce2..98a7a57a988 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -184,16 +184,17 @@ frame_inhibit_resize (struct frame *f, bool horizontal, Lisp_Object parameter)
184{ 184{
185 Lisp_Object fullscreen = get_frame_param (f, Qfullscreen); 185 Lisp_Object fullscreen = get_frame_param (f, Qfullscreen);
186 bool inhibit 186 bool inhibit
187 = ((f->after_make_frame 187 = (f->after_make_frame
188 && (EQ (frame_inhibit_implied_resize, Qt) 188 ? (EQ (frame_inhibit_implied_resize, Qt)
189 || (CONSP (frame_inhibit_implied_resize) 189 || (CONSP (frame_inhibit_implied_resize)
190 && !NILP (Fmemq (parameter, frame_inhibit_implied_resize))))) 190 && !NILP (Fmemq (parameter, frame_inhibit_implied_resize)))
191 || (horizontal 191 || (horizontal
192 && !EQ (fullscreen, Qnil) && !EQ (fullscreen, Qfullheight)) 192 && !EQ (fullscreen, Qnil) && !EQ (fullscreen, Qfullheight))
193 || (!horizontal 193 || (!horizontal
194 && !EQ (fullscreen, Qnil) && !EQ (fullscreen, Qfullwidth)) 194 && !EQ (fullscreen, Qnil) && !EQ (fullscreen, Qfullwidth))
195 || FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f)); 195 || FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f))
196 196 : ((horizontal && f->inhibit_horizontal_resize)
197 || (!horizontal && f->inhibit_vertical_resize)));
197 if (inhibit && !FRAME_TERMCAP_P (f) && !FRAME_MSDOS_P (f)) 198 if (inhibit && !FRAME_TERMCAP_P (f) && !FRAME_MSDOS_P (f))
198 frame_size_history_add 199 frame_size_history_add
199 (f, Qframe_inhibit_resize, 0, 0, 200 (f, Qframe_inhibit_resize, 0, 0,
@@ -425,17 +426,15 @@ adjust_frame_size (struct frame *f, int new_width, int new_height, int inhibit,
425 426
426 if (inhibit >= 2 && inhibit <= 4) 427 if (inhibit >= 2 && inhibit <= 4)
427 /* When INHIBIT is in [2..4] inhibit if the "old" window sizes stay 428 /* When INHIBIT is in [2..4] inhibit if the "old" window sizes stay
428 within the limits and either frame_inhibit_resize tells us to do 429 within the limits and either resizing is inhibited or INHIBIT
429 so or INHIBIT equals 4. */ 430 equals 4. */
430 { 431 {
431 inhibit_horizontal = ((windows_width >= min_windows_width 432 inhibit_horizontal = (windows_width >= min_windows_width
432 && (inhibit == 4 433 && (inhibit == 4
433 || frame_inhibit_resize (f, true, parameter))) 434 || frame_inhibit_resize (f, true, parameter)));
434 ? true : false); 435 inhibit_vertical = (windows_height >= min_windows_height
435 inhibit_vertical = ((windows_height >= min_windows_height 436 && (inhibit == 4
436 && (inhibit == 4 437 || frame_inhibit_resize (f, false, parameter)));
437 || frame_inhibit_resize (f, false, parameter)))
438 ? true : false);
439 } 438 }
440 else 439 else
441 /* Otherwise inhibit if INHIBIT equals 5. */ 440 /* Otherwise inhibit if INHIBIT equals 5. */
@@ -634,6 +633,10 @@ make_frame (bool mini_p)
634 f->garbaged = true; 633 f->garbaged = true;
635 f->can_x_set_window_size = false; 634 f->can_x_set_window_size = false;
636 f->after_make_frame = false; 635 f->after_make_frame = false;
636 f->inhibit_horizontal_resize = false;
637 f->inhibit_vertical_resize = false;
638 f->tool_bar_redisplayed = false;
639 f->tool_bar_resized = false;
637 f->column_width = 1; /* !FRAME_WINDOW_P value. */ 640 f->column_width = 1; /* !FRAME_WINDOW_P value. */
638 f->line_height = 1; /* !FRAME_WINDOW_P value. */ 641 f->line_height = 1; /* !FRAME_WINDOW_P value. */
639#ifdef HAVE_WINDOW_SYSTEM 642#ifdef HAVE_WINDOW_SYSTEM
@@ -2303,6 +2306,8 @@ otherwise used with utter care to avoid that running functions on
2303{ 2306{
2304 struct frame *f = decode_live_frame (frame); 2307 struct frame *f = decode_live_frame (frame);
2305 f->after_make_frame = !NILP (made); 2308 f->after_make_frame = !NILP (made);
2309 f->inhibit_horizontal_resize = false;
2310 f->inhibit_vertical_resize = false;
2306 return made; 2311 return made;
2307} 2312}
2308 2313
@@ -3166,15 +3171,33 @@ x_set_frame_parameters (struct frame *f, Lisp_Object alist)
3166 prop = parms[i]; 3171 prop = parms[i];
3167 val = values[i]; 3172 val = values[i];
3168 3173
3169 if (EQ (prop, Qwidth) && RANGED_INTEGERP (0, val, INT_MAX)) 3174 if (EQ (prop, Qwidth))
3170 { 3175 {
3171 width_change = 1; 3176 if (RANGED_INTEGERP (0, val, INT_MAX))
3172 width = XFASTINT (val) * FRAME_COLUMN_WIDTH (f) ; 3177 {
3178 width = XFASTINT (val) * FRAME_COLUMN_WIDTH (f) ;
3179 width_change = true;
3180 }
3181 else if (CONSP (val) && EQ (XCAR (val), Qtext_pixels)
3182 && RANGED_INTEGERP (0, XCDR (val), INT_MAX))
3183 {
3184 width = XFASTINT (XCDR (val));
3185 width_change = true;
3186 }
3173 } 3187 }
3174 else if (EQ (prop, Qheight) && RANGED_INTEGERP (0, val, INT_MAX)) 3188 else if (EQ (prop, Qheight))
3175 { 3189 {
3176 height_change = 1; 3190 if (RANGED_INTEGERP (0, val, INT_MAX))
3177 height = XFASTINT (val) * FRAME_LINE_HEIGHT (f); 3191 {
3192 height = XFASTINT (val) * FRAME_LINE_HEIGHT (f);
3193 height_change = true;
3194 }
3195 else if (CONSP (val) && EQ (XCAR (val), Qtext_pixels)
3196 && RANGED_INTEGERP (0, XCDR (val), INT_MAX))
3197 {
3198 height = XFASTINT (XCDR (val));
3199 height_change = true;
3200 }
3178 } 3201 }
3179 else if (EQ (prop, Qtop)) 3202 else if (EQ (prop, Qtop))
3180 top = val; 3203 top = val;
@@ -3262,28 +3285,15 @@ x_set_frame_parameters (struct frame *f, Lisp_Object alist)
3262 XSETFRAME (frame, f); 3285 XSETFRAME (frame, f);
3263 3286
3264 if ((width_change && width != FRAME_TEXT_WIDTH (f)) 3287 if ((width_change && width != FRAME_TEXT_WIDTH (f))
3265 || (height_change && height != FRAME_TEXT_HEIGHT (f)) 3288 || (height_change && height != FRAME_TEXT_HEIGHT (f)))
3266 || (f->can_x_set_window_size && (f->new_height || f->new_width))) 3289 /* We could consider checking f->after_make_frame here, but I
3267 { 3290 don't have the faintest idea why the following is needed at
3268 /* If necessary provide default values for HEIGHT and WIDTH. Do 3291 all. With the old setting it can get a Heisenbug when
3269 that here since otherwise a size change implied by an 3292 EmacsFrameResize intermittently provokes a delayed
3270 intermittent font change may get lost as in Bug#17142. */ 3293 change_frame_size in the middle of adjust_frame_size. */
3271 if (!width_change) 3294 /** || (f->can_x_set_window_size && (f->new_height || f->new_width))) **/
3272 width = ((f->can_x_set_window_size && f->new_width) 3295 adjust_frame_size (f, width_change ? width : -1,
3273 ? (f->new_pixelwise 3296 height_change ? height : -1, 1, 0, Qx_set_frame_parameters);
3274 ? f->new_width
3275 : (f->new_width * FRAME_COLUMN_WIDTH (f)))
3276 : FRAME_TEXT_WIDTH (f));
3277
3278 if (!height_change)
3279 height = ((f->can_x_set_window_size && f->new_height)
3280 ? (f->new_pixelwise
3281 ? f->new_height
3282 : (f->new_height * FRAME_LINE_HEIGHT (f)))
3283 : FRAME_TEXT_HEIGHT (f));
3284
3285 Fset_frame_size (frame, make_number (width), make_number (height), Qt);
3286 }
3287 3297
3288 if ((!NILP (left) || !NILP (top)) 3298 if ((!NILP (left) || !NILP (top))
3289 && ! (left_no_change && top_no_change) 3299 && ! (left_no_change && top_no_change)
@@ -4552,7 +4562,7 @@ On Nextstep, this just calls `ns-parse-geometry'. */)
4552#define DEFAULT_COLS 80 4562#define DEFAULT_COLS 80
4553 4563
4554long 4564long
4555x_figure_window_size (struct frame *f, Lisp_Object parms, bool toolbar_p) 4565x_figure_window_size (struct frame *f, Lisp_Object parms, bool toolbar_p, int *x_width, int *x_height)
4556{ 4566{
4557 Lisp_Object height, width, user_size, top, left, user_position; 4567 Lisp_Object height, width, user_size, top, left, user_position;
4558 long window_prompting = 0; 4568 long window_prompting = 0;
@@ -4571,44 +4581,11 @@ x_figure_window_size (struct frame *f, Lisp_Object parms, bool toolbar_p)
4571 f->top_pos = 0; 4581 f->top_pos = 0;
4572 f->left_pos = 0; 4582 f->left_pos = 0;
4573 4583
4574 /* Ensure that earlier new_width and new_height settings won't 4584 /* Calculate a tool bar height so that the user gets a text display
4575 override what we specify below. */ 4585 area of the size he specified with -g or via .Xdefaults. Later
4576 f->new_width = f->new_height = 0; 4586 changes of the tool bar height don't change the frame size. This
4577 4587 is done so that users can create tall Emacs frames without having
4578 height = x_get_arg (dpyinfo, parms, Qheight, 0, 0, RES_TYPE_NUMBER); 4588 to guess how tall the tool bar will get. */
4579 width = x_get_arg (dpyinfo, parms, Qwidth, 0, 0, RES_TYPE_NUMBER);
4580 if (!EQ (width, Qunbound) || !EQ (height, Qunbound))
4581 {
4582 if (!EQ (width, Qunbound))
4583 {
4584 CHECK_NUMBER (width);
4585 if (! (0 <= XINT (width) && XINT (width) <= INT_MAX))
4586 xsignal1 (Qargs_out_of_range, width);
4587
4588 SET_FRAME_WIDTH (f, XINT (width) * FRAME_COLUMN_WIDTH (f));
4589 }
4590
4591 if (!EQ (height, Qunbound))
4592 {
4593 CHECK_NUMBER (height);
4594 if (! (0 <= XINT (height) && XINT (height) <= INT_MAX))
4595 xsignal1 (Qargs_out_of_range, height);
4596
4597 SET_FRAME_HEIGHT (f, XINT (height) * FRAME_LINE_HEIGHT (f));
4598 }
4599
4600 user_size = x_get_arg (dpyinfo, parms, Quser_size, 0, 0, RES_TYPE_NUMBER);
4601 if (!NILP (user_size) && !EQ (user_size, Qunbound))
4602 window_prompting |= USSize;
4603 else
4604 window_prompting |= PSize;
4605 }
4606
4607 /* Add a tool bar height to the initial frame height so that the user
4608 gets a text display area of the size he specified with -g or via
4609 .Xdefaults. Later changes of the tool bar height don't change the
4610 frame size. This is done so that users can create tall Emacs
4611 frames without having to guess how tall the tool bar will get. */
4612 if (toolbar_p && FRAME_TOOL_BAR_LINES (f)) 4589 if (toolbar_p && FRAME_TOOL_BAR_LINES (f))
4613 { 4590 {
4614 if (frame_default_tool_bar_height) 4591 if (frame_default_tool_bar_height)
@@ -4634,6 +4611,65 @@ x_figure_window_size (struct frame *f, Lisp_Object parms, bool toolbar_p)
4634 } 4611 }
4635 } 4612 }
4636 4613
4614 /* Ensure that earlier new_width and new_height settings won't
4615 override what we specify below. */
4616 f->new_width = f->new_height = 0;
4617
4618 height = x_get_arg (dpyinfo, parms, Qheight, 0, 0, RES_TYPE_NUMBER);
4619 width = x_get_arg (dpyinfo, parms, Qwidth, 0, 0, RES_TYPE_NUMBER);
4620 if (!EQ (width, Qunbound) || !EQ (height, Qunbound))
4621 {
4622 if (!EQ (width, Qunbound))
4623 {
4624 if (CONSP (width) && EQ (XCAR (width), Qtext_pixels))
4625 {
4626 CHECK_NUMBER (XCDR (width));
4627 if ((XINT (XCDR (width)) < 0 || XINT (XCDR (width)) > INT_MAX))
4628 xsignal1 (Qargs_out_of_range, XCDR (width));
4629
4630 SET_FRAME_WIDTH (f, XINT (XCDR (width)));
4631 f->inhibit_horizontal_resize = true;
4632 *x_width = XINT (XCDR (width));
4633 }
4634 else
4635 {
4636 CHECK_NUMBER (width);
4637 if ((XINT (width) < 0 || XINT (width) > INT_MAX))
4638 xsignal1 (Qargs_out_of_range, width);
4639
4640 SET_FRAME_WIDTH (f, XINT (width) * FRAME_COLUMN_WIDTH (f));
4641 }
4642 }
4643
4644 if (!EQ (height, Qunbound))
4645 {
4646 if (CONSP (height) && EQ (XCAR (height), Qtext_pixels))
4647 {
4648 CHECK_NUMBER (XCDR (height));
4649 if ((XINT (XCDR (height)) < 0 || XINT (XCDR (height)) > INT_MAX))
4650 xsignal1 (Qargs_out_of_range, XCDR (height));
4651
4652 SET_FRAME_HEIGHT (f, XINT (XCDR (height)));
4653 f->inhibit_vertical_resize = true;
4654 *x_height = XINT (XCDR (height));
4655 }
4656 else
4657 {
4658 CHECK_NUMBER (height);
4659 if ((XINT (height) < 0) || (XINT (height) > INT_MAX))
4660 xsignal1 (Qargs_out_of_range, height);
4661
4662 SET_FRAME_HEIGHT (f, XINT (height) * FRAME_LINE_HEIGHT (f));
4663 }
4664 }
4665
4666 user_size = x_get_arg (dpyinfo, parms, Quser_size, 0, 0, RES_TYPE_NUMBER);
4667 if (!NILP (user_size) && !EQ (user_size, Qunbound))
4668 window_prompting |= USSize;
4669 else
4670 window_prompting |= PSize;
4671 }
4672
4637 top = x_get_arg (dpyinfo, parms, Qtop, 0, 0, RES_TYPE_NUMBER); 4673 top = x_get_arg (dpyinfo, parms, Qtop, 0, 0, RES_TYPE_NUMBER);
4638 left = x_get_arg (dpyinfo, parms, Qleft, 0, 0, RES_TYPE_NUMBER); 4674 left = x_get_arg (dpyinfo, parms, Qleft, 0, 0, RES_TYPE_NUMBER);
4639 user_position = x_get_arg (dpyinfo, parms, Quser_position, 0, 0, RES_TYPE_NUMBER); 4675 user_position = x_get_arg (dpyinfo, parms, Quser_position, 0, 0, RES_TYPE_NUMBER);
@@ -4852,6 +4888,7 @@ syms_of_frame (void)
4852 DEFSYM (Qonly, "only"); 4888 DEFSYM (Qonly, "only");
4853 DEFSYM (Qnone, "none"); 4889 DEFSYM (Qnone, "none");
4854 DEFSYM (Qwidth, "width"); 4890 DEFSYM (Qwidth, "width");
4891 DEFSYM (Qtext_pixels, "text-pixels");
4855 DEFSYM (Qgeometry, "geometry"); 4892 DEFSYM (Qgeometry, "geometry");
4856 DEFSYM (Qicon_left, "icon-left"); 4893 DEFSYM (Qicon_left, "icon-left");
4857 DEFSYM (Qicon_top, "icon-top"); 4894 DEFSYM (Qicon_top, "icon-top");
@@ -4909,7 +4946,9 @@ syms_of_frame (void)
4909 DEFSYM (Qadjust_frame_size_1, "adjust-frame-size-1"); 4946 DEFSYM (Qadjust_frame_size_1, "adjust-frame-size-1");
4910 DEFSYM (Qadjust_frame_size_2, "adjust-frame-size-2"); 4947 DEFSYM (Qadjust_frame_size_2, "adjust-frame-size-2");
4911 DEFSYM (Qadjust_frame_size_3, "adjust-frame-size-3"); 4948 DEFSYM (Qadjust_frame_size_3, "adjust-frame-size-3");
4949 DEFSYM (Qx_set_frame_parameters, "x-set-frame-parameters");
4912 DEFSYM (QEmacsFrameResize, "EmacsFrameResize"); 4950 DEFSYM (QEmacsFrameResize, "EmacsFrameResize");
4951 DEFSYM (Qset_frame_size, "set-frame-size");
4913 DEFSYM (Qframe_inhibit_resize, "frame-inhibit-resize"); 4952 DEFSYM (Qframe_inhibit_resize, "frame-inhibit-resize");
4914 DEFSYM (Qx_set_fullscreen, "x-set-fullscreen"); 4953 DEFSYM (Qx_set_fullscreen, "x-set-fullscreen");
4915 DEFSYM (Qx_check_fullscreen, "x-check-fullscreen"); 4954 DEFSYM (Qx_check_fullscreen, "x-check-fullscreen");
@@ -4917,13 +4956,16 @@ syms_of_frame (void)
4917 DEFSYM (Qxg_frame_set_char_size_1, "xg-frame-set-char-size-1"); 4956 DEFSYM (Qxg_frame_set_char_size_1, "xg-frame-set-char-size-1");
4918 DEFSYM (Qxg_frame_set_char_size_2, "xg-frame-set-char-size-2"); 4957 DEFSYM (Qxg_frame_set_char_size_2, "xg-frame-set-char-size-2");
4919 DEFSYM (Qxg_frame_set_char_size_3, "xg-frame-set-char-size-3"); 4958 DEFSYM (Qxg_frame_set_char_size_3, "xg-frame-set-char-size-3");
4959 DEFSYM (Qx_set_window_size_1, "x-set-window-size-1");
4960 DEFSYM (Qx_set_window_size_2, "x-set-window-size-2");
4961 DEFSYM (Qx_set_window_size_3, "x-set-window-size-3");
4920 DEFSYM (Qxg_change_toolbar_position, "xg-change-toolbar-position"); 4962 DEFSYM (Qxg_change_toolbar_position, "xg-change-toolbar-position");
4921 DEFSYM (Qx_net_wm_state, "x-net-wm-state"); 4963 DEFSYM (Qx_net_wm_state, "x-net-wm-state");
4922 DEFSYM (Qx_handle_net_wm_state, "x-handle-net-wm-state"); 4964 DEFSYM (Qx_handle_net_wm_state, "x-handle-net-wm-state");
4923 DEFSYM (Qtb_size_cb, "tb-size-cb"); 4965 DEFSYM (Qtb_size_cb, "tb-size-cb");
4924 DEFSYM (Qupdate_frame_tool_bar, "update-frame-tool-bar"); 4966 DEFSYM (Qupdate_frame_tool_bar, "update-frame-tool-bar");
4925 DEFSYM (Qfree_frame_tool_bar, "free-frame-tool-bar"); 4967 DEFSYM (Qfree_frame_tool_bar, "free-frame-tool-bar");
4926 4968 DEFSYM (Qx_set_menu_bar_lines, "x-set-menu-bar-lines");
4927 DEFSYM (Qchange_frame_size, "change-frame-size"); 4969 DEFSYM (Qchange_frame_size, "change-frame-size");
4928 DEFSYM (Qxg_frame_set_char_size, "xg-frame-set-char-size"); 4970 DEFSYM (Qxg_frame_set_char_size, "xg-frame-set-char-size");
4929 DEFSYM (Qset_window_configuration, "set-window-configuration"); 4971 DEFSYM (Qset_window_configuration, "set-window-configuration");
@@ -4952,6 +4994,9 @@ syms_of_frame (void)
4952 DEFSYM (Qleft_fringe, "left-fringe"); 4994 DEFSYM (Qleft_fringe, "left-fringe");
4953 DEFSYM (Qline_spacing, "line-spacing"); 4995 DEFSYM (Qline_spacing, "line-spacing");
4954 DEFSYM (Qmenu_bar_lines, "menu-bar-lines"); 4996 DEFSYM (Qmenu_bar_lines, "menu-bar-lines");
4997 DEFSYM (Qupdate_frame_menubar, "update-frame-menubar");
4998 DEFSYM (Qfree_frame_menubar_1, "free-frame-menubar-1");
4999 DEFSYM (Qfree_frame_menubar_2, "free-frame-menubar-2");
4955 DEFSYM (Qmouse_color, "mouse-color"); 5000 DEFSYM (Qmouse_color, "mouse-color");
4956 DEFSYM (Qname, "name"); 5001 DEFSYM (Qname, "name");
4957 DEFSYM (Qright_divider_width, "right-divider-width"); 5002 DEFSYM (Qright_divider_width, "right-divider-width");
diff --git a/src/frame.h b/src/frame.h
index af0dadb3d99..acac51448d4 100644
--- a/src/frame.h
+++ b/src/frame.h
@@ -335,6 +335,14 @@ struct frame
335 /* Set to true after this frame was made by `make-frame'. */ 335 /* Set to true after this frame was made by `make-frame'. */
336 bool_bf after_make_frame : 1; 336 bool_bf after_make_frame : 1;
337 337
338 /* Whether the tool bar height change should be taken into account. */
339 bool_bf tool_bar_redisplayed : 1;
340 bool_bf tool_bar_resized : 1;
341
342 /* Inhibit implied resize before after_make_frame is set. */
343 bool_bf inhibit_horizontal_resize : 1;
344 bool_bf inhibit_vertical_resize : 1;
345
338 /* Non-zero if this frame's faces need to be recomputed. */ 346 /* Non-zero if this frame's faces need to be recomputed. */
339 bool_bf face_change : 1; 347 bool_bf face_change : 1;
340 348
@@ -1375,7 +1383,7 @@ extern void x_set_horizontal_scroll_bars (struct frame *, Lisp_Object, Lisp_Obje
1375extern void x_set_scroll_bar_width (struct frame *, Lisp_Object, Lisp_Object); 1383extern void x_set_scroll_bar_width (struct frame *, Lisp_Object, Lisp_Object);
1376extern void x_set_scroll_bar_height (struct frame *, Lisp_Object, Lisp_Object); 1384extern void x_set_scroll_bar_height (struct frame *, Lisp_Object, Lisp_Object);
1377 1385
1378extern long x_figure_window_size (struct frame *, Lisp_Object, bool); 1386extern long x_figure_window_size (struct frame *, Lisp_Object, bool, int *, int *);
1379 1387
1380extern void x_set_alpha (struct frame *, Lisp_Object, Lisp_Object); 1388extern void x_set_alpha (struct frame *, Lisp_Object, Lisp_Object);
1381 1389
diff --git a/src/gtkutil.c b/src/gtkutil.c
index 34e81b5c104..ad71b9ccbcb 100644
--- a/src/gtkutil.c
+++ b/src/gtkutil.c
@@ -951,6 +951,8 @@ xg_frame_set_char_size (struct frame *f, int width, int height)
951 totalwidth /= scale; 951 totalwidth /= scale;
952 } 952 }
953 953
954 x_wm_set_size_hint (f, 0, 0);
955
954 /* Resize the top level widget so rows and columns remain constant. 956 /* Resize the top level widget so rows and columns remain constant.
955 957
956 When the frame is fullheight and we only want to change the width 958 When the frame is fullheight and we only want to change the width
@@ -964,41 +966,34 @@ xg_frame_set_char_size (struct frame *f, int width, int height)
964 { 966 {
965 frame_size_history_add 967 frame_size_history_add
966 (f, Qxg_frame_set_char_size_1, width, height, 968 (f, Qxg_frame_set_char_size_1, width, height,
967 list2 (make_number (gheight), 969 list2 (make_number (gheight), make_number (totalheight)));
968 make_number (totalheight)));
969 970
970 gtk_window_resize (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), 971 gtk_window_resize (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
971 gwidth, 972 gwidth, totalheight);
972 totalheight);
973 } 973 }
974 else if (EQ (fullscreen, Qfullheight) && height == FRAME_TEXT_HEIGHT (f)) 974 else if (EQ (fullscreen, Qfullheight) && height == FRAME_TEXT_HEIGHT (f))
975 { 975 {
976 frame_size_history_add 976 frame_size_history_add
977 (f, Qxg_frame_set_char_size_2, width, height, 977 (f, Qxg_frame_set_char_size_2, width, height,
978 list2 (make_number (gwidth), 978 list2 (make_number (gwidth), make_number (totalwidth)));
979 make_number (totalwidth)));
980 979
981 gtk_window_resize (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), 980 gtk_window_resize (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
982 totalwidth, 981 totalwidth, gheight);
983 gheight);
984 } 982 }
985 else 983 else
986 { 984 {
987 frame_size_history_add 985 frame_size_history_add
988 (f, Qxg_frame_set_char_size_3, width, height, 986 (f, Qxg_frame_set_char_size_3, width, height,
989 list2 (make_number (totalwidth), 987 list2 (make_number (totalwidth), make_number (totalheight)));
990 make_number (totalheight)));
991 988
992 gtk_window_resize (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), 989 gtk_window_resize (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
993 totalwidth, 990 totalwidth, totalheight);
994 totalheight);
995 fullscreen = Qnil; 991 fullscreen = Qnil;
996 } 992 }
997 993
998 SET_FRAME_GARBAGED (f); 994 SET_FRAME_GARBAGED (f);
999 cancel_mouse_face (f); 995 cancel_mouse_face (f);
1000 996
1001 x_wm_set_size_hint (f, 0, 0);
1002 /* We can not call change_frame_size for a mapped frame, 997 /* We can not call change_frame_size for a mapped frame,
1003 we can not set pixel width/height either. The window manager may 998 we can not set pixel width/height either. The window manager may
1004 override our resize request, XMonad does this all the time. 999 override our resize request, XMonad does this all the time.
@@ -1399,7 +1394,8 @@ x_wm_set_size_hint (struct frame *f, long int flags, bool user_position)
1399 1394
1400 hint_flags |= GDK_HINT_BASE_SIZE; 1395 hint_flags |= GDK_HINT_BASE_SIZE;
1401 /* Use one row/col here so base_height/width does not become zero. 1396 /* Use one row/col here so base_height/width does not become zero.
1402 Gtk+ and/or Unity on Ubuntu 12.04 can't handle it. */ 1397 Gtk+ and/or Unity on Ubuntu 12.04 can't handle it.
1398 Obviously this makes the row/col value displayed off by 1. */
1403 base_width = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, 1) + FRAME_TOOLBAR_WIDTH (f); 1399 base_width = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, 1) + FRAME_TOOLBAR_WIDTH (f);
1404 base_height = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, 1) 1400 base_height = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, 1)
1405 + FRAME_MENUBAR_HEIGHT (f) + FRAME_TOOLBAR_HEIGHT (f); 1401 + FRAME_MENUBAR_HEIGHT (f) + FRAME_TOOLBAR_HEIGHT (f);
@@ -4998,9 +4994,23 @@ update_frame_tool_bar (struct frame *f)
4998 gtk_widget_show_all (x->toolbar_widget); 4994 gtk_widget_show_all (x->toolbar_widget);
4999 if (xg_update_tool_bar_sizes (f)) 4995 if (xg_update_tool_bar_sizes (f))
5000 { 4996 {
4997 int inhibit
4998 = ((f->after_make_frame
4999 && !f->tool_bar_resized
5000 && (EQ (frame_inhibit_implied_resize, Qt)
5001 || (CONSP (frame_inhibit_implied_resize)
5002 && !NILP (Fmemq (Qtool_bar_lines,
5003 frame_inhibit_implied_resize))))
5004 /* This will probably fail to DTRT in the
5005 fullheight/-width cases. */
5006 && NILP (get_frame_param (f, Qfullscreen)))
5007 ? 0
5008 : 2);
5009
5001 frame_size_history_add (f, Qupdate_frame_tool_bar, 0, 0, Qnil); 5010 frame_size_history_add (f, Qupdate_frame_tool_bar, 0, 0, Qnil);
5002 adjust_frame_size (f, -1, -1, 2, 0, Qtool_bar_lines); 5011 adjust_frame_size (f, -1, -1, inhibit, 0, Qtool_bar_lines);
5003 } 5012 }
5013 f->tool_bar_resized = f->tool_bar_redisplayed;
5004 } 5014 }
5005 5015
5006 unblock_input (); 5016 unblock_input ();
diff --git a/src/nsfns.m b/src/nsfns.m
index ad71a508248..43002ca6fef 100644
--- a/src/nsfns.m
+++ b/src/nsfns.m
@@ -679,7 +679,23 @@ x_set_tool_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
679 } 679 }
680 } 680 }
681 681
682 x_set_window_size (f, 0, f->text_cols, f->text_lines, 0); 682 {
683 int inhibit
684 = ((f->after_make_frame
685 && !f->tool_bar_resized
686 && (EQ (frame_inhibit_implied_resize, Qt)
687 || (CONSP (frame_inhibit_implied_resize)
688 && !NILP (Fmemq (Qtool_bar_lines,
689 frame_inhibit_implied_resize))))
690 /* This will probably fail to DTRT in the
691 fullheight/-width cases. */
692 && NILP (get_frame_param (f, Qfullscreen)))
693 ? 0
694 : 2);
695
696 frame_size_history_add (f, Qupdate_frame_tool_bar, 0, 0, Qnil);
697 adjust_frame_size (f, -1, -1, inhibit, 0, Qtool_bar_lines);
698 }
683} 699}
684 700
685 701
@@ -1082,6 +1098,7 @@ This function is an internal primitive--use `make-frame' instead. */)
1082 Lisp_Object parent; 1098 Lisp_Object parent;
1083 struct kboard *kb; 1099 struct kboard *kb;
1084 static int desc_ctr = 1; 1100 static int desc_ctr = 1;
1101 int x_width = 0, x_height = 0;
1085 1102
1086 /* x_get_arg modifies parms. */ 1103 /* x_get_arg modifies parms. */
1087 parms = Fcopy_alist (parms); 1104 parms = Fcopy_alist (parms);
@@ -1268,7 +1285,7 @@ This function is an internal primitive--use `make-frame' instead. */)
1268 RES_TYPE_STRING); 1285 RES_TYPE_STRING);
1269 1286
1270 parms = get_geometry_from_preferences (dpyinfo, parms); 1287 parms = get_geometry_from_preferences (dpyinfo, parms);
1271 window_prompting = x_figure_window_size (f, parms, 1); 1288 window_prompting = x_figure_window_size (f, parms, true, &x_width, &x_height);
1272 1289
1273 tem = x_get_arg (dpyinfo, parms, Qunsplittable, 0, 0, RES_TYPE_BOOLEAN); 1290 tem = x_get_arg (dpyinfo, parms, Qunsplittable, 0, 0, RES_TYPE_BOOLEAN);
1274 f->no_split = minibuffer_only || (!EQ (tem, Qunbound) && !EQ (tem, Qnil)); 1291 f->no_split = minibuffer_only || (!EQ (tem, Qunbound) && !EQ (tem, Qnil));
@@ -1322,6 +1339,11 @@ This function is an internal primitive--use `make-frame' instead. */)
1322 /* Allow x_set_window_size, now. */ 1339 /* Allow x_set_window_size, now. */
1323 f->can_x_set_window_size = true; 1340 f->can_x_set_window_size = true;
1324 1341
1342 if (x_width > 0)
1343 SET_FRAME_WIDTH (f, x_width);
1344 if (x_height > 0)
1345 SET_FRAME_HEIGHT (f, x_height);
1346
1325 adjust_frame_size (f, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f), 0, 1, 1347 adjust_frame_size (f, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f), 0, 1,
1326 Qx_create_frame_2); 1348 Qx_create_frame_2);
1327 1349
diff --git a/src/nsterm.m b/src/nsterm.m
index 65d07b2f1e4..c4bfd7c9914 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -1365,9 +1365,12 @@ x_set_window_size (struct frame *f,
1365 FRAME_TOOLBAR_HEIGHT (f) = 1365 FRAME_TOOLBAR_HEIGHT (f) =
1366 NSHeight ([window frameRectForContentRect: NSMakeRect (0, 0, 0, 0)]) 1366 NSHeight ([window frameRectForContentRect: NSMakeRect (0, 0, 0, 0)])
1367 - FRAME_NS_TITLEBAR_HEIGHT (f); 1367 - FRAME_NS_TITLEBAR_HEIGHT (f);
1368#if 0
1369 /* Only breaks things here, removed by martin 2015-09-30. */
1368#ifdef NS_IMPL_GNUSTEP 1370#ifdef NS_IMPL_GNUSTEP
1369 FRAME_TOOLBAR_HEIGHT (f) -= 3; 1371 FRAME_TOOLBAR_HEIGHT (f) -= 3;
1370#endif 1372#endif
1373#endif
1371 } 1374 }
1372 else 1375 else
1373 FRAME_TOOLBAR_HEIGHT (f) = 0; 1376 FRAME_TOOLBAR_HEIGHT (f) = 0;
@@ -1386,6 +1389,14 @@ x_set_window_size (struct frame *f,
1386 else 1389 else
1387 wr.origin.y += orig_height - wr.size.height; 1390 wr.origin.y += orig_height - wr.size.height;
1388 1391
1392 frame_size_history_add
1393 (f, Qx_set_window_size_1, width, height,
1394 list5 (Fcons (make_number (pixelwidth), make_number (pixelheight)),
1395 Fcons (make_number (wr.size.width), make_number (wr.size.height)),
1396 make_number (f->border_width),
1397 make_number (FRAME_NS_TITLEBAR_HEIGHT (f)),
1398 make_number (FRAME_TOOLBAR_HEIGHT (f))));
1399
1389 [view setRows: rows andColumns: cols]; 1400 [view setRows: rows andColumns: cols];
1390 [window setFrame: wr display: YES]; 1401 [window setFrame: wr display: YES];
1391 1402
@@ -7741,8 +7752,9 @@ x_new_font (struct frame *f, Lisp_Object font_object, int fontset)
7741 7752
7742 /* Now make the frame display the given font. */ 7753 /* Now make the frame display the given font. */
7743 if (FRAME_NS_WINDOW (f) != 0 && ! [view isFullscreen]) 7754 if (FRAME_NS_WINDOW (f) != 0 && ! [view isFullscreen])
7744 x_set_window_size (f, false, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f), 7755 adjust_frame_size (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f),
7745 FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), true); 7756 FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 3,
7757 false, Qfont);
7746 7758
7747 return font_object; 7759 return font_object;
7748} 7760}
diff --git a/src/w32fns.c b/src/w32fns.c
index 97dd40ba262..3773923fe9d 100644
--- a/src/w32fns.c
+++ b/src/w32fns.c
@@ -1762,14 +1762,24 @@ x_change_tool_bar_height (struct frame *f, int height)
1762 1762
1763 /* Recalculate toolbar height. */ 1763 /* Recalculate toolbar height. */
1764 f->n_tool_bar_rows = 0; 1764 f->n_tool_bar_rows = 0;
1765 if (old_height == 0
1766 && (!f->after_make_frame
1767 || NILP (frame_inhibit_implied_resize)
1768 || (CONSP (frame_inhibit_implied_resize)
1769 && NILP (Fmemq (Qtool_bar_lines, frame_inhibit_implied_resize)))))
1770 f->tool_bar_redisplayed = f->tool_bar_resized = false;
1765 1771
1766 adjust_frame_size (f, -1, -1, 1772 adjust_frame_size (f, -1, -1,
1767 ((NILP (fullscreen = get_frame_param (f, Qfullscreen)) 1773 ((!f->tool_bar_resized
1768 || EQ (fullscreen, Qfullwidth)) ? 1 1774 && (NILP (fullscreen =
1775 get_frame_param (f, Qfullscreen))
1776 || EQ (fullscreen, Qfullwidth))) ? 1
1769 : (old_height == 0 || height == 0) ? 2 1777 : (old_height == 0 || height == 0) ? 2
1770 : 4), 1778 : 4),
1771 false, Qtool_bar_lines); 1779 false, Qtool_bar_lines);
1772 1780
1781 f->tool_bar_resized = f->tool_bar_redisplayed;
1782
1773 /* adjust_frame_size might not have done anything, garbage frame 1783 /* adjust_frame_size might not have done anything, garbage frame
1774 here. */ 1784 here. */
1775 adjust_frame_glyphs (f); 1785 adjust_frame_glyphs (f);
@@ -4368,97 +4378,7 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
4368 case WM_WINDOWPOSCHANGING: 4378 case WM_WINDOWPOSCHANGING:
4369 /* Don't restrict the sizing of any kind of frames. If the window 4379 /* Don't restrict the sizing of any kind of frames. If the window
4370 manager doesn't, there's no reason to do it ourselves. */ 4380 manager doesn't, there's no reason to do it ourselves. */
4371#if 0 4381 return 0;
4372 if (frame_resize_pixelwise || hwnd == tip_window)
4373#endif
4374 return 0;
4375
4376#if 0
4377 /* Don't restrict the sizing of fullscreened frames, allowing them to be
4378 flush with the sides of the screen. */
4379 f = x_window_to_frame (dpyinfo, hwnd);
4380 if (f && FRAME_PREV_FSMODE (f) != FULLSCREEN_NONE)
4381 return 0;
4382
4383 {
4384 WINDOWPLACEMENT wp;
4385 LPWINDOWPOS lppos = (WINDOWPOS *) lParam;
4386
4387 wp.length = sizeof (WINDOWPLACEMENT);
4388 GetWindowPlacement (hwnd, &wp);
4389
4390 if (wp.showCmd != SW_SHOWMAXIMIZED && wp.showCmd != SW_SHOWMINIMIZED
4391 && (lppos->flags & SWP_NOSIZE) == 0)
4392 {
4393 RECT rect;
4394 int wdiff;
4395 int hdiff;
4396 DWORD font_width;
4397 DWORD line_height;
4398 DWORD internal_border;
4399 DWORD vscrollbar_extra;
4400 DWORD hscrollbar_extra;
4401 RECT wr;
4402
4403 wp.length = sizeof (wp);
4404 GetWindowRect (hwnd, &wr);
4405
4406 enter_crit ();
4407
4408 font_width = GetWindowLong (hwnd, WND_FONTWIDTH_INDEX);
4409 line_height = GetWindowLong (hwnd, WND_LINEHEIGHT_INDEX);
4410 internal_border = GetWindowLong (hwnd, WND_BORDER_INDEX);
4411 vscrollbar_extra = GetWindowLong (hwnd, WND_VSCROLLBAR_INDEX);
4412 hscrollbar_extra = GetWindowLong (hwnd, WND_HSCROLLBAR_INDEX);
4413
4414 leave_crit ();
4415
4416 memset (&rect, 0, sizeof (rect));
4417 AdjustWindowRect (&rect, GetWindowLong (hwnd, GWL_STYLE),
4418 GetMenu (hwnd) != NULL);
4419
4420 /* Force width and height of client area to be exact
4421 multiples of the character cell dimensions. */
4422 wdiff = (lppos->cx - (rect.right - rect.left)
4423 - 2 * internal_border - vscrollbar_extra)
4424 % font_width;
4425 hdiff = (lppos->cy - (rect.bottom - rect.top)
4426 - 2 * internal_border - hscrollbar_extra)
4427 % line_height;
4428
4429 if (wdiff || hdiff)
4430 {
4431 /* For right/bottom sizing we can just fix the sizes.
4432 However for top/left sizing we will need to fix the X
4433 and Y positions as well. */
4434
4435 int cx_mintrack = GetSystemMetrics (SM_CXMINTRACK);
4436 int cy_mintrack = GetSystemMetrics (SM_CYMINTRACK);
4437
4438 lppos->cx = max (lppos->cx - wdiff, cx_mintrack);
4439 lppos->cy = max (lppos->cy - hdiff, cy_mintrack);
4440
4441 if (wp.showCmd != SW_SHOWMAXIMIZED
4442 && (lppos->flags & SWP_NOMOVE) == 0)
4443 {
4444 if (lppos->x != wr.left || lppos->y != wr.top)
4445 {
4446 lppos->x += wdiff;
4447 lppos->y += hdiff;
4448 }
4449 else
4450 {
4451 lppos->flags |= SWP_NOMOVE;
4452 }
4453 }
4454
4455 return 0;
4456 }
4457 }
4458 }
4459
4460 goto dflt;
4461#endif
4462 4382
4463 case WM_GETMINMAXINFO: 4383 case WM_GETMINMAXINFO:
4464 /* Hack to allow resizing the Emacs frame above the screen size. 4384 /* Hack to allow resizing the Emacs frame above the screen size.
@@ -4977,6 +4897,7 @@ This function is an internal primitive--use `make-frame' instead. */)
4977 struct w32_display_info *dpyinfo = NULL; 4897 struct w32_display_info *dpyinfo = NULL;
4978 Lisp_Object parent; 4898 Lisp_Object parent;
4979 struct kboard *kb; 4899 struct kboard *kb;
4900 int x_width = 0, x_height = 0;
4980 4901
4981 if (!FRAME_W32_P (SELECTED_FRAME ()) 4902 if (!FRAME_W32_P (SELECTED_FRAME ())
4982 && !FRAME_INITIAL_P (SELECTED_FRAME ())) 4903 && !FRAME_INITIAL_P (SELECTED_FRAME ()))
@@ -5199,7 +5120,7 @@ This function is an internal primitive--use `make-frame' instead. */)
5199 5120
5200 f->output_data.w32->current_cursor = f->output_data.w32->nontext_cursor; 5121 f->output_data.w32->current_cursor = f->output_data.w32->nontext_cursor;
5201 5122
5202 window_prompting = x_figure_window_size (f, parameters, true); 5123 window_prompting = x_figure_window_size (f, parameters, true, &x_width, &x_height);
5203 5124
5204 tem = x_get_arg (dpyinfo, parameters, Qunsplittable, 0, 0, RES_TYPE_BOOLEAN); 5125 tem = x_get_arg (dpyinfo, parameters, Qunsplittable, 0, 0, RES_TYPE_BOOLEAN);
5205 f->no_split = minibuffer_only || EQ (tem, Qt); 5126 f->no_split = minibuffer_only || EQ (tem, Qt);
@@ -5233,8 +5154,10 @@ This function is an internal primitive--use `make-frame' instead. */)
5233 /* Allow x_set_window_size, now. */ 5154 /* Allow x_set_window_size, now. */
5234 f->can_x_set_window_size = true; 5155 f->can_x_set_window_size = true;
5235 5156
5236 adjust_frame_size (f, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f), 0, true, 5157 if (x_width > 0)
5237 Qx_create_frame_2); 5158 SET_FRAME_WIDTH (f, x_width);
5159 if (x_height > 0)
5160 SET_FRAME_HEIGHT (f, x_height);
5238 5161
5239 /* Tell the server what size and position, etc, we want, and how 5162 /* Tell the server what size and position, etc, we want, and how
5240 badly we want them. This should be done after we have the menu 5163 badly we want them. This should be done after we have the menu
@@ -5243,6 +5166,9 @@ This function is an internal primitive--use `make-frame' instead. */)
5243 x_wm_set_size_hint (f, window_prompting, false); 5166 x_wm_set_size_hint (f, window_prompting, false);
5244 unblock_input (); 5167 unblock_input ();
5245 5168
5169 adjust_frame_size (f, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f), 0, true,
5170 Qx_create_frame_2);
5171
5246 /* Process fullscreen parameter here in the hope that normalizing a 5172 /* Process fullscreen parameter here in the hope that normalizing a
5247 fullheight/fullwidth frame will produce the size set by the last 5173 fullheight/fullwidth frame will produce the size set by the last
5248 adjust_frame_size call. */ 5174 adjust_frame_size call. */
@@ -6179,6 +6105,7 @@ x_create_tip_frame (struct w32_display_info *dpyinfo,
6179 bool face_change_before = face_change; 6105 bool face_change_before = face_change;
6180 Lisp_Object buffer; 6106 Lisp_Object buffer;
6181 struct buffer *old_buffer; 6107 struct buffer *old_buffer;
6108 int x_width = 0, x_height = 0;
6182 6109
6183 /* Use this general default value to start with until we know if 6110 /* Use this general default value to start with until we know if
6184 this frame has a specified name. */ 6111 this frame has a specified name. */
@@ -6309,7 +6236,7 @@ x_create_tip_frame (struct w32_display_info *dpyinfo,
6309 f->output_data.w32->dwStyle = WS_BORDER | WS_POPUP | WS_DISABLED; 6236 f->output_data.w32->dwStyle = WS_BORDER | WS_POPUP | WS_DISABLED;
6310 f->output_data.w32->parent_desc = FRAME_DISPLAY_INFO (f)->root_window; 6237 f->output_data.w32->parent_desc = FRAME_DISPLAY_INFO (f)->root_window;
6311 6238
6312 window_prompting = x_figure_window_size (f, parms, false); 6239 window_prompting = x_figure_window_size (f, parms, true, &x_width, &x_height);
6313 6240
6314 /* No fringes on tip frame. */ 6241 /* No fringes on tip frame. */
6315 f->fringe_cols = 0; 6242 f->fringe_cols = 0;
diff --git a/src/w32term.c b/src/w32term.c
index 9dc6b17d1ce..bd6070f9091 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -6176,6 +6176,13 @@ x_set_window_size (struct frame *f, bool change_gravity,
6176 6176
6177 if (pixelwidth > 0 || pixelheight > 0) 6177 if (pixelwidth > 0 || pixelheight > 0)
6178 { 6178 {
6179 frame_size_history_add
6180 (f, Qx_set_window_size_1, width, height,
6181 list2 (Fcons (make_number (pixelwidth),
6182 make_number (pixelheight)),
6183 Fcons (make_number (rect.right - rect.left),
6184 make_number (rect.bottom - rect.top))));
6185
6179 my_set_window_pos (FRAME_W32_WINDOW (f), NULL, 6186 my_set_window_pos (FRAME_W32_WINDOW (f), NULL,
6180 0, 0, 6187 0, 0,
6181 rect.right - rect.left, 6188 rect.right - rect.left,
diff --git a/src/widget.c b/src/widget.c
index 0986ba61dbf..48872f55938 100644
--- a/src/widget.c
+++ b/src/widget.c
@@ -268,167 +268,26 @@ set_frame_size (EmacsFrame ew)
268 */ 268 */
269 269
270 /* Hairily merged geometry */ 270 /* Hairily merged geometry */
271 int w = FRAME_COLS (ew->emacs_frame.frame); 271 struct frame *f = ew->emacs_frame.frame;
272 int h = FRAME_LINES (ew->emacs_frame.frame); 272 int w = FRAME_COLS (f);
273 273 int h = FRAME_LINES (f);
274 Widget wmshell = get_wm_shell ((Widget) ew); 274 Widget wmshell = get_wm_shell ((Widget) ew);
275 Dimension pixel_width, pixel_height;
275 /* Each Emacs shell is now independent and top-level. */ 276 /* Each Emacs shell is now independent and top-level. */
276 277
277 if (! XtIsSubclass (wmshell, shellWidgetClass)) emacs_abort (); 278 if (! XtIsSubclass (wmshell, shellWidgetClass)) emacs_abort ();
278 279
279 /* We don't need this for the moment. The geometry is computed in 280 char_to_pixel_size (ew, w, h, &pixel_width, &pixel_height);
280 xfns.c. */ 281 ew->core.width = (frame_resize_pixelwise
281#if 0 282 ? FRAME_PIXEL_WIDTH (f)
282 /* If the EmacsFrame doesn't have a geometry but the shell does, 283 : pixel_width);
283 treat that as the geometry of the frame. (Is this bogus? 284 ew->core.height = (frame_resize_pixelwise
284 I'm not sure.) */ 285 ? FRAME_PIXEL_HEIGHT (f)
285 if (ew->emacs_frame.geometry == 0) 286 : pixel_height);
286 XtVaGetValues (wmshell, XtNgeometry, &ew->emacs_frame.geometry, NULL);
287
288 /* If the Shell is iconic, then the EmacsFrame is iconic. (Is
289 this bogus? I'm not sure.) */
290 if (!ew->emacs_frame.iconic)
291 XtVaGetValues (wmshell, XtNiconic, &ew->emacs_frame.iconic, NULL);
292
293
294 {
295 char *geom = 0;
296 XtVaGetValues (app_shell, XtNgeometry, &geom, NULL);
297 if (geom)
298 app_flags = XParseGeometry (geom, &app_x, &app_y, &app_w, &app_h);
299 }
300
301 if (ew->emacs_frame.geometry)
302 frame_flags = XParseGeometry (ew->emacs_frame.geometry,
303 &frame_x, &frame_y,
304 &frame_w, &frame_h);
305
306 if (first_frame_p)
307 {
308 /* If this is the first frame created:
309 ====================================
310
311 - Use the ApplicationShell's size/position, if specified.
312 (This is "Emacs.geometry", or the "-geometry" command line arg.)
313 - Else use the EmacsFrame's size/position.
314 (This is "*Frame-NAME.geometry")
315
316 - If the AppShell is iconic, the frame should be iconic.
317
318 AppShell comes first so that -geometry always applies to the first
319 frame created, even if there is an "every frame" entry in the
320 resource database.
321 */
322 if (app_flags & (XValue | YValue))
323 {
324 x = app_x; y = app_y;
325 flags |= (app_flags & (XValue | YValue | XNegative | YNegative));
326 }
327 else if (frame_flags & (XValue | YValue))
328 {
329 x = frame_x; y = frame_y;
330 flags |= (frame_flags & (XValue | YValue | XNegative | YNegative));
331 }
332
333 if (app_flags & (WidthValue | HeightValue))
334 {
335 w = app_w; h = app_h;
336 flags |= (app_flags & (WidthValue | HeightValue));
337 }
338 else if (frame_flags & (WidthValue | HeightValue))
339 {
340 w = frame_w; h = frame_h;
341 flags |= (frame_flags & (WidthValue | HeightValue));
342 }
343
344 /* If the AppShell is iconic, then the EmacsFrame is iconic. */
345 if (!ew->emacs_frame.iconic)
346 XtVaGetValues (app_shell, XtNiconic, &ew->emacs_frame.iconic, NULL);
347
348 first_frame_p = False;
349 }
350 else
351 {
352 /* If this is not the first frame created:
353 ========================================
354
355 - use the EmacsFrame's size/position if specified
356 - Otherwise, use the ApplicationShell's size, but not position.
357
358 So that means that one can specify the position of the first frame
359 with "Emacs.geometry" or `-geometry'; but can only specify the
360 position of subsequent frames with "*Frame-NAME.geometry".
361
362 AppShell comes second so that -geometry does not apply to subsequent
363 frames when there is an "every frame" entry in the resource db,
364 but does apply to the first frame.
365 */
366 if (frame_flags & (XValue | YValue))
367 {
368 x = frame_x; y = frame_y;
369 flags |= (frame_flags & (XValue | YValue | XNegative | YNegative));
370 }
371 287
372 if (frame_flags & (WidthValue | HeightValue)) 288 frame_size_history_add
373 { 289 (f, Qset_frame_size, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f),
374 w = frame_w; h = frame_h; 290 list2 (make_number (ew->core.width), make_number (ew->core.height)));
375 flags |= (frame_flags & (WidthValue | HeightValue));
376 }
377 else if (app_flags & (WidthValue | HeightValue))
378 {
379 w = app_w;
380 h = app_h;
381 flags |= (app_flags & (WidthValue | HeightValue));
382 }
383 }
384#endif /* 0 */
385 {
386 Dimension pixel_width, pixel_height;
387
388 /* Take into account the size of the scrollbar. Always use the
389 number of columns occupied by the scroll bar here otherwise we
390 might end up with a frame width that is not a multiple of the
391 frame's character width which is bad for vertically split
392 windows. */
393
394#if 0 /* This can run Lisp code, and it is dangerous to give
395 out the frame to Lisp code before it officially exists.
396 This is handled in Fx_create_frame so not needed here. */
397 change_frame_size (f, w, h, 1, 0, 0, 0);
398#endif
399 char_to_pixel_size (ew, w, h, &pixel_width, &pixel_height);
400 ew->core.width = pixel_width;
401 ew->core.height = pixel_height;
402
403#if 0 /* xfns.c takes care of this now. */
404 /* If a position was specified, assign it to the shell widget.
405 (Else WM won't do anything with it.)
406 */
407 if (flags & (XValue | YValue))
408 {
409 /* the tricky things with the sign is to make sure that
410 -0 is printed -0. */
411 sprintf (shell_position, "=%c%d%c%d",
412 flags & XNegative ? '-' : '+', x < 0 ? -x : x,
413 flags & YNegative ? '-' : '+', y < 0 ? -y : y);
414 XtVaSetValues (wmshell, XtNgeometry, xstrdup (shell_position), NULL);
415 }
416 else if (flags & (WidthValue | HeightValue))
417 {
418 sprintf (shell_position, "=%dx%d", pixel_width, pixel_height);
419 XtVaSetValues (wmshell, XtNgeometry, xstrdup (shell_position), NULL);
420 }
421
422 /* If the geometry spec we're using has W/H components, mark the size
423 in the WM_SIZE_HINTS as user specified. */
424 if (flags & (WidthValue | HeightValue))
425 mark_shell_size_user_specified (wmshell);
426
427 /* Also assign the iconic status of the frame to the Shell, so that
428 the WM sees it. */
429 XtVaSetValues (wmshell, XtNiconic, ew->emacs_frame.iconic, NULL);
430#endif /* 0 */
431 }
432} 291}
433 292
434static void 293static void
@@ -486,16 +345,6 @@ update_various_frame_slots (EmacsFrame ew)
486{ 345{
487 struct frame *f = ew->emacs_frame.frame; 346 struct frame *f = ew->emacs_frame.frame;
488 347
489 /* Don't do that: It confuses the check in change_frame_size_1 whether
490 the pixel size of the frame changed due to a change of the internal
491 border width. Bug#16736. */
492 if (false)
493 {
494 struct x_output *x = f->output_data.x;
495 FRAME_PIXEL_HEIGHT (f) = ew->core.height + x->menubar_height;
496 FRAME_PIXEL_WIDTH (f) = ew->core.width;
497 }
498
499 f->internal_border_width = ew->emacs_frame.internal_border_width; 348 f->internal_border_width = ew->emacs_frame.internal_border_width;
500} 349}
501 350
@@ -504,6 +353,7 @@ update_from_various_frame_slots (EmacsFrame ew)
504{ 353{
505 struct frame *f = ew->emacs_frame.frame; 354 struct frame *f = ew->emacs_frame.frame;
506 struct x_output *x = f->output_data.x; 355 struct x_output *x = f->output_data.x;
356
507 ew->core.height = FRAME_PIXEL_HEIGHT (f) - x->menubar_height; 357 ew->core.height = FRAME_PIXEL_HEIGHT (f) - x->menubar_height;
508 ew->core.width = FRAME_PIXEL_WIDTH (f); 358 ew->core.width = FRAME_PIXEL_WIDTH (f);
509 ew->core.background_pixel = FRAME_BACKGROUND_PIXEL (f); 359 ew->core.background_pixel = FRAME_BACKGROUND_PIXEL (f);
@@ -576,7 +426,10 @@ EmacsFrameResize (Widget widget)
576 426
577 frame_size_history_add 427 frame_size_history_add
578 (f, QEmacsFrameResize, width, height, 428 (f, QEmacsFrameResize, width, height,
579 list2 (make_number (ew->core.width), make_number (ew->core.height))); 429 list5 (make_number (ew->core.width), make_number (ew->core.height),
430 make_number (FRAME_TOP_MARGIN_HEIGHT (f)),
431 make_number (FRAME_SCROLL_BAR_AREA_HEIGHT (f)),
432 make_number (2 * FRAME_INTERNAL_BORDER_WIDTH (f))));
580 433
581 change_frame_size (f, width, height, 0, 1, 0, 1); 434 change_frame_size (f, width, height, 0, 1, 0, 1);
582 435
@@ -596,11 +449,12 @@ EmacsFrameQueryGeometry (Widget widget, XtWidgetGeometry *request, XtWidgetGeome
596 449
597 if (mask & (CWWidth | CWHeight)) 450 if (mask & (CWWidth | CWHeight))
598 { 451 {
599 round_size_to_char (ew, 452 if (!frame_resize_pixelwise)
600 (mask & CWWidth) ? request->width : ew->core.width, 453 round_size_to_char (ew,
601 ((mask & CWHeight) ? request->height 454 (mask & CWWidth) ? request->width : ew->core.width,
602 : ew->core.height), 455 ((mask & CWHeight) ? request->height
603 &ok_width, &ok_height); 456 : ew->core.height),
457 &ok_width, &ok_height);
604 if ((mask & CWWidth) && (ok_width != request->width)) 458 if ((mask & CWWidth) && (ok_width != request->width))
605 { 459 {
606 result->request_mode |= CWWidth; 460 result->request_mode |= CWWidth;
diff --git a/src/xdisp.c b/src/xdisp.c
index 44983bb4f9d..a793157f086 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -12342,6 +12342,7 @@ PIXELWISE non-nil means return the height of the tool bar in pixels. */)
12342static bool 12342static bool
12343redisplay_tool_bar (struct frame *f) 12343redisplay_tool_bar (struct frame *f)
12344{ 12344{
12345 f->tool_bar_redisplayed = true;
12345#if defined (USE_GTK) || defined (HAVE_NS) 12346#if defined (USE_GTK) || defined (HAVE_NS)
12346 12347
12347 if (FRAME_EXTERNAL_TOOL_BAR (f)) 12348 if (FRAME_EXTERNAL_TOOL_BAR (f))
diff --git a/src/xfns.c b/src/xfns.c
index fefd8e8f91f..8251f939b8c 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -1090,7 +1090,7 @@ x_set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
1090#else /* not USE_X_TOOLKIT && not USE_GTK */ 1090#else /* not USE_X_TOOLKIT && not USE_GTK */
1091 FRAME_MENU_BAR_LINES (f) = nlines; 1091 FRAME_MENU_BAR_LINES (f) = nlines;
1092 FRAME_MENU_BAR_HEIGHT (f) = nlines * FRAME_LINE_HEIGHT (f); 1092 FRAME_MENU_BAR_HEIGHT (f) = nlines * FRAME_LINE_HEIGHT (f);
1093 adjust_frame_size (f, -1, -1, 2, true, Qmenu_bar_lines); 1093 adjust_frame_size (f, -1, -1, 2, true, Qx_set_menu_bar_lines);
1094 if (FRAME_X_WINDOW (f)) 1094 if (FRAME_X_WINDOW (f))
1095 x_clear_under_internal_border (f); 1095 x_clear_under_internal_border (f);
1096 1096
@@ -1212,14 +1212,24 @@ x_change_tool_bar_height (struct frame *f, int height)
1212 1212
1213 /* Recalculate toolbar height. */ 1213 /* Recalculate toolbar height. */
1214 f->n_tool_bar_rows = 0; 1214 f->n_tool_bar_rows = 0;
1215 if (old_height == 0
1216 && (!f->after_make_frame
1217 || NILP (frame_inhibit_implied_resize)
1218 || (CONSP (frame_inhibit_implied_resize)
1219 && NILP (Fmemq (Qtool_bar_lines, frame_inhibit_implied_resize)))))
1220 f->tool_bar_redisplayed = f->tool_bar_resized = false;
1215 1221
1216 adjust_frame_size (f, -1, -1, 1222 adjust_frame_size (f, -1, -1,
1217 ((NILP (fullscreen = get_frame_param (f, Qfullscreen)) 1223 ((!f->tool_bar_resized
1218 || EQ (fullscreen, Qfullwidth)) ? 1 1224 && (NILP (fullscreen =
1225 get_frame_param (f, Qfullscreen))
1226 || EQ (fullscreen, Qfullwidth))) ? 1
1219 : (old_height == 0 || height == 0) ? 2 1227 : (old_height == 0 || height == 0) ? 2
1220 : 4), 1228 : 4),
1221 false, Qtool_bar_lines); 1229 false, Qtool_bar_lines);
1222 1230
1231 f->tool_bar_resized = f->tool_bar_redisplayed;
1232
1223 /* adjust_frame_size might not have done anything, garbage frame 1233 /* adjust_frame_size might not have done anything, garbage frame
1224 here. */ 1234 here. */
1225 adjust_frame_glyphs (f); 1235 adjust_frame_glyphs (f);
@@ -3001,6 +3011,7 @@ This function is an internal primitive--use `make-frame' instead. */)
3001 struct x_display_info *dpyinfo = NULL; 3011 struct x_display_info *dpyinfo = NULL;
3002 Lisp_Object parent; 3012 Lisp_Object parent;
3003 struct kboard *kb; 3013 struct kboard *kb;
3014 int x_width = 0, x_height = 0;
3004 3015
3005 parms = Fcopy_alist (parms); 3016 parms = Fcopy_alist (parms);
3006 3017
@@ -3275,7 +3286,7 @@ This function is an internal primitive--use `make-frame' instead. */)
3275 FRAME_TOOL_BAR_POSITION (f), 0, 0, RES_TYPE_SYMBOL); 3286 FRAME_TOOL_BAR_POSITION (f), 0, 0, RES_TYPE_SYMBOL);
3276 3287
3277 /* Compute the size of the X window. */ 3288 /* Compute the size of the X window. */
3278 window_prompting = x_figure_window_size (f, parms, true); 3289 window_prompting = x_figure_window_size (f, parms, true, &x_width, &x_height);
3279 3290
3280 tem = x_get_arg (dpyinfo, parms, Qunsplittable, 0, 0, RES_TYPE_BOOLEAN); 3291 tem = x_get_arg (dpyinfo, parms, Qunsplittable, 0, 0, RES_TYPE_BOOLEAN);
3281 f->no_split = minibuffer_only || EQ (tem, Qt); 3292 f->no_split = minibuffer_only || EQ (tem, Qt);
@@ -3317,12 +3328,6 @@ This function is an internal primitive--use `make-frame' instead. */)
3317 x_default_parameter (f, parms, Qalpha, Qnil, 3328 x_default_parameter (f, parms, Qalpha, Qnil,
3318 "alpha", "Alpha", RES_TYPE_NUMBER); 3329 "alpha", "Alpha", RES_TYPE_NUMBER);
3319 3330
3320 /* Consider frame official, now. */
3321 f->can_x_set_window_size = true;
3322
3323 adjust_frame_size (f, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f), 0, true,
3324 Qx_create_frame_2);
3325
3326#if defined (USE_X_TOOLKIT) || defined (USE_GTK) 3331#if defined (USE_X_TOOLKIT) || defined (USE_GTK)
3327 /* Create the menu bar. */ 3332 /* Create the menu bar. */
3328 if (!minibuffer_only && FRAME_EXTERNAL_MENU_BAR (f)) 3333 if (!minibuffer_only && FRAME_EXTERNAL_MENU_BAR (f))
@@ -3341,6 +3346,14 @@ This function is an internal primitive--use `make-frame' instead. */)
3341 } 3346 }
3342#endif /* USE_X_TOOLKIT || USE_GTK */ 3347#endif /* USE_X_TOOLKIT || USE_GTK */
3343 3348
3349 /* Consider frame official, now. */
3350 f->can_x_set_window_size = true;
3351
3352 if (x_width > 0)
3353 SET_FRAME_WIDTH (f, x_width);
3354 if (x_height > 0)
3355 SET_FRAME_HEIGHT (f, x_height);
3356
3344 /* Tell the server what size and position, etc, we want, and how 3357 /* Tell the server what size and position, etc, we want, and how
3345 badly we want them. This should be done after we have the menu 3358 badly we want them. This should be done after we have the menu
3346 bar so that its size can be taken into account. */ 3359 bar so that its size can be taken into account. */
@@ -3348,6 +3361,9 @@ This function is an internal primitive--use `make-frame' instead. */)
3348 x_wm_set_size_hint (f, window_prompting, false); 3361 x_wm_set_size_hint (f, window_prompting, false);
3349 unblock_input (); 3362 unblock_input ();
3350 3363
3364 adjust_frame_size (f, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f),
3365 0, true, Qx_create_frame_2);
3366
3351 /* Process fullscreen parameter here in the hope that normalizing a 3367 /* Process fullscreen parameter here in the hope that normalizing a
3352 fullheight/fullwidth frame will produce the size set by the last 3368 fullheight/fullwidth frame will produce the size set by the last
3353 adjust_frame_size call. */ 3369 adjust_frame_size call. */
@@ -5161,6 +5177,7 @@ x_create_tip_frame (struct x_display_info *dpyinfo,
5161 bool face_change_before = face_change; 5177 bool face_change_before = face_change;
5162 Lisp_Object buffer; 5178 Lisp_Object buffer;
5163 struct buffer *old_buffer; 5179 struct buffer *old_buffer;
5180 int x_width = 0, x_height = 0;
5164 5181
5165 if (!dpyinfo->terminal->name) 5182 if (!dpyinfo->terminal->name)
5166 error ("Terminal is not live, can't create new frames on it"); 5183 error ("Terminal is not live, can't create new frames on it");
@@ -5333,7 +5350,7 @@ x_create_tip_frame (struct x_display_info *dpyinfo,
5333 5350
5334 f->output_data.x->parent_desc = FRAME_DISPLAY_INFO (f)->root_window; 5351 f->output_data.x->parent_desc = FRAME_DISPLAY_INFO (f)->root_window;
5335 5352
5336 x_figure_window_size (f, parms, false); 5353 x_figure_window_size (f, parms, false, &x_width, &x_height);
5337 5354
5338 { 5355 {
5339 XSetWindowAttributes attrs; 5356 XSetWindowAttributes attrs;
diff --git a/src/xmenu.c b/src/xmenu.c
index 192ed89e2c6..4379cddaf2e 100644
--- a/src/xmenu.c
+++ b/src/xmenu.c
@@ -636,13 +636,7 @@ update_frame_menubar (struct frame *f)
636 lw_refigure_widget (x->column_widget, True); 636 lw_refigure_widget (x->column_widget, True);
637 637
638 /* Force the pane widget to resize itself. */ 638 /* Force the pane widget to resize itself. */
639 int new_height = -1; 639 adjust_frame_size (f, -1, -1, 2, false, Qupdate_frame_menubar);
640#ifdef USE_LUCID
641 /* For reasons I don't know Lucid wants to add one pixel to the frame
642 height when adding the menu bar. Compensate that here. */
643 new_height = FRAME_TEXT_HEIGHT (f) - 1;
644#endif /* USE_LUCID */
645 adjust_frame_size (f, -1, new_height, 2, false, Qmenu_bar_lines);
646 unblock_input (); 640 unblock_input ();
647#endif /* USE_GTK */ 641#endif /* USE_GTK */
648} 642}
@@ -979,7 +973,15 @@ set_frame_menubar (struct frame *f, bool first_time, bool deep_p)
979 menubar_size 973 menubar_size
980 = (f->output_data.x->menubar_widget 974 = (f->output_data.x->menubar_widget
981 ? (f->output_data.x->menubar_widget->core.height 975 ? (f->output_data.x->menubar_widget->core.height
982 + f->output_data.x->menubar_widget->core.border_width) 976#ifndef USE_LUCID
977 /* Damn me... With Lucid I get a core.border_width of 1
978 only the first time this is called and an ibw of 1 every
979 time this is called. So the first time this is called I
980 was off by one. Fix that here by never adding
981 core.border_width for Lucid. */
982 + f->output_data.x->menubar_widget->core.border_width
983#endif /* USE_LUCID */
984 )
983 : 0); 985 : 0);
984 986
985#ifdef USE_LUCID 987#ifdef USE_LUCID
@@ -990,9 +992,10 @@ set_frame_menubar (struct frame *f, bool first_time, bool deep_p)
990 if (FRAME_EXTERNAL_MENU_BAR (f)) 992 if (FRAME_EXTERNAL_MENU_BAR (f))
991 { 993 {
992 Dimension ibw = 0; 994 Dimension ibw = 0;
995
993 XtVaGetValues (f->output_data.x->column_widget, 996 XtVaGetValues (f->output_data.x->column_widget,
994 XtNinternalBorderWidth, &ibw, NULL); 997 XtNinternalBorderWidth, &ibw, NULL);
995 menubar_size += ibw; 998 menubar_size += ibw;
996 } 999 }
997#endif /* USE_LUCID */ 1000#endif /* USE_LUCID */
998 1001
@@ -1073,21 +1076,24 @@ free_frame_menubar (struct frame *f)
1073 1076
1074 if (f->output_data.x->widget) 1077 if (f->output_data.x->widget)
1075 { 1078 {
1076 int new_height = -1;
1077#ifdef USE_MOTIF 1079#ifdef USE_MOTIF
1078 XtVaGetValues (f->output_data.x->widget, XtNx, &x1, XtNy, &y1, NULL); 1080 XtVaGetValues (f->output_data.x->widget, XtNx, &x1, XtNy, &y1, NULL);
1079 if (x1 == 0 && y1 == 0) 1081 if (x1 == 0 && y1 == 0)
1080 XtVaSetValues (f->output_data.x->widget, XtNx, x0, XtNy, y0, NULL); 1082 XtVaSetValues (f->output_data.x->widget, XtNx, x0, XtNy, y0, NULL);
1081 if (frame_inhibit_resize (f, false, Qmenu_bar_lines)) 1083 if (frame_inhibit_resize (f, false, Qmenu_bar_lines))
1082 new_height = old_height; 1084 adjust_frame_size (f, -1, old_height, 1, false, Qfree_frame_menubar_1);
1085 else
1086 adjust_frame_size (f, -1, -1, 2, false, Qfree_frame_menubar_1);
1087#else
1088 adjust_frame_size (f, -1, -1, 2, false, Qfree_frame_menubar_1);
1083#endif /* USE_MOTIF */ 1089#endif /* USE_MOTIF */
1084 adjust_frame_size (f, -1, new_height, 2, false, Qmenu_bar_lines);
1085 } 1090 }
1086 else 1091 else
1087 { 1092 {
1088#ifdef USE_MOTIF 1093#ifdef USE_MOTIF
1089 if (frame_inhibit_resize (f, false, Qmenu_bar_lines)) 1094 if (WINDOWP (FRAME_ROOT_WINDOW (f))
1090 adjust_frame_size (f, -1, old_height, 1, false, Qmenu_bar_lines); 1095 && frame_inhibit_resize (f, false, Qmenu_bar_lines))
1096 adjust_frame_size (f, -1, old_height, 1, false, Qfree_frame_menubar_2);
1091#endif 1097#endif
1092 } 1098 }
1093 1099
diff --git a/src/xterm.c b/src/xterm.c
index dd57a548393..fdf0eee689f 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -9579,6 +9579,10 @@ x_new_font (struct frame *f, Lisp_Object font_object, int fontset)
9579{ 9579{
9580 struct font *font = XFONT_OBJECT (font_object); 9580 struct font *font = XFONT_OBJECT (font_object);
9581 int unit, font_ascent, font_descent; 9581 int unit, font_ascent, font_descent;
9582#ifndef USE_X_TOOLKIT
9583 int old_menu_bar_height = FRAME_MENU_BAR_HEIGHT (f);
9584 Lisp_Object fullscreen;
9585#endif
9582 9586
9583 if (fontset < 0) 9587 if (fontset < 0)
9584 fontset = fontset_from_font (font_object); 9588 fontset = fontset_from_font (font_object);
@@ -9615,9 +9619,25 @@ x_new_font (struct frame *f, Lisp_Object font_object, int fontset)
9615 doing it because it's done in Fx_show_tip, and it leads to 9619 doing it because it's done in Fx_show_tip, and it leads to
9616 problems because the tip frame has no widget. */ 9620 problems because the tip frame has no widget. */
9617 if (NILP (tip_frame) || XFRAME (tip_frame) != f) 9621 if (NILP (tip_frame) || XFRAME (tip_frame) != f)
9622 {
9618 adjust_frame_size (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f), 9623 adjust_frame_size (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f),
9619 FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 3, 9624 FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 3,
9620 false, Qfont); 9625 false, Qfont);
9626#ifndef USE_X_TOOLKIT
9627 if (FRAME_MENU_BAR_HEIGHT (f) != old_menu_bar_height
9628 && !f->after_make_frame
9629 && (EQ (frame_inhibit_implied_resize, Qt)
9630 || (CONSP (frame_inhibit_implied_resize)
9631 && NILP (Fmemq (Qfont, frame_inhibit_implied_resize))))
9632 && (NILP (fullscreen = get_frame_param (f, Qfullscreen))
9633 || EQ (fullscreen, Qfullwidth)))
9634 /* If the menu bar height changes, try to keep text height
9635 constant. */
9636 adjust_frame_size
9637 (f, -1, FRAME_TEXT_HEIGHT (f) + FRAME_MENU_BAR_HEIGHT (f)
9638 - old_menu_bar_height, 1, false, Qfont);
9639#endif /* USE_X_TOOLKIT */
9640 }
9621 } 9641 }
9622 9642
9623#ifdef HAVE_X_I18N 9643#ifdef HAVE_X_I18N
@@ -10549,7 +10569,7 @@ x_set_window_size_1 (struct frame *f, bool change_gravity,
10549 if (EQ (fullscreen, Qfullwidth) && width == FRAME_TEXT_WIDTH (f)) 10569 if (EQ (fullscreen, Qfullwidth) && width == FRAME_TEXT_WIDTH (f))
10550 { 10570 {
10551 frame_size_history_add 10571 frame_size_history_add
10552 (f, Qxg_frame_set_char_size_1, width, height, 10572 (f, Qx_set_window_size_1, width, height,
10553 list2 (make_number (old_height), 10573 list2 (make_number (old_height),
10554 make_number (pixelheight + FRAME_MENUBAR_HEIGHT (f)))); 10574 make_number (pixelheight + FRAME_MENUBAR_HEIGHT (f))));
10555 10575
@@ -10559,7 +10579,7 @@ x_set_window_size_1 (struct frame *f, bool change_gravity,
10559 else if (EQ (fullscreen, Qfullheight) && height == FRAME_TEXT_HEIGHT (f)) 10579 else if (EQ (fullscreen, Qfullheight) && height == FRAME_TEXT_HEIGHT (f))
10560 { 10580 {
10561 frame_size_history_add 10581 frame_size_history_add
10562 (f, Qxg_frame_set_char_size_2, width, height, 10582 (f, Qx_set_window_size_2, width, height,
10563 list2 (make_number (old_width), make_number (pixelwidth))); 10583 list2 (make_number (old_width), make_number (pixelwidth)));
10564 10584
10565 XResizeWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), 10585 XResizeWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
@@ -10569,10 +10589,11 @@ x_set_window_size_1 (struct frame *f, bool change_gravity,
10569 else 10589 else
10570 { 10590 {
10571 frame_size_history_add 10591 frame_size_history_add
10572 (f, Qxg_frame_set_char_size_3, width, height, 10592 (f, Qx_set_window_size_3, width, height,
10573 list2 (make_number (pixelwidth + FRAME_TOOLBAR_WIDTH (f)), 10593 list3 (make_number (pixelwidth + FRAME_TOOLBAR_WIDTH (f)),
10574 make_number (pixelheight + FRAME_TOOLBAR_HEIGHT (f) 10594 make_number (pixelheight + FRAME_TOOLBAR_HEIGHT (f)
10575 + FRAME_MENUBAR_HEIGHT (f)))); 10595 + FRAME_MENUBAR_HEIGHT (f)),
10596 make_number (FRAME_MENUBAR_HEIGHT (f))));
10576 10597
10577 XResizeWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), 10598 XResizeWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
10578 pixelwidth, pixelheight + FRAME_MENUBAR_HEIGHT (f)); 10599 pixelwidth, pixelheight + FRAME_MENUBAR_HEIGHT (f));
@@ -11342,8 +11363,8 @@ x_wm_set_size_hint (struct frame *f, long flags, bool user_position)
11342 size_hints.x = f->left_pos; 11363 size_hints.x = f->left_pos;
11343 size_hints.y = f->top_pos; 11364 size_hints.y = f->top_pos;
11344 11365
11345 size_hints.height = FRAME_PIXEL_HEIGHT (f);
11346 size_hints.width = FRAME_PIXEL_WIDTH (f); 11366 size_hints.width = FRAME_PIXEL_WIDTH (f);
11367 size_hints.height = FRAME_PIXEL_HEIGHT (f);
11347 11368
11348 size_hints.width_inc = frame_resize_pixelwise ? 1 : FRAME_COLUMN_WIDTH (f); 11369 size_hints.width_inc = frame_resize_pixelwise ? 1 : FRAME_COLUMN_WIDTH (f);
11349 size_hints.height_inc = frame_resize_pixelwise ? 1 : FRAME_LINE_HEIGHT (f); 11370 size_hints.height_inc = frame_resize_pixelwise ? 1 : FRAME_LINE_HEIGHT (f);
@@ -11356,34 +11377,21 @@ x_wm_set_size_hint (struct frame *f, long flags, bool user_position)
11356 /* Calculate the base and minimum sizes. */ 11377 /* Calculate the base and minimum sizes. */
11357 { 11378 {
11358 int base_width, base_height; 11379 int base_width, base_height;
11359 int min_rows = 0, min_cols = 0;
11360 11380
11361 base_width = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, 0); 11381 base_width = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, 0);
11362 base_height = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, 0); 11382 base_height = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, 0);
11363 11383
11364 if (frame_resize_pixelwise)
11365 /* Needed to prevent a bad protocol error crash when making the
11366 frame size very small. */
11367 {
11368 min_cols = 2 * min_cols;
11369 min_rows = 2 * min_rows;
11370 }
11371
11372 /* The window manager uses the base width hints to calculate the 11384 /* The window manager uses the base width hints to calculate the
11373 current number of rows and columns in the frame while 11385 current number of rows and columns in the frame while
11374 resizing; min_width and min_height aren't useful for this 11386 resizing; min_width and min_height aren't useful for this
11375 purpose, since they might not give the dimensions for a 11387 purpose, since they might not give the dimensions for a
11376 zero-row, zero-column frame. 11388 zero-row, zero-column frame. */
11377
11378 We use the base_width and base_height members if we have
11379 them; otherwise, we set the min_width and min_height members
11380 to the size for a zero x zero frame. */
11381 11389
11382 size_hints.flags |= PBaseSize; 11390 size_hints.flags |= PBaseSize;
11383 size_hints.base_width = base_width; 11391 size_hints.base_width = base_width;
11384 size_hints.base_height = base_height + FRAME_MENUBAR_HEIGHT (f); 11392 size_hints.base_height = base_height + FRAME_MENUBAR_HEIGHT (f);
11385 size_hints.min_width = base_width + min_cols * FRAME_COLUMN_WIDTH (f); 11393 size_hints.min_width = base_width;
11386 size_hints.min_height = base_height + min_rows * FRAME_LINE_HEIGHT (f); 11394 size_hints.min_height = base_height;
11387 } 11395 }
11388 11396
11389 /* If we don't need the old flags, we don't need the old hint at all. */ 11397 /* If we don't need the old flags, we don't need the old hint at all. */