Document pixelwise frame resizing and fix related bug on Windows.
* w32term.c (x_set_window_size): When frame-resize-pixelwise is nil, always resize character wise to avoid potential loss of the mode line (Bug#16923 related). * display.texi (Temporary Displays): Say that with-temp-buffer-window makes its buffer current. * frames.texi (Size and Position): Describe new option `frame-resize-pixelwise'. Rewrite descriptions of `set-frame-size', `set-frame-height' and `set-frame-width'.
This commit is contained in:
parent
56759cf12a
commit
cfd5e825ae
5 changed files with 118 additions and 41 deletions
|
@ -1,3 +1,11 @@
|
|||
2014-03-14 Martin Rudalics <rudalics@gmx.at>
|
||||
|
||||
* display.texi (Temporary Displays): Say that
|
||||
with-temp-buffer-window makes its buffer current.
|
||||
* frames.texi (Size and Position): Describe new option
|
||||
`frame-resize-pixelwise'. Rewrite descriptions of
|
||||
`set-frame-size', `set-frame-height' and `set-frame-width'.
|
||||
|
||||
2014-03-09 Martin Rudalics <rudalics@gmx.at>
|
||||
|
||||
* elisp.texi (Top): Rename section "Width" to "Size of Displayed
|
||||
|
|
|
@ -1175,12 +1175,11 @@ is current, and the window it was displayed in is selected.
|
|||
@end defvar
|
||||
|
||||
@defmac with-temp-buffer-window buffer-or-name action quit-function forms@dots{}
|
||||
This macro is similar to @code{with-output-to-temp-buffer}.
|
||||
Like that construct, it executes @var{forms} while arranging to insert
|
||||
any output they print into the buffer named @var{buffer-or-name}.
|
||||
Finally, the buffer is displayed in some window, but not selected.
|
||||
Unlike @code{with-output-to-temp-buffer}, this does not switch to Help
|
||||
mode.
|
||||
This macro is similar to @code{with-output-to-temp-buffer}. Like that
|
||||
construct, it executes @var{forms} while arranging to insert any output
|
||||
they print into the buffer named @var{buffer-or-name} and displays the
|
||||
buffer in some window. Unlike @code{with-output-to-temp-buffer},
|
||||
however, this makes the buffer current and does not switch to Help mode.
|
||||
|
||||
The argument @var{buffer-or-name} specifies the temporary buffer.
|
||||
It can be either a buffer, which must already exist, or a string,
|
||||
|
|
|
@ -1147,21 +1147,46 @@ font. If you don't supply @var{frame}, these functions use the selected
|
|||
frame.
|
||||
@end defun
|
||||
|
||||
@defun set-frame-size frame cols rows
|
||||
This function sets the size of @var{frame}, measured in characters;
|
||||
@var{cols} and @var{rows} specify the new width and height.
|
||||
@defopt frame-resize-pixelwise
|
||||
If this option is @code{nil}, a frame's size is usually rounded to a
|
||||
multiple of the current values of that frame's @code{frame-char-height}
|
||||
and @code{frame-char-width}. If this is non-@code{nil}, no rounding
|
||||
occurs, hence frame sizes can increase/decrease by one pixel.
|
||||
|
||||
To set the size based on values measured in pixels, use
|
||||
@code{frame-char-height} and @code{frame-char-width} to convert
|
||||
them to units of characters.
|
||||
Setting this causes the next resize operation to pass the corresponding
|
||||
size hints to the window manager. This means that this variable should
|
||||
be set only in a user's initial file; applications should never bind it
|
||||
temporarily.
|
||||
|
||||
The precise semantics of a value of @code{nil} for this option depends
|
||||
on the toolkit used: Dragging the frame border with the mouse is usually
|
||||
always done character-wise. Calling @code{set-frame-size} (see below)
|
||||
with arguments that do not specify the frame size as an integer multiple
|
||||
of its character size may be, however, either ignored or cause a
|
||||
rounding (GTK+, Windows) or get accepted (Lucid, Motif). This also
|
||||
means that with some toolkits and a display whose size is not an
|
||||
integral multiple of your default font, you may have to set this to
|
||||
non-@code{nil} in order to fully maximize a frame.
|
||||
@end defopt
|
||||
|
||||
@defun set-frame-size frame width height pixelwise
|
||||
This function sets the size of @var{frame}, measured in characters;
|
||||
@var{width} and @var{height} specify the new width in columns and the
|
||||
new height in lines.
|
||||
|
||||
The optional argument @var{pixelwise} non-@code{nil} means to measure
|
||||
the new width and height in units of pixels instead. Note that if
|
||||
@code{frame-resize-pixelwise} is @code{nil}, some toolkits may refuse to
|
||||
fully honor the request if it does not increase/decrease the frame size
|
||||
to a multiple of its character size.
|
||||
@end defun
|
||||
|
||||
@defun set-frame-height frame lines &optional pretend
|
||||
This function resizes @var{frame} to a height of @var{lines} lines. The
|
||||
@defun set-frame-height frame height &optional pretend pixelwise
|
||||
This function resizes @var{frame} to a height of @var{height} lines. The
|
||||
sizes of existing windows in @var{frame} are altered proportionally to
|
||||
fit.
|
||||
|
||||
If @var{pretend} is non-@code{nil}, then Emacs displays @var{lines}
|
||||
If @var{pretend} is non-@code{nil}, then Emacs displays @var{height}
|
||||
lines of output in @var{frame}, but does not change its value for the
|
||||
actual height of the frame. This is only useful on text terminals.
|
||||
Using a smaller height than the terminal actually implements may be
|
||||
|
@ -1170,12 +1195,24 @@ terminal malfunctions when using its whole screen. Setting the frame
|
|||
height ``for real'' does not always work, because knowing the correct
|
||||
actual size may be necessary for correct cursor positioning on
|
||||
text terminals.
|
||||
|
||||
The optional fourth argument @var{pixelwise} non-@code{nil} means that
|
||||
@var{frame} should be @var{height} pixels high. Note that if
|
||||
@code{frame-resize-pixelwise} is @code{nil}, some toolkits may refuse to
|
||||
fully honor the request if it does not increase/decrease the frame
|
||||
height to a multiple of its character height.
|
||||
@end defun
|
||||
|
||||
@defun set-frame-width frame width &optional pretend
|
||||
@defun set-frame-width frame width &optional pretend pixelwise
|
||||
This function sets the width of @var{frame}, measured in characters.
|
||||
The argument @var{pretend} has the same meaning as in
|
||||
@code{set-frame-height}.
|
||||
|
||||
The optional fourth argument @var{pixelwise} non-@code{nil} means that
|
||||
@var{frame} should be @var{width} pixels wide. Note that if
|
||||
@code{frame-resize-pixelwise} is @code{nil}, some toolkits may refuse to
|
||||
fully honor the request if it does not increase/decrease the frame width
|
||||
to a multiple of its character width.
|
||||
@end defun
|
||||
|
||||
@c FIXME? Belongs more in Emacs manual than here?
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
2014-03-14 Martin Rudalics <rudalics@gmx.at>
|
||||
|
||||
* w32term.c (x_set_window_size): When frame-resize-pixelwise is
|
||||
nil, always resize character wise to avoid potential loss of the
|
||||
mode line (Bug#16923 related).
|
||||
|
||||
2014-03-12 Martin Rudalics <rudalics@gmx.at>
|
||||
|
||||
* frame.c (x_set_frame_parameters): Always calculate new sizes
|
||||
|
|
|
@ -5648,6 +5648,31 @@ x_set_window_size (struct frame *f, int change_gravity, int width, int height, b
|
|||
pixelheight = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, height);
|
||||
}
|
||||
|
||||
if (!frame_resize_pixelwise)
|
||||
{
|
||||
/* If we don't resize frames pixelwise, round sizes to multiples
|
||||
of character sizes. Otherwise, Windows may clip our frame
|
||||
rectangle at a character size boundary and we risk losing our
|
||||
mode line. Bug#16923 might be a consequence of this.
|
||||
|
||||
So far, this is a Windows specific problem; other toolkits may
|
||||
prefer to not resize the frame if the delta is not large enough
|
||||
(GTK) or resize the frame pixelwise as requested (Lucid,
|
||||
Motif). Windows just doesn't call us back (probably because of
|
||||
the size hint settings which it apparently interprets strictly)
|
||||
neither when the user tries to mouse-drag a frame border by,
|
||||
nor when calling `set-frame-size' with a delta of less than the
|
||||
canonical character size. If w32_enable_frame_resize_hack is
|
||||
enabled (which it now is by default) we'd then below resize the
|
||||
frame's root window in preparation of a WM_SIZE message to come
|
||||
which, however, is not going to happen. */
|
||||
int unit_width = FRAME_COLUMN_WIDTH (f);
|
||||
int unit_height = FRAME_LINE_HEIGHT (f);
|
||||
|
||||
pixelwidth = (pixelwidth / unit_width) * unit_width;
|
||||
pixelheight = (pixelheight / unit_height) * unit_height;
|
||||
}
|
||||
|
||||
f->win_gravity = NorthWestGravity;
|
||||
x_wm_set_size_hint (f, (long) 0, 0);
|
||||
|
||||
|
@ -5670,39 +5695,40 @@ x_set_window_size (struct frame *f, int change_gravity, int width, int height, b
|
|||
}
|
||||
|
||||
/* If w32_enable_frame_resize_hack is non-nil, immediately apply the
|
||||
new pixel sizes to the frame and its subwindows. See discussion
|
||||
of Bug#16028 for why we need this. */
|
||||
new pixel sizes to the frame and its subwindows. This approach is
|
||||
fragile because Windows might not honor the resize request issued
|
||||
by my_set_window_pos with a WM_SIZE message (see previous comment).
|
||||
|
||||
if (w32_enable_frame_resize_hack)
|
||||
/* The following mirrors what is done in xterm.c. It appears to be
|
||||
for informing lisp of the new size immediately, while the actual
|
||||
resize will happen asynchronously. But on Windows, the menu bar
|
||||
automatically wraps when the frame is too narrow to contain it,
|
||||
and that causes any calculations made here to come out wrong. The
|
||||
end is some nasty buggy behavior, including the potential loss
|
||||
of the minibuffer.
|
||||
Jason Rumney earlier refused to call change_frame_size right here
|
||||
with the following argument:
|
||||
|
||||
The following mirrors what is done in xterm.c. It appears to be for
|
||||
informing lisp of the new size immediately, while the actual resize
|
||||
will happen asynchronously. But on Windows, the menu bar
|
||||
automatically wraps when the frame is too narrow to contain it, and
|
||||
that causes any calculations made here to come out wrong. The end
|
||||
is some nasty buggy behavior, including the potential loss of the
|
||||
minibuffer.
|
||||
|
||||
Disabling this code is either not sufficient to fix the problems
|
||||
completely, or it causes fresh problems, but at least it removes
|
||||
the most problematic symptom of the minibuffer becoming unusable.
|
||||
|
||||
-----------------------------------------------------------------
|
||||
However, as the discussion about how to handle frame size
|
||||
parameters on Windows (Bug#1348, Bug#16028) shows, that cure seems
|
||||
worse than the disease. In particular, menu bar wrapping looks
|
||||
like a non-issue - maybe so because Windows eventually gets back to
|
||||
us with the correct client rectangle anyway. But we have to avoid
|
||||
calling change_frame_size with a delta of less than one canoncial
|
||||
character size when frame_resize_pixelwise is nil, as explained in
|
||||
the comment above. */
|
||||
|
||||
Now, strictly speaking, we can't be sure that this is accurate,
|
||||
but the window manager will get around to dealing with the size
|
||||
change request eventually, and we'll hear how it went when the
|
||||
ConfigureNotify event gets here.
|
||||
if (w32_enable_frame_resize_hack)
|
||||
|
||||
We could just not bother storing any of this information here,
|
||||
and let the ConfigureNotify event set everything up, but that
|
||||
might be kind of confusing to the Lisp code, since size changes
|
||||
wouldn't be reported in the frame parameters until some random
|
||||
point in the future when the ConfigureNotify event arrives.
|
||||
|
||||
We pass 1 for DELAY since we can't run Lisp code inside of
|
||||
a BLOCK_INPUT. */
|
||||
{
|
||||
change_frame_size (f, width, height, 0, 1, 0, pixelwise);
|
||||
change_frame_size (f, FRAME_PIXEL_TO_TEXT_WIDTH (f, pixelwidth),
|
||||
FRAME_PIXEL_TO_TEXT_HEIGHT (f, pixelheight),
|
||||
0, 1, 0, 1);
|
||||
SET_FRAME_GARBAGED (f);
|
||||
|
||||
/* If cursor was outside the new size, mark it as off. */
|
||||
|
@ -5711,7 +5737,8 @@ x_set_window_size (struct frame *f, int change_gravity, int width, int height, b
|
|||
/* Clear out any recollection of where the mouse highlighting was,
|
||||
since it might be in a place that's outside the new frame size.
|
||||
Actually checking whether it is outside is a pain in the neck,
|
||||
so don't try--just let the highlighting be done afresh with new size. */
|
||||
so don't try--just let the highlighting be done afresh with new
|
||||
size. */
|
||||
cancel_mouse_face (f);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue