Package: emacs;
Reported by: Daniel Clemente <n142857 <at> gmail.com>
Date: Mon, 3 Jun 2024 15:56:01 UTC
Severity: normal
Found in version 30.0.50
View this message in rfc822 format
From: Daniel Clemente <n142857 <at> gmail.com> To: Eli Zaretskii <eliz <at> gnu.org> Cc: eggert <at> cs.ucla.edu, 71343 <at> debbugs.gnu.org Subject: bug#71343: 30.0.50; TTY frame doesn't automatically redisplay itself after having closed another frame Date: Fri, 21 Jun 2024 10:47:07 +0000
> Emacs doesn't really talk to the terminal emulator, unless the > emulator supports known protocols of doing so. You will see in > lisp/term/xterm.el that Emacs supports that for xterm that is new > enough. Don't know what happens with urxvt, but did you try using > xterm and saw the same problems? I tried with xterm and I don't see the same problem. There's more flickering and slowness but the frame I'm resizing gets redrawn. I'm using: xterm -e "emasclient" "-c" & I just installed other terminals: mlterm, cool-retro-term, Eterm. They show the problem, just like urxvt. The frame being resized (just after closing another frame) isn't redrawn. To simplify testing I'm using for i in `seq 2`; do mlterm -e "emacsclient" "-c" "-e" '(dired "~")' & sleep 1; done and closing the second one and resizing the first one.. I also saw 2 other SIGSEGV with xterm and others, that show possibly corrupted memory. I reported them as separate bugs but I don't know whether they're related to this one. > > > > > - What if, when resizing the frame (something which Emacs detects), > > > > Emacs knows/detects that a frame was closed, and decides not to delay > > > > the redisplay? > > > > > > Redisplay of which frame? Emacs only redisplays a frame if some > > > change in buffer text justifies that. > > > > I propose it should repaint/redisplay the frame whose size changed. > > When a frame is resized, it is redisplayed, yes. But that requires > Emacs to know that it is resized. > > > Don't we know which frame is the one being resized? It should be f in > > adjust_frame_size. It realizes that e.g. it's being resized from 72 to > > 61 columns. > > I need a backtrace showing the call to adjust_frame_size, of a frame > that is not redrawn. I don't think I saw such a backtrace. In this one, I made a frame less wide (it was around 70 columns, I made it 60 columns) in the conditions when redraw doesn't happen. Breakpoint 2, adjust_frame_size (f=0x6210000ede00, new_text_width=60, new_text_height=49, inhibit=5, pretend=false, parameter=XIL(0x40e0)) at frame.c:646 646 int unit_width = FRAME_COLUMN_WIDTH (f); (gdb) bt #0 adjust_frame_size (f=0x6210000ede00, new_text_width=60, new_text_height=49, inhibit=5, pretend=false, parameter=XIL(0x40e0)) at frame.c:646 #1 0x00005555564e04c3 in change_frame_size_1 (f=0x6210000ede00, new_width=60, new_height=50, pretend=false, delay=false, safe=false) at dispnew.c:6054 #2 0x00005555564e0526 in change_frame_size (f=0x6210000ede00, new_width=60, new_height=50, pretend=false, delay=false, safe=false) at dispnew.c:6087 #3 0x00005555564df618 in do_pending_window_change (safe=false) at dispnew.c:6014 #4 0x0000555556e479ee in wait_reading_process_output (time_limit=0, nsecs=0, read_kbd=-1, do_display=true, wait_for_cell=XIL(0), wait_proc=0x0, just_wait_proc=0) at process.c:5784 #5 0x00005555569b57da in kbd_buffer_get_event (kbp=0x7fffffffca50, used_mouse_menu=0x7fffffffd4f0, end_time=0x0) at keyboard.c:4079 #6 0x00005555569a6c45 in read_event_from_main_queue (end_time=0x0, local_getcjmp=0x7fffffffd110, used_mouse_menu=0x7fffffffd4f0) at keyboard.c:2330 #7 0x00005555569a75b1 in read_decoded_event_from_main_queue ( end_time=0x0, local_getcjmp=0x7fffffffd110, prev_event=XIL(0), used_mouse_menu=0x7fffffffd4f0) at keyboard.c:2394 #8 0x00005555569adaa6 in read_char (commandflag=1, map=XIL(0x7fffec72ab93), prev_event=XIL(0), used_mouse_menu=0x7fffffffd4f0, end_time=0x0) at keyboard.c:3015 #9 0x00005555569e9ca2 in read_key_sequence (keybuf=0x7fffffffd7e0, prompt=XIL(0), dont_downcase_last=false, can_return_switch_frame=true, fix_current_buffer=true, prevent_redisplay=false, disable_text_conversion_p=false) at keyboard.c:10728 --Type <RET> for more, q to quit, c to continue without paging-- #10 0x000055555699b122 in command_loop_1 () at keyboard.c:1429 #11 0x0000555556cbb678 in internal_condition_case ( bfun=0x55555699a22d <command_loop_1>, handlers=XIL(0x90), hfun=0x555556998204 <cmd_error>) at eval.c:1613 #12 0x0000555556999797 in command_loop_2 (handlers=XIL(0x90)) at keyboard.c:1168 #13 0x0000555556cb84d8 in internal_catch (tag=XIL(0xfb40), func=0x555556999767 <command_loop_2>, arg=XIL(0x90)) at eval.c:1292 #14 0x000055555699969a in command_loop () at keyboard.c:1146 #15 0x0000555556996e7a in recursive_edit_1 () at keyboard.c:754 #16 0x0000555556997531 in Frecursive_edit () at keyboard.c:837 #17 0x0000555556989057 in main (argc=3, argv=0x7fffffffdee8) at emacs.c:2629 (gdb) bt full #0 adjust_frame_size (f=0x6210000ede00, new_text_width=60, new_text_height=49, inhibit=5, pretend=false, parameter=XIL(0x40e0)) at frame.c:646 unit_width = 1458155539 unit_height = 21845 old_native_width = 1492352256 old_native_height = 21845 new_native_width = 0 new_native_height = 0 min_inner_width = -1 min_inner_height = -1 r = 0x7ffff4f2b8e4 <mcount+52> old_inner_width = -1 old_inner_height = 32767 new_inner_width = 0 new_inner_height = 1718964966 old_text_cols = 247 old_text_lines = 0 new_text_cols = 0 new_text_lines = 0 old_text_width = 0 old_text_height = 0 inhibit_horizontal = false inhibit_vertical = false frame = make_fixnum(23456254819227) #1 0x00005555564e04c3 in change_frame_size_1 (f=0x6210000ede00, new_width=60, new_height=50, pretend=false, delay=false, safe=false) at dispnew.c:6054 No locals. #2 0x00005555564e0526 in change_frame_size (f=0x6210000ede00, --Type <RET> for more, q to quit, c to continue without paging-- new_width=60, new_height=50, pretend=false, delay=false, safe=false) at dispnew.c:6087 tail = <optimized out> frame = <optimized out> #3 0x00005555564df618 in do_pending_window_change (safe=false) at dispnew.c:6014 f = 0x6210000ede00 tail = XIL(0x7fffec71a083) frame = XIL(0x6210000ede05) #4 0x0000555556e479ee in wait_reading_process_output (time_limit=0, […] > > (gdb) p *SELECTED_FRAME() > > $102 = { > > header = { > > size = 4611686018595348501 > > }, > [...] > > output_data = { > > tty = 0x0, > > x = 0x0, > > w32 = 0x0, > > ns = 0x0, > > pgtk = 0x0, > > haiku = 0x0, > > android = 0x0 > > }, > > This zero value exactly means this frame is "initial" it has not yet > been set up as a terminal frame. That setup happens inside > make-terminal-frame, here: > > f = make_terminal_frame (t); > > and make_terminal_frame does > > f->output_method = output_termcap; > > Somehow this frame escaped this code, so all kinds of weird things can > happen with it. It seems that under normal Emacs operation, the emacs daemon creates an initial frame which has no output_data->tty. In addition there are non-initial frames, created by make_terminal_frame; one for each frame opened by the user. Could it be that adjust_frame_size is wrongly running on the initial frame, instead of on the terminal frame? Mmm… apparently no, it's not that; I just verified it with the commands below. There's the initial frame (F1) and the visible one (F5), and f matches F5. (gdb) list 641 */ 642 void 643 adjust_frame_size (struct frame *f, int new_text_width, int new_text_height, 644 int inhibit, bool pretend, Lisp_Object parameter) 645 { 646 int unit_width = FRAME_COLUMN_WIDTH (f); 647 int unit_height = FRAME_LINE_HEIGHT (f); 648 int old_native_width = FRAME_PIXEL_WIDTH (f); 649 int old_native_height = FRAME_PIXEL_HEIGHT (f); 650 int new_native_width, new_native_height; (gdb) p f $34 = (struct frame *) 0x6210000ede00 (gdb) p f->name $35 = XIL(0x619000159144) (gdb) xpr Lisp_String $36 = (struct Lisp_String *) 0x619000159140 "F5" (gdb) p Vframe_list $37 = XIL(0x7fffec71a083) (gdb) xcons $38 = (struct Lisp_Cons *) 0x7fffec71a080 { u = { s = { car = XIL(0x6210000ede05), u = { cdr = XIL(0x7ffff18f00f3), chain = 0x7ffff18f00f3 } }, gcaligned = 0x5 } } (gdb) nextcons $39 = XIL(0x7ffff18f00f3) $40 = (struct Lisp_Cons *) 0x7ffff18f00f0 { u = { s = { car = XIL(0x621000003f05), u = { cdr = XIL(0), chain = 0x0 } }, gcaligned = 0x5 } } (gdb) p 0x6210000ede05 $41 = 107820859973125 (gdb) xpr Lisp_Vectorlike PVEC_FRAME $42 = (struct frame *) 0x6210000ede00 "F5" No symbol "PVEC_TS_QUERY" in current context. (gdb) p 0x621000003f05 $43 = 107820859014917 (gdb) xpr Lisp_Vectorlike PVEC_FRAME $44 = (struct frame *) 0x621000003f00 "F1" No symbol "PVEC_TS_QUERY" in current context. (gdb) > > By the way, C-x # isn't enough to close any Emacs frame. If I have > > opened it by running urxvtcd -e 'emacsclient' '-nw', then later C-x > > # doesn't close it, it just says „No server buffers remain to edit“. > > But C-x C-c does close it. > > Use "C-x 5 0" to delete the current frame. Ok. The problem reported in this bug report also happens if I use C-x 5 0
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.