Subject: bug#32777: 27.0.50; window-buffer gets wrong point

From: martin rudalics <[email-masked]>
Date: Mon, 15 Oct 2018 09:56:08 +0200

> So far I'm clueless.

Here are the clues: FWIW the problem we see here is a redisplay
problem exemplified by the backtrace below.  Recall that Juri did a
M-x M-n with *scratch* selected in a window W1 on a frame F1 and
*scratch* also shown with a different value of window point in a
window W2 on another frame say F2.

Now the M-x makes the minibuffer window on frame F1 the selected
window.  When Juri now types M-n the backtrace below kicks in.  In
particular, the x_consider_frame_title call in frame #10 does

       record_unwind_protect (unwind_format_mode_line,
			     format_mode_line_unwind_data
			       (f, current_buffer, selected_window, false));

and then continues to select window W2 on F2 from frame #9 to frame #3
and, since the window point of W2 differs from that of W1, sets the
point of *scratch* to the value of W2's point from frame #2 to frame
#0.  Everything normal, it seems.

But now the unwind form above kicks and, since the selected window of
F1 is not the window on *scratch* but the minibuffer window, it will
reselect the minibuffer window on F1.  This will, however, fail to
restore the position of point in *scratch* from the window point of W1
with the ensuing problem described by Juri.

I hope this explains now why Federico's patch fixes Juri's scenario:
Selecting minibuf_selected_window sets the point of *scratch* to the
window point of W1 with the desired effect.

I can see two possible fixes for the underlying problem:

(1) Handle the minibuf_selected_window case specially.  This means
that, if on the target frame of the unwind form this variable is
non-nil, we restore the value of point of the buffer shown in
minibuf_selected_window to that window's point.

(2) Ignore minibuf_selected_window and handle point of the buffer
shown in the selected window of the frame whose title we consider for
drawing its title.  That is, record the buffer shown in
f->selected_window together with its position of point before
selecting f->selected_window in x_consider_frame_title and restore the
buffer's position of point in the unwind form.

I think (1) is more conservative because it strictly handles just
scenarios like Juri's.  But (1) does not handle the case where the
buffer of W2 is not shown anywhere else when x_consider_frame_title is
called.  So IMHO (2) should be the correct approach but I have no idea
what further consequences it could have.

martin

