Further redesign of window change functions
* doc/lispref/windows.texi (Window Hooks): Revise description of window change functions. Add documentation for 'window-state-change-hook' and window state change flag. * etc/NEWS: Update entry for window change functions. * src/frame.c (Fframe_window_state_change) (Fset_frame_window_state_change): New functions. * src/frame.h (struct frame): New boolean window_state_change. (FRAME_WINDOW_STATE_CHANGE): New macro. * src/window.c (window_change_record_frames): New static boolean. (window_change_record_frame): Remove function - code moved to window_change_record. (window_change_record): Record frame changes here taking window_change_record_frames into account. (run_window_change_functions_1): Set window_change_record_frames whenever we run one of our hooks. (run_window_change_functions): Run hooks also when FRAME_WINDOW_STATE_CHANGE has been set. Run Vwindow_state_change_hook. Leave decision whether to record changes for all frames to window_change_record. (Vwindow_state_change_functions): Update doc-string. (Vwindow_state_change_hook): New normal hook.
This commit is contained in:
parent
d2270d8fc9
commit
4e082ce394
5 changed files with 247 additions and 116 deletions
|
@ -6046,8 +6046,8 @@ buffer are (re)fontified because a window was scrolled or its size
|
|||
changed. @xref{Other Font Lock Variables}.
|
||||
|
||||
@cindex window change functions
|
||||
The remainder of this section covers five hooks that are called at
|
||||
the end of redisplay provided a significant, non-scrolling change of a
|
||||
The remainder of this section covers six hooks that are called
|
||||
during redisplay provided a significant, non-scrolling change of a
|
||||
window has been detected. For simplicity, these hooks and the
|
||||
functions they call will be collectively referred to as @dfn{window
|
||||
change functions}.
|
||||
|
@ -6058,9 +6058,9 @@ detected, which means that a window was created, deleted or assigned
|
|||
another buffer.
|
||||
|
||||
@defvar window-buffer-change-functions
|
||||
This variable specifies functions called at the end of redisplay when
|
||||
window buffers have changed. The value should be a list of functions
|
||||
that take one argument.
|
||||
This variable specifies functions called during redisplay when window
|
||||
buffers have changed. The value should be a list of functions that
|
||||
take one argument.
|
||||
|
||||
Functions specified buffer-locally are called for any window showing
|
||||
the corresponding buffer if that window has been created or assigned
|
||||
|
@ -6074,14 +6074,14 @@ In this case the frame is passed as argument.
|
|||
@end defvar
|
||||
|
||||
@cindex window size change
|
||||
The second of these hooks is run after a @dfn{window size change} has
|
||||
The second of these hooks is run when a @dfn{window size change} has
|
||||
been detected which means that a window was created, assigned another
|
||||
buffer, or changed its total size or that of its text area.
|
||||
|
||||
@defvar window-size-change-functions
|
||||
This variable specifies functions called at the end of redisplay when
|
||||
a window size change occurred. The value should be a list of
|
||||
functions that take one argument.
|
||||
This variable specifies functions called during redisplay when a
|
||||
window size change occurred. The value should be a list of functions
|
||||
that take one argument.
|
||||
|
||||
Functions specified buffer-locally are called for any window showing
|
||||
the corresponding buffer if that window has been added or assigned
|
||||
|
@ -6097,13 +6097,13 @@ argument.
|
|||
@end defvar
|
||||
|
||||
@cindex window selection change
|
||||
The third of these hooks is run after a @dfn{window selection change}
|
||||
The third of these hooks is run when a @dfn{window selection change}
|
||||
has selected another window since the last redisplay.
|
||||
|
||||
@defvar window-selection-change-functions
|
||||
This variable specifies functions called at the end of redisplay when
|
||||
the selected window or a frame's selected window has changed. The
|
||||
value should be a list of functions that take one argument.
|
||||
This variable specifies functions called during redisplay when the
|
||||
selected window or a frame's selected window has changed. The value
|
||||
should be a list of functions that take one argument.
|
||||
|
||||
Functions specified buffer-locally are called for any window showing
|
||||
the corresponding buffer if that window has been selected or
|
||||
|
@ -6118,13 +6118,13 @@ run. In this case the frame is passed as argument.
|
|||
@end defvar
|
||||
|
||||
@cindex window state change
|
||||
The fourth of these hooks is run after a @dfn{window state change} has
|
||||
The fourth of these hooks is run when a @dfn{window state change} has
|
||||
been detected, which means that at least one of the three preceding
|
||||
window changes has occurred.
|
||||
|
||||
@defvar window-state-change-functions
|
||||
This variable specifies functions called at the end of redisplay when
|
||||
a window buffer or size change occurred or the selected window or a
|
||||
This variable specifies functions called during redisplay when a
|
||||
window buffer or size change occurred or the selected window or a
|
||||
frame's selected window has changed. The value should be a list of
|
||||
functions that take one argument.
|
||||
|
||||
|
@ -6141,6 +6141,10 @@ another buffer, changed its total or body size or that frame has been
|
|||
selected or deselected or the frame's selected window has changed
|
||||
since the last time window change functions were run. In this case
|
||||
the frame is passed as argument.
|
||||
|
||||
Functions specified by the default value are also run for a frame when
|
||||
that frame's window state change flag (see below) has been set since
|
||||
last redisplay.
|
||||
@end defvar
|
||||
|
||||
@cindex window configuration change
|
||||
|
@ -6150,9 +6154,9 @@ size of a window changed. It differs from the four preceding hooks in
|
|||
the way it is run.
|
||||
|
||||
@defvar window-configuration-change-hook
|
||||
This variable specifies functions called at the end of redisplay when
|
||||
either the buffer or the size of a window has changed. The value
|
||||
should be a list of functions that take no argument.
|
||||
This variable specifies functions called during redisplay when either
|
||||
the buffer or the size of a window has changed. The value should be a
|
||||
list of functions that take no argument.
|
||||
|
||||
Functions specified buffer-locally are called for any window showing
|
||||
the corresponding buffer if at least one window on that frame has been
|
||||
|
@ -6168,14 +6172,29 @@ window change functions were run. Each call is performed with the
|
|||
frame temporarily selected and the selected window's buffer current.
|
||||
@end defvar
|
||||
|
||||
Window change functions are called at the end of redisplay for each
|
||||
frame as follows: First, any buffer-local window buffer change
|
||||
function, window size change function, selected window change and
|
||||
window state change functions are called in this order. Next, the
|
||||
default values for these functions are called in the same order. Then
|
||||
any buffer-local window configuration change functions are called
|
||||
followed by functions specified by the default value of those
|
||||
functions.
|
||||
Finally, Emacs runs a normal hook that generalizes the behavior of
|
||||
@code{window-state-change-functions}.
|
||||
|
||||
@defvar window-state-change-hook
|
||||
The default value of this variable specifies functions called during
|
||||
redisplay when a window state change has been detected or the window
|
||||
state change flag has been set on at least one frame. The value
|
||||
should be a list of functions that take no argument.
|
||||
|
||||
Applications should put a function on this hook only if they want to
|
||||
react to changes that happened on (or have been signaled for) two or
|
||||
more frames since last redisplay. In every other case, putting the
|
||||
function on @code{window-state-change-functions} should be preferred.
|
||||
@end defvar
|
||||
|
||||
Window change functions are called during redisplay for each frame as
|
||||
follows: First, any buffer-local window buffer change function, window
|
||||
size change function, selected window change and window state change
|
||||
functions are called in this order. Next, the default values for
|
||||
these functions are called in the same order. Then any buffer-local
|
||||
window configuration change functions are called followed by functions
|
||||
specified by the default value of those functions. Finally, functions
|
||||
on @code{window-state-change-hook} are run.
|
||||
|
||||
Window change functions are run for a specific frame only if a
|
||||
corresponding change was registered for that frame earlier. Such
|
||||
|
@ -6189,6 +6208,27 @@ only if that excursion still persists at the time change functions are
|
|||
run. If it is exited earlier, hooks will be run only if registered by
|
||||
a change outside the scope of that excursion.
|
||||
|
||||
@cindex window state change flag
|
||||
The @dfn{window state change flag} of a frame, if set, will cause
|
||||
the default values of @code{window-state-change-functions} (for that
|
||||
frame) and @code{window-state-change-hook} to be run during next
|
||||
redisplay regardless of whether a window state change actually
|
||||
occurred for that frame or not. After running any functions on these
|
||||
hooks, the flag is reset for each frame. Applications can set that
|
||||
flag and inspect its value using the following functions.
|
||||
|
||||
@defun set-frame-window-state-change &optional frame arg
|
||||
This function sets @var{frame}'s window state change flag if @var{arg}
|
||||
is non-@code{nil} and resets it otherwise. @var{frame} must be a live
|
||||
frame and defaults to the selected one.
|
||||
@end defun
|
||||
|
||||
@defun frame-window-state-change &optional frame
|
||||
This functions returns @code{t} if @var{frame}'s window state change
|
||||
flag is set and @code{nil} otherwise. @var{frame} must be a live
|
||||
frame and defaults to the selected one.
|
||||
@end defun
|
||||
|
||||
While window change functions are run, the functions described next
|
||||
can be called to get more insight into what has changed for a specific
|
||||
window or frame since the last redisplay. All these functions take a
|
||||
|
@ -6250,12 +6290,10 @@ change functions were run.
|
|||
|
||||
Note that window change functions provide no information about which
|
||||
windows have been deleted since the last time they were run. If
|
||||
necessary, an application should remember any window showing a
|
||||
specific buffer in a local variable of that buffer and update it in a
|
||||
function run by the default value of
|
||||
@code{window-buffer-change-functions} or
|
||||
@code{window-configuration-change-hook} (the only hooks triggered by
|
||||
the deletion of windows).
|
||||
necessary, applications should remember any window showing a specific
|
||||
buffer in a local variable of that buffer and update it in a function
|
||||
run by the default values of any of the hooks that are run when a
|
||||
window buffer change was detected.
|
||||
|
||||
The following caveats should be considered when adding a function
|
||||
to window change functions:
|
||||
|
@ -6272,7 +6310,7 @@ the buffer, size or selection status of any window because there is no
|
|||
guarantee that the information about such a change will be propagated
|
||||
to other window change functions. If at all, any such change should
|
||||
be executed only by the last function listed by the default value of
|
||||
@code{window-configuration-change-hook}.
|
||||
@code{window-state-change-hook}.
|
||||
|
||||
@item
|
||||
Macros like @code{save-window-excursion}, @code{with-selected-window}
|
||||
|
|
18
etc/NEWS
18
etc/NEWS
|
@ -1424,18 +1424,20 @@ displaying the same buffer. See the node "(elisp) Face Remapping"
|
|||
of the Emacs Lisp Reference manual for more detail.
|
||||
|
||||
+++
|
||||
** Window change functions have been redesigned completely.
|
||||
** Window change functions have been redesigned.
|
||||
|
||||
Hooks reacting to window changes run now only when redisplay detects
|
||||
that a change has actually occurred. The five hooks provided are:
|
||||
that a change has actually occurred. Six hooks are now provided:
|
||||
'window-buffer-change-functions' (run after window buffers have
|
||||
changed), 'window-size-change-functions' (run after a window was
|
||||
assigned a new buffer or size), 'window-configuration-change-hook'
|
||||
(like the former but run also when a window was deleted),
|
||||
'window-selection-change-functions' (run when the selected window
|
||||
changed) and 'window-state-change-functions' (run when any of the
|
||||
preceding ones is run). 'window-scroll-functions' are unaffected by
|
||||
these changes.
|
||||
changed) and 'window-state-change-functions' and
|
||||
'window-state-change-hook' (run when any of the preceding ones is
|
||||
run). Applications can enforce running the latter two using the new
|
||||
function 'set-frame-window-state-change'. 'window-scroll-functions'
|
||||
are unaffected by these changes.
|
||||
|
||||
In addition, a number of functions now allow the caller to detect what
|
||||
has changed since last redisplay: 'window-old-buffer' returns for any
|
||||
|
@ -1447,10 +1449,8 @@ during last redisplay. 'window-old-pixel-width' (renamed from
|
|||
'window-old-body-pixel-width' and 'window-old-body-pixel-height'
|
||||
return the total and body sizes of any window during last redisplay.
|
||||
|
||||
One consequence of these changes is that all window change functions
|
||||
run now after functions run by 'post-command-hook'. See the section
|
||||
"(elisp) Window Hooks" in the Elisp manual for a detailed explanation
|
||||
of the new behavior.
|
||||
See the section "(elisp) Window Hooks" in the Elisp manual for a
|
||||
detailed explanation of the new behavior.
|
||||
|
||||
+++
|
||||
** New buffer display action alist entry 'dedicated'.
|
||||
|
|
36
src/frame.c
36
src/frame.c
|
@ -3611,6 +3611,40 @@ bottom edge of FRAME's display. */)
|
|||
|
||||
return Qt;
|
||||
}
|
||||
|
||||
DEFUN ("frame-window-state-change", Fframe_window_state_change,
|
||||
Sframe_window_state_change, 0, 1, 0,
|
||||
doc: /* Return t if FRAME's window state change flag is set, nil otherwise.
|
||||
FRAME must be a live frame and defaults to the selected one.
|
||||
|
||||
If FRAME's window state change flag is set, the default values of
|
||||
`window-state-change-functions' and `window-state-change-hook' will be
|
||||
run during next redisplay, regardless of whether a window state change
|
||||
actually occurred on FRAME or not. After that, the value of this flag
|
||||
is reset. */)
|
||||
(Lisp_Object frame)
|
||||
{
|
||||
return FRAME_WINDOW_STATE_CHANGE (decode_live_frame (frame)) ? Qt : Qnil;
|
||||
}
|
||||
|
||||
DEFUN ("set-frame-window-state-change", Fset_frame_window_state_change,
|
||||
Sset_frame_window_state_change, 0, 2, 0,
|
||||
doc: /* Set FRAME's window state change flag according to ARG.
|
||||
Set FRAME's window state change flag if ARG is non-nil, reset it
|
||||
otherwise.
|
||||
|
||||
If FRAME's window state change flag is set, the default values of
|
||||
`window-state-change-functions' and `window-state-change-hook' will be
|
||||
run during next redisplay, regardless of whether a window state change
|
||||
actually occurred on FRAME or not. After that, the value of FRAME's
|
||||
window state change flag is reset. */)
|
||||
(Lisp_Object frame, Lisp_Object arg)
|
||||
{
|
||||
struct frame *f = decode_live_frame (frame);
|
||||
|
||||
return (FRAME_WINDOW_STATE_CHANGE (f) = !NILP (arg)) ? Qt : Qnil;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
Frame Parameters
|
||||
|
@ -6256,6 +6290,8 @@ iconify the top level frame instead. */);
|
|||
defsubr (&Sframe_position);
|
||||
defsubr (&Sset_frame_position);
|
||||
defsubr (&Sframe_pointer_visible_p);
|
||||
defsubr (&Sframe_window_state_change);
|
||||
defsubr (&Sset_frame_window_state_change);
|
||||
|
||||
#ifdef HAVE_WINDOW_SYSTEM
|
||||
defsubr (&Sx_get_resource);
|
||||
|
|
|
@ -334,6 +334,10 @@ struct frame
|
|||
frame. */
|
||||
bool_bf window_change : 1;
|
||||
|
||||
/* True if running window state change functions has been explicitly
|
||||
requested for this frame since last redisplay. */
|
||||
bool_bf window_state_change : 1;
|
||||
|
||||
/* True if the mouse has moved on this display device
|
||||
since the last time we checked. */
|
||||
bool_bf mouse_moved : 1;
|
||||
|
@ -944,6 +948,10 @@ default_pixels_per_inch_y (void)
|
|||
window change functions were run on F. */
|
||||
#define FRAME_WINDOW_CHANGE(f) (f)->window_change
|
||||
|
||||
/* True if running window state change functions has been explicitly
|
||||
requested for this frame since last redisplay. */
|
||||
#define FRAME_WINDOW_STATE_CHANGE(f) (f)->window_state_change
|
||||
|
||||
/* The minibuffer window of frame F, if it has one; otherwise nil. */
|
||||
#define FRAME_MINIBUF_WINDOW(f) f->minibuffer_window
|
||||
|
||||
|
|
195
src/window.c
195
src/window.c
|
@ -88,6 +88,9 @@ static Lisp_Object old_selected_window;
|
|||
by setting it to nil. */
|
||||
Lisp_Object Vwindow_list;
|
||||
|
||||
/* True mean window_change_record has to record all live frames. */
|
||||
static bool window_change_record_frames;
|
||||
|
||||
/* The mini-buffer window of the selected frame.
|
||||
Note that you cannot test for mini-bufferness of an arbitrary window
|
||||
by comparing against this; but you can test for mini-bufferness of
|
||||
|
@ -3426,8 +3429,8 @@ run_window_configuration_change_hook (struct frame *f)
|
|||
XSETFRAME (frame, f);
|
||||
|
||||
if (NILP (Vrun_hooks)
|
||||
|| !(f->can_x_set_window_size)
|
||||
|| !(f->after_make_frame))
|
||||
|| !f->can_x_set_window_size
|
||||
|| !f->after_make_frame)
|
||||
return;
|
||||
|
||||
/* Use the right buffer. Matters when running the local hooks. */
|
||||
|
@ -3573,49 +3576,50 @@ window_change_record_windows (Lisp_Object window, int stamp, ptrdiff_t number)
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* window_change_record_frame:
|
||||
*
|
||||
* Record changes for FRAME. This records FRAME's selected window,
|
||||
* updates FRAME's change stamp, records the states of all live
|
||||
* windows of FRAME via window_change_record_windows and resets
|
||||
* FRAME's window_change flag.
|
||||
*/
|
||||
static void
|
||||
window_change_record_frame (Lisp_Object frame)
|
||||
{
|
||||
struct frame *f = XFRAME (frame);
|
||||
|
||||
/* Record selected window. */
|
||||
fset_old_selected_window (f, FRAME_SELECTED_WINDOW (f));
|
||||
|
||||
/* Bump up FRAME's change stamp. If this wraps, make it 1 to avoid
|
||||
that a new window (whose change stamp is always set to 0) gets
|
||||
reported as "existing before". */
|
||||
f->change_stamp += 1;
|
||||
if (f->change_stamp == 0)
|
||||
f->change_stamp = 1;
|
||||
|
||||
/* Bump up the change stamps of all live windows on this frame so
|
||||
the next call of this function can tell whether any of them
|
||||
"existed before" and record state for each of these windows. */
|
||||
f->number_of_windows
|
||||
= window_change_record_windows (f->root_window, f->change_stamp, 0);
|
||||
|
||||
/* Reset our flag. */
|
||||
FRAME_WINDOW_CHANGE (f) = false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* window_change_record:
|
||||
*
|
||||
* For each frame that has recorded changes, record its selected
|
||||
* window, update Fchange stamp, record the states of all its live
|
||||
* windows via window_change_record_windows and reset its
|
||||
* window_change and window_state_change flags.
|
||||
*
|
||||
* Record selected window in old_selected_window and selected frame in
|
||||
* old_selected_frame.
|
||||
*/
|
||||
static void
|
||||
window_change_record (void)
|
||||
{
|
||||
if (window_change_record_frames)
|
||||
{
|
||||
Lisp_Object tail, frame;
|
||||
|
||||
FOR_EACH_FRAME (tail, frame)
|
||||
{
|
||||
struct frame *f = XFRAME (frame);
|
||||
|
||||
/* Record FRAME's selected window. */
|
||||
fset_old_selected_window (f, FRAME_SELECTED_WINDOW (f));
|
||||
|
||||
/* Bump up FRAME's change stamp. If this wraps, make it 1 to avoid
|
||||
that a new window (whose change stamp is always set to 0) gets
|
||||
reported as "existing before". */
|
||||
f->change_stamp += 1;
|
||||
if (f->change_stamp == 0)
|
||||
f->change_stamp = 1;
|
||||
|
||||
/* Bump up the change stamps of all live windows on this frame so
|
||||
the next call of this function can tell whether any of them
|
||||
"existed before" and record state for each of these windows. */
|
||||
f->number_of_windows
|
||||
= window_change_record_windows (f->root_window, f->change_stamp, 0);
|
||||
|
||||
/* Reset our flags. */
|
||||
FRAME_WINDOW_CHANGE (f) = false;
|
||||
FRAME_WINDOW_STATE_CHANGE (f) = false;
|
||||
}
|
||||
}
|
||||
|
||||
/* Strictly spoken we don't need old_selected_window at all - its
|
||||
value is the old selected window of old_selected_frame. */
|
||||
old_selected_window = selected_window;
|
||||
|
@ -3647,8 +3651,18 @@ run_window_change_functions_1 (Lisp_Object symbol, Lisp_Object buffer,
|
|||
|
||||
while (CONSP (funs))
|
||||
{
|
||||
if (!EQ (XCAR (funs), Qt))
|
||||
safe_call1 (XCAR (funs), window_or_frame);
|
||||
if (!EQ (XCAR (funs), Qt)
|
||||
&& (NILP (buffer)
|
||||
? FRAME_LIVE_P (XFRAME (window_or_frame))
|
||||
: WINDOW_LIVE_P (window_or_frame)))
|
||||
{
|
||||
/* Any function called here may change the state of any
|
||||
frame. Make sure to record changes for each live frame
|
||||
in window_change_record later. */
|
||||
window_change_record_frames = true;
|
||||
safe_call1 (XCAR (funs), window_or_frame);
|
||||
}
|
||||
|
||||
funs = XCDR (funs);
|
||||
}
|
||||
}
|
||||
|
@ -3661,8 +3675,9 @@ run_window_change_functions_1 (Lisp_Object symbol, Lisp_Object buffer,
|
|||
* must be called from a "safe" position in redisplay_internal.
|
||||
*
|
||||
* Do not run any functions for a frame whose window_change flag is
|
||||
* nil and where no window selection happened since the last time this
|
||||
* function was called. Also, skip any tooltip frame.
|
||||
* nil, where no window selection happened and whose window state
|
||||
* change flag was not set since the last time this function was
|
||||
* called. Never run any functions for tooltip frames.
|
||||
*
|
||||
* The change functions run are, in this order:
|
||||
*
|
||||
|
@ -3679,25 +3694,35 @@ run_window_change_functions_1 (Lisp_Object symbol, Lisp_Object buffer,
|
|||
* `window-selected-change-functions' run for a window that was
|
||||
* (de-)selected since the last time window change functions were run.
|
||||
*
|
||||
* `window-state-change-functions' run for a window for which any of
|
||||
* the above three changes occurred.
|
||||
*
|
||||
* A buffer-local value of these functions is run if and only if the
|
||||
* window for which the functions are run, currently shows the buffer.
|
||||
* window for which the functions are run currently shows the buffer.
|
||||
* Each call gets one argument - the window showing the buffer. This
|
||||
* means that the buffer-local value of these functions may be called
|
||||
* as many times at the buffer is shown on the frame.
|
||||
* as many times as the buffer is shown on the frame.
|
||||
*
|
||||
* The default value of these functions is called only after all
|
||||
* The default values of these functions are called only after all
|
||||
* buffer-local values for all of these functions have been run. Each
|
||||
* such call receives one argument - the frame for which this function
|
||||
* is run.
|
||||
* such call receives one argument - the frame for which a change
|
||||
* occurred. Functions on `window-state-change-functions' are run
|
||||
* also if the corresponding frame's window state change flag has been
|
||||
* set.
|
||||
*
|
||||
* After the three change functions cited above have been run in the
|
||||
* After the four change functions cited above have been run in the
|
||||
* indicated way, functions on 'window-configuration-change-hook' are
|
||||
* run. A buffer-local value is run if a window shows that buffer and
|
||||
* has either changed its buffer or its body or total size or did not
|
||||
* appear on this frame since the last time window change functions
|
||||
* were run. The functions are called without argument and the
|
||||
* were run. The functions are called without argument and with the
|
||||
* buffer's window selected. The default value is run without
|
||||
* argument and the frame for which the function is run selected.
|
||||
* argument and with the frame for which the function is run selected.
|
||||
*
|
||||
* In a final step, functions on `window-state-change-hook' are run
|
||||
* provided a window state change has occurred or the window state
|
||||
* change flag has been set on at least one frame. Each of these
|
||||
* functions is called without argument.
|
||||
*
|
||||
* This function does not save and restore match data. Any functions
|
||||
* it calls are responsible for doing that themselves.
|
||||
|
@ -3707,8 +3732,10 @@ run_window_change_functions (void)
|
|||
{
|
||||
Lisp_Object tail, frame;
|
||||
bool selected_frame_change = !EQ (selected_frame, old_selected_frame);
|
||||
ptrdiff_t count_outer = SPECPDL_INDEX ();
|
||||
bool run_window_state_change_hook = false;
|
||||
ptrdiff_t count = SPECPDL_INDEX ();
|
||||
|
||||
window_change_record_frames = false;
|
||||
record_unwind_protect_void (window_change_record);
|
||||
specbind (Qinhibit_redisplay, Qt);
|
||||
|
||||
|
@ -3725,19 +3752,21 @@ run_window_change_functions (void)
|
|||
|| EQ (frame, selected_frame)));
|
||||
bool frame_selected_window_change
|
||||
= !EQ (FRAME_OLD_SELECTED_WINDOW (f), FRAME_SELECTED_WINDOW (f));
|
||||
bool frame_window_state_change = FRAME_WINDOW_STATE_CHANGE (f);
|
||||
bool window_deleted = false;
|
||||
Lisp_Object windows;
|
||||
ptrdiff_t number_of_windows;
|
||||
ptrdiff_t count_inner = SPECPDL_INDEX ();
|
||||
|
||||
if (!f->can_x_set_window_size
|
||||
if (!FRAME_LIVE_P (f)
|
||||
|| !f->can_x_set_window_size
|
||||
|| !f->after_make_frame
|
||||
|| FRAME_TOOLTIP_P (f)
|
||||
|| !(frame_window_change
|
||||
|| frame_selected_change
|
||||
|| frame_selected_window_change))
|
||||
/* Either we cannot run hooks for this frame yet or no window
|
||||
change has been reported for this frame since the last time
|
||||
|| frame_selected_window_change
|
||||
|| frame_window_state_change))
|
||||
/* Either we are not allowed to run hooks for this frame or no
|
||||
window change has been reported for it since the last time
|
||||
we ran window change functions on it. */
|
||||
continue;
|
||||
|
||||
|
@ -3745,8 +3774,6 @@ run_window_change_functions (void)
|
|||
windows = Fnreverse (window_sub_list (root, Qnil));
|
||||
number_of_windows = 0;
|
||||
|
||||
record_unwind_protect (window_change_record_frame, frame);
|
||||
|
||||
/* The following loop collects all data needed to tell whether
|
||||
the default value of a hook shall be run and runs any buffer
|
||||
local hooks right away. */
|
||||
|
@ -3857,13 +3884,21 @@ run_window_change_functions (void)
|
|||
(Qwindow_selection_change_functions, Qnil, frame);
|
||||
|
||||
/* A frame has changed state when a size or buffer change
|
||||
occurrd or its selected window has changed or when it was
|
||||
(de-)selected. */
|
||||
occurred, its selected window has changed, when it was
|
||||
(de-)selected or its window state change flag was set. */
|
||||
if ((frame_selected_change || frame_selected_window_change
|
||||
|| frame_buffer_change || window_deleted || frame_size_change)
|
||||
|| frame_buffer_change || window_deleted
|
||||
|| frame_size_change || frame_window_state_change)
|
||||
&& FRAME_LIVE_P (f))
|
||||
run_window_change_functions_1
|
||||
(Qwindow_state_change_functions, Qnil, frame);
|
||||
{
|
||||
run_window_change_functions_1
|
||||
(Qwindow_state_change_functions, Qnil, frame);
|
||||
/* Make sure to run 'window-state-change-hook' later. */
|
||||
run_window_state_change_hook = true;
|
||||
/* Make sure to record changes for each live frame in
|
||||
window_change_record later. */
|
||||
window_change_record_frames = true;
|
||||
}
|
||||
|
||||
/* A frame's configuration changed when one of its windows has
|
||||
changed buffer or size or at least one window was deleted. */
|
||||
|
@ -3871,17 +3906,16 @@ run_window_change_functions (void)
|
|||
/* This will run any buffer local window configuration change
|
||||
hook as well. */
|
||||
run_window_configuration_change_hook (f);
|
||||
|
||||
if (!FRAME_LIVE_P (f))
|
||||
continue;
|
||||
|
||||
/* Record changes (via window_change_record_frame) for this
|
||||
frame, even when an unhandled error occurred. */
|
||||
unbind_to (count_inner, Qnil);
|
||||
}
|
||||
|
||||
/* Record selected window and frame. */
|
||||
unbind_to (count_outer, Qnil);
|
||||
/* Run 'window-state-change-hook' if at least one frame has changed
|
||||
state. */
|
||||
if (run_window_state_change_hook && !NILP (Vwindow_state_change_hook))
|
||||
safe_run_hooks (Qwindow_state_change_hook);
|
||||
|
||||
/* Record changes for all frames (if asked for), selected window and
|
||||
frame. */
|
||||
unbind_to (count, Qnil);
|
||||
}
|
||||
|
||||
/* Make WINDOW display BUFFER. RUN_HOOKS_P means it's allowed
|
||||
|
@ -7999,6 +8033,7 @@ syms_of_window (void)
|
|||
Fput (Qscroll_down, Qscroll_command, Qt);
|
||||
|
||||
DEFSYM (Qwindow_configuration_change_hook, "window-configuration-change-hook");
|
||||
DEFSYM (Qwindow_state_change_hook, "window-state-change-hook");
|
||||
DEFSYM (Qwindow_state_change_functions, "window-state-change-functions");
|
||||
DEFSYM (Qwindow_size_change_functions, "window-size-change-functions");
|
||||
DEFSYM (Qwindow_buffer_change_functions, "window-buffer-change-functions");
|
||||
|
@ -8132,11 +8167,25 @@ redisplay. In this case the window is passed as argument.
|
|||
|
||||
Functions specified by the default value are called for each frame if
|
||||
at least one window on that frame has been added, deleted, changed its
|
||||
buffer or its total or body size or the frame has been (de-)selected
|
||||
or its selected window has changed since the last redisplay. In this
|
||||
case the frame is passed as argument. */);
|
||||
buffer or its total or body size or the frame has been (de-)selected,
|
||||
its selected window has changed or the window state change flag has
|
||||
been set for this frame since the last redisplay. In this case the
|
||||
frame is passed as argument. */);
|
||||
Vwindow_state_change_functions = Qnil;
|
||||
|
||||
DEFVAR_LISP ("window-state-change-hook", Vwindow_state_change_hook,
|
||||
doc: /* Functions called during redisplay when the window state changed.
|
||||
The value should be a list of functions that take no argument.
|
||||
|
||||
This hook is called during redisplay when at least one window has been
|
||||
added, deleted, (de-)selected, changed its buffer or its total or body
|
||||
size or the window state change flag has been set for at least one
|
||||
frame. This hook is called after all other window change functions
|
||||
have been run and should be used only if a function should react to
|
||||
changes that happened on at least two frames since last redisplay or
|
||||
the function intends to change the window configuration. */);
|
||||
Vwindow_state_change_hook = Qnil;
|
||||
|
||||
DEFVAR_LISP ("window-configuration-change-hook", Vwindow_configuration_change_hook,
|
||||
doc: /* Functions called during redisplay when window configuration has changed.
|
||||
The value should be a list of functions that take no argument.
|
||||
|
|
Loading…
Add table
Reference in a new issue