diff --git a/src/frame.c b/src/frame.c index 88d6f22fc0..ef42f230ef 100644 --- a/src/frame.c +++ b/src/frame.c @@ -1466,6 +1466,11 @@ do_switch_frame (Lisp_Object frame, int track, int for_deletion, Lisp_Object nor tty->top_frame = frame; } + if (!FRAME_LIVE_P (f)) + /* Return nil if for some reason FRAME has become dead now + (Bug#39977). */ + return Qnil; + selected_frame = frame; if (! FRAME_MINIBUF_ONLY_P (XFRAME (selected_frame))) last_nonminibuf_frame = XFRAME (selected_frame); @@ -2009,8 +2014,6 @@ delete_frame (Lisp_Object frame, Lisp_Object force) error ("Attempt to delete the only frame"); } - /* At this point, we are committed to deleting the frame. - There is no more chance for errors to prevent it. */ minibuffer_selected = EQ (minibuf_window, selected_window); sf = SELECTED_FRAME (); /* Don't let the frame remain selected. */ @@ -2066,10 +2069,17 @@ delete_frame (Lisp_Object frame, Lisp_Object force) Fraise_frame (frame1); #endif - do_switch_frame (frame1, 0, 1, Qnil); + if (!EQ (do_switch_frame (frame1, 0, 1, Qnil), frame1)) + /* Error out if for some reason FRAME1 was not live + (Bug#39977). */ + error ("No frame to switch to found"); + sf = SELECTED_FRAME (); } + /* At this point, we are committed to deleting the frame. + There is no more chance for errors to prevent it. */ + /* Don't allow minibuf_window to remain on a deleted frame. */ check_minibuf_window (frame, minibuffer_selected); diff --git a/src/xdisp.c b/src/xdisp.c index 3a8b5e3f1d..e573c7cf88 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -12608,6 +12608,16 @@ fast_set_selected_frame (Lisp_Object frame) } } +static void +fast_set_selected_frame_if_live (Lisp_Object frame) +{ + if (!EQ (selected_frame, frame) && FRAME_LIVE_P (XFRAME (frame))) + { + selected_frame = frame; + selected_window = XFRAME (frame)->selected_window; + } +} + #endif /* HAVE_WINDOW_SYSTEM */ /* Update the tab-bar item list for frame F. This has to be done @@ -12681,7 +12691,7 @@ update_tab_bar (struct frame *f, bool save_match_data) XFRAME (selected_frame)->selected_window)); #ifdef HAVE_WINDOW_SYSTEM Lisp_Object frame; - record_unwind_protect (fast_set_selected_frame, selected_frame); + record_unwind_protect (fast_set_selected_frame_if_live, selected_frame); XSETFRAME (frame, f); fast_set_selected_frame (frame); #endif @@ -13625,7 +13635,7 @@ update_tool_bar (struct frame *f, bool save_match_data) /* Since we only explicitly preserve selected_frame, check that selected_window would be redundant. */ XFRAME (selected_frame)->selected_window)); - record_unwind_protect (fast_set_selected_frame, selected_frame); + record_unwind_protect (fast_set_selected_frame_if_live, selected_frame); XSETFRAME (frame, f); fast_set_selected_frame (frame); @@ -25009,9 +25019,14 @@ display_mode_lines (struct window *w) ++n; } - XFRAME (new_frame)->selected_window = old_frame_selected_window; - selected_frame = old_selected_frame; - selected_window = old_selected_window; + if (WINDOW_LIVE_P (old_frame_selected_window)) + XFRAME (new_frame)->selected_window = old_frame_selected_window; + if (FRAME_LIVE_P (XFRAME (old_selected_frame))) + { + selected_frame = old_selected_frame; + selected_window = old_selected_window; + } + if (n > 0) w->must_be_updated_p = true; return n;