diff options
| author | Martin Rudalics | 2025-10-06 10:27:27 +0200 |
|---|---|---|
| committer | Martin Rudalics | 2025-10-06 10:27:27 +0200 |
| commit | 1434bc97dc9b4bee6b0463c969abe905a3b2ec1f (patch) | |
| tree | 570bf73a8c9fdee1a9a137119275a3562ba65ed7 /src | |
| parent | 129119aef1c850de9d20ecc828c889801f3e668f (diff) | |
| download | emacs-1434bc97dc9b4bee6b0463c969abe905a3b2ec1f.tar.gz emacs-1434bc97dc9b4bee6b0463c969abe905a3b2ec1f.zip | |
Run buffer-local window change functions in their buffers now
The buffer-local-versions of 'window-buffer-change-functions',
'window-size-change-functions',
'window-selection-change-functions' and
'window-state-change-functions' are now run with the respective
buffer temporarily current. Also, the local version of
'window-buffer-change-functions' is run for the buffer removed
from the window too.
* src/window.c (run_window_change_functions_locally)
(run_window_change_functions_globally): New functions replacing
'run_window_change_functions_1'.
(run_window_change_functions): Run the buffer local versions of
these hooks in their respective buffers. Run
'window-buffer-change-functions' for the buffer removed from the
window too.
(Vwindow_buffer_change_functions, Vwindow_size_change_functions)
(Vwindow_selection_change_functions)
(Vwindow_state_change_functions): Mention that the buffer-local
versions are run with their buffer temporarily current.
* doc/lispref/windows.texi (Window Hooks): Mention that
buffer-local-versions of window change functions are run with
their buffer temporarily current. Also say that
'window-buffer-change-functions' will be run for removed buffer
too.
* etc/NEWS: Advertise changes for the buffer-local versions of
window change functions.
Diffstat (limited to 'src')
| -rw-r--r-- | src/window.c | 129 |
1 files changed, 79 insertions, 50 deletions
diff --git a/src/window.c b/src/window.c index 1ac004af5e0..dee17ae445a 100644 --- a/src/window.c +++ b/src/window.c | |||
| @@ -3991,47 +3991,56 @@ window_change_record (void) | |||
| 3991 | } | 3991 | } |
| 3992 | 3992 | ||
| 3993 | 3993 | ||
| 3994 | /** | 3994 | /** Run the buffer local value of SYMBOL in BUFFER, if any, with |
| 3995 | * run_window_change_functions_1: | 3995 | argument WINDOW. WINDOW must specify a live window that shows or |
| 3996 | * | 3996 | recently has shown BUFFER. |
| 3997 | * Run window change functions specified by SYMBOL with argument | ||
| 3998 | * WINDOW_OR_FRAME. If BUFFER is nil, WINDOW_OR_FRAME specifies a | ||
| 3999 | * frame. In this case, run the default value of SYMBOL. Otherwise, | ||
| 4000 | * WINDOW_OR_FRAME denotes a window showing BUFFER. In this case, run | ||
| 4001 | * the buffer local value of SYMBOL in BUFFER, if any. | ||
| 4002 | */ | 3997 | */ |
| 4003 | static void | 3998 | static void |
| 4004 | run_window_change_functions_1 (Lisp_Object symbol, Lisp_Object buffer, | 3999 | run_window_change_functions_locally (Lisp_Object symbol, Lisp_Object buffer, |
| 4005 | Lisp_Object window_or_frame) | 4000 | Lisp_Object window) |
| 4006 | { | 4001 | { |
| 4007 | Lisp_Object funs = Qnil; | ||
| 4008 | 4002 | ||
| 4009 | if (NILP (buffer)) | 4003 | if (!NILP (assq_no_quit (symbol, BVAR (XBUFFER (buffer), local_var_alist)))) |
| 4010 | funs = Fdefault_value (symbol); | ||
| 4011 | else if (!NILP (Fassoc (symbol, BVAR (XBUFFER (buffer), local_var_alist), | ||
| 4012 | Qnil))) | ||
| 4013 | /* Don't run global value buffer-locally. */ | ||
| 4014 | funs = buffer_local_value (symbol, buffer); | ||
| 4015 | |||
| 4016 | while (CONSP (funs)) | ||
| 4017 | { | 4004 | { |
| 4018 | if (!EQ (XCAR (funs), Qt) | 4005 | Lisp_Object funs = buffer_local_value (symbol, buffer); |
| 4019 | && (NILP (buffer) | 4006 | |
| 4020 | ? FRAME_LIVE_P (XFRAME (window_or_frame)) | 4007 | Fset_buffer (buffer); |
| 4021 | : WINDOW_LIVE_P (window_or_frame))) | 4008 | |
| 4009 | while (CONSP (funs)) | ||
| 4022 | { | 4010 | { |
| 4023 | /* Any function called here may change the state of any | 4011 | if (!EQ (XCAR (funs), Qt)) |
| 4024 | frame. Make sure to record changes for each live frame | 4012 | { |
| 4025 | in window_change_record later. */ | 4013 | window_change_record_frames = true; |
| 4026 | window_change_record_frames = true; | 4014 | safe_calln (XCAR (funs), window); |
| 4027 | safe_calln (XCAR (funs), window_or_frame); | 4015 | } |
| 4028 | } | ||
| 4029 | 4016 | ||
| 4030 | funs = XCDR (funs); | 4017 | funs = XCDR (funs); |
| 4018 | } | ||
| 4031 | } | 4019 | } |
| 4032 | } | 4020 | } |
| 4033 | 4021 | ||
| 4034 | 4022 | ||
| 4023 | /** Run the default value of SYMBOL, if any, with argument FRAME. */ | ||
| 4024 | static void | ||
| 4025 | run_window_change_functions_globally (Lisp_Object symbol, Lisp_Object frame) | ||
| 4026 | { | ||
| 4027 | Lisp_Object funs = Fdefault_value (symbol); | ||
| 4028 | |||
| 4029 | if (!NILP (funs)) | ||
| 4030 | { | ||
| 4031 | while (CONSP (funs)) | ||
| 4032 | { | ||
| 4033 | if (!EQ (XCAR (funs), Qt)) | ||
| 4034 | { | ||
| 4035 | window_change_record_frames = true; | ||
| 4036 | safe_calln (XCAR (funs), frame); | ||
| 4037 | } | ||
| 4038 | |||
| 4039 | funs = XCDR (funs); | ||
| 4040 | } | ||
| 4041 | } | ||
| 4042 | } | ||
| 4043 | |||
| 4035 | /** | 4044 | /** |
| 4036 | * run_window_change_functions: | 4045 | * run_window_change_functions: |
| 4037 | * | 4046 | * |
| @@ -4149,6 +4158,7 @@ run_window_change_functions (void) | |||
| 4149 | Lisp_Object window = XCAR (windows); | 4158 | Lisp_Object window = XCAR (windows); |
| 4150 | struct window *w = XWINDOW (window); | 4159 | struct window *w = XWINDOW (window); |
| 4151 | Lisp_Object buffer = WINDOW_BUFFER (w); | 4160 | Lisp_Object buffer = WINDOW_BUFFER (w); |
| 4161 | specpdl_ref count1 = SPECPDL_INDEX (); | ||
| 4152 | 4162 | ||
| 4153 | /* Count this window even if it has been deleted while | 4163 | /* Count this window even if it has been deleted while |
| 4154 | running a hook. */ | 4164 | running a hook. */ |
| @@ -4188,12 +4198,22 @@ run_window_change_functions (void) | |||
| 4188 | frame_buffer_change = frame_buffer_change || window_buffer_change; | 4198 | frame_buffer_change = frame_buffer_change || window_buffer_change; |
| 4189 | frame_size_change = frame_size_change || window_size_change; | 4199 | frame_size_change = frame_size_change || window_size_change; |
| 4190 | 4200 | ||
| 4201 | /* Prepare for running local hooks in their buffers. */ | ||
| 4202 | record_unwind_current_buffer (); | ||
| 4203 | |||
| 4191 | if (window_buffer_change) | 4204 | if (window_buffer_change) |
| 4192 | run_window_change_functions_1 | 4205 | { |
| 4193 | (Qwindow_buffer_change_functions, buffer, window); | 4206 | if (BUFFERP (w->old_buffer) |
| 4207 | && BUFFER_LIVE_P (XBUFFER (w->old_buffer))) | ||
| 4208 | run_window_change_functions_locally | ||
| 4209 | (Qwindow_buffer_change_functions, w->old_buffer, window); | ||
| 4210 | |||
| 4211 | run_window_change_functions_locally | ||
| 4212 | (Qwindow_buffer_change_functions, buffer, window); | ||
| 4213 | } | ||
| 4194 | 4214 | ||
| 4195 | if (window_size_change && WINDOW_LIVE_P (window)) | 4215 | if (window_size_change && WINDOW_LIVE_P (window)) |
| 4196 | run_window_change_functions_1 | 4216 | run_window_change_functions_locally |
| 4197 | (Qwindow_size_change_functions, buffer, window); | 4217 | (Qwindow_size_change_functions, buffer, window); |
| 4198 | 4218 | ||
| 4199 | /* This window's selection has changed when it was | 4219 | /* This window's selection has changed when it was |
| @@ -4206,7 +4226,7 @@ run_window_change_functions (void) | |||
| 4206 | && (EQ (window, FRAME_OLD_SELECTED_WINDOW (f)) | 4226 | && (EQ (window, FRAME_OLD_SELECTED_WINDOW (f)) |
| 4207 | || EQ (window, FRAME_SELECTED_WINDOW (f))))) | 4227 | || EQ (window, FRAME_SELECTED_WINDOW (f))))) |
| 4208 | && WINDOW_LIVE_P (window)) | 4228 | && WINDOW_LIVE_P (window)) |
| 4209 | run_window_change_functions_1 | 4229 | run_window_change_functions_locally |
| 4210 | (Qwindow_selection_change_functions, buffer, window); | 4230 | (Qwindow_selection_change_functions, buffer, window); |
| 4211 | 4231 | ||
| 4212 | /* This window's state has changed when its buffer or size | 4232 | /* This window's state has changed when its buffer or size |
| @@ -4221,8 +4241,11 @@ run_window_change_functions (void) | |||
| 4221 | && (EQ (window, FRAME_OLD_SELECTED_WINDOW (f)) | 4241 | && (EQ (window, FRAME_OLD_SELECTED_WINDOW (f)) |
| 4222 | || EQ (window, FRAME_SELECTED_WINDOW (f)))))) | 4242 | || EQ (window, FRAME_SELECTED_WINDOW (f)))))) |
| 4223 | && WINDOW_LIVE_P (window)) | 4243 | && WINDOW_LIVE_P (window)) |
| 4224 | run_window_change_functions_1 | 4244 | run_window_change_functions_locally |
| 4225 | (Qwindow_state_change_functions, buffer, window); | 4245 | (Qwindow_state_change_functions, buffer, window); |
| 4246 | |||
| 4247 | /* Restore current buffer for running the global hooks. */ | ||
| 4248 | unbind_to (count1, Qnil); | ||
| 4226 | } | 4249 | } |
| 4227 | 4250 | ||
| 4228 | /* When the number of windows on a frame has decreased, at least | 4251 | /* When the number of windows on a frame has decreased, at least |
| @@ -4236,21 +4259,21 @@ run_window_change_functions (void) | |||
| 4236 | /* A frame changed buffers when one of its windows has changed | 4259 | /* A frame changed buffers when one of its windows has changed |
| 4237 | its buffer or at least one window was deleted. */ | 4260 | its buffer or at least one window was deleted. */ |
| 4238 | if ((frame_buffer_change || window_deleted) && FRAME_LIVE_P (f)) | 4261 | if ((frame_buffer_change || window_deleted) && FRAME_LIVE_P (f)) |
| 4239 | run_window_change_functions_1 | 4262 | run_window_change_functions_globally |
| 4240 | (Qwindow_buffer_change_functions, Qnil, frame); | 4263 | (Qwindow_buffer_change_functions, frame); |
| 4241 | 4264 | ||
| 4242 | /* A size change occurred when at least one of the frame's | 4265 | /* A size change occurred when at least one of the frame's |
| 4243 | windows has changed size. */ | 4266 | windows has changed size. */ |
| 4244 | if (frame_size_change && FRAME_LIVE_P (f)) | 4267 | if (frame_size_change && FRAME_LIVE_P (f)) |
| 4245 | run_window_change_functions_1 | 4268 | run_window_change_functions_globally |
| 4246 | (Qwindow_size_change_functions, Qnil, frame); | 4269 | (Qwindow_size_change_functions, frame); |
| 4247 | 4270 | ||
| 4248 | /* A frame has changed its window selection when its selected | 4271 | /* A frame has changed its window selection when its selected |
| 4249 | window has changed or when it was (de-)selected. */ | 4272 | window has changed or when it was (de-)selected. */ |
| 4250 | if ((frame_selected_change || frame_selected_window_change) | 4273 | if ((frame_selected_change || frame_selected_window_change) |
| 4251 | && FRAME_LIVE_P (f)) | 4274 | && FRAME_LIVE_P (f)) |
| 4252 | run_window_change_functions_1 | 4275 | run_window_change_functions_globally |
| 4253 | (Qwindow_selection_change_functions, Qnil, frame); | 4276 | (Qwindow_selection_change_functions, frame); |
| 4254 | 4277 | ||
| 4255 | #if defined HAVE_TEXT_CONVERSION | 4278 | #if defined HAVE_TEXT_CONVERSION |
| 4256 | 4279 | ||
| @@ -4272,8 +4295,8 @@ run_window_change_functions (void) | |||
| 4272 | || frame_size_change || frame_window_state_change) | 4295 | || frame_size_change || frame_window_state_change) |
| 4273 | && FRAME_LIVE_P (f)) | 4296 | && FRAME_LIVE_P (f)) |
| 4274 | { | 4297 | { |
| 4275 | run_window_change_functions_1 | 4298 | run_window_change_functions_globally |
| 4276 | (Qwindow_state_change_functions, Qnil, frame); | 4299 | (Qwindow_state_change_functions, frame); |
| 4277 | /* Make sure to run 'window-state-change-hook' later. */ | 4300 | /* Make sure to run 'window-state-change-hook' later. */ |
| 4278 | run_window_state_change_hook = true; | 4301 | run_window_state_change_hook = true; |
| 4279 | /* Make sure to record changes for each live frame in | 4302 | /* Make sure to record changes for each live frame in |
| @@ -8959,8 +8982,12 @@ The value should be a list of functions that take one argument. | |||
| 8959 | 8982 | ||
| 8960 | Functions specified buffer-locally are called for each window showing | 8983 | Functions specified buffer-locally are called for each window showing |
| 8961 | the corresponding buffer if and only if that window has been added or | 8984 | the corresponding buffer if and only if that window has been added or |
| 8962 | changed its buffer since the last redisplay. In this case the window | 8985 | changed its buffer since the last redisplay. This means that functions |
| 8963 | is passed as argument. | 8986 | may be run twice for such a window: Once for the buffer shown in the |
| 8987 | window at the time of the last redisplay (provided that buffer is still | ||
| 8988 | live) and once for the buffer currently shown in the window. In either | ||
| 8989 | case the window is passed as argument and the respective buffer is made | ||
| 8990 | temporarily current. | ||
| 8964 | 8991 | ||
| 8965 | Functions specified by the default value are called for each frame if | 8992 | Functions specified by the default value are called for each frame if |
| 8966 | at least one window on that frame has been added, deleted or changed | 8993 | at least one window on that frame has been added, deleted or changed |
| @@ -8975,7 +9002,8 @@ The value should be a list of functions that take one argument. | |||
| 8975 | Functions specified buffer-locally are called for each window showing | 9002 | Functions specified buffer-locally are called for each window showing |
| 8976 | the corresponding buffer if and only if that window has been added or | 9003 | the corresponding buffer if and only if that window has been added or |
| 8977 | changed its buffer or its total or body size since the last redisplay. | 9004 | changed its buffer or its total or body size since the last redisplay. |
| 8978 | In this case the window is passed as argument. | 9005 | In this case the window is passed as argument and the respective buffer |
| 9006 | is temporarily made current. | ||
| 8979 | 9007 | ||
| 8980 | Functions specified by the default value are called for each frame if | 9008 | Functions specified by the default value are called for each frame if |
| 8981 | at least one window on that frame has been added or changed its buffer | 9009 | at least one window on that frame has been added or changed its buffer |
| @@ -8991,9 +9019,9 @@ can add `frame-hide-title-bar-when-maximized' to this variable. */); | |||
| 8991 | The value should be a list of functions that take one argument. | 9019 | The value should be a list of functions that take one argument. |
| 8992 | 9020 | ||
| 8993 | Functions specified buffer-locally are called for each window showing | 9021 | Functions specified buffer-locally are called for each window showing |
| 8994 | the corresponding buffer if and only if that window has been selected | 9022 | the corresponding buffer if and only if that window has been selected or |
| 8995 | or deselected since the last redisplay. In this case the window is | 9023 | deselected since the last redisplay. In this case the window is passed |
| 8996 | passed as argument. | 9024 | as argument and the respective buffer is temporarily made current. |
| 8997 | 9025 | ||
| 8998 | Functions specified by the default value are called for each frame if | 9026 | Functions specified by the default value are called for each frame if |
| 8999 | the frame's selected window has changed since the last redisplay. In | 9027 | the frame's selected window has changed since the last redisplay. In |
| @@ -9007,7 +9035,8 @@ The value should be a list of functions that take one argument. | |||
| 9007 | Functions specified buffer-locally are called for each window showing | 9035 | Functions specified buffer-locally are called for each window showing |
| 9008 | the corresponding buffer if and only if that window has been added, | 9036 | the corresponding buffer if and only if that window has been added, |
| 9009 | resized, changed its buffer or has been (de-)selected since the last | 9037 | resized, changed its buffer or has been (de-)selected since the last |
| 9010 | redisplay. In this case the window is passed as argument. | 9038 | redisplay. In this case the window is passed as argument and the |
| 9039 | respective buffer is temporarily made current. | ||
| 9011 | 9040 | ||
| 9012 | Functions specified by the default value are called for each frame if | 9041 | Functions specified by the default value are called for each frame if |
| 9013 | at least one window on that frame has been added, deleted, changed its | 9042 | at least one window on that frame has been added, deleted, changed its |