wez / wezterm

A GPU-accelerated cross-platform terminal emulator and multiplexer written by @wez and implemented in Rust
https://wezfurlong.org/wezterm/
Other
17.93k stars 805 forks source link

resizing in mux domains has issues #5142

Open crides opened 8 months ago

crides commented 8 months ago

What Operating System(s) are you seeing this problem on?

Linux X11, macOS

Which Wayland compositor or X11 Window manager(s) are you using?

No response

WezTerm version

wezterm 20240102-011725-2f7ca41a

Did you try the latest nightly build to see if the issue is better (or worse!) than your current version?

No, and I'll explain why below

Describe the bug

  1. Resizing makes the bar glitchy
  2. Resizing can change the window size
  3. Resizing can take a long time, where the server resizes and redraws each pane one step at a time, even if the dragging itself is very quick (doesn't happen for resizing with keybinds, which is expected)

To Reproduce

  1. attach to mux ((slow) ssh is better, but unix works fine for at least the first 2)
  2. split (it's easier to see the problems when split vertically)
  3. drag the bar

Configuration

no config

Expected Behavior

No response

Logs

01:05:37.087 ERROR wezterm_term::terminalstate::iterm > my pixel dimensions are wacky! 0x0
01:05:37.149 ERROR mux::connui > while running ConnectionUI loop: recv_timeout: channel is empty and disconnected
01:05:37.560 ERROR wezterm_term::terminalstate::iterm > my pixel dimensions are wacky! 0x0
01:05:37.633 ERROR mux::connui > while running ConnectionUI loop: recv_timeout: channel is empty and disconnected
01:05:38.008 ERROR wezterm_term::terminalstate::iterm > my pixel dimensions are wacky! 0x0
01:05:38.074 ERROR mux::connui > while running ConnectionUI loop: recv_timeout: channel is empty and disconnected
01:05:38.445 ERROR wezterm_term::terminalstate::iterm > my pixel dimensions are wacky! 0x0
01:05:38.514 ERROR mux::connui > while running ConnectionUI loop: recv_timeout: channel is empty and disconnected

Anything else?

mux with unix

https://github.com/wez/wezterm/assets/15631555/6544b25b-b26b-49a9-b80a-bb408bf70d51

mux with ssh. Slightly easier to see the effects, but I wanted to show issue 3 which didn't show up. Issue 3 is clearly visible on my work computer.

https://github.com/wez/wezterm/assets/15631555/ace74c15-6692-4d5d-a128-749db0c4359b

yshui commented 3 months ago

I have the same issue.

The problem is much more pronounced if there is a lot of text in the pane. And sometimes the panes will keep dancing around even after I let go of them, and will only stop after I have detached then re-attached the domain.

yshui commented 3 months ago

actually, it doesn't take that much, mostly empty panes will struggle too.

here is a video showing off this behavior, it's a bit long. at the start you will notice resizing was extremely slow even for empty panes, then several seconds after I have let go, the panes started to dance around.

the experience is really bad, basically wezterm isn't a viable tmux replacement because of this.

https://github.com/user-attachments/assets/cf762eb9-06ee-41e0-bdb7-0e5beaafd959

yshui commented 3 months ago

I see now that there are actually 2 different problems here. One being that pane resizing is extremely slow. With some profiling I found out one hotspot is TermWindow::update_title_impl. I believe it is called in response to MuxNotification::TabResized, which is sent an extraordinary amount of times, clearly more than what is necessary.

The second being the panes jumping around. This is exacerbated by the first problem, but even after I commented out the call to update_title and saw the CPU usage drop by a lot, this still happens. I haven't figured out this one yet.

yshui commented 3 months ago

I have noticed that the MuxNotification::TabResized is sometimes sent repeated even after I have let go of the mouse button, and is correlated with the dancing panes.

yshui commented 2 months ago

I think there is a feedback loop in sync_with_pane_tree

yshui commented 2 months ago

Yes, so MuxNotification:TabResized leads to the server sending a Pdu::TabResized, which triggers a pane list resync in the client. And because resizing is slow, the pane resize is behind what the client thinks it would be. so the client thinks it was resized again, so it calls mux::tab::TabInner::resize, and the whole thing starts over.