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))
......
This diff is collapsed.
......@@ -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;
lppos->y += hdiff;
}
else
{
lppos->flags |= SWP_NOMOVE;
}
}
return 0;
}
}
}
goto dflt;
#endif
return 0;
case WM_GETMINMAXINFO:
/* 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. */)
struct w32_display_info *dpyinfo = NULL;
Lisp_Object parent;
struct kboard *kb;
int x_width = 0, x_height = 0;
if (!FRAME_W32_P (SELECTED_FRAME ())
&& !FRAME_INITIAL_P (SELECTED_FRAME ()))
......@@ -5199,7 +5120,7 @@ This function is an internal primitive--use `make-frame' instead. */)
f->output_data.w32->current_cursor = f->output_data.w32->nontext_cursor;
window_prompting = x_figure_window_size (f, parameters, true);
window_prompting = x_figure_window_size (f, parameters, true, &x_width, &x_height);
tem = x_get_arg (dpyinfo, parameters, Qunsplittable, 0, 0, RES_TYPE_BOOLEAN);
f->no_split = minibuffer_only || EQ (tem, Qt);
......@@ -5233,8 +5154,10 @@ This function is an internal primitive--use `make-frame' instead. */)
/* Allow x_set_window_size, now. */
f->can_x_set_window_size = true;
adjust_frame_size (f, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f), 0, true,
Qx_create_frame_2);
if (x_width > 0)
SET_FRAME_WIDTH (f, x_width);
if (x_height > 0)
SET_FRAME_HEIGHT (f, x_height);
/* Tell the server what size and position, etc, we want, and how
badly we want them. This should be done after we have the menu
......@@ -5243,6 +5166,9 @@ This function is an internal primitive--use `make-frame' instead. */)
x_wm_set_size_hint (f, window_prompting, false);
unblock_input ();
adjust_frame_size (f, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f), 0, true,
Qx_create_frame_2);
/* Process fullscreen parameter here in the hope that normalizing a
fullheight/fullwidth frame will produce the size set by the last
adjust_frame_size call. */
......@@ -6179,6 +6105,7 @@ x_create_tip_frame (struct w32_display_info *dpyinfo,
bool face_change_before = face_change;
Lisp_Object buffer;
struct buffer *old_buffer;
int x_width = 0, x_height = 0;
/* Use this general default value to start with until we know if
this frame has a specified name. */
......@@ -6309,7 +6236,7 @@ x_create_tip_frame (struct w32_display_info *dpyinfo,
f->output_data.w32->dwStyle = WS_BORDER | WS_POPUP | WS_DISABLED;
f->output_data.w32->parent_desc = FRAME_DISPLAY_INFO (f)->root_window;
window_prompting = x_figure_window_size (f, parms, false);
window_prompting = x_figure_window_size (f, parms, true, &x_width, &x_height);
/* No fringes on tip frame. */
f->fringe_cols = 0;
......
......@@ -6176,6 +6176,13 @@ x_set_window_size (struct frame *f, bool change_gravity,
if (pixelwidth > 0 || pixelheight > 0)
{
frame_size_history_add
(f, Qx_set_window_size_1, width, height,
list2 (Fcons (make_number (pixelwidth),
make_number (pixelheight)),
Fcons (make_number (rect.right - rect.left),
make_number (rect.bottom - rect.top))));
my_set_window_pos (FRAME_W32_WINDOW (f), NULL,
0, 0,
rect.right - rect.left,
......
......@@ -268,167 +268,26 @@ set_frame_size (EmacsFrame ew)
*/
/* Hairily merged geometry */
int w = FRAME_COLS (ew->emacs_frame.frame);
int h = FRAME_LINES (ew->emacs_frame.frame);
struct frame *f = ew->emacs_frame.frame;
int w = FRAME_COLS (f);
int h = FRAME_LINES (f);
Widget wmshell = get_wm_shell ((Widget) ew);
Dimension pixel_width, pixel_height;
/* Each Emacs shell is now independent and top-level. */
if (! XtIsSubclass (wmshell, shellWidgetClass)) emacs_abort ();
/* We don't need this for the moment. The geometry is computed in
xfns.c. */
#if 0
/* If the EmacsFrame doesn't have a geometry but the shell does,
treat that as the geometry of the frame. (Is this bogus?
I'm not sure.) */
if (ew->emacs_frame.geometry == 0)
XtVaGetValues (wmshell, XtNgeometry, &ew->emacs_frame.geometry, NULL);
/* If the Shell is iconic, then the EmacsFrame is iconic. (Is
this bogus? I'm not sure.) */
if (!ew->emacs_frame.iconic)
XtVaGetValues (wmshell, XtNiconic, &ew->emacs_frame.iconic, NULL);
{
char *geom = 0;
XtVaGetValues (app_shell, XtNgeometry, &geom, NULL);
if (geom)
app_flags = XParseGeometry (geom, &app_x, &app_y, &app_w, &app_h);
}
if (ew->emacs_frame.geometry)
frame_flags = XParseGeometry (ew->emacs_frame.geometry,
&frame_x, &frame_y,
&frame_w, &frame_h);
if (first_frame_p)
{
/* If this is the first frame created:
====================================
- Use the ApplicationShell's size/position, if specified.
(This is "Emacs.geometry", or the "-geometry" command line arg.)
- Else use the EmacsFrame's size/position.
(This is "*Frame-NAME.geometry")
- If the AppShell is iconic, the frame should be iconic.
AppShell comes first so that -geometry always applies to the first
frame created, even if there is an "every frame" entry in the
resource database.
*/
if (app_flags & (XValue | YValue))
{
x = app_x; y = app_y;
flags |= (app_flags & (XValue | YValue | XNegative | YNegative));
}
else if (frame_flags & (XValue | YValue))
{
x = frame_x; y = frame_y;
flags |= (frame_flags & (XValue | YValue | XNegative | YNegative));
}
if (app_flags & (WidthValue | HeightValue))
{
w = app_w; h = app_h;
flags |= (app_flags & (WidthValue | HeightValue));
}
else if (frame_flags & (WidthValue | HeightValue))
{
w = frame_w; h = frame_h;
flags |= (frame_flags & (WidthValue | HeightValue));
}
/* If the AppShell is iconic, then the EmacsFrame is iconic. */
if (!ew->emacs_frame.iconic)
XtVaGetValues (app_shell, XtNiconic, &ew->emacs_frame.iconic, NULL);
first_frame_p = False;
}
else
{
/* If this is not the first frame created:
========================================
- use the EmacsFrame's size/position if specified
- Otherwise, use the ApplicationShell's size, but not position.
So that means that one can specify the position of the first frame
with "Emacs.geometry" or `-geometry'; but can only specify the
position of subsequent frames with "*Frame-NAME.geometry".
AppShell comes second so that -geometry does not apply to subsequent
frames when there is an "every frame" entry in the resource db,
but does apply to the first frame.
*/
if (frame_flags & (XValue | YValue))
{
x = frame_x; y = frame_y;
flags |= (frame_flags & (XValue | YValue | XNegative | YNegative));
}
char_to_pixel_size (ew, w, h, &pixel_width, &pixel_height);
ew->core.width = (frame_resize_pixelwise
? FRAME_PIXEL_WIDTH (f)
: pixel_width);
ew->core.height = (frame_resize_pixelwise
? FRAME_PIXEL_HEIGHT (f)
: pixel_height);
if (frame_flags & (WidthValue | HeightValue))
{
w = frame_w; h = frame_h;
flags |= (frame_flags & (WidthValue | HeightValue));
}
else if (app_flags & (WidthValue | HeightValue))
{
w = app_w;
h = app_h;
flags |= (app_flags & (WidthValue | HeightValue));
}
}
#endif /* 0 */
{
Dimension pixel_width, pixel_height;
/* Take into account the size of the scrollbar. Always use the
number of columns occupied by the scroll bar here otherwise we
might end up with a frame width that is not a multiple of the
frame's character width which is bad for vertically split
windows. */
#if 0 /* This can run Lisp code, and it is dangerous to give
out the frame to Lisp code before it officially exists.
This is handled in Fx_create_frame so not needed here. */
change_frame_size (f, w, h, 1, 0, 0, 0);
#endif
char_to_pixel_size (ew, w, h, &pixel_width, &pixel_height);
ew->core.width = pixel_width;
ew->core.height = pixel_height;
#if 0 /* xfns.c takes care of this now. */
/* If a position was specified, assign it to the shell widget.
(Else WM won't do anything with it.)
*/
if (flags & (XValue | YValue))
{
/* the tricky things with the sign is to make sure that
-0 is printed -0. */
sprintf (shell_position, "=%c%d%c%d",
flags & XNegative ? '-' : '+', x < 0 ? -x : x,
flags & YNegative ? '-' : '+', y < 0 ? -y : y);
XtVaSetValues (wmshell, XtNgeometry, xstrdup (shell_position), NULL);
}
else if (flags & (WidthValue | HeightValue))
{
sprintf (shell_position, "=%dx%d", pixel_width, pixel_height);
XtVaSetValues (wmshell, XtNgeometry, xstrdup (shell_position), NULL);
}
/* If the geometry spec we're using has W/H components, mark the size
in the WM_SIZE_HINTS as user specified. */
if (flags & (WidthValue | HeightValue))
mark_shell_size_user_specified (wmshell);
/* Also assign the iconic status of the frame to the Shell, so that
the WM sees it. */
XtVaSetValues (wmshell, XtNiconic, ew->emacs_frame.iconic, NULL);
#endif /* 0 */
}
frame_size_history_add
(f, Qset_frame_size, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f),
list2 (make_number (ew->core.width), make_number (ew->core.height)));
}
static void
......@@ -486,16 +345,6 @@ update_various_frame_slots (EmacsFrame ew)
{
struct frame *f = ew->emacs_frame.frame;
/* Don't do that: It confuses the check in change_frame_size_1 whether
the pixel size of the frame changed due to a change of the internal
border width. Bug#16736. */
if (false)
{
struct x_output *x = f->output_data.x;
FRAME_PIXEL_HEIGHT (f) = ew->core.height + x->menubar_height;
FRAME_PIXEL_WIDTH (f) = ew->core.width;
}
f->internal_border_width = ew->emacs_frame.internal_border_width;
}
......@@ -504,6 +353,7 @@ update_from_various_frame_slots (EmacsFrame ew)
{
struct frame *f = ew->emacs_frame.frame;
struct x_output *x = f->output_data.x;
ew->core.height = FRAME_PIXEL_HEIGHT (f) - x->menubar_height;
ew->core.width = FRAME_PIXEL_WIDTH (f);
ew->core.background_pixel = FRAME_BACKGROUND_PIXEL (f);
......@@ -576,7 +426,10 @@ EmacsFrameResize (Widget widget)
frame_size_history_add
(f, QEmacsFrameResize, width, height,
list2 (make_number (ew->core.width), make_number (ew->core.height)));
list5 (make_number (ew->core.width), make_number (ew->core.height),
make_number (FRAME_TOP_MARGIN_HEIGHT (f)),
make_number (FRAME_SCROLL_BAR_AREA_HEIGHT (f)),
make_number (2 * FRAME_INTERNAL_BORDER_WIDTH (f))));
change_frame_size (f, width, height, 0, 1, 0, 1);
......@@ -596,11 +449,12 @@ EmacsFrameQueryGeometry (Widget widget, XtWidgetGeometry *request, XtWidgetGeome
if (mask & (CWWidth | CWHeight))
{