aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMartin Rudalics2025-10-06 10:27:27 +0200
committerMartin Rudalics2025-10-06 10:27:27 +0200
commit1434bc97dc9b4bee6b0463c969abe905a3b2ec1f (patch)
tree570bf73a8c9fdee1a9a137119275a3562ba65ed7 /src
parent129119aef1c850de9d20ecc828c889801f3e668f (diff)
downloademacs-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.c129
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 */
4003static void 3998static void
4004run_window_change_functions_1 (Lisp_Object symbol, Lisp_Object buffer, 3999run_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. */
4024static void
4025run_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
8960Functions specified buffer-locally are called for each window showing 8983Functions specified buffer-locally are called for each window showing
8961the corresponding buffer if and only if that window has been added or 8984the corresponding buffer if and only if that window has been added or
8962changed its buffer since the last redisplay. In this case the window 8985changed its buffer since the last redisplay. This means that functions
8963is passed as argument. 8986may be run twice for such a window: Once for the buffer shown in the
8987window at the time of the last redisplay (provided that buffer is still
8988live) and once for the buffer currently shown in the window. In either
8989case the window is passed as argument and the respective buffer is made
8990temporarily current.
8964 8991
8965Functions specified by the default value are called for each frame if 8992Functions specified by the default value are called for each frame if
8966at least one window on that frame has been added, deleted or changed 8993at 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.
8975Functions specified buffer-locally are called for each window showing 9002Functions specified buffer-locally are called for each window showing
8976the corresponding buffer if and only if that window has been added or 9003the corresponding buffer if and only if that window has been added or
8977changed its buffer or its total or body size since the last redisplay. 9004changed its buffer or its total or body size since the last redisplay.
8978In this case the window is passed as argument. 9005In this case the window is passed as argument and the respective buffer
9006is temporarily made current.
8979 9007
8980Functions specified by the default value are called for each frame if 9008Functions specified by the default value are called for each frame if
8981at least one window on that frame has been added or changed its buffer 9009at 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. */);
8991The value should be a list of functions that take one argument. 9019The value should be a list of functions that take one argument.
8992 9020
8993Functions specified buffer-locally are called for each window showing 9021Functions specified buffer-locally are called for each window showing
8994the corresponding buffer if and only if that window has been selected 9022the corresponding buffer if and only if that window has been selected or
8995or deselected since the last redisplay. In this case the window is 9023deselected since the last redisplay. In this case the window is passed
8996passed as argument. 9024as argument and the respective buffer is temporarily made current.
8997 9025
8998Functions specified by the default value are called for each frame if 9026Functions specified by the default value are called for each frame if
8999the frame's selected window has changed since the last redisplay. In 9027the 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.
9007Functions specified buffer-locally are called for each window showing 9035Functions specified buffer-locally are called for each window showing
9008the corresponding buffer if and only if that window has been added, 9036the corresponding buffer if and only if that window has been added,
9009resized, changed its buffer or has been (de-)selected since the last 9037resized, changed its buffer or has been (de-)selected since the last
9010redisplay. In this case the window is passed as argument. 9038redisplay. In this case the window is passed as argument and the
9039respective buffer is temporarily made current.
9011 9040
9012Functions specified by the default value are called for each frame if 9041Functions specified by the default value are called for each frame if
9013at least one window on that frame has been added, deleted, changed its 9042at least one window on that frame has been added, deleted, changed its