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:
parent
b03e27adb1
commit
1a44255529
@ -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(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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 => {
|
||||||
|
@ -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:
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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,
|
||||||
|
)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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)
|
||||||
|
@ -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)
|
||||||
|
@ -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 {
|
||||||
|
Loading…
Reference in New Issue
Block a user