#0  temp_set_point_both (buffer=0x161ce10 <dumped_data+97936>, charpos=4141, bytepos=4141) at ../../src/intervals.c:1737
#1  0x01210b80 in set_point_both (charpos=4141, bytepos=4141) at ../../src/intervals.c:1895
#2  0x012106a1 in set_point_from_marker (marker=XIL(0x5e09b15)) at ../../src/intervals.c:1774
#3  0x0108a363 in select_window_1 (window=XIL(0x5dfcf25), inhibit_point_swap=false) at ../../src/window.c:565
#4  0x0108a17b in select_window (window=XIL(0x5dfcf25), norecord=XIL(0x8720), inhibit_point_swap=false) at ../../src/window.c:523
#5  0x0108a38a in Fselect_window (window=XIL(0x5dfcf25), norecord=XIL(0x8720)) at ../../src/window.c:593
#6  0x01013d60 in do_switch_frame (frame=XIL(0x5dfcda5), track=1, for_deletion=0, norecord=XIL(0x8720)) at ../../src/frame.c:1418
#7  0x01013dba in Fselect_frame (frame=XIL(0x5dfcda5), norecord=XIL(0x8720)) at ../../src/frame.c:1451
#8  0x0108a11c in select_window (window=XIL(0x5dfcf25), norecord=XIL(0x8720), inhibit_point_swap=false) at ../../src/window.c:515
#9  0x0108a38a in Fselect_window (window=XIL(0x5dfcf25), norecord=XIL(0x8720)) at ../../src/window.c:593
#10 0x0104651b in x_consider_frame_title (frame=XIL(0x5dfcda5)) at ../../src/xdisp.c:12032
#11 0x01046a62 in prepare_menu_bars () at ../../src/xdisp.c:12134
#12 0x0104afd2 in redisplay_internal () at ../../src/xdisp.c:14042
#13 0x01049d46 in redisplay () at ../../src/xdisp.c:13620
#14 0x0110ae22 in read_char (commandflag=1, map=XIL(0x1776a33), prev_event=XIL(0), used_mouse_menu=0x82e323, end_time=0x0) at ../../src/keyboard.c:2451
#15 0x0111969a in read_key_sequence (keybuf=0x82e464, prompt=XIL(0), dont_downcase_last=false, can_return_switch_frame=true, fix_current_buffer=true, prevent_redisplay=false) at ../../src/keyboard.c:9117
#16 0x0110844d in command_loop_1 () at ../../src/keyboard.c:1338
#17 0x011a39d2 in internal_condition_case (bfun=0x1108000 <command_loop_1>, handlers=XIL(0x35c0), hfun=0x11076a9 <cmd_error>) at ../../src/eval.c:1373
#18 0x01107c29 in command_loop_2 (ignore=XIL(0)) at ../../src/keyboard.c:1079
#19 0x011a2fba in internal_catch (tag=XIL(0x37a0), func=0x1107bfe <command_loop_2>, arg=XIL(0)) at ../../src/eval.c:1136
#20 0x01107b4b in command_loop () at ../../src/keyboard.c:1050
#21 0x01107221 in recursive_edit_1 () at ../../src/keyboard.c:703
#22 0x0114637b in read_minibuf (map=XIL(0x17862bb), initial=XIL(0), prompt=XIL(0x1a82b3c), expflag=false, histvar=XIL(0x2723e0), histpos=make_number(0), defalt=XIL(0), allow_props=false, inherit_input_method=false) at ../../src/minibuf.c:669
#23 0x01146df2 in Fread_from_minibuffer (prompt=XIL(0x1a82b3c), initial_contents=XIL(0), keymap=XIL(0x17862bb), sys_read=XIL(0), hist=XIL(0x2723e0), default_value=XIL(0), inherit_input_method=XIL(0)) at ../../src/minibuf.c:940
#24 0x011a7982 in funcall_subr (subr=0x12c1dc0 <Sread_from_minibuffer>, numargs=7, args=0x82e810) at ../../src/eval.c:2954
#25 0x011a73bb in Ffuncall (nargs=8, args=0x82e80c) at ../../src/eval.c:2859
#26 0x011efd21 in exec_byte_code (bytestr=XIL(0x1322e14), vector=XIL(0x1322e25), maxdepth=make_number(18), args_template=make_number(2050), nargs=8, args=0x82eb20) at ../../src/bytecode.c:632
#27 0x011a7ed7 in funcall_lambda (fun=XIL(0x1322dfd), nargs=8, arg_vector=0x82eb00) at ../../src/eval.c:3060
#28 0x011a73fd in Ffuncall (nargs=9, args=0x82eafc) at ../../src/eval.c:2861
#29 0x011486b1 in Fcompleting_read (prompt=XIL(0x1a82b3c), collection=XIL(0x1a0385b), predicate=XIL(0x2800), require_match=XIL(0x8720), initial_input=XIL(0), hist=XIL(0x2723e0), def=XIL(0), inherit_input_method=XIL(0)) at ../../src/minibuf.c:1644
#30 0x011a605d in eval_sub (form=XIL(0x1a03833)) at ../../src/eval.c:2354
#31 0x011a09dd in Fprogn (body=XIL(0)) at ../../src/eval.c:481
#32 0x011a5b12 in eval_sub (form=XIL(0x1a037db)) at ../../src/eval.c:2276
#33 0x011a328e in Funwind_protect (args=XIL(0x1a037ab)) at ../../src/eval.c:1230
#34 0x011a5b12 in eval_sub (form=XIL(0x1a037b3)) at ../../src/eval.c:2276
#35 0x011a09dd in Fprogn (body=XIL(0)) at ../../src/eval.c:481
#36 0x011a2b5f in Flet (args=XIL(0x1a0377b)) at ../../src/eval.c:1009
#37 0x011a5b12 in eval_sub (form=XIL(0x1a0376b)) at ../../src/eval.c:2276
#38 0x011a09dd in Fprogn (body=XIL(0)) at ../../src/eval.c:481
#39 0x011a8287 in funcall_lambda (fun=XIL(0x1a0375b), nargs=0, arg_vector=0x0) at ../../src/eval.c:3131
#40 0x011a7503 in Ffuncall (nargs=1, args=0x82f048) at ../../src/eval.c:2873
#41 0x011efd21 in exec_byte_code (bytestr=XIL(0x13270dc), vector=XIL(0x13270f5), maxdepth=make_number(3), args_template=XIL(0), nargs=0, args=0x0) at ../../src/bytecode.c:632
#42 0x011ef157 in Fbyte_code (bytestr=XIL(0x13270dc), vector=XIL(0x13270f5), maxdepth=make_number(3)) at ../../src/bytecode.c:322
#43 0x011a5ed3 in eval_sub (form=XIL(0x13270cb)) at ../../src/eval.c:2330
#44 0x011a55ca in Feval (form=XIL(0x13270cb), lexical=XIL(0)) at ../../src/eval.c:2144
#45 0x0119db0d in Fcall_interactively (function=XIL(0x4bea0), record_flag=XIL(0), keys=XIL(0x161a30d)) at ../../src/callint.c:321
#46 0x011a7842 in funcall_subr (subr=0x151f0c0 <Scall_interactively>, numargs=3, args=0x82f550) at ../../src/eval.c:2939
#47 0x011a73bb in Ffuncall (nargs=4, args=0x82f54c) at ../../src/eval.c:2859
#48 0x011efd21 in exec_byte_code (bytestr=XIL(0x1327124), vector=XIL(0x1327135), maxdepth=make_number(13), args_template=make_number(1025), nargs=1, args=0x82f870) at ../../src/bytecode.c:632
#49 0x011a7ed7 in funcall_lambda (fun=XIL(0x132710d), nargs=1, arg_vector=0x82f86c) at ../../src/eval.c:3060
#50 0x011a73fd in Ffuncall (nargs=2, args=0x82f868) at ../../src/eval.c:2861
#51 0x011a6dfd in call1 (fn=XIL(0x27e0), arg1=XIL(0x4bea0)) at ../../src/eval.c:2710
#52 0x011087c2 in command_loop_1 () at ../../src/keyboard.c:1451
#53 0x011a39d2 in internal_condition_case (bfun=0x1108000 <command_loop_1>, handlers=XIL(0x35c0), hfun=0x11076a9 <cmd_error>) at ../../src/eval.c:1373
#54 0x01107c29 in command_loop_2 (ignore=XIL(0)) at ../../src/keyboard.c:1079
#55 0x011a2fba in internal_catch (tag=XIL(0x8cc0), func=0x1107bfe <command_loop_2>, arg=XIL(0)) at ../../src/eval.c:1136
#56 0x01107bc3 in command_loop () at ../../src/keyboard.c:1058
#57 0x01107221 in recursive_edit_1 () at ../../src/keyboard.c:703
#58 0x011073f7 in Frecursive_edit () at ../../src/keyboard.c:774
#59 0x01105384 in main (argc=2, argv=0xa33f88) at ../../src/emacs.c:1731

Lisp Backtrace:
"redisplay_internal (C function)" (0x0)
"read-from-minibuffer" (0x82e810)
"completing-read-default" (0x82eb00)
"completing-read" (0x82eb68)
"progn" (0x82ec78)
"unwind-protect" (0x82ed68)
"let" (0x82eed8)
"read-extended-command" (0x82f04c)
"byte-code" (0x82f268)
"call-interactively" (0x82f550)
"command-execute" (0x82f86c)