Commit d4fe840d authored by Martin Rudalics's avatar Martin Rudalics

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.
parent e53e1a04
......@@ -461,7 +461,7 @@ there (in decreasing order of priority)."
(cons (1- (car frame-size-history))
(cons
(list frame-initial-frame
"frame-notice-user-settings"
"FRAME-NOTICE-USER"
nil newparms)
(cdr frame-size-history)))))
......@@ -702,7 +702,7 @@ the new frame according to its own rules."
(when (numberp (car frame-size-history))
(setq frame-size-history
(cons (1- (car frame-size-history))
(cons (list frame "make-frame")
(cons (list frame "MAKE-FRAME")
(cdr frame-size-history)))))
;; We can run `window-configuration-change-hook' for this frame now.
......@@ -1382,6 +1382,27 @@ and width values are in pixels.
(cons 'internal-border-width
(frame-parameter frame 'internal-border-width)))))))
(defun frame--size-history (&optional frame)
"Print history of resize operations for FRAME.
Print prettified version of `frame-size-history' into a buffer
called *frame-size-history*. Optional argument FRAME denotes the
frame whose history will be printed. FRAME defaults to the
selected frame."
(let ((history (reverse frame-size-history))
entry)
(setq frame (window-normalize-frame frame))
(with-current-buffer (get-buffer-create "*frame-size-history*")
(erase-buffer)
(insert (format "Frame size history of %s\n" frame))
(while (listp (setq entry (pop history)))
(when (eq (car entry) frame)
(pop entry)
(insert (format "%s" (pop entry)))
(move-to-column 24 t)
(while entry
(insert (format " %s" (pop entry))))
(insert "\n"))))))
(declare-function x-frame-edges "xfns.c" (&optional frame type))
(declare-function w32-frame-edges "w32fns.c" (&optional frame type))
(declare-function ns-frame-edges "nsfns.m" (&optional frame type))
......
......@@ -184,16 +184,17 @@ frame_inhibit_resize (struct frame *f, bool horizontal, Lisp_Object parameter)
{
Lisp_Object fullscreen = get_frame_param (f, Qfullscreen);
bool inhibit
= ((f->after_make_frame
&& (EQ (frame_inhibit_implied_resize, Qt)
|| (CONSP (frame_inhibit_implied_resize)
&& !NILP (Fmemq (parameter, frame_inhibit_implied_resize)))))
|| (horizontal
&& !EQ (fullscreen, Qnil) && !EQ (fullscreen, Qfullheight))
|| (!horizontal
&& !EQ (fullscreen, Qnil) && !EQ (fullscreen, Qfullwidth))
|| FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f));
= (f->after_make_frame
? (EQ (frame_inhibit_implied_resize, Qt)
|| (CONSP (frame_inhibit_implied_resize)
&& !NILP (Fmemq (parameter, frame_inhibit_implied_resize)))
|| (horizontal
&& !EQ (fullscreen, Qnil) && !EQ (fullscreen, Qfullheight))
|| (!horizontal
&& !EQ (fullscreen, Qnil) && !EQ (fullscreen, Qfullwidth))
|| FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f))
: ((horizontal && f->inhibit_horizontal_resize)
|| (!horizontal && f->inhibit_vertical_resize)));
if (inhibit && !FRAME_TERMCAP_P (f) && !FRAME_MSDOS_P (f))
frame_size_history_add
(f, Qframe_inhibit_resize, 0, 0,
......@@ -425,17 +426,15 @@ adjust_frame_size (struct frame *f, int new_width, int new_height, int inhibit,
if (inhibit >= 2 && inhibit <= 4)
/* When INHIBIT is in [2..4] inhibit if the "old" window sizes stay
within the limits and either frame_inhibit_resize tells us to do
so or INHIBIT equals 4. */
within the limits and either resizing is inhibited or INHIBIT
equals 4. */
{
inhibit_horizontal = ((windows_width >= min_windows_width
&& (inhibit == 4
|| frame_inhibit_resize (f, true, parameter)))
? true : false);
inhibit_vertical = ((windows_height >= min_windows_height
&& (inhibit == 4
|| frame_inhibit_resize (f, false, parameter)))
? true : false);
inhibit_horizontal = (windows_width >= min_windows_width
&& (inhibit == 4
|| frame_inhibit_resize (f, true, parameter)));
inhibit_vertical = (windows_height >= min_windows_height
&& (inhibit == 4
|| frame_inhibit_resize (f, false, parameter)));
}
else
/* Otherwise inhibit if INHIBIT equals 5. */
......@@ -634,6 +633,10 @@ make_frame (bool mini_p)
f->garbaged = true;
f->can_x_set_window_size = false;
f->after_make_frame = false;
f->inhibit_horizontal_resize = false;
f->inhibit_vertical_resize = false;
f->tool_bar_redisplayed = false;
f->tool_bar_resized = false;
f->column_width = 1; /* !FRAME_WINDOW_P value. */
f->line_height = 1; /* !FRAME_WINDOW_P value. */
#ifdef HAVE_WINDOW_SYSTEM
......@@ -2303,6 +2306,8 @@ otherwise used with utter care to avoid that running functions on
{
struct frame *f = decode_live_frame (frame);
f->after_make_frame = !NILP (made);
f->inhibit_horizontal_resize = false;
f->inhibit_vertical_resize = false;
return made;
}
......@@ -3166,15 +3171,33 @@ x_set_frame_parameters (struct frame *f, Lisp_Object alist)
prop = parms[i];
val = values[i];
if (EQ (prop, Qwidth) && RANGED_INTEGERP (0, val, INT_MAX))
if (EQ (prop, Qwidth))
{
width_change = 1;
width = XFASTINT (val) * FRAME_COLUMN_WIDTH (f) ;
if (RANGED_INTEGERP (0, val, INT_MAX))
{
width = XFASTINT (val) * FRAME_COLUMN_WIDTH (f) ;
width_change = true;
}
else if (CONSP (val) && EQ (XCAR (val), Qtext_pixels)
&& RANGED_INTEGERP (0, XCDR (val), INT_MAX))
{
width = XFASTINT (XCDR (val));
width_change = true;
}
}
else if (EQ (prop, Qheight) && RANGED_INTEGERP (0, val, INT_MAX))
else if (EQ (prop, Qheight))
{
height_change = 1;
height = XFASTINT (val) * FRAME_LINE_HEIGHT (f);
if (RANGED_INTEGERP (0, val, INT_MAX))
{
height = XFASTINT (val) * FRAME_LINE_HEIGHT (f);
height_change = true;
}
else if (CONSP (val) && EQ (XCAR (val), Qtext_pixels)
&& RANGED_INTEGERP (0, XCDR (val), INT_MAX))
{
height = XFASTINT (XCDR (val));
height_change = true;
}
}
else if (EQ (prop, Qtop))
top = val;
......@@ -3262,28 +3285,15 @@ x_set_frame_parameters (struct frame *f, Lisp_Object alist)
XSETFRAME (frame, f);
if ((width_change && width != FRAME_TEXT_WIDTH (f))
|| (height_change && height != FRAME_TEXT_HEIGHT (f))
|| (f->can_x_set_window_size && (f->new_height || f->new_width)))
{
/* If necessary provide default values for HEIGHT and WIDTH. Do
that here since otherwise a size change implied by an
intermittent font change may get lost as in Bug#17142. */
if (!width_change)
width = ((f->can_x_set_window_size && f->new_width)
? (f->new_pixelwise
? f->new_width
: (f->new_width * FRAME_COLUMN_WIDTH (f)))
: FRAME_TEXT_WIDTH (f));
if (!height_change)
height = ((f->can_x_set_window_size && f->new_height)
? (f->new_pixelwise
? f->new_height
: (f->new_height * FRAME_LINE_HEIGHT (f)))
: FRAME_TEXT_HEIGHT (f));
Fset_frame_size (frame, make_number (width), make_number (height), Qt);
}
|| (height_change && height != FRAME_TEXT_HEIGHT (f)))
/* We could consider checking f->after_make_frame here, but I
don't have the faintest idea why the following is needed at
all. With the old setting it can get a Heisenbug when
EmacsFrameResize intermittently provokes a delayed
change_frame_size in the middle of adjust_frame_size. */
/** || (f->can_x_set_window_size && (f->new_height || f->new_width))) **/
adjust_frame_size (f, width_change ? width : -1,
height_change ? height : -1, 1, 0, Qx_set_frame_parameters);
if ((!NILP (left) || !NILP (top))
&& ! (left_no_change && top_no_change)
......@@ -4552,7 +4562,7 @@ On Nextstep, this just calls `ns-parse-geometry'. */)
#define DEFAULT_COLS 80
long
x_figure_window_size (struct frame *f, Lisp_Object parms, bool toolbar_p)
x_figure_window_size (struct frame *f, Lisp_Object parms, bool toolbar_p, int *x_width, int *x_height)
{
Lisp_Object height, width, user_size, top, left, user_position;
long window_prompting = 0;
......@@ -4571,44 +4581,11 @@ x_figure_window_size (struct frame *f, Lisp_Object parms, bool toolbar_p)
f->top_pos = 0;
f->left_pos = 0;
/* Ensure that earlier new_width and new_height settings won't
override what we specify below. */
f->new_width = f->new_height = 0;
height = x_get_arg (dpyinfo, parms, Qheight, 0, 0, RES_TYPE_NUMBER);
width = x_get_arg (dpyinfo, parms, Qwidth, 0, 0, RES_TYPE_NUMBER);
if (!EQ (width, Qunbound) || !EQ (height, Qunbound))
{
if (!EQ (width, Qunbound))
{
CHECK_NUMBER (width);
if (! (0 <= XINT (width) && XINT (width) <= INT_MAX))
xsignal1 (Qargs_out_of_range, width);
SET_FRAME_WIDTH (f, XINT (width) * FRAME_COLUMN_WIDTH (f));
}
if (!EQ (height, Qunbound))
{
CHECK_NUMBER (height);
if (! (0 <= XINT (height) && XINT (height) <= INT_MAX))
xsignal1 (Qargs_out_of_range, height);
SET_FRAME_HEIGHT (f, XINT (height) * FRAME_LINE_HEIGHT (f));
}
user_size = x_get_arg (dpyinfo, parms, Quser_size, 0, 0, RES_TYPE_NUMBER);
if (!NILP (user_size) && !EQ (user_size, Qunbound))
window_prompting |= USSize;
else
window_prompting |= PSize;
}
/* Add a tool bar height to the initial frame height so that the user
gets a text display area of the size he specified with -g or via
.Xdefaults. Later changes of the tool bar height don't change the
frame size. This is done so that users can create tall Emacs
frames without having to guess how tall the tool bar will get. */
/* Calculate a tool bar height so that the user gets a text display
area of the size he specified with -g or via .Xdefaults. Later
changes of the tool bar height don't change the frame size. This
is done so that users can create tall Emacs frames without having
to guess how tall the tool bar will get. */
if (toolbar_p && FRAME_TOOL_BAR_LINES (f))
{
if (frame_default_tool_bar_height)
......@@ -4634,6 +4611,65 @@ x_figure_window_size (struct frame *f, Lisp_Object parms, bool toolbar_p)
}
}
/* Ensure that earlier new_width and new_height settings won't
override what we specify below. */
f->new_width = f->new_height = 0;
height = x_get_arg (dpyinfo, parms, Qheight, 0, 0, RES_TYPE_NUMBER);
width = x_get_arg (dpyinfo, parms, Qwidth, 0, 0, RES_TYPE_NUMBER);
if (!EQ (width, Qunbound) || !EQ (height, Qunbound))
{
if (!EQ (width, Qunbound))
{
if (CONSP (width) && EQ (XCAR (width), Qtext_pixels))
{
CHECK_NUMBER (XCDR (width));
if ((XINT (XCDR (width)) < 0 || XINT (XCDR (width)) > INT_MAX))
xsignal1 (Qargs_out_of_range, XCDR (width));
SET_FRAME_WIDTH (f, XINT (XCDR (width)));
f->inhibit_horizontal_resize = true;
*x_width = XINT (XCDR (width));
}
else
{
CHECK_NUMBER (width);
if ((XINT (width) < 0 || XINT (width) > INT_MAX))
xsignal1 (Qargs_out_of_range, width);
SET_FRAME_WIDTH (f, XINT (width) * FRAME_COLUMN_WIDTH (f));
}
}
if (!EQ (height, Qunbound))
{
if (CONSP (height) && EQ (XCAR (height), Qtext_pixels))
{
CHECK_NUMBER (XCDR (height));
if ((XINT (XCDR (height)) < 0 || XINT (XCDR (height)) > INT_MAX))
xsignal1 (Qargs_out_of_range, XCDR (height));
SET_FRAME_HEIGHT (f, XINT (XCDR (height)));
f->inhibit_vertical_resize = true;
*x_height = XINT (XCDR (height));
}
else
{
CHECK_NUMBER (height);
if ((XINT (height) < 0) || (XINT (height) > INT_MAX))
xsignal1 (Qargs_out_of_range, height);
SET_FRAME_HEIGHT (f, XINT (height) * FRAME_LINE_HEIGHT (f));
}
}
user_size = x_get_arg (dpyinfo, parms, Quser_size, 0, 0, RES_TYPE_NUMBER);
if (!NILP (user_size) && !EQ (user_size, Qunbound))
window_prompting |= USSize;
else
window_prompting |= PSize;
}
top = x_get_arg (dpyinfo, parms, Qtop, 0, 0, RES_TYPE_NUMBER);
left = x_get_arg (dpyinfo, parms, Qleft, 0, 0, RES_TYPE_NUMBER);
user_position = x_get_arg (dpyinfo, parms, Quser_position, 0, 0, RES_TYPE_NUMBER);
......@@ -4852,6 +4888,7 @@ syms_of_frame (void)
DEFSYM (Qonly, "only");
DEFSYM (Qnone, "none");
DEFSYM (Qwidth, "width");
DEFSYM (Qtext_pixels, "text-pixels");
DEFSYM (Qgeometry, "geometry");
DEFSYM (Qicon_left, "icon-left");
DEFSYM (Qicon_top, "icon-top");
......@@ -4909,7 +4946,9 @@ syms_of_frame (void)
DEFSYM (Qadjust_frame_size_1, "adjust-frame-size-1");
DEFSYM (Qadjust_frame_size_2, "adjust-frame-size-2");
DEFSYM (Qadjust_frame_size_3, "adjust-frame-size-3");
DEFSYM (Qx_set_frame_parameters, "x-set-frame-parameters");
DEFSYM (QEmacsFrameResize, "EmacsFrameResize");
DEFSYM (Qset_frame_size, "set-frame-size");
DEFSYM (Qframe_inhibit_resize, "frame-inhibit-resize");
DEFSYM (Qx_set_fullscreen, "x-set-fullscreen");
DEFSYM (Qx_check_fullscreen, "x-check-fullscreen");
......@@ -4917,13 +4956,16 @@ syms_of_frame (void)
DEFSYM (Qxg_frame_set_char_size_1, "xg-frame-set-char-size-1");
DEFSYM (Qxg_frame_set_char_size_2, "xg-frame-set-char-size-2");
DEFSYM (Qxg_frame_set_char_size_3, "xg-frame-set-char-size-3");
DEFSYM (Qx_set_window_size_1, "x-set-window-size-1");
DEFSYM (Qx_set_window_size_2, "x-set-window-size-2");
DEFSYM (Qx_set_window_size_3, "x-set-window-size-3");
DEFSYM (Qxg_change_toolbar_position, "xg-change-toolbar-position");
DEFSYM (Qx_net_wm_state, "x-net-wm-state");
DEFSYM (Qx_handle_net_wm_state, "x-handle-net-wm-state");
DEFSYM (Qtb_size_cb, "tb-size-cb");
DEFSYM (Qupdate_frame_tool_bar, "update-frame-tool-bar");
DEFSYM (Qfree_frame_tool_bar, "free-frame-tool-bar");
DEFSYM (Qx_set_menu_bar_lines, "x-set-menu-bar-lines");
DEFSYM (Qchange_frame_size, "change-frame-size");
DEFSYM (Qxg_frame_set_char_size, "xg-frame-set-char-size");
DEFSYM (Qset_window_configuration, "set-window-configuration");
......@@ -4952,6 +4994,9 @@ syms_of_frame (void)
DEFSYM (Qleft_fringe, "left-fringe");
DEFSYM (Qline_spacing, "line-spacing");
DEFSYM (Qmenu_bar_lines, "menu-bar-lines");
DEFSYM (Qupdate_frame_menubar, "update-frame-menubar");
DEFSYM (Qfree_frame_menubar_1, "free-frame-menubar-1");
DEFSYM (Qfree_frame_menubar_2, "free-frame-menubar-2");
DEFSYM (Qmouse_color, "mouse-color");
DEFSYM (Qname, "name");
DEFSYM (Qright_divider_width, "right-divider-width");
......
......@@ -335,6 +335,14 @@ struct frame
/* Set to true after this frame was made by `make-frame'. */
bool_bf after_make_frame : 1;
/* Whether the tool bar height change should be taken into account. */
bool_bf tool_bar_redisplayed : 1;
bool_bf tool_bar_resized : 1;
/* Inhibit implied resize before after_make_frame is set. */
bool_bf inhibit_horizontal_resize : 1;
bool_bf inhibit_vertical_resize : 1;
/* Non-zero if this frame's faces need to be recomputed. */
bool_bf face_change : 1;
......@@ -1375,7 +1383,7 @@ extern void x_set_horizontal_scroll_bars (struct frame *, Lisp_Object, Lisp_Obje
extern void x_set_scroll_bar_width (struct frame *, Lisp_Object, Lisp_Object);
extern void x_set_scroll_bar_height (struct frame *, Lisp_Object, Lisp_Object);
extern long x_figure_window_size (struct frame *, Lisp_Object, bool);
extern long x_figure_window_size (struct frame *, Lisp_Object, bool, int *, int *);
extern void x_set_alpha (struct frame *, Lisp_Object, Lisp_Object);
......
......@@ -951,6 +951,8 @@ xg_frame_set_char_size (struct frame *f, int width, int height)
totalwidth /= scale;
}
x_wm_set_size_hint (f, 0, 0);
/* Resize the top level widget so rows and columns remain constant.
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)
{
frame_size_history_add
(f, Qxg_frame_set_char_size_1, width, height,
list2 (make_number (gheight),
make_number (totalheight)));
list2 (make_number (gheight), make_number (totalheight)));
gtk_window_resize (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
gwidth,
totalheight);
gwidth, totalheight);
}
else if (EQ (fullscreen, Qfullheight) && height == FRAME_TEXT_HEIGHT (f))
{
frame_size_history_add
(f, Qxg_frame_set_char_size_2, width, height,
list2 (make_number (gwidth),
make_number (totalwidth)));
list2 (make_number (gwidth), make_number (totalwidth)));
gtk_window_resize (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
totalwidth,
gheight);
totalwidth, gheight);
}
else
{
frame_size_history_add
(f, Qxg_frame_set_char_size_3, width, height,
list2 (make_number (totalwidth),
make_number (totalheight)));
list2 (make_number (totalwidth), make_number (totalheight)));
gtk_window_resize (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
totalwidth,
totalheight);
totalwidth, totalheight);
fullscreen = Qnil;
}
SET_FRAME_GARBAGED (f);
cancel_mouse_face (f);
x_wm_set_size_hint (f, 0, 0);
/* We can not call change_frame_size for a mapped frame,
we can not set pixel width/height either. The window manager may
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)
hint_flags |= GDK_HINT_BASE_SIZE;
/* Use one row/col here so base_height/width does not become zero.
Gtk+ and/or Unity on Ubuntu 12.04 can't handle it. */
Gtk+ and/or Unity on Ubuntu 12.04 can't handle it.
Obviously this makes the row/col value displayed off by 1. */
base_width = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, 1) + FRAME_TOOLBAR_WIDTH (f);
base_height = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, 1)
+ FRAME_MENUBAR_HEIGHT (f) + FRAME_TOOLBAR_HEIGHT (f);
......@@ -4998,9 +4994,23 @@ update_frame_tool_bar (struct frame *f)
gtk_widget_show_all (x->toolbar_widget);
if (xg_update_tool_bar_sizes (f))
{
int inhibit
= ((f->after_make_frame
&& !f->tool_bar_resized
&& (EQ (frame_inhibit_implied_resize, Qt)
|| (CONSP (frame_inhibit_implied_resize)
&& !NILP (Fmemq (Qtool_bar_lines,
frame_inhibit_implied_resize))))
/* This will probably fail to DTRT in the
fullheight/-width cases. */
&& NILP (get_frame_param (f, Qfullscreen)))
? 0
: 2);
frame_size_history_add (f, Qupdate_frame_tool_bar, 0, 0, Qnil);
adjust_frame_size (f, -1, -1, 2, 0, Qtool_bar_lines);
adjust_frame_size (f, -1, -1, inhibit, 0, Qtool_bar_lines);
}
f->tool_bar_resized = f->tool_bar_redisplayed;
}
unblock_input ();
......
......@@ -679,7 +679,23 @@ Turn the input menu (an NSMenu) into a lisp list for tracking on lisp side
}
}
x_set_window_size (f, 0, f->text_cols, f->text_lines, 0);
{
int inhibit
= ((f->after_make_frame
&& !f->tool_bar_resized
&& (EQ (frame_inhibit_implied_resize, Qt)
|| (CONSP (frame_inhibit_implied_resize)
&& !NILP (Fmemq (Qtool_bar_lines,
frame_inhibit_implied_resize))))
/* This will probably fail to DTRT in the
fullheight/-width cases. */
&& NILP (get_frame_param (f, Qfullscreen)))
? 0
: 2);
frame_size_history_add (f, Qupdate_frame_tool_bar, 0, 0, Qnil);
adjust_frame_size (f, -1, -1, inhibit, 0, Qtool_bar_lines);
}
}
......@@ -1082,6 +1098,7 @@ Turn the input menu (an NSMenu) into a lisp list for tracking on lisp side
Lisp_Object parent;
struct kboard *kb;
static int desc_ctr = 1;
int x_width = 0, x_height = 0;
/* x_get_arg modifies parms. */
parms = Fcopy_alist (parms);
......@@ -1268,7 +1285,7 @@ Turn the input menu (an NSMenu) into a lisp list for tracking on lisp side
RES_TYPE_STRING);
parms = get_geometry_from_preferences (dpyinfo, parms);
window_prompting = x_figure_window_size (f, parms, 1);
window_prompting = x_figure_window_size (f, parms, true, &x_width, &x_height);
tem = x_get_arg (dpyinfo, parms, Qunsplittable, 0, 0, RES_TYPE_BOOLEAN);
f->no_split = minibuffer_only || (!EQ (tem, Qunbound) && !EQ (tem, Qnil));
......@@ -1322,6 +1339,11 @@ Turn the input menu (an NSMenu) into a lisp list for tracking on lisp side
/* Allow x_set_window_size, now. */
f->can_x_set_window_size = true;
if (x_width > 0)
SET_FRAME_WIDTH (f, x_width);
if (x_height > 0)
SET_FRAME_HEIGHT (f, x_height);
adjust_frame_size (f, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f), 0, 1,
Qx_create_frame_2);
......
......@@ -1365,8 +1365,11 @@ Free a pool and temporary objects it refers to (callable from C)
FRAME_TOOLBAR_HEIGHT (f) =
NSHeight ([window frameRectForContentRect: NSMakeRect (0, 0, 0, 0)])
- FRAME_NS_TITLEBAR_HEIGHT (f);
#if 0
/* Only breaks things here, removed by martin 2015-09-30. */
#ifdef NS_IMPL_GNUSTEP
FRAME_TOOLBAR_HEIGHT (f) -= 3;
#endif
#endif
}
else
......@@ -1386,6 +1389,14 @@ Free a pool and temporary objects it refers to (callable from C)
else
wr.origin.y += orig_height - wr.size.height;
frame_size_history_add
(f, Qx_set_window_size_1, width, height,
list5 (Fcons (make_number (pixelwidth), make_number (pixelheight)),
Fcons (make_number (wr.size.width), make_number (wr.size.height)),
make_number (f->border_width),
make_number (FRAME_NS_TITLEBAR_HEIGHT (f)),
make_number (FRAME_TOOLBAR_HEIGHT (f))));
[view setRows: rows andColumns: cols];
[window setFrame: wr display: YES];
......@@ -7741,8 +7752,9 @@ @implementation EmacsDocument
/* Now make the frame display the given font. */
if (FRAME_NS_WINDOW (f) != 0 && ! [view isFullscreen])
x_set_window_size (f, false, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f),
FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), true);
adjust_frame_size (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f),
FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 3,
false, Qfont);
return font_object;
}
......
......@@ -1762,14 +1762,24 @@ x_change_tool_bar_height (struct frame *f, int height)
/* Recalculate toolbar height. */
f->n_tool_bar_rows = 0;
if (old_height == 0
&& (!f->after_make_frame
|| NILP (frame_inhibit_implied_resize)
|| (CONSP (frame_inhibit_implied_resize)
&& NILP (Fmemq (Qtool_bar_lines, frame_inhibit_implied_resize)))))
f->tool_bar_redisplayed = f->tool_bar_resized = false;
adjust_frame_size (f, -1, -1,
((NILP (fullscreen = get_frame_param (f, Qfullscreen))
|| EQ (fullscreen, Qfullwidth)) ? 1
((!f->tool_bar_resized
&& (NILP (fullscreen =
get_frame_param (f, Qfullscreen))
|| EQ (fullscreen, Qfullwidth))) ? 1
: (old_height == 0 || height == 0) ? 2
: 4),
false, Qtool_bar_lines);
f->tool_bar_resized = f->tool_bar_redisplayed;
/* adjust_frame_size might not have done anything, garbage frame
here. */
adjust_frame_glyphs (f);
......@@ -4368,97 +4378,7 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
case WM_WINDOWPOSCHANGING:
/* Don't restrict the sizing of any kind of frames. If the window
manager doesn't, there's no reason to do it ourselves. */
#if 0
if (frame_resize_pixelwise || hwnd == tip_window)
#endif
return 0;
#if 0
/* Don't restrict the sizing of fullscreened frames, allowing them to be
flush with the sides of the screen. */
f = x_window_to_frame (dpyinfo, hwnd);
if (f && FRAME_PREV_FSMODE (f) != FULLSCREEN_NONE)
return 0;
{
WINDOWPLACEMENT wp;
LPWINDOWPOS lppos = (WINDOWPOS *) lParam;
wp.length = sizeof (WINDOWPLACEMENT);
GetWindowPlacement (hwnd, &wp);
if (wp.showCmd != SW_SHOWMAXIMIZED && wp.showCmd != SW_SHOWMINIMIZED
&& (lppos->flags & SWP_NOSIZE) == 0)
{
RECT rect;
int wdiff;
int hdiff;
DWORD font_width;
DWORD line_height;
DWORD internal_border;
DWORD vscrollbar_extra;
DWORD hscrollbar_extra;
RECT wr;
wp.length = sizeof (wp);
GetWindowRect (hwnd, &wr);
enter_crit ();
font_width = GetWindowLong (hwnd, WND_FONTWIDTH_INDEX);
line_height = GetWindowLong (hwnd, WND_LINEHEIGHT_INDEX);
internal_border = GetWindowLong (hwnd, WND_BORDER_INDEX);
vscrollbar_extra = GetWindowLong (hwnd, WND_VSCROLLBAR_INDEX);
hscrollbar_extra = GetWindowLong (hwnd, WND_HSCROLLBAR_INDEX);
leave_crit ();
memset (&rect, 0, sizeof (rect));
AdjustWindowRect (&rect, GetWindowLong (hwnd, GWL_STYLE),
GetMenu (hwnd) != NULL);
/* Force width and height of client area to be exact
multiples of the character cell dimensions. */
wdiff = (lppos->cx - (rect.right - rect.left)
- 2 * internal_border - vscrollbar_extra)
% font_width;
hdiff = (lppos->cy - (rect.bottom - rect.top)
- 2 * internal_border - hscrollbar_extra)
% line_height;
if (wdiff || hdiff)
{
/* For right/bottom sizing we can just fix the sizes.
However for top/left sizing we will need to fix the X
and Y positions as well. */
int cx_mintrack = GetSystemMetrics (SM_CXMINTRACK);
int cy_mintrack = GetSystemMetrics (SM_CYMINTRACK);
lppos->cx = max (lppos->cx - wdiff, cx_mintrack);
lppos->cy = max (lppos->cy - hdiff, cy_mintrack);
if (wp.showCmd != SW_SHOWMAXIMIZED
&& (lppos->flags & SWP_NOMOVE) == 0)
{
if (lppos->x != wr.left || lppos->y != wr.top)
{
lppos->x += wdiff;