mirror of
https://github.com/wez/wezterm.git
synced 2024-12-24 13:52:55 +03:00
mux: more robust handling of pane killing
Work harder to notice and handle the PaneRemoved notification more centrally, which allows removing some earlier workarounds. Now when we receive PaneRemoved, we take the opportunity to handle missing mapping or stale mapping between local and remote ids and perform a resync before continuing to handle the PaneRemoved message. Doing it this way means that we don't need to second guess the timing of notification or the resync, so we end up with the correct sequence of notifications, and the result is the correct size of the splits because the local and remote aren't independently managing the the pane removal with conflicting ideas of the new size. refs: https://github.com/wez/wezterm/issues/3386
This commit is contained in:
parent
05919acb29
commit
07e1c5834b
@ -27,6 +27,7 @@ As features stabilize some brief notes about them will accumulate here.
|
|||||||
|
|
||||||
#### Fixed
|
#### Fixed
|
||||||
* mux: Stale remote window mapping could prevent spawning new tabs in remote domain. #2759
|
* mux: Stale remote window mapping could prevent spawning new tabs in remote domain. #2759
|
||||||
|
* mux: Splitting then killing a pane could result in incorrect pane sizes. #3386
|
||||||
|
|
||||||
### 20230326-111934-3666303c
|
### 20230326-111934-3666303c
|
||||||
|
|
||||||
|
@ -142,6 +142,7 @@ async fn process_unilateral_inner_async(
|
|||||||
let local_pane_id = match client_domain.remote_to_local_pane_id(pane_id) {
|
let local_pane_id = match client_domain.remote_to_local_pane_id(pane_id) {
|
||||||
Some(p) => p,
|
Some(p) => p,
|
||||||
None => {
|
None => {
|
||||||
|
log::debug!("got {decoded:?}, pane not found locally, resync");
|
||||||
client_domain.resync().await?;
|
client_domain.resync().await?;
|
||||||
client_domain
|
client_domain
|
||||||
.remote_to_local_pane_id(pane_id)
|
.remote_to_local_pane_id(pane_id)
|
||||||
@ -151,9 +152,23 @@ async fn process_unilateral_inner_async(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let pane = mux
|
let pane = match mux.get_pane(local_pane_id) {
|
||||||
.get_pane(local_pane_id)
|
Some(p) => p,
|
||||||
.ok_or_else(|| anyhow!("no such pane {}", local_pane_id))?;
|
None => {
|
||||||
|
log::debug!("got {decoded:?}, but local pane {local_pane_id} no longer exists; resync");
|
||||||
|
client_domain.resync().await?;
|
||||||
|
|
||||||
|
let local_pane_id =
|
||||||
|
client_domain
|
||||||
|
.remote_to_local_pane_id(pane_id)
|
||||||
|
.ok_or_else(|| {
|
||||||
|
anyhow!("remote pane id {} does not have a local pane id", pane_id)
|
||||||
|
})?;
|
||||||
|
|
||||||
|
mux.get_pane(local_pane_id)
|
||||||
|
.ok_or_else(|| anyhow!("local pane {local_pane_id} not found"))?
|
||||||
|
}
|
||||||
|
};
|
||||||
let client_pane = pane.downcast_ref::<ClientPane>().ok_or_else(|| {
|
let client_pane = pane.downcast_ref::<ClientPane>().ok_or_else(|| {
|
||||||
log::error!(
|
log::error!(
|
||||||
"received unilateral PDU for pane {} which is \
|
"received unilateral PDU for pane {} which is \
|
||||||
|
@ -466,39 +466,10 @@ impl Pane for ClientPane {
|
|||||||
.kill_pane(KillPane {
|
.kill_pane(KillPane {
|
||||||
pane_id: remote_pane_id,
|
pane_id: remote_pane_id,
|
||||||
})
|
})
|
||||||
.await?;
|
.await
|
||||||
|
|
||||||
// Arrange to resync the layout, to avoid artifacts
|
|
||||||
// <https://github.com/wez/wezterm/issues/1277>.
|
|
||||||
// We need a short delay to avoid racing with the observable
|
|
||||||
// effects of killing the pane.
|
|
||||||
// <https://github.com/wez/wezterm/issues/1752#issuecomment-1088269363>
|
|
||||||
smol::Timer::after(std::time::Duration::from_millis(200)).await;
|
|
||||||
let mux = Mux::get();
|
|
||||||
let client_domain = mux
|
|
||||||
.get_domain(local_domain_id)
|
|
||||||
.ok_or_else(|| anyhow::anyhow!("no such domain {}", local_domain_id))?;
|
|
||||||
let client_domain =
|
|
||||||
client_domain
|
|
||||||
.downcast_ref::<ClientDomain>()
|
|
||||||
.ok_or_else(|| {
|
|
||||||
anyhow::anyhow!(
|
|
||||||
"domain {} is not a ClientDomain instance",
|
|
||||||
local_domain_id
|
|
||||||
)
|
|
||||||
})?;
|
|
||||||
|
|
||||||
client_domain.resync().await?;
|
|
||||||
anyhow::Result::<()>::Ok(())
|
|
||||||
})
|
})
|
||||||
.detach();
|
.detach();
|
||||||
}
|
}
|
||||||
// Explicitly mark ourselves as dead.
|
|
||||||
// Ideally we'd discover this later when polling the
|
|
||||||
// status, but killing the pane prevents the server
|
|
||||||
// side from sending us further data.
|
|
||||||
// <https://github.com/wez/wezterm/issues/1752>
|
|
||||||
self.renderable.lock().inner.borrow_mut().dead = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn mouse_event(&self, event: MouseEvent) -> anyhow::Result<()> {
|
fn mouse_event(&self, event: MouseEvent) -> anyhow::Result<()> {
|
||||||
|
Loading…
Reference in New Issue
Block a user