aboutsummaryrefslogtreecommitdiffstats
path: root/src/window.c
diff options
context:
space:
mode:
authorMartin Rudalics2013-12-22 16:19:09 +0100
committerMartin Rudalics2013-12-22 16:19:09 +0100
commita2b89a519573ae5ef301ef5c9b0eb224df8bd960 (patch)
tree7bbafcd11a6f6fda23e6b5a020a3e6c8342dccea /src/window.c
parentdca38cf96056f20a1b03cf24ff93644b0e44ea4e (diff)
downloademacs-a2b89a519573ae5ef301ef5c9b0eb224df8bd960.tar.gz
emacs-a2b89a519573ae5ef301ef5c9b0eb224df8bd960.zip
Handle Bug#16207 by being more restrictive when running hooks.
* window.c (unwind_change_frame): New function. (Fset_window_configuration): Don't run configuration change hook while the frame configuration is unsafe. Call select_window twice.
Diffstat (limited to 'src/window.c')
-rw-r--r--src/window.c42
1 files changed, 28 insertions, 14 deletions
diff --git a/src/window.c b/src/window.c
index e0c44ad344b..9939ec1d8fc 100644
--- a/src/window.c
+++ b/src/window.c
@@ -5917,6 +5917,13 @@ DEFUN ("window-configuration-frame", Fwindow_configuration_frame, Swindow_config
5917 return XWINDOW (SAVED_WINDOW_N (saved_windows, 0)->window)->frame; 5917 return XWINDOW (SAVED_WINDOW_N (saved_windows, 0)->window)->frame;
5918} 5918}
5919 5919
5920/* From Chong's unwind_create_frame_1. */
5921static void
5922unwind_change_frame (Lisp_Object val)
5923{
5924 inhibit_lisp_code = val;
5925}
5926
5920DEFUN ("set-window-configuration", Fset_window_configuration, 5927DEFUN ("set-window-configuration", Fset_window_configuration,
5921 Sset_window_configuration, 1, 1, 0, 5928 Sset_window_configuration, 1, 1, 0,
5922 doc: /* Set the configuration of windows and buffers as specified by CONFIGURATION. 5929 doc: /* Set the configuration of windows and buffers as specified by CONFIGURATION.
@@ -5996,7 +6003,7 @@ the return value is nil. Otherwise the value is t. */)
5996 int n_leaf_windows; 6003 int n_leaf_windows;
5997 ptrdiff_t k; 6004 ptrdiff_t k;
5998 int i, n; 6005 int i, n;
5999 6006 ptrdiff_t count = SPECPDL_INDEX ();
6000 /* If the frame has been resized since this window configuration was 6007 /* If the frame has been resized since this window configuration was
6001 made, we change the frame to the size specified in the 6008 made, we change the frame to the size specified in the
6002 configuration, restore the configuration, and then resize it 6009 configuration, restore the configuration, and then resize it
@@ -6025,6 +6032,10 @@ the return value is nil. Otherwise the value is t. */)
6025 call1 (Qrecord_window_buffer, window); 6032 call1 (Qrecord_window_buffer, window);
6026 } 6033 }
6027 6034
6035 /* Don't run lisp in the following segment since the frame is in a
6036 completely inconsistent state. See Bug#16207. */
6037 record_unwind_protect (unwind_change_frame, inhibit_lisp_code);
6038 inhibit_lisp_code = Qt;
6028 /* The mouse highlighting code could get screwed up 6039 /* The mouse highlighting code could get screwed up
6029 if it runs during this. */ 6040 if it runs during this. */
6030 block_input (); 6041 block_input ();
@@ -6222,6 +6233,18 @@ the return value is nil. Otherwise the value is t. */)
6222 make_number (old_point), 6233 make_number (old_point),
6223 XWINDOW (data->current_window)->contents); 6234 XWINDOW (data->current_window)->contents);
6224 6235
6236 /* In the following call to `select-window', prevent "swapping out
6237 point" in the old selected window using the buffer that has
6238 been restored into it. We already swapped out that point from
6239 that window's old buffer.
6240
6241 Do not record the buffer here. We do that in a separate call
6242 to select_window below. See also Bug#16207. */
6243 select_window (data->current_window, Qt, 1);
6244 BVAR (XBUFFER (XWINDOW (selected_window)->contents),
6245 last_selected_window)
6246 = selected_window;
6247
6225 if (NILP (data->focus_frame) 6248 if (NILP (data->focus_frame)
6226 || (FRAMEP (data->focus_frame) 6249 || (FRAMEP (data->focus_frame)
6227 && FRAME_LIVE_P (XFRAME (data->focus_frame)))) 6250 && FRAME_LIVE_P (XFRAME (data->focus_frame))))
@@ -6262,6 +6285,7 @@ the return value is nil. Otherwise the value is t. */)
6262 6285
6263 adjust_frame_glyphs (f); 6286 adjust_frame_glyphs (f);
6264 unblock_input (); 6287 unblock_input ();
6288 unbind_to (count, Qnil);
6265 6289
6266 /* Scan dead buffer windows. */ 6290 /* Scan dead buffer windows. */
6267 for (; CONSP (dead_windows); dead_windows = XCDR (dead_windows)) 6291 for (; CONSP (dead_windows); dead_windows = XCDR (dead_windows))
@@ -6271,19 +6295,9 @@ the return value is nil. Otherwise the value is t. */)
6271 delete_deletable_window (window); 6295 delete_deletable_window (window);
6272 } 6296 }
6273 6297
6274 /* In the following call to `select-window', prevent "swapping out 6298 /* Record the selected window's buffer here. The window should
6275 point" in the old selected window using the buffer that has 6299 already be the selected one from the call above. */
6276 been restored into it. We already swapped out that point from 6300 select_window (data->current_window, Qnil, 0);
6277 that window's old buffer. */
6278 /* This `select_window' calls record_buffer which calls Fdelq which
6279 invokes QUIT, so we do it here at the end rather than earlier,
6280 to minimize the risk of interrupting the Fset_window_configuration
6281 in an inconsistent state (e.g. before frame-focus redirection is
6282 canceled). */
6283 select_window (data->current_window, Qnil, 1);
6284 BVAR (XBUFFER (XWINDOW (selected_window)->contents),
6285 last_selected_window)
6286 = selected_window;
6287 6301
6288 /* Fselect_window will have made f the selected frame, so we 6302 /* Fselect_window will have made f the selected frame, so we
6289 reselect the proper frame here. Fhandle_switch_frame will change the 6303 reselect the proper frame here. Fhandle_switch_frame will change the