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'.