[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: |
Eli Zaretskii |
Subject: |
bug#71343: 30.0.50; TTY frame doesn't automatically redisplay itself after having closed another frame |
Date: |
Sun, 16 Jun 2024 09:33:06 +0300 |
> From: Daniel Clemente <n142857@gmail.com>
> Date: Sun, 16 Jun 2024 05:40:12 +0000
> Cc: eggert@cs.ucla.edu, 71343@debbugs.gnu.org
>
> I have a new discovery (it's about „initial frame“), you can skip to
> the gdb info below (line 16876).
It's a problematic discovery from where I stand...
> > > Random ideas, without knowing much about terminals.
> > > - Can't an X terminal detect „I've been given X focus“ and pass this
> > > signal to the program running inside it?
> >
> > You assume that it will be a terminal belonging to Emacs that will get
> > focus? That is not given.
>
> I was thinking that maybe X always does this (X notifies the terminal
> emulator, which notifies the program running inside it, whatever
> program it is).
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?
> > > - 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 normal conditions, resizing a frame calls: adjust_frame size, then
> redisplay_internal, then clear_garbaged_frames, then redraw_frame
>
> But when I reproduce this bug (i.e. just after closing a frame),
> resizing a frame calls: adjust_frame_size, then redisplay_internal. It
> doesn't call the other two.
> (Only later when I press a key, it calls redisplay_internal, then
> clear_garbaged_frames, then redraw_frame)
> In this scenario, why doesn't redisplay_internal reach the point where
> it calls clear_garbaged_frames?
> Because this happens:
> Breakpoint 5, redisplay_internal () at xdisp.c:16831
> 16831 struct window *w = XWINDOW (selected_window);
> (gdb) n
> 16835 bool must_finish = false, match_p;
> (gdb)
> 16839 bool polling_stopped_here = false;
> (gdb)
> 16846 int hscroll_retries = 0;
> (gdb)
> 16854 int garbaged_frame_retries = 0;
> (gdb)
> 16862 bool update_miniwindow_p = false;
> (gdb)
> 16864 redisplay_trace ("redisplay_internal %d\n", redisplaying_p);
> (gdb)
> 16870 if (redisplaying_p)
> (gdb)
> 16876 if ((FRAME_INITIAL_P (SELECTED_FRAME ())
> (gdb)
> 16877 && redisplay_skip_initial_frame)
> (gdb)
> 16879 return;
> (gdb)
>
>
> So, apparently it thinks that my frame is initial.
And for a good reason:
> Some more data about the looks-initial frame:
>
> (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.
> 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.