-
-
Notifications
You must be signed in to change notification settings - Fork 799
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix pane focus rapidly switching back and forth #4737
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for this! I've only quickly skimmed this without really following the call stacks through at the moment, and have one quick and easy bit of feedback!
Switching panes multiple times too quickly sometimes causes the focus to get stuck rapidly switching back and forth between two panes by itself. This happens both locally and on an SSH domain. The root cause is similar in both cases. In the local case, GuiFrontend handles a MuxNotification::PaneFocused event by calling Mux::focus_pane_and_containing_tab, which calls through Tab::set_active_pane -> TabInner::set_active_pane -> TabInner::advise_focus_change. TabInner::advise_focus_change then calls Mux::notify with a new MuxNotification::PaneFocused event, which is a redundant notification focusing the same pane again. This is normally harmless other than a small amount of wasted work; TabInner::set_active_pane notices that the focused pane didn't change and doesn't generate yet another event. However, if another real focus change is queued between the original focus change and the redundant one, we get into trouble. For example, if the user switches to pane 0 and then immediately to pane 1, the event queue contains [PaneFocused(0), PaneFocused(1)]. When the first event is handled, pane 0 is focused, and a redundant notification is generated, so the event queue contains [PaneFocused(1), PaneFocused(0)]. Then after the next event is handled, pane 1 is focused, and we add another redundant notification, so the event queue contains [PaneFocused(0), PaneFocused(1)]. Repeat ad nauseam. Fix this by not generating the notification from TabInner::advise_focus_change when it would be redundant, which we indicate with a new boolean parameter. The mux server case is very similar, except that Pdu::SetFocusedPane in SessionHandler is the vector for the bug. This bug appears to have been introduced by commit f71bce1. I verified that `wezterm cli activate-pane-direction` still works over SSH after this fix. closes: wez#4390 closes: wez#4693
0530181
to
2f7ca41
Compare
Done. I went with |
Thanks! Now, do |
Ugh, I tested My guess is that we need to avoid sending a redundant update back to the source it originally came from, but we need to send updates everywhere else. Is that possible? P.S. There are some vaguely related issues I've run into with SSH sessions that I hadn't written up as issues yet: rotating panes through the command palette gets undone on the next keypress, and resizing panes by dragging the borders flickers. Ignoring |
Thanks for checking! I'm not in the right frame of mind to seriously design this right now, but I'll throw out a couple of possible approaches and let you noodle on them.
wezterm/wezterm-client/src/pane/renderable.rs Lines 333 to 346 in 4921f13
|
Tested. This does fix the problem when it's caused by the terminal hanging on much output (i.e. #4517). |
I'm not going to get around to resolving the other muxing issues here, so I'm going to close this. Anyone else is welcome to pick this up. |
Switching panes multiple times too quickly sometimes causes the focus to get stuck rapidly switching back and forth between two panes by itself. This happens both locally and on an SSH domain. The root cause is similar in both cases.
In the local case, GuiFrontend handles a MuxNotification::PaneFocused event by calling Mux::focus_pane_and_containing_tab, which calls through Tab::set_active_pane -> TabInner::set_active_pane -> TabInner::advise_focus_change. TabInner::advise_focus_change then calls Mux::notify with a new MuxNotification::PaneFocused event, which is a redundant notification focusing the same pane again.
This is normally harmless other than a small amount of wasted work; TabInner::set_active_pane notices that the focused pane didn't change and doesn't generate yet another event.
However, if another real focus change is queued between the original focus change and the redundant one, we get into trouble. For example, if the user switches to pane 0 and then immediately to pane 1, the event queue contains [PaneFocused(0), PaneFocused(1)]. When the first event is handled, pane 0 is focused, and a redundant notification is generated, so the event queue contains [PaneFocused(1), PaneFocused(0)]. Then after the next event is handled, pane 1 is focused, and we add another redundant notification, so the event queue contains [PaneFocused(0), PaneFocused(1)]. Repeat ad nauseam.
Fix this by not generating the notification from
TabInner::advise_focus_change when it would be redundant, which we indicate with a new boolean parameter.
The mux server case is very similar, except that Pdu::SetFocusedPane in SessionHandler is the vector for the bug.
This bug appears to have been introduced by commit f71bce1. I verified that
wezterm cli activate-pane-direction
still works over SSH after this fix.closes: #4390
closes: #4693