summaryrefslogtreecommitdiff
path: root/src/frame.c
diff options
context:
space:
mode:
authorMartin Rudalics <rudalics@gmx.at>2015-10-13 12:11:43 +0200
committerMartin Rudalics <rudalics@gmx.at>2015-10-13 12:11:43 +0200
commitd4fe840df0b5fdb3aed538fae2ced143a471f60a (patch)
tree13ff9d7115616a99af7e0257277a1ca6edf31f72 /src/frame.c
parente53e1a0426539aa3f2902632fdd8025da8f710f2 (diff)
downloademacs-d4fe840df0b5fdb3aed538fae2ced143a471f60a.tar.gz
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/frame.c')
-rw-r--r--src/frame.c221
1 files changed, 133 insertions, 88 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)
{
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");