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

mux client: connect all mux panes in window to clipboard when attaching

refs: https://github.com/wez/wezterm/issues/836
This commit is contained in:
Wez Furlong 2021-05-31 08:21:19 -07:00
parent b03e27adb1
commit 1a44255529
8 changed files with 51 additions and 6 deletions

View File

@ -36,6 +36,7 @@ use crate::activity::Activity;
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub enum MuxNotification { pub enum MuxNotification {
PaneOutput(PaneId), PaneOutput(PaneId),
PaneAdded(PaneId),
PaneRemoved(PaneId), PaneRemoved(PaneId),
WindowCreated(WindowId), WindowCreated(WindowId),
WindowRemoved(WindowId), WindowRemoved(WindowId),
@ -365,6 +366,7 @@ impl Mux {
let pane_id = pane.pane_id(); let pane_id = pane.pane_id();
let banner = self.banner.borrow().clone(); let banner = self.banner.borrow().clone();
thread::spawn(move || read_from_pane_pty(pane_id, banner, reader)); thread::spawn(move || read_from_pane_pty(pane_id, banner, reader));
self.notify(MuxNotification::PaneAdded(pane_id));
Ok(()) Ok(())
} }

View File

@ -112,6 +112,13 @@ impl ClientPane {
.. ..
}) => match self.clipboard.borrow().as_ref() { }) => match self.clipboard.borrow().as_ref() {
Some(clip) => { Some(clip) => {
log::debug!(
"Pdu::SetClipboard pane={} remote={} {:?} {:?}",
self.local_pane_id,
self.remote_pane_id,
selection,
clipboard
);
clip.set_contents(selection, clipboard)?; clip.set_contents(selection, clipboard)?;
} }
None => { None => {

View File

@ -42,6 +42,7 @@ impl GuiFrontEnd {
MuxNotification::PaneRemoved(_) => {} MuxNotification::PaneRemoved(_) => {}
MuxNotification::WindowInvalidated(_) => {} MuxNotification::WindowInvalidated(_) => {}
MuxNotification::PaneOutput(_) => {} MuxNotification::PaneOutput(_) => {}
MuxNotification::PaneAdded(_) => {}
MuxNotification::Alert { MuxNotification::Alert {
pane_id: _, pane_id: _,
alert: alert:

View File

@ -66,8 +66,8 @@ impl TermWindow {
mux_window.set_clipboard(&clipboard); mux_window.set_clipboard(&clipboard);
for tab in mux_window.iter() { for tab in mux_window.iter() {
for pane in tab.get_active_pane() { for pos in tab.iter_panes() {
pane.set_clipboard(&clipboard); pos.pane.set_clipboard(&clipboard);
} }
} }
} }

View File

@ -844,6 +844,7 @@ impl TermWindow {
window: &Window, window: &Window,
mux_window_id: MuxWindowId, mux_window_id: MuxWindowId,
dead: &Arc<AtomicBool>, dead: &Arc<AtomicBool>,
clipboard_contents: &Arc<Mutex<Option<String>>>,
) -> bool { ) -> bool {
if dead.load(Ordering::Relaxed) { if dead.load(Ordering::Relaxed) {
// Subscription cancelled asynchronously // Subscription cancelled asynchronously
@ -869,6 +870,30 @@ impl TermWindow {
} }
let _ = pane_id; let _ = pane_id;
} }
MuxNotification::PaneAdded(pane_id) => {
// If some other client spawns a pane inside this window, this
// gives us an opportunity to attach it to the clipboard.
let mux = Mux::get().expect("mux is calling us");
if let Some(mux_window) = mux.get_window(mux_window_id) {
for tab in mux_window.iter() {
for pos in tab.iter_panes() {
if pos.pane.pane_id() == pane_id {
let clipboard: Arc<dyn wezterm_term::Clipboard> =
Arc::new(ClipboardHelper {
window: window.clone(),
clipboard_contents: Arc::clone(clipboard_contents),
});
pos.pane.set_clipboard(&clipboard);
break;
}
}
}
return true;
} else {
// Something inconsistent: cancel subscription
return false;
};
}
MuxNotification::WindowRemoved(window_id) MuxNotification::WindowRemoved(window_id)
| MuxNotification::WindowInvalidated(window_id) => { | MuxNotification::WindowInvalidated(window_id) => {
if window_id != mux_window_id { if window_id != mux_window_id {
@ -888,8 +913,15 @@ impl TermWindow {
let mux_window_id = self.mux_window_id; let mux_window_id = self.mux_window_id;
let mux = Mux::get().expect("mux started and running on main thread"); let mux = Mux::get().expect("mux started and running on main thread");
let dead = Arc::new(AtomicBool::new(false)); let dead = Arc::new(AtomicBool::new(false));
let clipboard_contents = Arc::clone(&self.clipboard_contents);
mux.subscribe(move |n| { mux.subscribe(move |n| {
Self::mux_pane_output_event_callback(n, &window, mux_window_id, &dead) Self::mux_pane_output_event_callback(
n,
&window,
mux_window_id,
&dead,
&clipboard_contents,
)
}); });
} }

View File

@ -160,6 +160,8 @@ impl super::TermWindow {
None None
}; };
let clipboard: Arc<dyn wezterm_term::Clipboard> = Arc::new(clipboard);
match spawn_where { match spawn_where {
SpawnWhere::SplitPane(direction) => { SpawnWhere::SplitPane(direction) => {
let mux = Mux::get().unwrap(); let mux = Mux::get().unwrap();
@ -169,9 +171,10 @@ impl super::TermWindow {
.ok_or_else(|| anyhow!("tab to have a pane"))?; .ok_or_else(|| anyhow!("tab to have a pane"))?;
log::trace!("doing split_pane"); log::trace!("doing split_pane");
domain let pane = domain
.split_pane(cmd_builder, cwd, tab.tab_id(), pane.pane_id(), direction) .split_pane(cmd_builder, cwd, tab.tab_id(), pane.pane_id(), direction)
.await?; .await?;
pane.set_clipboard(&clipboard);
} else { } else {
log::error!("there is no active tab while splitting pane!?"); log::error!("there is no active tab while splitting pane!?");
} }
@ -186,7 +189,6 @@ impl super::TermWindow {
.ok_or_else(|| anyhow!("newly spawned tab to have a pane"))?; .ok_or_else(|| anyhow!("newly spawned tab to have a pane"))?;
if spawn_where != SpawnWhere::NewWindow { if spawn_where != SpawnWhere::NewWindow {
let clipboard: Arc<dyn wezterm_term::Clipboard> = Arc::new(clipboard);
pane.set_clipboard(&clipboard); pane.set_clipboard(&clipboard);
let mut window = mux let mut window = mux
.get_window_mut(target_window_id) .get_window_mut(target_window_id)

View File

@ -81,6 +81,7 @@ where
Ok(Item::Notif(MuxNotification::PaneOutput(pane_id))) => { Ok(Item::Notif(MuxNotification::PaneOutput(pane_id))) => {
handler.schedule_pane_push(pane_id); handler.schedule_pane_push(pane_id);
} }
Ok(Item::Notif(MuxNotification::PaneAdded(_pane_id))) => {}
Ok(Item::Notif(MuxNotification::PaneRemoved(pane_id))) => { Ok(Item::Notif(MuxNotification::PaneRemoved(pane_id))) => {
Pdu::PaneRemoved(codec::PaneRemoved { pane_id }) Pdu::PaneRemoved(codec::PaneRemoved { pane_id })
.encode_async(&mut stream, 0) .encode_async(&mut stream, 0)

View File

@ -610,7 +610,7 @@ where
struct RemoteClipboard { struct RemoteClipboard {
sender: PduSender, sender: PduSender,
pane_id: TabId, pane_id: PaneId,
} }
impl Clipboard for RemoteClipboard { impl Clipboard for RemoteClipboard {