diff options
| author | Martin Rudalics | 2019-01-17 10:21:07 +0100 |
|---|---|---|
| committer | Martin Rudalics | 2019-01-17 10:21:07 +0100 |
| commit | 0aece3e1181e66f2a1a067ae876e55bdaa45edd5 (patch) | |
| tree | 240c9dca3ff8a81460e5150d6b24993766bd707e | |
| parent | 978cf88bda9c9b41f1cc20cf8e53a9e6caeb91be (diff) | |
| download | emacs-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.texi | 46 | ||||
| -rw-r--r-- | etc/NEWS | 9 | ||||
| -rw-r--r-- | src/window.c | 53 |
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 |
| 1763 | For historical reasons, Emacs does not run a separate hook whenever a | 1763 | For historical reasons, Emacs does not run a separate hook whenever a |
| 1764 | window gets selected. Applications and internal routines often | 1764 | window 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 |
| 1776 | the normal hook @code{buffer-list-update-hook} (@pxref{Buffer List}). | 1776 | the normal hook @code{buffer-list-update-hook} (@pxref{Buffer List}). |
| 1777 | Consequently, that hook provides a reasonable way to run a function | 1777 | Consequently, that hook provides one way to run a function whenever a |
| 1778 | whenever a window gets selected more ``permanently''. | 1778 | window 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 |
| 1781 | not related to window management, it will usually make sense to save the | 1781 | 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 | |||
| 1787 | possible, the macro @code{with-selected-window} (see below) should be | 1787 | possible, the macro @code{with-selected-window} (see below) should be |
| 1788 | used in such cases. | 1788 | used in such cases. |
| 1789 | 1789 | ||
| 1790 | Emacs also runs the hook @code{window-selection-change-functions} | ||
| 1791 | whenever the redisplay routine detects that another window has been | ||
| 1792 | selected since last redisplay. @xref{Window Hooks}, for a detailed | ||
| 1793 | explanation. @code{window-state-change-functions} (described in the | ||
| 1794 | same section) is another abnormal hook run after a different window | ||
| 1795 | has 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 | |||
| 6039 | changed. @xref{Other Font Lock Variables}. | 6046 | changed. @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 |
| 6043 | the end of redisplay provided a significant, non-scrolling change of a | 6050 | the end of redisplay provided a significant, non-scrolling change of a |
| 6044 | window has been detected. For simplicity, these hooks and the | 6051 | window has been detected. For simplicity, these hooks and the |
| 6045 | functions they call will be collectively referred to as @dfn{window | 6052 | 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 | |||
| 6108 | run. In this case the frame is passed as argument. | 6115 | run. In this case the frame is passed as argument. |
| 6109 | @end defvar | 6116 | @end defvar |
| 6110 | 6117 | ||
| 6118 | @cindex window state change | ||
| 6119 | The fourth of these hooks is run after a @dfn{window state change} has | ||
| 6120 | been detected, which means that at least one of the three preceding | ||
| 6121 | window changes has occurred. | ||
| 6122 | |||
| 6123 | @defvar window-state-change-functions | ||
| 6124 | This variable specifies functions called at the end of redisplay when | ||
| 6125 | a window buffer or size change occurred or the selected window or a | ||
| 6126 | frame's selected window has changed. The value should be a list of | ||
| 6127 | functions that take one argument. | ||
| 6128 | |||
| 6129 | Functions specified buffer-locally are called for any window showing | ||
| 6130 | the corresponding buffer if that window has been added or assigned | ||
| 6131 | another 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 | ||
| 6133 | time window change functions were run. In this case the window is | ||
| 6134 | passed as argument. | ||
| 6135 | |||
| 6136 | Functions specified by the default value are called for a frame if at | ||
| 6137 | least one window on that frame has been added, deleted or assigned | ||
| 6138 | another buffer, total or body size or that frame has been selected or | ||
| 6139 | deselected or the frame's selected window has changed since the last | ||
| 6140 | time window change functions were run. In this case the frame is | ||
| 6141 | passed as argument. | ||
| 6142 | @end defvar | ||
| 6143 | |||
| 6111 | @cindex window configuration change | 6144 | @cindex window configuration change |
| 6112 | The fourth of these hooks is run when a @dfn{window configuration | 6145 | The fifth of these hooks is run when a @dfn{window configuration |
| 6113 | change} has been detected which means that either the buffer or the | 6146 | change} has been detected which means that either the buffer or the |
| 6114 | size of a window changed. | 6147 | size of a window changed. It differs from the four preceding hooks in |
| 6148 | the way it is run. | ||
| 6115 | 6149 | ||
| 6116 | @defvar window-configuration-change-hook | 6150 | @defvar window-configuration-change-hook |
| 6117 | This variable specifies functions called at the end of redisplay when | 6151 | This variable specifies functions called at the end of redisplay when |
| @@ -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 | |||
| 1306 | Hooks reacting to window changes run now only when redisplay detects | 1307 | Hooks reacting to window changes run now only when redisplay detects |
| 1307 | that a change has actually occurred. The four hooks provided are: | 1308 | that 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 |
| 1309 | changed), 'window-size-change-functions' (run after a window was | 1310 | changed), 'window-size-change-functions' (run after a window was |
| 1310 | assigned a new buffer or size), 'window-configuration-change-hook' | 1311 | assigned 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 |
| 1313 | changed). 'window-scroll-functions' are unaffected by these changes. | 1314 | changed) and 'window-state-change-functions' (run when any of the |
| 1315 | preceding ones is run). 'window-scroll-functions' are unaffected by | ||
| 1316 | these changes. | ||
| 1314 | 1317 | ||
| 1315 | In addition, a number of functions now allow the caller to detect what | 1318 | In addition, a number of functions now allow the caller to detect what |
| 1316 | has changed since last redisplay: 'window-old-buffer' returns for any | 1319 | has 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 | |||
| 8074 | this case the frame is passed as argument. */); | 8109 | this 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. | ||
| 8114 | The value should be a list of functions that take one argument. | ||
| 8115 | |||
| 8116 | Functions specified buffer-locally are called for each window showing | ||
| 8117 | the corresponding buffer if and only if that window has been added, | ||
| 8118 | resized, changed its buffer or has been (de-)selected since the last | ||
| 8119 | redisplay. In this case the window is passed as argument. | ||
| 8120 | |||
| 8121 | Functions specified by the default value are called for each frame if | ||
| 8122 | at least one window on that frame has been added, deleted, changed its | ||
| 8123 | buffer or its total or body size or the frame has been (de-)selected | ||
| 8124 | or its selected window has changed since the last redisplay. In this | ||
| 8125 | case 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. |
| 8079 | The value should be a list of functions that take no argument. | 8130 | The value should be a list of functions that take no argument. |