diff --git a/src/xdisp.c b/src/xdisp.c index 94742c2..315dce2 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -11860,7 +11860,7 @@ static void ATTRIBUTE_FORMAT_PRINTF (1, 0) Vmode_line_unwind_vector = Qnil; if (NILP (vector)) - vector = make_nil_vector (10); + vector = make_nil_vector (12); ASET (vector, 0, make_fixnum (mode_line_target)); ASET (vector, 1, make_fixnum (MODE_LINE_NOPROP_LEN (0))); @@ -11877,12 +11877,24 @@ static void ATTRIBUTE_FORMAT_PRINTF (1, 0) ASET (vector, 7, owin); if (target_frame) { + Lisp_Object buffer = XWINDOW (target_frame->selected_window)->contents; + struct buffer *b = XBUFFER (buffer); + struct buffer *cb = current_buffer; + /* Similarly to `with-selected-window', if the operation selects a window on another frame, we must restore that frame's selected window, and (for a tty) the top-frame. */ ASET (vector, 8, target_frame->selected_window); if (FRAME_TERMCAP_P (target_frame)) ASET (vector, 9, FRAME_TTY (target_frame)->top_frame); + + /* If we select a window on another frame, make sure that that + selection does not leave its buffer's point modified when + unwinding (Bug#32777). */ + ASET (vector, 10, buffer); + current_buffer = b; + ASET (vector, 11, build_marker (current_buffer, PT, PT_BYTE)); + current_buffer = cb; } return vector; @@ -11913,12 +11925,26 @@ static void ATTRIBUTE_FORMAT_PRINTF (1, 0) { Lisp_Object frame = WINDOW_FRAME (XWINDOW (target_frame_window)); + Lisp_Object buffer = AREF (vector, 10); if (!EQ (frame, WINDOW_FRAME (XWINDOW (old_window)))) Fselect_window (target_frame_window, Qt); if (!NILP (old_top_frame) && !EQ (old_top_frame, frame)) Fselect_frame (old_top_frame, Qt); + + if (BUFFER_LIVE_P (XBUFFER (buffer)) + && !EQ (XWINDOW (old_window)->contents, buffer)) + { + /* Restore point of target_frame_window's buffer + (Bug#32777). */ + struct buffer *cb = current_buffer; + + current_buffer = XBUFFER (buffer); + set_point_from_marker (AREF (vector, 11)); + ASET (vector, 11, Qnil); + current_buffer = cb; + } } Fselect_window (old_window, Qt);