diff options
| author | Martin Rudalics | 2013-12-22 16:19:09 +0100 |
|---|---|---|
| committer | Martin Rudalics | 2013-12-22 16:19:09 +0100 |
| commit | a2b89a519573ae5ef301ef5c9b0eb224df8bd960 (patch) | |
| tree | 7bbafcd11a6f6fda23e6b5a020a3e6c8342dccea /src/window.c | |
| parent | dca38cf96056f20a1b03cf24ff93644b0e44ea4e (diff) | |
| download | emacs-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.c | 42 |
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. */ | ||
| 5921 | static void | ||
| 5922 | unwind_change_frame (Lisp_Object val) | ||
| 5923 | { | ||
| 5924 | inhibit_lisp_code = val; | ||
| 5925 | } | ||
| 5926 | |||
| 5920 | DEFUN ("set-window-configuration", Fset_window_configuration, | 5927 | DEFUN ("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 |