1
1
mirror of https://github.com/wez/wezterm.git synced 2024-12-23 13:21:38 +03:00

mux: forward move-pane-to-new-tab requests to hosting mux

refs: #3374
This commit is contained in:
Wez Furlong 2023-03-26 10:39:40 -07:00
parent b99ecead8b
commit d9d6b2a01a
No known key found for this signature in database
GPG Key ID: 7A7F66A31EC9B387
4 changed files with 83 additions and 1 deletions

View File

@ -80,6 +80,9 @@ As features stabilize some brief notes about them will accumulate here.
in incorrect image scaling for imgcat. #3366
* mux: `wezterm cli move-pane-to-new-tab` didn't resync new window structure
and would appear to have had no effect until you detached and re-attached. #3219
* mux: `wezterm cli move-pane-to-new-tab` didn't forward the structural change
to a remote mux, so if you ran it against the mux in your GUI, the state on
the actual mux server was not updated. #3374
#### Updated
* Bundled JetBrainsMono to 2.304. #3362

View File

@ -135,6 +135,19 @@ pub trait Domain: Downcast + Send + Sync {
command_dir: Option<String>,
) -> anyhow::Result<Arc<dyn Pane>>;
/// The mux will call this method on the domain of the pane that
/// is being moved to give the domain a chance to handle the movement.
/// If this method returns Ok(None), then the mux will handle the
/// movement itself by mutating its local Tabs and Windows.
async fn move_pane_to_new_tab(
&self,
_pane_id: PaneId,
_window_id: Option<WindowId>,
_workspace_for_new_window: Option<String>,
) -> anyhow::Result<Option<(Arc<Tab>, WindowId)>> {
Ok(None)
}
/// Returns false if the `spawn` method will never succeed.
/// There are some internal placeholder domains that are
/// pre-created with local UI that we do not want to allow

View File

@ -1134,9 +1134,21 @@ impl Mux {
window_id: Option<WindowId>,
workspace_for_new_window: Option<String>,
) -> anyhow::Result<(Arc<Tab>, WindowId)> {
let (_domain, _src_window, src_tab) = self
let (domain_id, _src_window, src_tab) = self
.resolve_pane_id(pane_id)
.ok_or_else(|| anyhow::anyhow!("pane {} not found", pane_id))?;
let domain = self
.get_domain(domain_id)
.ok_or_else(|| anyhow::anyhow!("domain {domain_id} of pane {pane_id} not found"))?;
if let Some((tab, window_id)) = domain
.move_pane_to_new_tab(pane_id, window_id, workspace_for_new_window.clone())
.await?
{
return Ok((tab, window_id));
}
let src_tab = match self.get_tab(src_tab) {
Some(t) => t,
None => anyhow::bail!("Invalid tab id {}", src_tab),

View File

@ -593,6 +593,60 @@ impl Domain for ClientDomain {
anyhow::bail!("spawn_pane not implemented for ClientDomain")
}
/// Forward the request to the remote; we need to translate the local ids
/// to those that match the remote for the request, resync the changed
/// structure, and then translate the results back to local
async fn move_pane_to_new_tab(
&self,
pane_id: PaneId,
window_id: Option<WindowId>,
workspace_for_new_window: Option<String>,
) -> anyhow::Result<Option<(Arc<Tab>, WindowId)>> {
let inner = self
.inner()
.ok_or_else(|| anyhow!("domain is not attached"))?;
let local_pane = Mux::get()
.get_pane(pane_id)
.ok_or_else(|| anyhow!("pane_id {} is invalid", pane_id))?;
let pane = local_pane
.downcast_ref::<ClientPane>()
.ok_or_else(|| anyhow!("pane_id {} is not a ClientPane", pane_id))?;
let remote_window_id =
window_id.and_then(|local_window| self.local_to_remote_window_id(local_window));
let result = inner
.client
.move_pane_to_new_tab(codec::MovePaneToNewTab {
pane_id: pane.remote_pane_id,
window_id: remote_window_id,
workspace_for_new_window,
})
.await?;
self.resync().await?;
let local_tab_id = inner
.remote_to_local_tab_id(result.tab_id)
.ok_or_else(|| anyhow!("remote tab {} didn't resolve after resync", result.tab_id))?;
let local_win_id = self
.remote_to_local_window_id(result.window_id)
.ok_or_else(|| {
anyhow!(
"remote window {} didn't resolve after resync",
result.window_id
)
})?;
let tab = Mux::get()
.get_tab(local_tab_id)
.ok_or_else(|| anyhow!("local tab {local_tab_id} is invalid"))?;
Ok(Some((tab, local_win_id)))
}
async fn spawn(
&self,
size: TerminalSize,