[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
bug#71343: 30.0.50; TTY frame doesn't automatically redisplay itself aft
From: |
Daniel Clemente |
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