Expand spectrum of window change functions
* src/window.c (run_window_change_functions): Run window change functions for Qwindow_state_change_functions. (resize_frame_windows): Set frame's window_change slot when single-window frames change size. (Qwindow_state_change_functions): New symbol. (Vwindow_state_change_functions): New Lisp variable. * doc/lispref/windows.texi (Selecting Windows): Mention 'window-selection/state-change-functions' and add reference to Window Hooks. (Window Hooks): Document 'window-state-change-functions'. * etc/NEWS: Mention new hook 'window-state-change-functions'.
This commit is contained in:
parent
978cf88bda
commit
0aece3e118
3 changed files with 98 additions and 10 deletions
|
@ -1758,7 +1758,7 @@ raise the frame or make sure input focus is directed to that frame.
|
|||
@xref{Input Focus}.
|
||||
@end defun
|
||||
|
||||
@cindex select window hook
|
||||
@cindex select window hooks
|
||||
@cindex running a hook when a window gets selected
|
||||
For historical reasons, Emacs does not run a separate hook whenever a
|
||||
window gets selected. Applications and internal routines often
|
||||
|
@ -1774,8 +1774,8 @@ useful.
|
|||
However, when its @var{norecord} argument is @code{nil},
|
||||
@code{select-window} updates the buffer list and thus indirectly runs
|
||||
the normal hook @code{buffer-list-update-hook} (@pxref{Buffer List}).
|
||||
Consequently, that hook provides a reasonable way to run a function
|
||||
whenever a window gets selected more ``permanently''.
|
||||
Consequently, that hook provides one way to run a function whenever a
|
||||
window gets selected more ``permanently''.
|
||||
|
||||
Since @code{buffer-list-update-hook} is also run by functions that are
|
||||
not related to window management, it will usually make sense to save the
|
||||
|
@ -1787,6 +1787,13 @@ temporarily passes a non-@code{nil} @var{norecord} argument. If
|
|||
possible, the macro @code{with-selected-window} (see below) should be
|
||||
used in such cases.
|
||||
|
||||
Emacs also runs the hook @code{window-selection-change-functions}
|
||||
whenever the redisplay routine detects that another window has been
|
||||
selected since last redisplay. @xref{Window Hooks}, for a detailed
|
||||
explanation. @code{window-state-change-functions} (described in the
|
||||
same section) is another abnormal hook run after a different window
|
||||
has been selected but is triggered by other window changes as well.
|
||||
|
||||
@cindex most recently selected windows
|
||||
The sequence of calls to @code{select-window} with a non-@code{nil}
|
||||
@var{norecord} argument determines an ordering of windows by their
|
||||
|
@ -6039,7 +6046,7 @@ 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 four hooks that are called at
|
||||
The remainder of this section covers five hooks that are called at
|
||||
the end of 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
|
||||
|
@ -6108,10 +6115,37 @@ window has changed since the last time window change functions were
|
|||
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
|
||||
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
|
||||
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 added or assigned
|
||||
another buffer, total or body size or has been selected or deselected
|
||||
(among all windows or among all windows on its frame) since the last
|
||||
time window change functions were run. In this case the window is
|
||||
passed as argument.
|
||||
|
||||
Functions specified by the default value are called for a frame if at
|
||||
least one window on that frame has been added, deleted or assigned
|
||||
another buffer, 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.
|
||||
@end defvar
|
||||
|
||||
@cindex window configuration change
|
||||
The fourth of these hooks is run when a @dfn{window configuration
|
||||
The fifth of these hooks is run when a @dfn{window configuration
|
||||
change} has been detected which means that either the buffer or the
|
||||
size of a window changed.
|
||||
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
|
||||
|
|
9
etc/NEWS
9
etc/NEWS
|
@ -1303,14 +1303,17 @@ of the Emacs Lisp Reference manual for more detail.
|
|||
|
||||
+++
|
||||
** Window change functions have been redesigned completely.
|
||||
|
||||
Hooks reacting to window changes run now only when redisplay detects
|
||||
that a change has actually occurred. The four hooks provided are:
|
||||
that a change has actually occurred. The five hooks provided are:
|
||||
'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) and
|
||||
(like the former but run also when a window was deleted),
|
||||
'window-selection-change-functions' (run when the selected window
|
||||
changed). 'window-scroll-functions' are unaffected by these changes.
|
||||
changed) and 'window-state-change-functions' (run when any of the
|
||||
preceding ones is run). '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
|
||||
|
|
53
src/window.c
53
src/window.c
|
@ -3799,7 +3799,7 @@ run_window_change_functions (void)
|
|||
run_window_change_functions_1
|
||||
(Qwindow_size_change_functions, buffer, window);
|
||||
|
||||
/* This window's selection has changed when it it was
|
||||
/* This window's selection has changed when it was
|
||||
(de-)selected as its frame's or the globally selected
|
||||
window. */
|
||||
if (((frame_selected_change
|
||||
|
@ -3811,6 +3811,21 @@ run_window_change_functions (void)
|
|||
&& WINDOW_LIVE_P (window))
|
||||
run_window_change_functions_1
|
||||
(Qwindow_selection_change_functions, buffer, window);
|
||||
|
||||
/* This window's state has changed when its buffer or size
|
||||
changed or it was (de-)selected as its frame's or the
|
||||
globally selected window. */
|
||||
if ((window_buffer_change
|
||||
|| window_size_change
|
||||
|| ((frame_selected_change
|
||||
&& (EQ (window, old_selected_window)
|
||||
|| EQ (window, selected_window)))
|
||||
|| (frame_selected_window_change
|
||||
&& (EQ (window, FRAME_OLD_SELECTED_WINDOW (f))
|
||||
|| EQ (window, FRAME_SELECTED_WINDOW (f))))))
|
||||
&& WINDOW_LIVE_P (window))
|
||||
run_window_change_functions_1
|
||||
(Qwindow_state_change_functions, buffer, window);
|
||||
}
|
||||
|
||||
/* When the number of windows on a frame has decreased, at least
|
||||
|
@ -3840,6 +3855,15 @@ run_window_change_functions (void)
|
|||
run_window_change_functions_1
|
||||
(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. */
|
||||
if ((frame_selected_change || frame_selected_window_change
|
||||
|| frame_buffer_change || window_deleted || frame_size_change)
|
||||
&& FRAME_LIVE_P (f))
|
||||
run_window_change_functions_1
|
||||
(Qwindow_state_change_functions, Qnil, frame);
|
||||
|
||||
/* A frame's configuration changed when one of its windows has
|
||||
changed buffer or size or at least one window was deleted. */
|
||||
if ((frame_size_change || window_deleted) && FRAME_LIVE_P (f))
|
||||
|
@ -4650,16 +4674,26 @@ resize_frame_windows (struct frame *f, int size, bool horflag, bool pixelwise)
|
|||
/* For a leaf root window just set the size. */
|
||||
if (horflag)
|
||||
{
|
||||
bool changed = r->pixel_width != new_pixel_size;
|
||||
|
||||
r->total_cols = new_size;
|
||||
r->pixel_width = new_pixel_size;
|
||||
|
||||
if (changed && !WINDOW_PSEUDO_P (r))
|
||||
FRAME_WINDOW_CHANGE (f) = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
bool changed = r->pixel_height != new_pixel_size;
|
||||
|
||||
r->top_line = FRAME_TOP_MARGIN (f);
|
||||
r->pixel_top = FRAME_TOP_MARGIN_HEIGHT (f);
|
||||
|
||||
r->total_lines = new_size;
|
||||
r->pixel_height = new_pixel_size;
|
||||
|
||||
if (changed && !WINDOW_PSEUDO_P (r))
|
||||
FRAME_WINDOW_CHANGE (f) = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -7953,6 +7987,7 @@ syms_of_window (void)
|
|||
Fput (Qscroll_down, Qscroll_command, Qt);
|
||||
|
||||
DEFSYM (Qwindow_configuration_change_hook, "window-configuration-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");
|
||||
DEFSYM (Qwindow_selection_change_functions, "window-selection-change-functions");
|
||||
|
@ -8074,6 +8109,22 @@ the frame's selected window has changed since the last redisplay. In
|
|||
this case the frame is passed as argument. */);
|
||||
Vwindow_selection_change_functions = Qnil;
|
||||
|
||||
DEFVAR_LISP ("window-state-change-functions", Vwindow_state_change_functions,
|
||||
doc: /* Functions called during redisplay when the window state changed.
|
||||
The value should be a list of functions that take one argument.
|
||||
|
||||
Functions specified buffer-locally are called for each window showing
|
||||
the corresponding buffer if and only if that window has been added,
|
||||
resized, changed its buffer or has been (de-)selected since the last
|
||||
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. */);
|
||||
Vwindow_selection_change_functions = 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