Fix frame height calculations with added menu bar on Windows (Bug#22105)

* doc/lispref/frames.texi (Parameter Access): Mention pitfalls
when simultaneously specifying multiple parameters for
`modify-frame-parameters' that all may change the frame's size.
* src/w32fns.c (x_set_menu_bar_lines): Don't set
windows_or_buffers_changed here.
(my_create_tip_window, Fx_show_tip): Call AdjustWindowRect
with third argument false.
* src/w32menu.c (set_frame_menubar): Set
windows_or_buffers_changed here.
* src/w32term.c (x_set_window_size): Determine third argument of
AdjustWindowRect from whether the frame has a menu bar and not
from whether it wants one.
This commit is contained in:
Martin Rudalics 2015-12-12 14:38:11 +01:00
parent 4b0e421374
commit 06f00d39ff
4 changed files with 39 additions and 19 deletions

View file

@ -1013,12 +1013,28 @@ display (@pxref{Frames}). If @var{alist} includes parameters that are
not meaningful for the @var{frame}'s display, this function will
change its value in the frame's parameter list, but will otherwise
ignore it.
When @var{alist} specifies more than one parameter whose value can
affect the new size of @var{frame}, the final size of the frame may
differ according to the toolkit used. For example, specifying that a
frame should from now on have a menu and/or tool bar instead of none and
simultaneously specifying the new height of the frame will inevitably
lead to a recalculation of the frame's height. Conceptually, in such
case, this function will try to have the explicit height specification
prevail. It cannot be excluded, however, that the addition (or removal)
of the menu or tool bar, when eventually performed by the toolkit, will
defeat this intention.
Sometimes, binding @code{frame-inhibit-implied-resize} (@pxref{Implied
Frame Resizing}) to a non-@code{nil} value around calls to this function
may fix the problem sketched here. Sometimes, however, exactly such
binding may be hit by the problem.
@end defun
@defun set-frame-parameter frame parm value
This function sets the frame parameter @var{parm} to the specified
@var{value}. If @var{frame} is @code{nil}, it defaults to the
selected frame.
@var{value}. If @var{frame} is @code{nil}, it defaults to the selected
frame.
@end defun
@defun modify-all-frames-parameters alist

View file

@ -1666,10 +1666,7 @@ x_set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
FRAME_MENU_BAR_LINES (f) = 0;
FRAME_MENU_BAR_HEIGHT (f) = 0;
if (nlines)
{
FRAME_EXTERNAL_MENU_BAR (f) = 1;
windows_or_buffers_changed = 23;
}
FRAME_EXTERNAL_MENU_BAR (f) = 1;
else
{
if (FRAME_EXTERNAL_MENU_BAR (f) == 1)
@ -4620,8 +4617,7 @@ my_create_tip_window (struct frame *f)
rect.right = FRAME_PIXEL_WIDTH (f);
rect.bottom = FRAME_PIXEL_HEIGHT (f);
AdjustWindowRect (&rect, f->output_data.w32->dwStyle,
FRAME_EXTERNAL_MENU_BAR (f));
AdjustWindowRect (&rect, f->output_data.w32->dwStyle, false);
tip_window = FRAME_W32_WINDOW (f)
= CreateWindow (EMACS_CLASS,
@ -6681,8 +6677,7 @@ Text larger than the specified size is clipped. */)
rect.left = rect.top = 0;
rect.right = width;
rect.bottom = height;
AdjustWindowRect (&rect, f->output_data.w32->dwStyle,
FRAME_EXTERNAL_MENU_BAR (f));
AdjustWindowRect (&rect, f->output_data.w32->dwStyle, false);
/* Position and size tooltip, and put it in the topmost group.
The add-on of FRAME_COLUMN_WIDTH to the 5th argument is a

View file

@ -494,7 +494,10 @@ set_frame_menubar (struct frame *f, bool first_time, bool deep_p)
/* Force the window size to be recomputed so that the frame's text
area remains the same, if menubar has just been created. */
if (old_widget == NULL)
adjust_frame_size (f, -1, -1, 2, false, Qmenu_bar_lines);
{
windows_or_buffers_changed = 23;
adjust_frame_size (f, -1, -1, 2, false, Qmenu_bar_lines);
}
}
unblock_input ();

View file

@ -6115,9 +6115,22 @@ x_set_window_size (struct frame *f, bool change_gravity,
int pixelwidth, pixelheight;
Lisp_Object fullscreen = get_frame_param (f, Qfullscreen);
RECT rect;
MENUBARINFO info;
int menu_bar_height;
block_input ();
/* Get the height of the menu bar here. It's used below to detect
whether the menu bar is wrapped. It's also used to specify the
third argument for AdjustWindowRect. FRAME_EXTERNAL_MENU_BAR which
has been used before for that reason is unreliable because it only
specifies whether we _want_ a menu bar for this frame and not
whether this frame _has_ a menu bar. See bug#22105. */
info.cbSize = sizeof (info);
info.rcBar.top = info.rcBar.bottom = 0;
GetMenuBarInfo (FRAME_W32_WINDOW (f), 0xFFFFFFFD, 0, &info);
menu_bar_height = info.rcBar.bottom - info.rcBar.top;
if (pixelwise)
{
pixelwidth = FRAME_TEXT_TO_PIXEL_WIDTH (f, width);
@ -6135,17 +6148,11 @@ x_set_window_size (struct frame *f, bool change_gravity,
height of the frame then the wrapped menu bar lines are not
accounted for (Bug#15174 and Bug#18720). Here we add these
extra lines to the frame height. */
MENUBARINFO info;
int default_menu_bar_height;
int menu_bar_height;
/* Why is (apparently) SM_CYMENUSIZE needed here instead of
SM_CYMENU ?? */
default_menu_bar_height = GetSystemMetrics (SM_CYMENUSIZE);
info.cbSize = sizeof (info);
info.rcBar.top = info.rcBar.bottom = 0;
GetMenuBarInfo (FRAME_W32_WINDOW (f), 0xFFFFFFFD, 0, &info);
menu_bar_height = info.rcBar.bottom - info.rcBar.top;
if ((default_menu_bar_height > 0)
&& (menu_bar_height > default_menu_bar_height)
@ -6160,8 +6167,7 @@ x_set_window_size (struct frame *f, bool change_gravity,
rect.right = pixelwidth;
rect.bottom = pixelheight;
AdjustWindowRect (&rect, f->output_data.w32->dwStyle,
FRAME_EXTERNAL_MENU_BAR (f));
AdjustWindowRect (&rect, f->output_data.w32->dwStyle, menu_bar_height > 0);
if (!(f->after_make_frame)
&& !(f->want_fullscreen & FULLSCREEN_WAIT)