Mercurial > emacs
comparison src/window.c @ 112267:bee0a8fef127
Avoid crash in Fselect_frame due to null selected_window (Bug#7728).
* window.c (inhibit_point_swap): New variable.
(Fselect_window): If inhibit_point_swap is nonzero, avoid swapping
point this time.
(Fset_window_configuration): Set inhibit_point_swap to 1 instead
of setting selected_window to nil (Bug#7728).
author | Chong Yidong <cyd@stupidchicken.com> |
---|---|
date | Fri, 14 Jan 2011 21:55:58 -0500 |
parents | 376148b31b5e |
children | cc0887b67703 e99b4c7a3af4 |
comparison
equal
deleted
inserted
replaced
112266:704fa1a3d5b4 | 112267:bee0a8fef127 |
---|---|
156 | 156 |
157 /* Nonzero after init_window_once has finished. */ | 157 /* Nonzero after init_window_once has finished. */ |
158 | 158 |
159 static int window_initialized; | 159 static int window_initialized; |
160 | 160 |
161 /* Set in `set-window-configuration' to prevent "swapping out point" | |
162 in the old selected window. */ | |
163 | |
164 static int inhibit_point_swap; | |
165 | |
161 /* Hook to run when window config changes. */ | 166 /* Hook to run when window config changes. */ |
162 | 167 |
163 static Lisp_Object Qwindow_configuration_change_hook; | 168 static Lisp_Object Qwindow_configuration_change_hook; |
164 static Lisp_Object Vwindow_configuration_change_hook; | 169 static Lisp_Object Vwindow_configuration_change_hook; |
165 | 170 |
183 | 188 |
184 /* Same for window_scroll_line_based. */ | 189 /* Same for window_scroll_line_based. */ |
185 | 190 |
186 static int window_scroll_preserve_hpos; | 191 static int window_scroll_preserve_hpos; |
187 static int window_scroll_preserve_vpos; | 192 static int window_scroll_preserve_vpos; |
188 | |
189 #if 0 /* This isn't used anywhere. */ | |
190 /* Nonzero means we can split a frame even if it is "unsplittable". */ | |
191 static int inhibit_frame_unsplittable; | |
192 #endif /* 0 */ | |
193 | 193 |
194 extern EMACS_INT scroll_margin; | 194 extern EMACS_INT scroll_margin; |
195 | 195 |
196 extern Lisp_Object Qwindow_scroll_functions, Vwindow_scroll_functions; | 196 extern Lisp_Object Qwindow_scroll_functions, Vwindow_scroll_functions; |
197 | 197 |
3636 sf->selected_window = window; | 3636 sf->selected_window = window; |
3637 | 3637 |
3638 /* Store the current buffer's actual point into the | 3638 /* Store the current buffer's actual point into the |
3639 old selected window. It belongs to that window, | 3639 old selected window. It belongs to that window, |
3640 and when the window is not selected, must be in the window. */ | 3640 and when the window is not selected, must be in the window. */ |
3641 if (!NILP (selected_window)) | 3641 if (inhibit_point_swap) |
3642 inhibit_point_swap = 0; | |
3643 else | |
3642 { | 3644 { |
3643 ow = XWINDOW (selected_window); | 3645 ow = XWINDOW (selected_window); |
3644 if (! NILP (ow->buffer)) | 3646 if (! NILP (ow->buffer)) |
3645 set_marker_both (ow->pointm, ow->buffer, | 3647 set_marker_both (ow->pointm, ow->buffer, |
3646 BUF_PT (XBUFFER (ow->buffer)), | 3648 BUF_PT (XBUFFER (ow->buffer)), |
5859 if (!(BUFFERP (w->buffer) | 5861 if (!(BUFFERP (w->buffer) |
5860 && XBUFFER (w->buffer) == current_buffer)) | 5862 && XBUFFER (w->buffer) == current_buffer)) |
5861 /* This test is needed to make sure PT/PT_BYTE make sense in w->buffer | 5863 /* This test is needed to make sure PT/PT_BYTE make sense in w->buffer |
5862 when passed below to set_marker_both. */ | 5864 when passed below to set_marker_both. */ |
5863 error ("move-to-window-line called from unrelated buffer"); | 5865 error ("move-to-window-line called from unrelated buffer"); |
5864 | 5866 |
5865 window = selected_window; | 5867 window = selected_window; |
5866 start = marker_position (w->start); | 5868 start = marker_position (w->start); |
5867 if (start < BEGV || start > ZV) | 5869 if (start < BEGV || start > ZV) |
5868 { | 5870 { |
5869 int height = window_internal_height (w); | 5871 int height = window_internal_height (w); |
6239 } | 6241 } |
6240 } | 6242 } |
6241 } | 6243 } |
6242 | 6244 |
6243 FRAME_ROOT_WINDOW (f) = data->root_window; | 6245 FRAME_ROOT_WINDOW (f) = data->root_window; |
6244 /* Prevent "swapping out point" in the old selected window | |
6245 using the buffer that has been restored into it. | |
6246 We already swapped out point that from that window's old buffer. */ | |
6247 selected_window = Qnil; | |
6248 | 6246 |
6249 /* Arrange *not* to restore point in the buffer that was | 6247 /* Arrange *not* to restore point in the buffer that was |
6250 current when the window configuration was saved. */ | 6248 current when the window configuration was saved. */ |
6251 if (EQ (XWINDOW (data->current_window)->buffer, new_current_buffer)) | 6249 if (EQ (XWINDOW (data->current_window)->buffer, new_current_buffer)) |
6252 set_marker_restricted (XWINDOW (data->current_window)->pointm, | 6250 set_marker_restricted (XWINDOW (data->current_window)->pointm, |
6253 make_number (old_point), | 6251 make_number (old_point), |
6254 XWINDOW (data->current_window)->buffer); | 6252 XWINDOW (data->current_window)->buffer); |
6255 | 6253 |
6254 /* In the following call to `select-window, prevent "swapping | |
6255 out point" in the old selected window using the buffer that | |
6256 has been restored into it. We already swapped out that point | |
6257 from that window's old buffer. */ | |
6258 inhibit_point_swap = 1; | |
6256 Fselect_window (data->current_window, Qnil); | 6259 Fselect_window (data->current_window, Qnil); |
6257 XBUFFER (XWINDOW (selected_window)->buffer)->last_selected_window | 6260 XBUFFER (XWINDOW (selected_window)->buffer)->last_selected_window |
6258 = selected_window; | 6261 = selected_window; |
6259 | 6262 |
6260 if (NILP (data->focus_frame) | 6263 if (NILP (data->focus_frame) |
6261 || (FRAMEP (data->focus_frame) | 6264 || (FRAMEP (data->focus_frame) |
6262 && FRAME_LIVE_P (XFRAME (data->focus_frame)))) | 6265 && FRAME_LIVE_P (XFRAME (data->focus_frame)))) |
6263 Fredirect_frame_focus (frame, data->focus_frame); | 6266 Fredirect_frame_focus (frame, data->focus_frame); |
6264 | |
6265 #if 0 /* I don't understand why this is needed, and it causes problems | |
6266 when the frame's old selected window has been deleted. */ | |
6267 if (f != selected_frame && FRAME_WINDOW_P (f)) | |
6268 do_switch_frame (WINDOW_FRAME (XWINDOW (data->root_window)), | |
6269 0, 0, Qnil); | |
6270 #endif | |
6271 | 6267 |
6272 /* Set the screen height to the value it had before this function. */ | 6268 /* Set the screen height to the value it had before this function. */ |
6273 if (previous_frame_lines != FRAME_LINES (f) | 6269 if (previous_frame_lines != FRAME_LINES (f) |
6274 || previous_frame_cols != FRAME_COLS (f)) | 6270 || previous_frame_cols != FRAME_COLS (f)) |
6275 change_frame_size (f, previous_frame_lines, previous_frame_cols, | 6271 change_frame_size (f, previous_frame_lines, previous_frame_cols, |
7215 | 7211 |
7216 window_scroll_pixel_based_preserve_x = -1; | 7212 window_scroll_pixel_based_preserve_x = -1; |
7217 window_scroll_pixel_based_preserve_y = -1; | 7213 window_scroll_pixel_based_preserve_y = -1; |
7218 window_scroll_preserve_hpos = -1; | 7214 window_scroll_preserve_hpos = -1; |
7219 window_scroll_preserve_vpos = -1; | 7215 window_scroll_preserve_vpos = -1; |
7216 | |
7217 inhibit_point_swap = 0; | |
7220 | 7218 |
7221 DEFVAR_LISP ("temp-buffer-show-function", &Vtemp_buffer_show_function, | 7219 DEFVAR_LISP ("temp-buffer-show-function", &Vtemp_buffer_show_function, |
7222 doc: /* Non-nil means call as function to display a help buffer. | 7220 doc: /* Non-nil means call as function to display a help buffer. |
7223 The function is called with one argument, the buffer to be displayed. | 7221 The function is called with one argument, the buffer to be displayed. |
7224 Used by `with-output-to-temp-buffer'. | 7222 Used by `with-output-to-temp-buffer'. |