Commit 8e7712c7 authored by Martin Rudalics's avatar Martin Rudalics
Browse files

Fix `window-configuration-change-hook' and `window-size-change-functions'

(1) Run `window-configuration-change-hook' if and only if at least
one window was deleted or created or shows another buffer since
last redisplay.

(2) Run `window-size-change-functions' if and only if at least
one window changed its size since last redisplay (in a few cases
`window-size-change-functions' will also run when no window
changed its size).

(3) Provide two functions `window-pixel-height-before-size-change'
and `window-pixel-width-before-size-change' that allow to easily
detect which window changed size.

* src/frame.h (struct frame): New boolean member
window_configuration_changed.
(FRAME_WINDOW_SIZES_CHANGED): Remove macro.
(FRAME_WINDOW_CONFIGURATION_CHANGED): New macro.
* src/frame.c (adjust_frame_size): Don't run
`window-configuration-change-hook'.
* src/window.h (struct window): New fields
pixel_width_before_size_change and pixel_height_before_size_change.
(WINDOW_INTERNAL_P): New macro.
* src/window.c (Fwindow_pixel_width_before_size_change)
(Fwindow_pixel_height_before_size_change): New functions.
(Fdelete_other_windows_internal, Fwindow_resize_apply)
(resize_frame_windows, Fsplit_window_internal)
(Fdelete_window_internal, grow_mini_window)
(shrink_mini_window, Fresize_mini_window_internal): Don't call
FRAME_WINDOW_SIZES_CHANGED.
(window_size_changed, window_set_before_size_change_sizes)
(run_window_size_change_functions): New functions.
(make_window): Initialize pixel_width_before_size_change and
pixel_height_before_size_change.
(Fdelete_window_internal): Don't call
run_window_configuration_change_hook.
(struct saved_window): Add pixel_height_before_size_change and
pixel_width_before_size_change.
(Fset_window_configuration): Try to identify window configuration
changes correctly so run_window_configuration_change_hook and
run_window_size_change_functions run only if configuration and size
really changed.
(save_window_save): Set the pixel_height_before_size_change and
pixel_width_before_size_change fields.
(Vwindow_size_change_functions): Move here definiton from xdisp.c.
* src/xdisp.c (prepare_menu_bars, redisplay_internal): Call
run_window_size_change_functions.
(Vwindow_size_change_functions): Move definition to window.c.
* src/xfns.c (x_set_menu_bar_lines): Don't call
run_window_configuration_change_hook.
* doc/lispref/windows.texi (Window Sizes): Document new
functions `window-pixel-height-before-size-change' and
`window-pixel-width-before-size-change'.
(Window Configurations): Mention that this may trigger
execution of `window-size-change-functions' although no window
changed size.
(Window Hooks): Update descriptions of `window-size-change-functions'
and `window-configuration-change-hook'.
parent ef52e66e
......@@ -545,6 +545,12 @@ its pixel height is the pixel height of the screen areas spanned by its
children.
@end defun
@defun window-pixel-height-before-size-change &optional Lisp_Object &optional window
This function returns the height of window @var{window} in pixels at the
time @code{window-size-change-functions} was run for the last time on
@var{window}'s frame (@pxref{Window Hooks}).
@end defun
@cindex window pixel width
@cindex pixel width of a window
@cindex total pixel width of a window
......@@ -559,6 +565,12 @@ If @var{window} is an internal window, its pixel width is the width of
the screen areas spanned by its children.
@end defun
@defun window-pixel-width-before-size-change &optional Lisp_Object &optional window
This function returns the width of window @var{window} in pixels at the
time @code{window-size-change-functions} was run for the last time on
@var{window}'s frame (@pxref{Window Hooks}).
@end defun
@cindex full-width window
@cindex full-height window
The following functions can be used to determine whether a given
......@@ -4087,11 +4099,11 @@ was created for.
The argument @var{configuration} must be a value that was previously
returned by @code{current-window-configuration}. The configuration is
restored in the frame from which @var{configuration} was made, whether
that frame is selected or not. This always counts as a window size
change and triggers execution of the @code{window-size-change-functions}
(@pxref{Window Hooks}), because @code{set-window-configuration} doesn't
know how to tell whether the new configuration actually differs from the
old one.
that frame is selected or not. In some rare cases this may trigger
execution of the @code{window-size-change-functions} (@pxref{Window
Hooks}) even if the size of windows did not change at all. The
@code{window-configuration-change-hook} functions will be called if and
only if at least one window was added to or deleted from the frame.
If the frame from which @var{configuration} was saved is dead, all this
function does is restore the three variables @code{window-min-height},
......@@ -4378,33 +4390,38 @@ work.
@end defvar
@defvar window-size-change-functions
This variable holds a list of functions to be called if the size of
any window changes for any reason. The functions are called at the
beginning of a redisplay cycle, and just once for each frame on which
size changes have occurred.
Each function receives the frame as its sole argument. There is no
direct way to find out which windows on that frame have changed size, or
precisely how. However, if a size-change function records, at each
call, the existing windows and their sizes, it can also compare the
present sizes and the previous sizes.
Creating or deleting windows counts as a size change, and therefore
causes these functions to be called. Changing the frame size also
counts, because it changes the sizes of the existing windows.
This variable holds a list of functions to be called if the size of any
window changes for any reason. The functions are called once per
redisplay, and once for each frame on which size changes have occurred.
Each function receives the frame as its sole argument. To find out
whether a specific window has changed size, compare the return values of
@code{window-pixel-width-before-size-change} and
@code{window-pixel-width} respectively
@code{window-pixel-height-before-size-change} and
@code{window-pixel-height} for that window (@pxref{Window Sizes}).
These function are usually only called when at least one window was
added or has changed size since the last time this hook was run for the
associated frame. In some rare cases this hook also runs when a window
that was added intermittently has been deleted afterwards. In these
cases none of the windows on the frame will appear to have changed its
size.
You may use @code{save-selected-window} in these functions
(@pxref{Selecting Windows}). However, do not use
@code{save-window-excursion} (@pxref{Window Configurations}); exiting
that macro counts as a size change, which would cause these functions
to be called over and over.
that macro counts as a size change, which would cause these functions to
be called again.
@end defvar
@defvar window-configuration-change-hook
A normal hook that is run every time you change the window configuration
of an existing frame. This includes splitting or deleting windows,
changing the sizes of windows, or displaying a different buffer in a
window.
A normal hook that is run every time the window configuration of a frame
changes. Window configuration changes include splitting and deleting
windows and the display of a different buffer in a window. Resizing the
frame or individual windows do not count as configuration changes. Use
@code{window-size-change-functions}, see above, when you want to track
size changes that are not caused by the deletion or creation of windows.
The buffer-local part of this hook is run once for each window on the
affected frame, with the relevant window selected and its buffer
......
......@@ -591,8 +591,6 @@ adjust_frame_size (struct frame *f, int new_width, int new_height, int inhibit,
|| new_pixel_height != old_pixel_height);
unblock_input ();
run_window_configuration_change_hook (f);
}
/* Allocate basically initialized frame. */
......
......@@ -288,8 +288,9 @@ struct frame
cleared. */
bool_bf explicit_name : 1;
/* True if size of some window on this frame has changed. */
bool_bf window_sizes_changed : 1;
/* True if configuration of windows on this frame has changed since
last call of run_window_size_change_functions. */
bool_bf window_configuration_changed : 1;
/* True if the mouse has moved on this display device
since the last time we checked. */
......@@ -828,10 +829,10 @@ default_pixels_per_inch_y (void)
are frozen on frame F. */
#define FRAME_WINDOWS_FROZEN(f) (f)->frozen_window_starts
/* True if a size change has been requested for frame F
but not yet really put into effect. This can be true temporarily
when an X event comes in at a bad time. */
#define FRAME_WINDOW_SIZES_CHANGED(f) (f)->window_sizes_changed
/* True if the frame's window configuration has changed since last call
of run_window_size_change_functions. */
#define FRAME_WINDOW_CONFIGURATION_CHANGED(f) \
((f)->window_configuration_changed)
/* The minibuffer window of frame F, if it has one; otherwise nil. */
#define FRAME_MINIBUF_WINDOW(f) f->minibuffer_window
......
......@@ -720,6 +720,34 @@ the height of the screen areas spanned by its children. */)
return make_number (decode_valid_window (window)->pixel_height);
}
DEFUN ("window-pixel-width-before-size-change", Fwindow_pixel_width_before_size_change,
Swindow_pixel_width_before_size_change, 0, 1, 0,
doc: /* Return pixel width of window WINDOW before last size changes.
WINDOW must be a valid window and defaults to the selected one.
The return value is the pixel width of WINDOW at the last time
`window-size-change-functions' was run. It's zero if WINDOW was made
after that. */)
(Lisp_Object window)
{
return (make_number
(decode_valid_window (window)->pixel_width_before_size_change));
}
DEFUN ("window-pixel-height-before-size-change", Fwindow_pixel_height_before_size_change,
Swindow_pixel_height_before_size_change, 0, 1, 0,
doc: /* Return pixel height of window WINDOW before last size changes.
WINDOW must be a valid window and defaults to the selected one.
The return value is the pixel height of WINDOW at the last time
`window-size-change-functions' was run. It's zero if WINDOW was made
after that. */)
(Lisp_Object window)
{
return (make_number
(decode_valid_window (window)->pixel_height_before_size_change));
}
DEFUN ("window-total-height", Fwindow_total_height, Swindow_total_height, 0, 2, 0,
doc: /* Return the height of window WINDOW in lines.
WINDOW must be a valid window and defaults to the selected one.
......@@ -2879,6 +2907,7 @@ window-start value is reasonable when this function is called. */)
Lisp_Object sibling, pwindow, swindow IF_LINT (= Qnil), delta;
ptrdiff_t startpos IF_LINT (= 0), startbyte IF_LINT (= 0);
int top IF_LINT (= 0), new_top;
bool resize_failed = false;
w = decode_valid_window (window);
XSETWINDOW (window, w);
......@@ -2978,8 +3007,6 @@ window-start value is reasonable when this function is called. */)
fset_redisplay (f);
Vwindow_list = Qnil;
FRAME_WINDOW_SIZES_CHANGED (f) = true;
bool resize_failed = false;
if (!WINDOW_LEAF_P (w))
{
......@@ -3229,6 +3256,76 @@ If WINDOW is omitted or nil, it defaults to the selected window. */)
return Qnil;
}
/* Compare old and present pixel sizes of windows in tree rooted at W.
Return true iff any of these windows differs in size. */
static bool
window_size_changed (struct window *w)
{
if (w->pixel_width != w->pixel_width_before_size_change
|| w->pixel_height != w->pixel_height_before_size_change)
return true;
if (WINDOW_INTERNAL_P (w))
{
w = XWINDOW (w->contents);
while (w)
{
if (window_size_changed (w))
return true;
w = NILP (w->next) ? 0 : XWINDOW (w->next);
}
}
return false;
}
/* Set before size change pixel sizes of windows in tree rooted at W to
their present pixel sizes. */
static void
window_set_before_size_change_sizes (struct window *w)
{
w->pixel_width_before_size_change = w->pixel_width;
w->pixel_height_before_size_change = w->pixel_height;
if (WINDOW_INTERNAL_P (w))
{
w = XWINDOW (w->contents);
while (w)
{
window_set_before_size_change_sizes (w);
w = NILP (w->next) ? 0 : XWINDOW (w->next);
}
}
}
void
run_window_size_change_functions (Lisp_Object frame)
{
struct frame *f = XFRAME (frame);
struct window *r = XWINDOW (FRAME_ROOT_WINDOW (f));
Lisp_Object functions = Vwindow_size_change_functions;
if (FRAME_WINDOW_CONFIGURATION_CHANGED (f) ||
window_size_changed (r))
{
while (CONSP (functions))
{
if (!EQ (XCAR (functions), Qt))
call1 (XCAR (functions), frame);
functions = XCDR (functions);
}
window_set_before_size_change_sizes (r);
FRAME_WINDOW_CONFIGURATION_CHANGED (f) = false;
}
}
/* Make WINDOW display BUFFER. RUN_HOOKS_P means it's allowed
to run hooks. See make_frame for a case where it's not allowed.
KEEP_MARGINS_P means that the current margins, fringes, and
......@@ -3263,15 +3360,9 @@ set_window_buffer (Lisp_Object window, Lisp_Object buffer,
if (!(keep_margins_p && samebuf))
{ /* If we're not actually changing the buffer, don't reset hscroll
and vscroll. This case happens for example when called from
change_frame_size_1, where we use a dummy call to
Fset_window_buffer on the frame's selected window (and no
other) just in order to run window-configuration-change-hook
(no longer true since change_frame_size_1 directly calls
run_window_configuration_change_hook). Resetting hscroll and
vscroll here is problematic for things like image-mode and
doc-view-mode since it resets the image's position whenever we
resize the frame. */
and vscroll. Resetting hscroll and vscroll here is problematic
for things like image-mode and doc-view-mode since it resets
the image's position whenever we resize the frame. */
w->hscroll = w->min_hscroll = w->hscroll_whole = 0;
w->suspend_auto_hscroll = false;
w->vscroll = 0;
......@@ -3283,10 +3374,8 @@ set_window_buffer (Lisp_Object window, Lisp_Object buffer,
w->start_at_line_beg = false;
w->force_start = false;
}
/* Maybe we could move this into the `if' but it's not obviously safe and
I doubt it's worth the trouble. */
wset_redisplay (w);
wset_redisplay (w);
wset_update_mode_line (w);
/* We must select BUFFER to run the window-scroll-functions and to look up
......@@ -3314,7 +3403,7 @@ set_window_buffer (Lisp_Object window, Lisp_Object buffer,
if (run_hooks_p)
{
if (! NILP (Vwindow_scroll_functions))
if (!NILP (Vwindow_scroll_functions))
run_hook_with_args_2 (Qwindow_scroll_functions, window,
Fmarker_position (w->start));
if (!samebuf)
......@@ -3559,6 +3648,8 @@ make_window (void)
w->phys_cursor_width = -1;
#endif
w->sequence_number = ++sequence_number;
w->pixel_width_before_size_change = 0;
w->pixel_height_before_size_change = 0;
w->scroll_bar_width = -1;
w->scroll_bar_height = -1;
w->column_number_displayed = -1;
......@@ -3922,7 +4013,6 @@ be applied on the Elisp level. */)
window_resize_apply (r, horflag);
fset_redisplay (f);
FRAME_WINDOW_SIZES_CHANGED (f) = true;
adjust_frame_glyphs (f);
unblock_input ();
......@@ -4087,7 +4177,6 @@ resize_frame_windows (struct frame *f, int size, bool horflag, bool pixelwise)
}
}
FRAME_WINDOW_SIZES_CHANGED (f) = true;
fset_redisplay (f);
}
......@@ -4214,7 +4303,6 @@ set correctly. See the code of `split-window' for how this is done. */)
p = XWINDOW (o->parent);
fset_redisplay (f);
FRAME_WINDOW_SIZES_CHANGED (f) = true;
new = make_window ();
n = XWINDOW (new);
wset_frame (n, frame);
......@@ -4383,7 +4471,6 @@ Signal an error when WINDOW is the only window on its frame. */)
fset_redisplay (f);
Vwindow_list = Qnil;
FRAME_WINDOW_SIZES_CHANGED (f) = true;
wset_next (w, Qnil); /* Don't delete w->next too. */
free_window_matrices (w);
......@@ -4451,9 +4538,6 @@ Signal an error when WINDOW is the only window on its frame. */)
}
else
unblock_input ();
/* Must be run by the caller:
run_window_configuration_change_hook (f); */
}
else
/* We failed: Relink WINDOW into window tree. */
......@@ -4527,7 +4611,6 @@ grow_mini_window (struct window *w, int delta, bool pixelwise)
/* Enforce full redisplay of the frame. */
/* FIXME: Shouldn't window--resize-root-window-vertically do it? */
fset_redisplay (f);
FRAME_WINDOW_SIZES_CHANGED (f) = true;
adjust_frame_glyphs (f);
unblock_input ();
}
......@@ -4567,7 +4650,6 @@ shrink_mini_window (struct window *w, bool pixelwise)
/* Enforce full redisplay of the frame. */
/* FIXME: Shouldn't window--resize-root-window-vertically do it? */
fset_redisplay (f);
FRAME_WINDOW_SIZES_CHANGED (f) = true;
adjust_frame_glyphs (f);
unblock_input ();
}
......@@ -4610,7 +4692,6 @@ DEFUN ("resize-mini-window-internal", Fresize_mini_window_internal, Sresize_mini
w->top_line = r->top_line + r->total_lines;
fset_redisplay (f);
FRAME_WINDOW_SIZES_CHANGED (f) = true;
adjust_frame_glyphs (f);
unblock_input ();
return Qt;
......@@ -5948,6 +6029,7 @@ struct saved_window
Lisp_Object window, buffer, start, pointm, old_pointm;
Lisp_Object pixel_left, pixel_top, pixel_height, pixel_width;
Lisp_Object pixel_height_before_size_change, pixel_width_before_size_change;
Lisp_Object left_col, top_line, total_cols, total_lines;
Lisp_Object normal_cols, normal_lines;
Lisp_Object hscroll, min_hscroll, hscroll_whole, suspend_auto_hscroll;
......@@ -6063,6 +6145,12 @@ the return value is nil. Otherwise the value is t. */)
struct window *root_window;
struct window **leaf_windows;
ptrdiff_t i, k, n_leaf_windows;
/* Records whether a window has been added or removed wrt the
original configuration. */
bool window_changed = false;
/* Records whether a window has changed its buffer wrt the
original configuration. */
bool buffer_changed = false;
/* Don't do this within the main loop below: This may call Lisp
code and is thus potentially unsafe while input is blocked. */
......@@ -6071,6 +6159,12 @@ the return value is nil. Otherwise the value is t. */)
p = SAVED_WINDOW_N (saved_windows, k);
window = p->window;
w = XWINDOW (window);
if (NILP (w->contents))
/* A dead window that will be resurrected, the window
configuration will change. */
window_changed = true;
if (BUFFERP (w->contents)
&& !EQ (w->contents, p->buffer)
&& BUFFER_LIVE_P (XBUFFER (p->buffer)))
......@@ -6100,7 +6194,6 @@ the return value is nil. Otherwise the value is t. */)
}
fset_redisplay (f);
FRAME_WINDOW_SIZES_CHANGED (f) = true;
/* Problem: Freeing all matrices and later allocating them again
is a serious redisplay flickering problem. What we would
......@@ -6156,6 +6249,10 @@ the return value is nil. Otherwise the value is t. */)
w->pixel_top = XFASTINT (p->pixel_top);
w->pixel_width = XFASTINT (p->pixel_width);
w->pixel_height = XFASTINT (p->pixel_height);
w->pixel_width_before_size_change
= XFASTINT (p->pixel_width_before_size_change);
w->pixel_height_before_size_change
= XFASTINT (p->pixel_height_before_size_change);
w->left_col = XFASTINT (p->left_col);
w->top_line = XFASTINT (p->top_line);
w->total_cols = XFASTINT (p->total_cols);
......@@ -6203,6 +6300,9 @@ the return value is nil. Otherwise the value is t. */)
if (BUFFERP (p->buffer) && BUFFER_LIVE_P (XBUFFER (p->buffer)))
/* If saved buffer is alive, install it. */
{
if (!EQ (w->contents, p->buffer))
/* Record buffer configuration change. */
buffer_changed = true;
wset_buffer (w, p->buffer);
w->start_at_line_beg = !NILP (p->start_at_line_beg);
set_marker_restricted (w->start, p->start, w->contents);
......@@ -6236,6 +6336,8 @@ the return value is nil. Otherwise the value is t. */)
else if (!NILP (w->start))
/* Leaf window has no live buffer, get one. */
{
/* Record buffer configuration change. */
buffer_changed = true;
/* Get the buffer via other_buffer_safely in order to
avoid showing an unimportant buffer and, if necessary, to
recreate *scratch* in the course (part of Juanma's bs-show
......@@ -6283,7 +6385,10 @@ the return value is nil. Otherwise the value is t. */)
/* Now, free glyph matrices in windows that were not reused. */
for (i = 0; i < n_leaf_windows; i++)
if (NILP (leaf_windows[i]->contents))
free_window_matrices (leaf_windows[i]);
{
free_window_matrices (leaf_windows[i]);
window_changed = true;
}
/* Allow x_set_window_size again and apply frame size changes if
needed. */
......@@ -6303,7 +6408,8 @@ the return value is nil. Otherwise the value is t. */)
/* Record the selected window's buffer here. The window should
already be the selected one from the call above. */
select_window (data->current_window, Qnil, false);
if (WINDOW_LIVE_P (data->current_window))
select_window (data->current_window, Qnil, false);
/* Fselect_window will have made f the selected frame, so we
reselect the proper frame here. Fhandle_switch_frame will change the
......@@ -6313,7 +6419,32 @@ the return value is nil. Otherwise the value is t. */)
if (FRAME_LIVE_P (XFRAME (data->selected_frame)))
do_switch_frame (data->selected_frame, 0, 0, Qnil);
run_window_configuration_change_hook (f);
if (window_changed)
/* At least one window has been added or removed. Run
`window-configuration-change-hook' and make sure
`window-size-change-functions' get run later.
We have to do this in order to capture the following
scenario: Suppose our frame contains two live windows W1 and
W2 and ‘set-window-configuration’ replaces them by two
windows W3 and W4 that were dead the last time
run_window_size_change_functions was run. If W3 and W4 have
the same values for their old and new pixel sizes but these
values differ from those of W1 and W2, the sizes of our
frame's two live windows changed but window_size_changed has
no means to detect that fact.
Obviously, this will get us false positives, for example,
when we restore the original configuration with W1 and W2
before run_window_size_change_functions gets called. */
{
run_window_configuration_change_hook (f);
FRAME_WINDOW_CONFIGURATION_CHANGED (f) = true;
}
else if (buffer_changed)
/* At least one window has changed its buffer. Run
`window-configuration-change-hook' only. */
run_window_configuration_change_hook (f);
}
if (!NILP (new_current_buffer))
......@@ -6464,6 +6595,10 @@ save_window_save (Lisp_Object window, struct Lisp_Vector *vector, ptrdiff_t i)
p->pixel_top = make_number (w->pixel_top);
p->pixel_width = make_number (w->pixel_width);
p->pixel_height = make_number (w->pixel_height);
p->pixel_width_before_size_change
= make_number (w->pixel_width_before_size_change);
p->pixel_height_before_size_change
= make_number (w->pixel_height_before_size_change);
p->left_col = make_number (w->left_col);
p->top_line = make_number (w->top_line);
p->total_cols = make_number (w->total_cols);
......@@ -7246,6 +7381,16 @@ selected; while the global part is run only once for the modified frame,
with the relevant frame selected. */);
Vwindow_configuration_change_hook = Qnil;
DEFVAR_LISP ("window-size-change-functions", Vwindow_size_change_functions,
doc: /* Functions called during redisplay, if window sizes have changed.
The value should be a list of functions that take one argument.
During the first part of redisplay, for each frame, if any of its windows
have changed size since the last redisplay, or have been split or deleted,
all the functions in the list are called, with the frame as argument.
If redisplay decides to resize the minibuffer window, it calls these
functions on behalf of that as well. */);
Vwindow_size_change_functions = Qnil;
DEFVAR_LISP ("recenter-redisplay", Vrecenter_redisplay,
doc: /* Non-nil means `recenter' redraws entire frame.
If this option is non-nil, then the `recenter' command with a nil
......@@ -7374,6 +7519,8 @@ displayed after a scrolling operation to be somewhat inaccurate. */);
defsubr (&Swindow_use_time);
defsubr (&Swindow_pixel_width);
defsubr (&Swindow_pixel_height);
defsubr (&Swindow_pixel_width_before_size_change);
defsubr (&Swindow_pixel_height_before_size_change);
defsubr (&Swindow_total_width);
defsubr (&Swindow_total_height);
defsubr (&Swindow_normal_size);
......
......@@ -214,6 +214,11 @@ struct window
int pixel_width;
int pixel_height;
/* The pixel sizes of the window at the last time
`window-size-change-functions' was run. */
int pixel_width_before_size_change;
int pixel_height_before_size_change;
/* The size of the window. */
int total_cols;
int total_lines;
......@@ -499,15 +504,17 @@ wset_next_buffers (struct window *w, Lisp_Object val)
#define WINDOW_LEAF_P(W) \
(BUFFERP ((W)->contents))
/* True if W is a member of horizontal combination. */
/* Non-nil if W is internal. */
#define WINDOW_INTERNAL_P(W) \
(WINDOWP ((W)->contents))
/* True if W is a member of horizontal combination. */
#define WINDOW_HORIZONTAL_COMBINATION_P(W) \
(WINDOWP ((W)->contents) && (W)->horizontal)
(WINDOW_INTERNAL_P (W) && (W)->horizontal)
/* True if W is a member of vertical combination. */
#define WINDOW_VERTICAL_COMBINATION_P(W) \
(WINDOWP ((W)->contents) && !(W)->horizontal)
(WINDOW_INTERNAL_P (W) && !(W)->horizontal)
/* WINDOW's XFRAME. */
#define WINDOW_XFRAME(W) (XFRAME (WINDOW_FRAME ((W))))
......@@ -1014,6 +1021,7 @@ extern void shrink_mini_window (struct window *, bool);
extern int window_relative_x_coord (struct window *, enum window_part, int);
void run_window_configuration_change_hook (struct frame *f);
void run_window_size_change_functions (Lisp_Object);
/* Make WINDOW display BUFFER. RUN_HOOKS_P means it's allowed
to run hooks. See make_frame for a case where it's not allowed. */
......
......@@ -11786,24 +11786,7 @@ prepare_menu_bars (void)
&& !XBUFFER (w->contents)->text->redisplay)
continue;
/* If a window on this frame changed size, report that to
the user and clear the size-change flag. */
if (FRAME_WINDOW_SIZES_CHANGED (f))
{
Lisp_Object functions;
/* Clear flag first in case we get an error below. */
FRAME_WINDOW_SIZES_CHANGED (f) = false;
functions = Vwindow_size_change_functions;
while (CONSP (functions))
{
if (!EQ (XCAR (functions), Qt))
call1 (XCAR (functions), frame);
functions = XCDR (functions);
}
}
run_window_size_change_functions (frame);
menu_bar_hooks_run = update_menu_bar (f, false, menu_bar_hooks_run);
#ifdef HAVE_WINDOW_SYSTEM
update_tool_bar (f, false);
......@@ -13599,24 +13582,12 @@ redisplay_internal (void)
it's too late for the hooks in window-size-change-functions,
which have been examined already in prepare_menu_bars. So in
that case we call the hooks here only for the selected frame. */
if (sf->redisplay && FRAME_WINDOW_SIZES_CHANGED (sf))
if (sf->redisplay)
{
Lisp_Object functions;
ptrdiff_t count1 = SPECPDL_INDEX ();
record_unwind_save_match_data ();
/* Clear flag first in case we get an error below. */
FRAME_WINDOW_SIZES_CHANGED (sf) = false;
functions = Vwindow_size_change_functions;
while (CONSP (functions))
{
if (!EQ (XCAR (functions), Qt))
call1 (XCAR (functions), selected_frame);
functions = XCDR (functions);
}
run_window_size_change_functions (selected_frame);
unbind_to (count1, Qnil);
}
......@@ -13638,22 +13609,10 @@ redisplay_internal (void)
{
if (sf->redisplay)
{
Lisp_Object functions;
ptrdiff_t count1 = SPECPDL_INDEX ();
record_unwind_save_match_data ();
/* Clear flag first in case we get an error below. */
FRAME_WINDOW_SIZES_CHANGED (sf) = false;
functions = Vwindow_size_change_functions;
while (CONSP (functions))
{
if (!EQ (XCAR (functions), Qt))
call1 (XCAR (functions), selected_frame);
functions = XCDR (functions);
}
run_window_size_change_functions (selected_frame);
unbind_to (count1, Qnil);
}
......@@ -31447,16 +31406,6 @@ If nil, disable message logging. If t, log messages but don't truncate
the buffer when it becomes large. */);
Vmessage_log_max = make_number (1000);
DEFVAR_LISP ("window-size-change-functions", Vwindow_size_change_functions,
doc: /* Functions called during redisplay, if window sizes have changed.
The value should be a list of functions that take one argument.
During the first part of redisplay, for each frame, if any of its windows
have changed size since the last redisplay, or have been split or deleted,
all the functions in the list are called, with the frame as argument.
If redisplay decides to resize the minibuffer window, it calls these
functions on behalf of that as well. */);
Vwindow_size_change_functions = Qnil;
DEFVAR_LISP ("window-scroll-functions", Vwindow_scroll_functions,
doc: /* List of functions to call before redisplaying a window with scrolling.
Each function is called with two arguments, the window and its new
......