aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Rudalics2019-01-17 10:21:07 +0100
committerMartin Rudalics2019-01-17 10:21:07 +0100
commit0aece3e1181e66f2a1a067ae876e55bdaa45edd5 (patch)
tree240c9dca3ff8a81460e5150d6b24993766bd707e
parent978cf88bda9c9b41f1cc20cf8e53a9e6caeb91be (diff)
downloademacs-0aece3e1181e66f2a1a067ae876e55bdaa45edd5.tar.gz
emacs-0aece3e1181e66f2a1a067ae876e55bdaa45edd5.zip
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'.
-rw-r--r--doc/lispref/windows.texi46
-rw-r--r--etc/NEWS9
-rw-r--r--src/window.c53
3 files changed, 98 insertions, 10 deletions
diff --git a/doc/lispref/windows.texi b/doc/lispref/windows.texi
index 6b5aa66a955..afb81e6874f 100644
--- a/doc/lispref/windows.texi
+++ b/doc/lispref/windows.texi
@@ -1758,7 +1758,7 @@ raise the frame or make sure input focus is directed to that frame.
1758@xref{Input Focus}. 1758@xref{Input Focus}.
1759@end defun 1759@end defun
1760 1760
1761@cindex select window hook 1761@cindex select window hooks
1762@cindex running a hook when a window gets selected 1762@cindex running a hook when a window gets selected
1763For historical reasons, Emacs does not run a separate hook whenever a 1763For historical reasons, Emacs does not run a separate hook whenever a
1764window gets selected. Applications and internal routines often 1764window gets selected. Applications and internal routines often
@@ -1774,8 +1774,8 @@ useful.
1774 However, when its @var{norecord} argument is @code{nil}, 1774 However, when its @var{norecord} argument is @code{nil},
1775@code{select-window} updates the buffer list and thus indirectly runs 1775@code{select-window} updates the buffer list and thus indirectly runs
1776the normal hook @code{buffer-list-update-hook} (@pxref{Buffer List}). 1776the normal hook @code{buffer-list-update-hook} (@pxref{Buffer List}).
1777Consequently, that hook provides a reasonable way to run a function 1777Consequently, that hook provides one way to run a function whenever a
1778whenever a window gets selected more ``permanently''. 1778window gets selected more ``permanently''.
1779 1779
1780 Since @code{buffer-list-update-hook} is also run by functions that are 1780 Since @code{buffer-list-update-hook} is also run by functions that are
1781not related to window management, it will usually make sense to save the 1781not 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
1787possible, the macro @code{with-selected-window} (see below) should be 1787possible, the macro @code{with-selected-window} (see below) should be
1788used in such cases. 1788used in such cases.
1789 1789
1790 Emacs also runs the hook @code{window-selection-change-functions}
1791whenever the redisplay routine detects that another window has been
1792selected since last redisplay. @xref{Window Hooks}, for a detailed
1793explanation. @code{window-state-change-functions} (described in the
1794same section) is another abnormal hook run after a different window
1795has been selected but is triggered by other window changes as well.
1796
1790@cindex most recently selected windows 1797@cindex most recently selected windows
1791 The sequence of calls to @code{select-window} with a non-@code{nil} 1798 The sequence of calls to @code{select-window} with a non-@code{nil}
1792@var{norecord} argument determines an ordering of windows by their 1799@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
6039changed. @xref{Other Font Lock Variables}. 6046changed. @xref{Other Font Lock Variables}.
6040 6047
6041@cindex window change functions 6048@cindex window change functions
6042 The remainder of this section covers four hooks that are called at 6049 The remainder of this section covers five hooks that are called at
6043the end of redisplay provided a significant, non-scrolling change of a 6050the end of redisplay provided a significant, non-scrolling change of a
6044window has been detected. For simplicity, these hooks and the 6051window has been detected. For simplicity, these hooks and the
6045functions they call will be collectively referred to as @dfn{window 6052functions 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
6108run. In this case the frame is passed as argument. 6115run. In this case the frame is passed as argument.
6109@end defvar 6116@end defvar
6110 6117
6118@cindex window state change
6119The fourth of these hooks is run after a @dfn{window state change} has
6120been detected, which means that at least one of the three preceding
6121window changes has occurred.
6122
6123@defvar window-state-change-functions
6124This variable specifies functions called at the end of redisplay when
6125a window buffer or size change occurred or the selected window or a
6126frame's selected window has changed. The value should be a list of
6127functions that take one argument.
6128
6129Functions specified buffer-locally are called for any window showing
6130the corresponding buffer if that window has been added or assigned
6131another buffer, total or body size or has been selected or deselected
6132(among all windows or among all windows on its frame) since the last
6133time window change functions were run. In this case the window is
6134passed as argument.
6135
6136Functions specified by the default value are called for a frame if at
6137least one window on that frame has been added, deleted or assigned
6138another buffer, total or body size or that frame has been selected or
6139deselected or the frame's selected window has changed since the last
6140time window change functions were run. In this case the frame is
6141passed as argument.
6142@end defvar
6143
6111@cindex window configuration change 6144@cindex window configuration change
6112The fourth of these hooks is run when a @dfn{window configuration 6145The fifth of these hooks is run when a @dfn{window configuration
6113change} has been detected which means that either the buffer or the 6146change} has been detected which means that either the buffer or the
6114size of a window changed. 6147size of a window changed. It differs from the four preceding hooks in
6148the way it is run.
6115 6149
6116@defvar window-configuration-change-hook 6150@defvar window-configuration-change-hook
6117This variable specifies functions called at the end of redisplay when 6151This variable specifies functions called at the end of redisplay when
diff --git a/etc/NEWS b/etc/NEWS
index 02503073c1c..10bcc5a2ecc 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -1303,14 +1303,17 @@ of the Emacs Lisp Reference manual for more detail.
1303 1303
1304+++ 1304+++
1305** Window change functions have been redesigned completely. 1305** Window change functions have been redesigned completely.
1306
1306Hooks reacting to window changes run now only when redisplay detects 1307Hooks reacting to window changes run now only when redisplay detects
1307that a change has actually occurred. The four hooks provided are: 1308that a change has actually occurred. The five hooks provided are:
1308'window-buffer-change-functions' (run after window buffers have 1309'window-buffer-change-functions' (run after window buffers have
1309changed), 'window-size-change-functions' (run after a window was 1310changed), 'window-size-change-functions' (run after a window was
1310assigned a new buffer or size), 'window-configuration-change-hook' 1311assigned a new buffer or size), 'window-configuration-change-hook'
1311(like the former but run also when a window was deleted) and 1312(like the former but run also when a window was deleted),
1312'window-selection-change-functions' (run when the selected window 1313'window-selection-change-functions' (run when the selected window
1313changed). 'window-scroll-functions' are unaffected by these changes. 1314changed) and 'window-state-change-functions' (run when any of the
1315preceding ones is run). 'window-scroll-functions' are unaffected by
1316these changes.
1314 1317
1315In addition, a number of functions now allow the caller to detect what 1318In addition, a number of functions now allow the caller to detect what
1316has changed since last redisplay: 'window-old-buffer' returns for any 1319has changed since last redisplay: 'window-old-buffer' returns for any
diff --git a/src/window.c b/src/window.c
index 7eb532f78cf..c0d745995a8 100644
--- a/src/window.c
+++ b/src/window.c
@@ -3799,7 +3799,7 @@ run_window_change_functions (void)
3799 run_window_change_functions_1 3799 run_window_change_functions_1
3800 (Qwindow_size_change_functions, buffer, window); 3800 (Qwindow_size_change_functions, buffer, window);
3801 3801
3802 /* This window's selection has changed when it it was 3802 /* This window's selection has changed when it was
3803 (de-)selected as its frame's or the globally selected 3803 (de-)selected as its frame's or the globally selected
3804 window. */ 3804 window. */
3805 if (((frame_selected_change 3805 if (((frame_selected_change
@@ -3811,6 +3811,21 @@ run_window_change_functions (void)
3811 && WINDOW_LIVE_P (window)) 3811 && WINDOW_LIVE_P (window))
3812 run_window_change_functions_1 3812 run_window_change_functions_1
3813 (Qwindow_selection_change_functions, buffer, window); 3813 (Qwindow_selection_change_functions, buffer, window);
3814
3815 /* This window's state has changed when its buffer or size
3816 changed or it was (de-)selected as its frame's or the
3817 globally selected window. */
3818 if ((window_buffer_change
3819 || window_size_change
3820 || ((frame_selected_change
3821 && (EQ (window, old_selected_window)
3822 || EQ (window, selected_window)))
3823 || (frame_selected_window_change
3824 && (EQ (window, FRAME_OLD_SELECTED_WINDOW (f))
3825 || EQ (window, FRAME_SELECTED_WINDOW (f))))))
3826 && WINDOW_LIVE_P (window))
3827 run_window_change_functions_1
3828 (Qwindow_state_change_functions, buffer, window);
3814 } 3829 }
3815 3830
3816 /* When the number of windows on a frame has decreased, at least 3831 /* When the number of windows on a frame has decreased, at least
@@ -3840,6 +3855,15 @@ run_window_change_functions (void)
3840 run_window_change_functions_1 3855 run_window_change_functions_1
3841 (Qwindow_selection_change_functions, Qnil, frame); 3856 (Qwindow_selection_change_functions, Qnil, frame);
3842 3857
3858 /* A frame has changed state when a size or buffer change
3859 occurrd or its selected window has changed or when it was
3860 (de-)selected. */
3861 if ((frame_selected_change || frame_selected_window_change
3862 || frame_buffer_change || window_deleted || frame_size_change)
3863 && FRAME_LIVE_P (f))
3864 run_window_change_functions_1
3865 (Qwindow_state_change_functions, Qnil, frame);
3866
3843 /* A frame's configuration changed when one of its windows has 3867 /* A frame's configuration changed when one of its windows has
3844 changed buffer or size or at least one window was deleted. */ 3868 changed buffer or size or at least one window was deleted. */
3845 if ((frame_size_change || window_deleted) && FRAME_LIVE_P (f)) 3869 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)
4650 /* For a leaf root window just set the size. */ 4674 /* For a leaf root window just set the size. */
4651 if (horflag) 4675 if (horflag)
4652 { 4676 {
4677 bool changed = r->pixel_width != new_pixel_size;
4678
4653 r->total_cols = new_size; 4679 r->total_cols = new_size;
4654 r->pixel_width = new_pixel_size; 4680 r->pixel_width = new_pixel_size;
4681
4682 if (changed && !WINDOW_PSEUDO_P (r))
4683 FRAME_WINDOW_CHANGE (f) = true;
4655 } 4684 }
4656 else 4685 else
4657 { 4686 {
4687 bool changed = r->pixel_height != new_pixel_size;
4688
4658 r->top_line = FRAME_TOP_MARGIN (f); 4689 r->top_line = FRAME_TOP_MARGIN (f);
4659 r->pixel_top = FRAME_TOP_MARGIN_HEIGHT (f); 4690 r->pixel_top = FRAME_TOP_MARGIN_HEIGHT (f);
4660 4691
4661 r->total_lines = new_size; 4692 r->total_lines = new_size;
4662 r->pixel_height = new_pixel_size; 4693 r->pixel_height = new_pixel_size;
4694
4695 if (changed && !WINDOW_PSEUDO_P (r))
4696 FRAME_WINDOW_CHANGE (f) = true;
4663 } 4697 }
4664 else 4698 else
4665 { 4699 {
@@ -7953,6 +7987,7 @@ syms_of_window (void)
7953 Fput (Qscroll_down, Qscroll_command, Qt); 7987 Fput (Qscroll_down, Qscroll_command, Qt);
7954 7988
7955 DEFSYM (Qwindow_configuration_change_hook, "window-configuration-change-hook"); 7989 DEFSYM (Qwindow_configuration_change_hook, "window-configuration-change-hook");
7990 DEFSYM (Qwindow_state_change_functions, "window-state-change-functions");
7956 DEFSYM (Qwindow_size_change_functions, "window-size-change-functions"); 7991 DEFSYM (Qwindow_size_change_functions, "window-size-change-functions");
7957 DEFSYM (Qwindow_buffer_change_functions, "window-buffer-change-functions"); 7992 DEFSYM (Qwindow_buffer_change_functions, "window-buffer-change-functions");
7958 DEFSYM (Qwindow_selection_change_functions, "window-selection-change-functions"); 7993 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
8074this case the frame is passed as argument. */); 8109this case the frame is passed as argument. */);
8075 Vwindow_selection_change_functions = Qnil; 8110 Vwindow_selection_change_functions = Qnil;
8076 8111
8112 DEFVAR_LISP ("window-state-change-functions", Vwindow_state_change_functions,
8113 doc: /* Functions called during redisplay when the window state changed.
8114The value should be a list of functions that take one argument.
8115
8116Functions specified buffer-locally are called for each window showing
8117the corresponding buffer if and only if that window has been added,
8118resized, changed its buffer or has been (de-)selected since the last
8119redisplay. In this case the window is passed as argument.
8120
8121Functions specified by the default value are called for each frame if
8122at least one window on that frame has been added, deleted, changed its
8123buffer or its total or body size or the frame has been (de-)selected
8124or its selected window has changed since the last redisplay. In this
8125case the frame is passed as argument. */);
8126 Vwindow_selection_change_functions = Qnil;
8127
8077 DEFVAR_LISP ("window-configuration-change-hook", Vwindow_configuration_change_hook, 8128 DEFVAR_LISP ("window-configuration-change-hook", Vwindow_configuration_change_hook,
8078 doc: /* Functions called during redisplay when window configuration has changed. 8129 doc: /* Functions called during redisplay when window configuration has changed.
8079The value should be a list of functions that take no argument. 8130The value should be a list of functions that take no argument.