mirror of
https://github.com/wez/wezterm.git
synced 2024-11-25 21:07:39 +03:00
mux: Pane is now required to be Send+Sync. Use Arc<dyn Pane>
This commit is contained in:
parent
758a09f55f
commit
6e06b9af02
3
Cargo.lock
generated
3
Cargo.lock
generated
@ -2918,6 +2918,7 @@ dependencies = [
|
||||
"names",
|
||||
"nix 0.25.1",
|
||||
"ntapi",
|
||||
"parking_lot 0.12.1",
|
||||
"percent-encoding",
|
||||
"portable-pty",
|
||||
"procinfo",
|
||||
@ -5781,6 +5782,7 @@ dependencies = [
|
||||
"metrics",
|
||||
"mux",
|
||||
"openssl",
|
||||
"parking_lot 0.12.1",
|
||||
"portable-pty",
|
||||
"promise",
|
||||
"rangeset",
|
||||
@ -5918,6 +5920,7 @@ dependencies = [
|
||||
"mux-lua",
|
||||
"open",
|
||||
"ordered-float",
|
||||
"parking_lot 0.12.1",
|
||||
"portable-pty",
|
||||
"promise",
|
||||
"pulldown-cmark",
|
||||
|
@ -1,11 +1,12 @@
|
||||
use super::*;
|
||||
use luahelper::dynamic_to_lua_value;
|
||||
use std::sync::Arc;
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub struct MuxPane(pub PaneId);
|
||||
|
||||
impl MuxPane {
|
||||
pub fn resolve<'a>(&self, mux: &'a Rc<Mux>) -> mlua::Result<Rc<dyn Pane>> {
|
||||
pub fn resolve<'a>(&self, mux: &'a Rc<Mux>) -> mlua::Result<Arc<dyn Pane>> {
|
||||
mux.get_pane(self.0)
|
||||
.ok_or_else(|| mlua::Error::external(format!("pane id {} not found in mux", self.0)))
|
||||
}
|
||||
|
@ -27,6 +27,7 @@ metrics = { version="0.17", features=["std"]}
|
||||
mlua = "0.8.3"
|
||||
names = { version = "0.12", default-features = false }
|
||||
nix = {version="0.25", features=["term"]}
|
||||
parking_lot = "0.12"
|
||||
percent-encoding = "2"
|
||||
portable-pty = { path = "../pty", features = ["serde_support"]}
|
||||
procinfo = { path = "../procinfo" }
|
||||
|
@ -74,7 +74,7 @@ pub trait Domain: Downcast {
|
||||
tab: TabId,
|
||||
pane_id: PaneId,
|
||||
split_request: SplitRequest,
|
||||
) -> anyhow::Result<Rc<dyn Pane>> {
|
||||
) -> anyhow::Result<Arc<dyn Pane>> {
|
||||
let mux = Mux::get().unwrap();
|
||||
let tab = match mux.get_tab(tab) {
|
||||
Some(t) => t,
|
||||
@ -124,7 +124,7 @@ pub trait Domain: Downcast {
|
||||
}
|
||||
};
|
||||
|
||||
tab.split_and_insert(pane_index, split_request, Rc::clone(&pane))?;
|
||||
tab.split_and_insert(pane_index, split_request, Arc::clone(&pane))?;
|
||||
Ok(pane)
|
||||
}
|
||||
|
||||
@ -133,7 +133,7 @@ pub trait Domain: Downcast {
|
||||
size: TerminalSize,
|
||||
command: Option<CommandBuilder>,
|
||||
command_dir: Option<String>,
|
||||
) -> anyhow::Result<Rc<dyn Pane>>;
|
||||
) -> anyhow::Result<Arc<dyn Pane>>;
|
||||
|
||||
/// Returns false if the `spawn` method will never succeed.
|
||||
/// There are some internal placeholder domains that are
|
||||
@ -475,7 +475,7 @@ impl Domain for LocalDomain {
|
||||
size: TerminalSize,
|
||||
command: Option<CommandBuilder>,
|
||||
command_dir: Option<String>,
|
||||
) -> anyhow::Result<Rc<dyn Pane>> {
|
||||
) -> anyhow::Result<Arc<dyn Pane>> {
|
||||
let pane_id = alloc_pane_id();
|
||||
let cmd = self.build_command(command, command_dir, pane_id).await?;
|
||||
let pair = self
|
||||
@ -510,7 +510,7 @@ impl Domain for LocalDomain {
|
||||
terminal.enable_conpty_quirks();
|
||||
}
|
||||
|
||||
let pane: Rc<dyn Pane> = Rc::new(LocalPane::new(
|
||||
let pane: Arc<dyn Pane> = Arc::new(LocalPane::new(
|
||||
pane_id,
|
||||
terminal,
|
||||
child,
|
||||
|
@ -82,7 +82,7 @@ static SUB_ID: AtomicUsize = AtomicUsize::new(0);
|
||||
|
||||
pub struct Mux {
|
||||
tabs: RefCell<HashMap<TabId, Rc<Tab>>>,
|
||||
panes: RefCell<HashMap<PaneId, Rc<dyn Pane>>>,
|
||||
panes: RefCell<HashMap<PaneId, Arc<dyn Pane>>>,
|
||||
windows: RefCell<HashMap<WindowId, Window>>,
|
||||
default_domain: RefCell<Option<Arc<dyn Domain>>>,
|
||||
domains: RefCell<HashMap<DomainId, Arc<dyn Domain>>>,
|
||||
@ -616,15 +616,15 @@ impl Mux {
|
||||
res
|
||||
}
|
||||
|
||||
pub fn get_pane(&self, pane_id: PaneId) -> Option<Rc<dyn Pane>> {
|
||||
self.panes.borrow().get(&pane_id).map(Rc::clone)
|
||||
pub fn get_pane(&self, pane_id: PaneId) -> Option<Arc<dyn Pane>> {
|
||||
self.panes.borrow().get(&pane_id).map(Arc::clone)
|
||||
}
|
||||
|
||||
pub fn get_tab(&self, tab_id: TabId) -> Option<Rc<Tab>> {
|
||||
self.tabs.borrow().get(&tab_id).map(Rc::clone)
|
||||
}
|
||||
|
||||
pub fn add_pane(&self, pane: &Rc<dyn Pane>) -> Result<(), Error> {
|
||||
pub fn add_pane(&self, pane: &Arc<dyn Pane>) -> Result<(), Error> {
|
||||
if self.panes.borrow().contains_key(&pane.pane_id()) {
|
||||
return Ok(());
|
||||
}
|
||||
@ -639,7 +639,7 @@ impl Mux {
|
||||
|
||||
self.panes
|
||||
.borrow_mut()
|
||||
.insert(pane.pane_id(), Rc::clone(pane));
|
||||
.insert(pane.pane_id(), Arc::clone(pane));
|
||||
let pane_id = pane.pane_id();
|
||||
if let Some(reader) = pane.reader()? {
|
||||
let banner = self.banner.borrow().clone();
|
||||
@ -857,11 +857,11 @@ impl Mux {
|
||||
self.is_workspace_empty(&workspace)
|
||||
}
|
||||
|
||||
pub fn iter_panes(&self) -> Vec<Rc<dyn Pane>> {
|
||||
pub fn iter_panes(&self) -> Vec<Arc<dyn Pane>> {
|
||||
self.panes
|
||||
.borrow()
|
||||
.iter()
|
||||
.map(|(_, v)| Rc::clone(v))
|
||||
.map(|(_, v)| Arc::clone(v))
|
||||
.collect()
|
||||
}
|
||||
|
||||
@ -965,7 +965,7 @@ impl Mux {
|
||||
fn resolve_cwd(
|
||||
&self,
|
||||
command_dir: Option<String>,
|
||||
pane: Option<Rc<dyn Pane>>,
|
||||
pane: Option<Arc<dyn Pane>>,
|
||||
) -> Option<String> {
|
||||
command_dir.or_else(|| {
|
||||
match pane {
|
||||
@ -1000,7 +1000,7 @@ impl Mux {
|
||||
request: SplitRequest,
|
||||
source: SplitSource,
|
||||
domain: config::keyassignment::SpawnTabDomain,
|
||||
) -> anyhow::Result<(Rc<dyn Pane>, TerminalSize)> {
|
||||
) -> anyhow::Result<(Arc<dyn Pane>, TerminalSize)> {
|
||||
let (_pane_domain_id, window_id, tab_id) = self
|
||||
.resolve_pane_id(pane_id)
|
||||
.ok_or_else(|| anyhow!("pane_id {} invalid", pane_id))?;
|
||||
@ -1024,7 +1024,7 @@ impl Mux {
|
||||
command_dir,
|
||||
} => SplitSource::Spawn {
|
||||
command,
|
||||
command_dir: self.resolve_cwd(command_dir, Some(Rc::clone(¤t_pane))),
|
||||
command_dir: self.resolve_cwd(command_dir, Some(Arc::clone(¤t_pane))),
|
||||
},
|
||||
other => other,
|
||||
};
|
||||
@ -1105,7 +1105,7 @@ impl Mux {
|
||||
size: TerminalSize,
|
||||
current_pane_id: Option<PaneId>,
|
||||
workspace_for_new_window: String,
|
||||
) -> anyhow::Result<(Rc<Tab>, Rc<dyn Pane>, WindowId)> {
|
||||
) -> anyhow::Result<(Rc<Tab>, Arc<dyn Pane>, WindowId)> {
|
||||
let domain = self
|
||||
.resolve_spawn_tab_domain(current_pane_id, &domain)
|
||||
.context("resolve_spawn_tab_domain")?;
|
||||
|
@ -10,12 +10,12 @@ use anyhow::Error;
|
||||
use async_trait::async_trait;
|
||||
use config::keyassignment::ScrollbackEraseMode;
|
||||
use config::{configuration, ExitBehavior};
|
||||
use parking_lot::{MappedMutexGuard, Mutex, MutexGuard};
|
||||
use portable_pty::{Child, ChildKiller, ExitStatus, MasterPty, PtySize};
|
||||
use procinfo::LocalProcessInfo;
|
||||
use rangeset::RangeSet;
|
||||
use smol::channel::{bounded, Receiver, TryRecvError};
|
||||
use std::borrow::Cow;
|
||||
use std::cell::{RefCell, RefMut};
|
||||
use std::collections::{BTreeMap, HashMap, HashSet};
|
||||
use std::convert::TryInto;
|
||||
use std::io::{Result as IoResult, Write};
|
||||
@ -39,7 +39,7 @@ enum ProcessState {
|
||||
Running {
|
||||
child_waiter: Receiver<IoResult<ExitStatus>>,
|
||||
pid: Option<u32>,
|
||||
signaller: Box<dyn ChildKiller>,
|
||||
signaller: Box<dyn ChildKiller + Send + Sync>,
|
||||
// Whether we've explicitly killed the child
|
||||
killed: bool,
|
||||
},
|
||||
@ -57,13 +57,13 @@ struct CachedProcInfo {
|
||||
|
||||
pub struct LocalPane {
|
||||
pane_id: PaneId,
|
||||
terminal: RefCell<Terminal>,
|
||||
process: RefCell<ProcessState>,
|
||||
pty: RefCell<Box<dyn MasterPty>>,
|
||||
writer: RefCell<Box<dyn Write>>,
|
||||
terminal: Mutex<Terminal>,
|
||||
process: Mutex<ProcessState>,
|
||||
pty: Mutex<Box<dyn MasterPty + Send>>,
|
||||
writer: Mutex<Box<dyn Write + Send>>,
|
||||
domain_id: DomainId,
|
||||
tmux_domain: RefCell<Option<Arc<TmuxDomainState>>>,
|
||||
proc_list: RefCell<Option<CachedProcInfo>>,
|
||||
tmux_domain: Mutex<Option<Arc<TmuxDomainState>>>,
|
||||
proc_list: Mutex<Option<CachedProcInfo>>,
|
||||
command_description: String,
|
||||
}
|
||||
|
||||
@ -78,7 +78,7 @@ impl Pane for LocalPane {
|
||||
let mut map: BTreeMap<Value, Value> = BTreeMap::new();
|
||||
|
||||
#[cfg(unix)]
|
||||
if let Some(tio) = self.pty.borrow().get_termios() {
|
||||
if let Some(tio) = self.pty.lock().get_termios() {
|
||||
use nix::sys::termios::LocalFlags;
|
||||
// Detect whether we might be in password input mode.
|
||||
// If local echo is disabled and canonical input mode
|
||||
@ -96,19 +96,19 @@ impl Pane for LocalPane {
|
||||
}
|
||||
|
||||
fn get_cursor_position(&self) -> StableCursorPosition {
|
||||
let mut cursor = terminal_get_cursor_position(&mut self.terminal.borrow_mut());
|
||||
if self.tmux_domain.borrow().is_some() {
|
||||
let mut cursor = terminal_get_cursor_position(&mut self.terminal.lock());
|
||||
if self.tmux_domain.lock().is_some() {
|
||||
cursor.visibility = termwiz::surface::CursorVisibility::Hidden;
|
||||
}
|
||||
cursor
|
||||
}
|
||||
|
||||
fn get_keyboard_encoding(&self) -> KeyboardEncoding {
|
||||
self.terminal.borrow().get_keyboard_encoding()
|
||||
self.terminal.lock().get_keyboard_encoding()
|
||||
}
|
||||
|
||||
fn get_current_seqno(&self) -> SequenceNo {
|
||||
self.terminal.borrow().current_seqno()
|
||||
self.terminal.lock().current_seqno()
|
||||
}
|
||||
|
||||
fn get_changed_since(
|
||||
@ -116,7 +116,7 @@ impl Pane for LocalPane {
|
||||
lines: Range<StableRowIndex>,
|
||||
seqno: SequenceNo,
|
||||
) -> RangeSet<StableRowIndex> {
|
||||
terminal_get_dirty_lines(&mut self.terminal.borrow_mut(), lines, seqno)
|
||||
terminal_get_dirty_lines(&mut self.terminal.lock(), lines, seqno)
|
||||
}
|
||||
|
||||
fn for_each_logical_line_in_stable_range_mut(
|
||||
@ -125,14 +125,14 @@ impl Pane for LocalPane {
|
||||
for_line: &mut dyn ForEachPaneLogicalLine,
|
||||
) {
|
||||
terminal_for_each_logical_line_in_stable_range_mut(
|
||||
&mut self.terminal.borrow_mut(),
|
||||
&mut self.terminal.lock(),
|
||||
lines,
|
||||
for_line,
|
||||
);
|
||||
}
|
||||
|
||||
fn with_lines_mut(&self, lines: Range<StableRowIndex>, with_lines: &mut dyn WithPaneLines) {
|
||||
terminal_with_lines_mut(&mut self.terminal.borrow_mut(), lines, with_lines)
|
||||
terminal_with_lines_mut(&mut self.terminal.lock(), lines, with_lines)
|
||||
}
|
||||
|
||||
fn get_lines(&self, lines: Range<StableRowIndex>) -> (StableRowIndex, Vec<Line>) {
|
||||
@ -144,15 +144,15 @@ impl Pane for LocalPane {
|
||||
}
|
||||
|
||||
fn get_dimensions(&self) -> RenderableDimensions {
|
||||
terminal_get_dimensions(&mut self.terminal.borrow_mut())
|
||||
terminal_get_dimensions(&mut self.terminal.lock())
|
||||
}
|
||||
|
||||
fn copy_user_vars(&self) -> HashMap<String, String> {
|
||||
self.terminal.borrow().user_vars().clone()
|
||||
self.terminal.lock().user_vars().clone()
|
||||
}
|
||||
|
||||
fn kill(&self) {
|
||||
let mut proc = self.process.borrow_mut();
|
||||
let mut proc = self.process.lock();
|
||||
log::debug!(
|
||||
"killing process in pane {}, state is {:?}",
|
||||
self.pane_id,
|
||||
@ -173,7 +173,7 @@ impl Pane for LocalPane {
|
||||
}
|
||||
|
||||
fn is_dead(&self) -> bool {
|
||||
let mut proc = self.process.borrow_mut();
|
||||
let mut proc = self.process.lock();
|
||||
let mut notify = None;
|
||||
|
||||
const EXIT_BEHAVIOR: &str = "This message is shown because \
|
||||
@ -255,79 +255,82 @@ impl Pane for LocalPane {
|
||||
}
|
||||
|
||||
fn set_clipboard(&self, clipboard: &Arc<dyn Clipboard>) {
|
||||
self.terminal.borrow_mut().set_clipboard(clipboard);
|
||||
self.terminal.lock().set_clipboard(clipboard);
|
||||
}
|
||||
|
||||
fn set_download_handler(&self, handler: &Arc<dyn DownloadHandler>) {
|
||||
self.terminal.borrow_mut().set_download_handler(handler);
|
||||
self.terminal.lock().set_download_handler(handler);
|
||||
}
|
||||
|
||||
fn set_config(&self, config: Arc<dyn TerminalConfiguration>) {
|
||||
self.terminal.borrow_mut().set_config(config);
|
||||
self.terminal.lock().set_config(config);
|
||||
}
|
||||
|
||||
fn get_config(&self) -> Option<Arc<dyn TerminalConfiguration>> {
|
||||
Some(self.terminal.borrow().get_config())
|
||||
Some(self.terminal.lock().get_config())
|
||||
}
|
||||
|
||||
fn perform_actions(&self, actions: Vec<termwiz::escape::Action>) {
|
||||
self.terminal.borrow_mut().perform_actions(actions)
|
||||
self.terminal.lock().perform_actions(actions)
|
||||
}
|
||||
|
||||
fn mouse_event(&self, event: MouseEvent) -> Result<(), Error> {
|
||||
Mux::get().unwrap().record_input_for_current_identity();
|
||||
self.terminal.borrow_mut().mouse_event(event)
|
||||
self.terminal.lock().mouse_event(event)
|
||||
}
|
||||
|
||||
fn key_down(&self, key: KeyCode, mods: KeyModifiers) -> Result<(), Error> {
|
||||
Mux::get().unwrap().record_input_for_current_identity();
|
||||
if self.tmux_domain.borrow().is_some() {
|
||||
if self.tmux_domain.lock().is_some() {
|
||||
log::error!("key: {:?}", key);
|
||||
if key == KeyCode::Char('q') {
|
||||
self.terminal.borrow_mut().send_paste("detach\n")?;
|
||||
self.terminal.lock().send_paste("detach\n")?;
|
||||
}
|
||||
return Ok(());
|
||||
} else {
|
||||
self.terminal.borrow_mut().key_down(key, mods)
|
||||
self.terminal.lock().key_down(key, mods)
|
||||
}
|
||||
}
|
||||
|
||||
fn key_up(&self, key: KeyCode, mods: KeyModifiers) -> Result<(), Error> {
|
||||
Mux::get().unwrap().record_input_for_current_identity();
|
||||
self.terminal.borrow_mut().key_up(key, mods)
|
||||
self.terminal.lock().key_up(key, mods)
|
||||
}
|
||||
|
||||
fn resize(&self, size: TerminalSize) -> Result<(), Error> {
|
||||
self.pty.borrow_mut().resize(PtySize {
|
||||
self.pty.lock().resize(PtySize {
|
||||
rows: size.rows.try_into()?,
|
||||
cols: size.cols.try_into()?,
|
||||
pixel_width: size.pixel_width.try_into()?,
|
||||
pixel_height: size.pixel_height.try_into()?,
|
||||
})?;
|
||||
self.terminal.borrow_mut().resize(size);
|
||||
self.terminal.lock().resize(size);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn writer(&self) -> RefMut<dyn std::io::Write> {
|
||||
fn writer(&self) -> MappedMutexGuard<dyn std::io::Write> {
|
||||
Mux::get().unwrap().record_input_for_current_identity();
|
||||
self.writer.borrow_mut()
|
||||
MutexGuard::map(self.writer.lock(), |writer| {
|
||||
let w: &mut dyn std::io::Write = writer;
|
||||
w
|
||||
})
|
||||
}
|
||||
|
||||
fn reader(&self) -> anyhow::Result<Option<Box<dyn std::io::Read + Send>>> {
|
||||
Ok(Some(self.pty.borrow_mut().try_clone_reader()?))
|
||||
Ok(Some(self.pty.lock().try_clone_reader()?))
|
||||
}
|
||||
|
||||
fn send_paste(&self, text: &str) -> Result<(), Error> {
|
||||
Mux::get().unwrap().record_input_for_current_identity();
|
||||
if self.tmux_domain.borrow().is_some() {
|
||||
if self.tmux_domain.lock().is_some() {
|
||||
Ok(())
|
||||
} else {
|
||||
self.terminal.borrow_mut().send_paste(text)
|
||||
self.terminal.lock().send_paste(text)
|
||||
}
|
||||
}
|
||||
|
||||
fn get_title(&self) -> String {
|
||||
let title = self.terminal.borrow_mut().get_title().to_string();
|
||||
let title = self.terminal.lock().get_title().to_string();
|
||||
// If the title is the default pane title, then try to spice
|
||||
// things up a bit by returning the process basename instead
|
||||
if title == "wezterm" {
|
||||
@ -343,7 +346,7 @@ impl Pane for LocalPane {
|
||||
}
|
||||
|
||||
fn palette(&self) -> ColorPalette {
|
||||
self.terminal.borrow().palette()
|
||||
self.terminal.lock().palette()
|
||||
}
|
||||
|
||||
fn domain_id(&self) -> DomainId {
|
||||
@ -353,41 +356,41 @@ impl Pane for LocalPane {
|
||||
fn erase_scrollback(&self, erase_mode: ScrollbackEraseMode) {
|
||||
match erase_mode {
|
||||
ScrollbackEraseMode::ScrollbackOnly => {
|
||||
self.terminal.borrow_mut().erase_scrollback();
|
||||
self.terminal.lock().erase_scrollback();
|
||||
}
|
||||
ScrollbackEraseMode::ScrollbackAndViewport => {
|
||||
self.terminal.borrow_mut().erase_scrollback_and_viewport();
|
||||
self.terminal.lock().erase_scrollback_and_viewport();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn focus_changed(&self, focused: bool) {
|
||||
self.terminal.borrow_mut().focus_changed(focused);
|
||||
self.terminal.lock().focus_changed(focused);
|
||||
}
|
||||
|
||||
fn has_unseen_output(&self) -> bool {
|
||||
self.terminal.borrow().has_unseen_output()
|
||||
self.terminal.lock().has_unseen_output()
|
||||
}
|
||||
|
||||
fn is_mouse_grabbed(&self) -> bool {
|
||||
if self.tmux_domain.borrow().is_some() {
|
||||
if self.tmux_domain.lock().is_some() {
|
||||
false
|
||||
} else {
|
||||
self.terminal.borrow().is_mouse_grabbed()
|
||||
self.terminal.lock().is_mouse_grabbed()
|
||||
}
|
||||
}
|
||||
|
||||
fn is_alt_screen_active(&self) -> bool {
|
||||
if self.tmux_domain.borrow().is_some() {
|
||||
if self.tmux_domain.lock().is_some() {
|
||||
false
|
||||
} else {
|
||||
self.terminal.borrow().is_alt_screen_active()
|
||||
self.terminal.lock().is_alt_screen_active()
|
||||
}
|
||||
}
|
||||
|
||||
fn get_current_working_dir(&self) -> Option<Url> {
|
||||
self.terminal
|
||||
.borrow()
|
||||
.lock()
|
||||
.get_current_dir()
|
||||
.cloned()
|
||||
.or_else(|| self.divine_current_working_dir())
|
||||
@ -395,7 +398,7 @@ impl Pane for LocalPane {
|
||||
|
||||
fn get_foreground_process_info(&self) -> Option<LocalProcessInfo> {
|
||||
#[cfg(unix)]
|
||||
if let Some(pid) = self.pty.borrow().process_group_leader() {
|
||||
if let Some(pid) = self.pty.lock().process_group_leader() {
|
||||
return LocalProcessInfo::with_root_pid(pid as u32);
|
||||
}
|
||||
|
||||
@ -404,7 +407,7 @@ impl Pane for LocalPane {
|
||||
|
||||
fn get_foreground_process_name(&self) -> Option<String> {
|
||||
#[cfg(unix)]
|
||||
if let Some(pid) = self.pty.borrow().process_group_leader() {
|
||||
if let Some(pid) = self.pty.lock().process_group_leader() {
|
||||
if let Some(path) = LocalProcessInfo::executable_path(pid as u32) {
|
||||
return Some(path.to_string_lossy().to_string());
|
||||
}
|
||||
@ -478,7 +481,7 @@ impl Pane for LocalPane {
|
||||
// If the process is dead but exit_behavior is holding the
|
||||
// window, we don't need to prompt to confirm closing.
|
||||
// That is detectable as no longer having a process group leader.
|
||||
if self.pty.borrow().process_group_leader().is_none() {
|
||||
if self.pty.lock().process_group_leader().is_none() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -488,7 +491,7 @@ impl Pane for LocalPane {
|
||||
}
|
||||
|
||||
fn get_semantic_zones(&self) -> anyhow::Result<Vec<SemanticZone>> {
|
||||
let mut term = self.terminal.borrow_mut();
|
||||
let mut term = self.terminal.lock();
|
||||
term.get_semantic_zones()
|
||||
}
|
||||
|
||||
@ -498,7 +501,7 @@ impl Pane for LocalPane {
|
||||
range: Range<StableRowIndex>,
|
||||
limit: Option<u32>,
|
||||
) -> anyhow::Result<Vec<SearchResult>> {
|
||||
let term = self.terminal.borrow();
|
||||
let term = self.terminal.lock();
|
||||
let screen = term.screen();
|
||||
|
||||
enum CompiledPattern {
|
||||
@ -713,9 +716,7 @@ impl wezterm_term::DeviceControlHandler for LocalPaneDCSHandler {
|
||||
|
||||
if let Some(pane) = mux.get_pane(self.pane_id) {
|
||||
let pane = pane.downcast_ref::<LocalPane>().unwrap();
|
||||
pane.tmux_domain
|
||||
.borrow_mut()
|
||||
.replace(Arc::clone(&tmux_domain));
|
||||
pane.tmux_domain.lock().replace(Arc::clone(&tmux_domain));
|
||||
|
||||
emit_output_for_pane(
|
||||
self.pane_id,
|
||||
@ -737,7 +738,7 @@ impl wezterm_term::DeviceControlHandler for LocalPaneDCSHandler {
|
||||
let mux = Mux::get().expect("to be called on main thread");
|
||||
if let Some(pane) = mux.get_pane(self.pane_id) {
|
||||
let pane = pane.downcast_ref::<LocalPane>().unwrap();
|
||||
pane.tmux_domain.borrow_mut().take();
|
||||
pane.tmux_domain.lock().take();
|
||||
}
|
||||
mux.domain_was_detached(tmux.domain_id);
|
||||
}
|
||||
@ -808,7 +809,7 @@ fn split_child(
|
||||
mut process: Box<dyn Child + Send>,
|
||||
) -> (
|
||||
Receiver<IoResult<ExitStatus>>,
|
||||
Box<dyn ChildKiller>,
|
||||
Box<dyn ChildKiller + Send + Sync>,
|
||||
Option<u32>,
|
||||
) {
|
||||
let pid = process.process_id();
|
||||
@ -834,8 +835,8 @@ impl LocalPane {
|
||||
pane_id: PaneId,
|
||||
mut terminal: Terminal,
|
||||
process: Box<dyn Child + Send>,
|
||||
pty: Box<dyn MasterPty>,
|
||||
writer: Box<dyn Write>,
|
||||
pty: Box<dyn MasterPty + Send>,
|
||||
writer: Box<dyn Write + Send>,
|
||||
domain_id: DomainId,
|
||||
command_description: String,
|
||||
) -> Self {
|
||||
@ -849,25 +850,25 @@ impl LocalPane {
|
||||
|
||||
Self {
|
||||
pane_id,
|
||||
terminal: RefCell::new(terminal),
|
||||
process: RefCell::new(ProcessState::Running {
|
||||
terminal: Mutex::new(terminal),
|
||||
process: Mutex::new(ProcessState::Running {
|
||||
child_waiter: process,
|
||||
pid,
|
||||
signaller,
|
||||
killed: false,
|
||||
}),
|
||||
pty: RefCell::new(pty),
|
||||
writer: RefCell::new(writer),
|
||||
pty: Mutex::new(pty),
|
||||
writer: Mutex::new(writer),
|
||||
domain_id,
|
||||
tmux_domain: RefCell::new(None),
|
||||
proc_list: RefCell::new(None),
|
||||
tmux_domain: Mutex::new(None),
|
||||
proc_list: Mutex::new(None),
|
||||
command_description,
|
||||
}
|
||||
}
|
||||
|
||||
fn divine_current_working_dir(&self) -> Option<Url> {
|
||||
#[cfg(unix)]
|
||||
if let Some(pid) = self.pty.borrow().process_group_leader() {
|
||||
if let Some(pid) = self.pty.lock().process_group_leader() {
|
||||
if let Some(path) = LocalProcessInfo::current_working_dir(pid as u32) {
|
||||
return Url::parse(&format!("file://localhost{}", path.display())).ok();
|
||||
}
|
||||
@ -885,9 +886,9 @@ impl LocalPane {
|
||||
None
|
||||
}
|
||||
|
||||
fn divine_process_list(&self, force_refresh: bool) -> Option<RefMut<CachedProcInfo>> {
|
||||
if let ProcessState::Running { pid: Some(pid), .. } = &*self.process.borrow() {
|
||||
let mut proc_list = self.proc_list.borrow_mut();
|
||||
fn divine_process_list(&self, force_refresh: bool) -> Option<MappedMutexGuard<CachedProcInfo>> {
|
||||
if let ProcessState::Running { pid: Some(pid), .. } = &*self.process.lock() {
|
||||
let mut proc_list = self.proc_list.lock();
|
||||
|
||||
let expired = force_refresh
|
||||
|| proc_list
|
||||
@ -934,7 +935,7 @@ impl LocalPane {
|
||||
log::trace!("CachedProcInfo updated");
|
||||
}
|
||||
|
||||
return Some(RefMut::map(proc_list, |info| info.as_mut().unwrap()));
|
||||
return Some(MutexGuard::map(proc_list, |info| info.as_mut().unwrap()));
|
||||
}
|
||||
None
|
||||
}
|
||||
@ -953,7 +954,7 @@ impl Drop for LocalPane {
|
||||
fn drop(&mut self) {
|
||||
// Avoid lingering zombies if we can, but don't block forever.
|
||||
// <https://github.com/wez/wezterm/issues/558>
|
||||
if let ProcessState::Running { signaller, .. } = &mut *self.process.borrow_mut() {
|
||||
if let ProcessState::Running { signaller, .. } = &mut *self.process.lock() {
|
||||
let _ = signaller.kill();
|
||||
}
|
||||
}
|
||||
|
@ -4,12 +4,12 @@ use crate::Mux;
|
||||
use async_trait::async_trait;
|
||||
use config::keyassignment::{KeyAssignment, ScrollbackEraseMode};
|
||||
use downcast_rs::{impl_downcast, Downcast};
|
||||
use parking_lot::{MappedMutexGuard, Mutex};
|
||||
use rangeset::RangeSet;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::cell::RefMut;
|
||||
use std::collections::HashMap;
|
||||
use std::ops::Range;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::sync::Arc;
|
||||
use termwiz::hyperlink::Rule;
|
||||
use termwiz::input::KeyboardEncoding;
|
||||
use termwiz::surface::{Line, SequenceNo};
|
||||
@ -107,7 +107,7 @@ struct Paste {
|
||||
}
|
||||
|
||||
fn paste_next_chunk(paste: &Arc<Mutex<Paste>>) {
|
||||
let mut locked = paste.lock().unwrap();
|
||||
let mut locked = paste.lock();
|
||||
let mux = Mux::get().unwrap();
|
||||
let pane = mux.get_pane(locked.pane_id).unwrap();
|
||||
|
||||
@ -186,7 +186,7 @@ impl LogicalLine {
|
||||
|
||||
/// A Pane represents a view on a terminal
|
||||
#[async_trait(?Send)]
|
||||
pub trait Pane: Downcast {
|
||||
pub trait Pane: Downcast + Send + Sync {
|
||||
fn pane_id(&self) -> PaneId;
|
||||
|
||||
/// Returns the 0-based cursor position relative to the top left of
|
||||
@ -256,7 +256,7 @@ pub trait Pane: Downcast {
|
||||
fn get_title(&self) -> String;
|
||||
fn send_paste(&self, text: &str) -> anyhow::Result<()>;
|
||||
fn reader(&self) -> anyhow::Result<Option<Box<dyn std::io::Read + Send>>>;
|
||||
fn writer(&self) -> RefMut<dyn std::io::Write>;
|
||||
fn writer(&self) -> MappedMutexGuard<dyn std::io::Write>;
|
||||
fn resize(&self, size: TerminalSize) -> anyhow::Result<()>;
|
||||
/// Called as a hint that the pane is being resized as part of
|
||||
/// a zoom-to-fill-all-the-tab-space operation.
|
||||
@ -562,12 +562,12 @@ pub fn impl_get_lines_via_with_lines<P: Pane + ?Sized>(
|
||||
mod test {
|
||||
use super::*;
|
||||
use k9::snapshot;
|
||||
use parking_lot::{MappedMutexGuard, Mutex};
|
||||
use std::borrow::Cow;
|
||||
use std::cell::RefCell;
|
||||
use termwiz::surface::SEQ_ZERO;
|
||||
|
||||
struct FakePane {
|
||||
lines: RefCell<Vec<Line>>,
|
||||
lines: Mutex<Vec<Line>>,
|
||||
}
|
||||
|
||||
impl Pane for FakePane {
|
||||
@ -596,7 +596,7 @@ mod test {
|
||||
with_lines: &mut dyn WithPaneLines,
|
||||
) {
|
||||
let mut line_refs = vec![];
|
||||
let mut lines = self.lines.borrow_mut();
|
||||
let mut lines = self.lines.lock();
|
||||
for line in lines
|
||||
.iter_mut()
|
||||
.skip(stable_range.start as usize)
|
||||
@ -624,7 +624,7 @@ mod test {
|
||||
(
|
||||
first,
|
||||
self.lines
|
||||
.borrow()
|
||||
.lock()
|
||||
.iter()
|
||||
.skip(lines.start as usize)
|
||||
.take((lines.end - lines.start) as usize)
|
||||
@ -645,7 +645,7 @@ mod test {
|
||||
fn reader(&self) -> anyhow::Result<Option<Box<dyn std::io::Read + Send>>> {
|
||||
Ok(None)
|
||||
}
|
||||
fn writer(&self) -> RefMut<dyn std::io::Write> {
|
||||
fn writer(&self) -> MappedMutexGuard<dyn std::io::Write> {
|
||||
unimplemented!()
|
||||
}
|
||||
fn resize(&self, _: TerminalSize) -> anyhow::Result<()> {
|
||||
@ -739,7 +739,7 @@ mod test {
|
||||
);
|
||||
|
||||
let pane = FakePane {
|
||||
lines: RefCell::new(physical_lines),
|
||||
lines: Mutex::new(physical_lines),
|
||||
};
|
||||
|
||||
let logical = pane.get_logical_lines(0..30);
|
||||
|
@ -13,7 +13,6 @@ use smol::channel::{bounded, Receiver as AsyncReceiver};
|
||||
use std::cell::RefCell;
|
||||
use std::collections::{HashMap, VecDeque};
|
||||
use std::io::{BufWriter, Read, Write};
|
||||
use std::rc::Rc;
|
||||
use std::sync::mpsc::{channel, Receiver, Sender, TryRecvError};
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::time::{Duration, Instant};
|
||||
@ -560,12 +559,12 @@ impl Domain for RemoteSshDomain {
|
||||
size: TerminalSize,
|
||||
command: Option<CommandBuilder>,
|
||||
command_dir: Option<String>,
|
||||
) -> anyhow::Result<Rc<dyn Pane>> {
|
||||
) -> anyhow::Result<Arc<dyn Pane>> {
|
||||
let pane_id = alloc_pane_id();
|
||||
|
||||
let (command_line, env) = self.build_command(pane_id, command, command_dir)?;
|
||||
|
||||
let pty: Box<dyn portable_pty::MasterPty>;
|
||||
let pty: Box<dyn portable_pty::MasterPty + Send>;
|
||||
let child: Box<dyn portable_pty::Child + Send>;
|
||||
let writer: BoxedWriter;
|
||||
|
||||
@ -677,7 +676,7 @@ impl Domain for RemoteSshDomain {
|
||||
Box::new(writer.clone()),
|
||||
);
|
||||
|
||||
let pane: Rc<dyn Pane> = Rc::new(LocalPane::new(
|
||||
let pane: Arc<dyn Pane> = Arc::new(LocalPane::new(
|
||||
pane_id,
|
||||
terminal,
|
||||
child,
|
||||
|
@ -10,12 +10,12 @@ use serde::{Deserialize, Serialize};
|
||||
use std::cell::{RefCell, RefMut};
|
||||
use std::collections::HashMap;
|
||||
use std::convert::TryInto;
|
||||
use std::rc::Rc;
|
||||
use std::sync::Arc;
|
||||
use url::Url;
|
||||
use wezterm_term::{StableRowIndex, TerminalSize};
|
||||
|
||||
pub type Tree = bintree::Tree<Rc<dyn Pane>, SplitDirectionAndSize>;
|
||||
pub type Cursor = bintree::Cursor<Rc<dyn Pane>, SplitDirectionAndSize>;
|
||||
pub type Tree = bintree::Tree<Arc<dyn Pane>, SplitDirectionAndSize>;
|
||||
pub type Cursor = bintree::Cursor<Arc<dyn Pane>, SplitDirectionAndSize>;
|
||||
|
||||
static TAB_ID: ::std::sync::atomic::AtomicUsize = ::std::sync::atomic::AtomicUsize::new(0);
|
||||
pub type TabId = usize;
|
||||
@ -43,7 +43,7 @@ pub struct Tab {
|
||||
pane: RefCell<Option<Tree>>,
|
||||
size: RefCell<TerminalSize>,
|
||||
active: RefCell<usize>,
|
||||
zoomed: RefCell<Option<Rc<dyn Pane>>>,
|
||||
zoomed: RefCell<Option<Arc<dyn Pane>>>,
|
||||
title: RefCell<String>,
|
||||
recency: RefCell<Recency>,
|
||||
}
|
||||
@ -69,7 +69,7 @@ pub struct PositionedPane {
|
||||
pub height: usize,
|
||||
pub pixel_height: usize,
|
||||
/// The pane instance
|
||||
pub pane: Rc<dyn Pane>,
|
||||
pub pane: Arc<dyn Pane>,
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for PositionedPane {
|
||||
@ -199,7 +199,7 @@ pub struct PositionedSplit {
|
||||
pub size: usize,
|
||||
}
|
||||
|
||||
fn is_pane(pane: &Rc<dyn Pane>, other: &Option<&Rc<dyn Pane>>) -> bool {
|
||||
fn is_pane(pane: &Arc<dyn Pane>, other: &Option<&Arc<dyn Pane>>) -> bool {
|
||||
if let Some(other) = other {
|
||||
other.pane_id() == pane.pane_id()
|
||||
} else {
|
||||
@ -211,8 +211,8 @@ fn pane_tree(
|
||||
tree: &Tree,
|
||||
tab_id: TabId,
|
||||
window_id: WindowId,
|
||||
active: Option<&Rc<dyn Pane>>,
|
||||
zoomed: Option<&Rc<dyn Pane>>,
|
||||
active: Option<&Arc<dyn Pane>>,
|
||||
zoomed: Option<&Arc<dyn Pane>>,
|
||||
workspace: &str,
|
||||
left_col: usize,
|
||||
top_row: usize,
|
||||
@ -278,12 +278,12 @@ fn pane_tree(
|
||||
|
||||
fn build_from_pane_tree<F>(
|
||||
tree: bintree::Tree<PaneEntry, SplitDirectionAndSize>,
|
||||
active: &mut Option<Rc<dyn Pane>>,
|
||||
zoomed: &mut Option<Rc<dyn Pane>>,
|
||||
active: &mut Option<Arc<dyn Pane>>,
|
||||
zoomed: &mut Option<Arc<dyn Pane>>,
|
||||
make_pane: &mut F,
|
||||
) -> Tree
|
||||
where
|
||||
F: FnMut(PaneEntry) -> Rc<dyn Pane>,
|
||||
F: FnMut(PaneEntry) -> Arc<dyn Pane>,
|
||||
{
|
||||
match tree {
|
||||
bintree::Tree::Empty => Tree::Empty,
|
||||
@ -297,10 +297,10 @@ where
|
||||
let is_active_pane = entry.is_active_pane;
|
||||
let pane = make_pane(entry);
|
||||
if is_zoomed_pane {
|
||||
zoomed.replace(Rc::clone(&pane));
|
||||
zoomed.replace(Arc::clone(&pane));
|
||||
}
|
||||
if is_active_pane {
|
||||
active.replace(Rc::clone(&pane));
|
||||
active.replace(Arc::clone(&pane));
|
||||
}
|
||||
Tree::Leaf(pane)
|
||||
}
|
||||
@ -533,7 +533,7 @@ impl Tab {
|
||||
/// a new pane, otherwise the pane won't poll/update in the GUI.
|
||||
pub fn sync_with_pane_tree<F>(&self, size: TerminalSize, root: PaneNode, mut make_pane: F)
|
||||
where
|
||||
F: FnMut(PaneEntry) -> Rc<dyn Pane>,
|
||||
F: FnMut(PaneEntry) -> Arc<dyn Pane>,
|
||||
{
|
||||
let mut active = None;
|
||||
let mut zoomed = None;
|
||||
@ -781,7 +781,7 @@ impl Tab {
|
||||
pixel_width: size.pixel_width.into(),
|
||||
height: size.rows.into(),
|
||||
pixel_height: size.pixel_height.into(),
|
||||
pane: Rc::clone(zoomed),
|
||||
pane: Arc::clone(zoomed),
|
||||
});
|
||||
return panes;
|
||||
}
|
||||
@ -813,7 +813,7 @@ impl Tab {
|
||||
}
|
||||
}
|
||||
|
||||
let pane = Rc::clone(cursor.leaf_mut().unwrap());
|
||||
let pane = Arc::clone(cursor.leaf_mut().unwrap());
|
||||
let dims = parent_size.unwrap_or_else(|| *self.size.borrow());
|
||||
|
||||
panes.push(PositionedPane {
|
||||
@ -1366,7 +1366,7 @@ impl Tab {
|
||||
/// Remove pane from tab.
|
||||
/// The pane is still live in the mux; the intent is for the pane to
|
||||
/// be added to a different tab.
|
||||
pub fn remove_pane(&self, pane_id: PaneId) -> Option<Rc<dyn Pane>> {
|
||||
pub fn remove_pane(&self, pane_id: PaneId) -> Option<Arc<dyn Pane>> {
|
||||
let panes = self.remove_pane_if(|_, pane| pane.pane_id() == pane_id, false);
|
||||
for pane in panes {
|
||||
return Some(pane);
|
||||
@ -1374,9 +1374,9 @@ impl Tab {
|
||||
None
|
||||
}
|
||||
|
||||
fn remove_pane_if<F>(&self, f: F, kill: bool) -> Vec<Rc<dyn Pane>>
|
||||
fn remove_pane_if<F>(&self, f: F, kill: bool) -> Vec<Arc<dyn Pane>>
|
||||
where
|
||||
F: Fn(usize, &Rc<dyn Pane>) -> bool,
|
||||
F: Fn(usize, &Arc<dyn Pane>) -> bool,
|
||||
{
|
||||
let mut dead_panes = vec![];
|
||||
let zoomed_pane = self.zoomed.borrow().as_ref().map(|p| p.pane_id());
|
||||
@ -1403,7 +1403,7 @@ impl Tab {
|
||||
};
|
||||
|
||||
if cursor.is_leaf() {
|
||||
let pane = Rc::clone(cursor.leaf_mut().unwrap());
|
||||
let pane = Arc::clone(cursor.leaf_mut().unwrap());
|
||||
if f(pane_index, &pane) {
|
||||
removed_indices.push(pane_index);
|
||||
if Some(pane.pane_id()) == zoomed_pane {
|
||||
@ -1506,15 +1506,15 @@ impl Tab {
|
||||
dead_count == panes.len()
|
||||
}
|
||||
|
||||
pub fn get_active_pane(&self) -> Option<Rc<dyn Pane>> {
|
||||
pub fn get_active_pane(&self) -> Option<Arc<dyn Pane>> {
|
||||
if let Some(zoomed) = self.zoomed.borrow().as_ref() {
|
||||
return Some(Rc::clone(zoomed));
|
||||
return Some(Arc::clone(zoomed));
|
||||
}
|
||||
|
||||
self.iter_panes_ignoring_zoom()
|
||||
.iter()
|
||||
.nth(*self.active.borrow())
|
||||
.map(|p| Rc::clone(&p.pane))
|
||||
.map(|p| Arc::clone(&p.pane))
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
@ -1522,7 +1522,7 @@ impl Tab {
|
||||
*self.active.borrow()
|
||||
}
|
||||
|
||||
pub fn set_active_pane(&self, pane: &Rc<dyn Pane>) {
|
||||
pub fn set_active_pane(&self, pane: &Arc<dyn Pane>) {
|
||||
if let Some(item) = self
|
||||
.iter_panes_ignoring_zoom()
|
||||
.iter()
|
||||
@ -1535,7 +1535,7 @@ impl Tab {
|
||||
}
|
||||
}
|
||||
|
||||
fn advise_focus_change(&self, prior: Option<Rc<dyn Pane>>) {
|
||||
fn advise_focus_change(&self, prior: Option<Arc<dyn Pane>>) {
|
||||
let current = self.get_active_pane();
|
||||
match (prior, current) {
|
||||
(Some(prior), Some(current)) if prior.pane_id() != current.pane_id() => {
|
||||
@ -1564,8 +1564,8 @@ impl Tab {
|
||||
/// Assigns the root pane.
|
||||
/// This is suitable when creating a new tab and then assigning
|
||||
/// the initial pane
|
||||
pub fn assign_pane(&self, pane: &Rc<dyn Pane>) {
|
||||
match Tree::new().cursor().assign_top(Rc::clone(pane)) {
|
||||
pub fn assign_pane(&self, pane: &Arc<dyn Pane>) {
|
||||
match Tree::new().cursor().assign_top(Arc::clone(pane)) {
|
||||
Ok(c) => *self.pane.borrow_mut() = Some(c.tree()),
|
||||
Err(_) => panic!("tried to assign root pane to non-empty tree"),
|
||||
}
|
||||
@ -1731,7 +1731,7 @@ impl Tab {
|
||||
&self,
|
||||
pane_index: usize,
|
||||
request: SplitRequest,
|
||||
pane: Rc<dyn Pane>,
|
||||
pane: Arc<dyn Pane>,
|
||||
) -> anyhow::Result<usize> {
|
||||
if self.zoomed.borrow().is_some() {
|
||||
anyhow::bail!("cannot split while zoomed");
|
||||
@ -1786,9 +1786,9 @@ impl Tab {
|
||||
|
||||
if request.top_level && !cursor.is_leaf() {
|
||||
let result = if request.target_is_second {
|
||||
cursor.split_node_and_insert_right(Rc::clone(&pane))
|
||||
cursor.split_node_and_insert_right(Arc::clone(&pane))
|
||||
} else {
|
||||
cursor.split_node_and_insert_left(Rc::clone(&pane))
|
||||
cursor.split_node_and_insert_left(Arc::clone(&pane))
|
||||
};
|
||||
cursor = match result {
|
||||
Ok(c) => {
|
||||
@ -1820,7 +1820,7 @@ impl Tab {
|
||||
}
|
||||
};
|
||||
|
||||
let existing_pane = Rc::clone(cursor.leaf_mut().unwrap());
|
||||
let existing_pane = Arc::clone(cursor.leaf_mut().unwrap());
|
||||
|
||||
let (pane1, pane2) = if request.target_is_second {
|
||||
(existing_pane, pane)
|
||||
@ -1965,6 +1965,7 @@ impl Into<String> for SerdeUrl {
|
||||
mod test {
|
||||
use super::*;
|
||||
use crate::renderable::*;
|
||||
use parking_lot::{MappedMutexGuard, Mutex};
|
||||
use rangeset::RangeSet;
|
||||
use std::ops::Range;
|
||||
use termwiz::surface::SequenceNo;
|
||||
@ -1974,14 +1975,14 @@ mod test {
|
||||
|
||||
struct FakePane {
|
||||
id: PaneId,
|
||||
size: RefCell<TerminalSize>,
|
||||
size: Mutex<TerminalSize>,
|
||||
}
|
||||
|
||||
impl FakePane {
|
||||
fn new(id: PaneId, size: TerminalSize) -> Rc<dyn Pane> {
|
||||
Rc::new(Self {
|
||||
fn new(id: PaneId, size: TerminalSize) -> Arc<dyn Pane> {
|
||||
Arc::new(Self {
|
||||
id,
|
||||
size: RefCell::new(size),
|
||||
size: Mutex::new(size),
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -2044,11 +2045,11 @@ mod test {
|
||||
fn reader(&self) -> anyhow::Result<Option<Box<dyn std::io::Read + Send>>> {
|
||||
Ok(None)
|
||||
}
|
||||
fn writer(&self) -> RefMut<dyn std::io::Write> {
|
||||
fn writer(&self) -> MappedMutexGuard<dyn std::io::Write> {
|
||||
unimplemented!()
|
||||
}
|
||||
fn resize(&self, size: TerminalSize) -> anyhow::Result<()> {
|
||||
*self.size.borrow_mut() = size;
|
||||
*self.size.lock() = size;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -16,9 +16,9 @@ use async_trait::async_trait;
|
||||
use config::keyassignment::ScrollbackEraseMode;
|
||||
use crossbeam::channel::{unbounded as channel, Receiver, Sender};
|
||||
use filedescriptor::{FileDescriptor, Pipe};
|
||||
use parking_lot::{MappedMutexGuard, Mutex, MutexGuard};
|
||||
use portable_pty::*;
|
||||
use rangeset::RangeSet;
|
||||
use std::cell::{RefCell, RefMut};
|
||||
use std::io::{BufWriter, Write};
|
||||
use std::ops::Range;
|
||||
use std::rc::Rc;
|
||||
@ -53,7 +53,7 @@ impl Domain for TermWizTerminalDomain {
|
||||
_size: TerminalSize,
|
||||
_command: Option<CommandBuilder>,
|
||||
_command_dir: Option<String>,
|
||||
) -> anyhow::Result<Rc<dyn Pane>> {
|
||||
) -> anyhow::Result<Arc<dyn Pane>> {
|
||||
bail!("cannot spawn panes in a TermWizTerminalPane");
|
||||
}
|
||||
|
||||
@ -84,10 +84,10 @@ impl Domain for TermWizTerminalDomain {
|
||||
pub struct TermWizTerminalPane {
|
||||
pane_id: PaneId,
|
||||
domain_id: DomainId,
|
||||
terminal: RefCell<wezterm_term::Terminal>,
|
||||
terminal: Mutex<wezterm_term::Terminal>,
|
||||
input_tx: Sender<InputEvent>,
|
||||
dead: RefCell<bool>,
|
||||
writer: RefCell<Vec<u8>>,
|
||||
dead: Mutex<bool>,
|
||||
writer: Mutex<Vec<u8>>,
|
||||
render_rx: FileDescriptor,
|
||||
}
|
||||
|
||||
@ -101,7 +101,7 @@ impl TermWizTerminalPane {
|
||||
) -> Self {
|
||||
let pane_id = alloc_pane_id();
|
||||
|
||||
let terminal = RefCell::new(wezterm_term::Terminal::new(
|
||||
let terminal = Mutex::new(wezterm_term::Terminal::new(
|
||||
size,
|
||||
term_config.unwrap_or_else(|| Arc::new(config::TermConfig::new())),
|
||||
"WezTerm",
|
||||
@ -113,10 +113,10 @@ impl TermWizTerminalPane {
|
||||
pane_id,
|
||||
domain_id,
|
||||
terminal,
|
||||
writer: RefCell::new(Vec::new()),
|
||||
writer: Mutex::new(Vec::new()),
|
||||
render_rx,
|
||||
input_tx,
|
||||
dead: RefCell::new(false),
|
||||
dead: Mutex::new(false),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -127,11 +127,11 @@ impl Pane for TermWizTerminalPane {
|
||||
}
|
||||
|
||||
fn get_cursor_position(&self) -> StableCursorPosition {
|
||||
terminal_get_cursor_position(&mut self.terminal.borrow_mut())
|
||||
terminal_get_cursor_position(&mut self.terminal.lock())
|
||||
}
|
||||
|
||||
fn get_current_seqno(&self) -> SequenceNo {
|
||||
self.terminal.borrow().current_seqno()
|
||||
self.terminal.lock().current_seqno()
|
||||
}
|
||||
|
||||
fn get_changed_since(
|
||||
@ -139,7 +139,7 @@ impl Pane for TermWizTerminalPane {
|
||||
lines: Range<StableRowIndex>,
|
||||
seqno: SequenceNo,
|
||||
) -> RangeSet<StableRowIndex> {
|
||||
terminal_get_dirty_lines(&mut self.terminal.borrow_mut(), lines, seqno)
|
||||
terminal_get_dirty_lines(&mut self.terminal.lock(), lines, seqno)
|
||||
}
|
||||
|
||||
fn for_each_logical_line_in_stable_range_mut(
|
||||
@ -148,7 +148,7 @@ impl Pane for TermWizTerminalPane {
|
||||
for_line: &mut dyn ForEachPaneLogicalLine,
|
||||
) {
|
||||
terminal_for_each_logical_line_in_stable_range_mut(
|
||||
&mut self.terminal.borrow_mut(),
|
||||
&mut self.terminal.lock(),
|
||||
lines,
|
||||
for_line,
|
||||
);
|
||||
@ -159,19 +159,19 @@ impl Pane for TermWizTerminalPane {
|
||||
}
|
||||
|
||||
fn with_lines_mut(&self, lines: Range<StableRowIndex>, with_lines: &mut dyn WithPaneLines) {
|
||||
terminal_with_lines_mut(&mut self.terminal.borrow_mut(), lines, with_lines)
|
||||
terminal_with_lines_mut(&mut self.terminal.lock(), lines, with_lines)
|
||||
}
|
||||
|
||||
fn get_lines(&self, lines: Range<StableRowIndex>) -> (StableRowIndex, Vec<Line>) {
|
||||
terminal_get_lines(&mut self.terminal.borrow_mut(), lines)
|
||||
terminal_get_lines(&mut self.terminal.lock(), lines)
|
||||
}
|
||||
|
||||
fn get_dimensions(&self) -> RenderableDimensions {
|
||||
terminal_get_dimensions(&mut self.terminal.borrow_mut())
|
||||
terminal_get_dimensions(&mut self.terminal.lock())
|
||||
}
|
||||
|
||||
fn get_title(&self) -> String {
|
||||
self.terminal.borrow_mut().get_title().to_string()
|
||||
self.terminal.lock().get_title().to_string()
|
||||
}
|
||||
|
||||
fn can_close_without_prompting(&self, _reason: CloseReason) -> bool {
|
||||
@ -188,8 +188,11 @@ impl Pane for TermWizTerminalPane {
|
||||
Ok(Some(Box::new(self.render_rx.try_clone()?)))
|
||||
}
|
||||
|
||||
fn writer(&self) -> RefMut<dyn std::io::Write> {
|
||||
self.writer.borrow_mut()
|
||||
fn writer(&self) -> MappedMutexGuard<dyn std::io::Write> {
|
||||
MutexGuard::map(self.writer.lock(), |writer| {
|
||||
let w: &mut dyn std::io::Write = writer;
|
||||
w
|
||||
})
|
||||
}
|
||||
|
||||
fn resize(&self, size: TerminalSize) -> anyhow::Result<()> {
|
||||
@ -198,7 +201,7 @@ impl Pane for TermWizTerminalPane {
|
||||
cols: size.cols as usize,
|
||||
})?;
|
||||
|
||||
self.terminal.borrow_mut().resize(size);
|
||||
self.terminal.lock().resize(size);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@ -206,7 +209,7 @@ impl Pane for TermWizTerminalPane {
|
||||
fn key_down(&self, key: KeyCode, modifiers: KeyModifiers) -> anyhow::Result<()> {
|
||||
let event = InputEvent::Key(KeyEvent { key, modifiers });
|
||||
if let Err(e) = self.input_tx.send(event) {
|
||||
*self.dead.borrow_mut() = true;
|
||||
*self.dead.lock() = true;
|
||||
return Err(e.into());
|
||||
}
|
||||
Ok(())
|
||||
@ -236,34 +239,34 @@ impl Pane for TermWizTerminalPane {
|
||||
modifiers: event.modifiers,
|
||||
});
|
||||
if let Err(e) = self.input_tx.send(event) {
|
||||
*self.dead.borrow_mut() = true;
|
||||
*self.dead.lock() = true;
|
||||
return Err(e.into());
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn set_config(&self, config: Arc<dyn TerminalConfiguration>) {
|
||||
self.terminal.borrow_mut().set_config(config);
|
||||
self.terminal.lock().set_config(config);
|
||||
}
|
||||
|
||||
fn get_config(&self) -> Option<Arc<dyn TerminalConfiguration>> {
|
||||
Some(self.terminal.borrow().get_config())
|
||||
Some(self.terminal.lock().get_config())
|
||||
}
|
||||
|
||||
fn perform_actions(&self, actions: Vec<termwiz::escape::Action>) {
|
||||
self.terminal.borrow_mut().perform_actions(actions)
|
||||
self.terminal.lock().perform_actions(actions)
|
||||
}
|
||||
|
||||
fn kill(&self) {
|
||||
*self.dead.borrow_mut() = true;
|
||||
*self.dead.lock() = true;
|
||||
}
|
||||
|
||||
fn is_dead(&self) -> bool {
|
||||
*self.dead.borrow()
|
||||
*self.dead.lock()
|
||||
}
|
||||
|
||||
fn palette(&self) -> ColorPalette {
|
||||
self.terminal.borrow().palette()
|
||||
self.terminal.lock().palette()
|
||||
}
|
||||
|
||||
fn domain_id(&self) -> DomainId {
|
||||
@ -271,24 +274,24 @@ impl Pane for TermWizTerminalPane {
|
||||
}
|
||||
|
||||
fn is_mouse_grabbed(&self) -> bool {
|
||||
self.terminal.borrow().is_mouse_grabbed()
|
||||
self.terminal.lock().is_mouse_grabbed()
|
||||
}
|
||||
|
||||
fn is_alt_screen_active(&self) -> bool {
|
||||
self.terminal.borrow().is_alt_screen_active()
|
||||
self.terminal.lock().is_alt_screen_active()
|
||||
}
|
||||
|
||||
fn get_current_working_dir(&self) -> Option<Url> {
|
||||
self.terminal.borrow().get_current_dir().cloned()
|
||||
self.terminal.lock().get_current_dir().cloned()
|
||||
}
|
||||
|
||||
fn erase_scrollback(&self, erase_mode: ScrollbackEraseMode) {
|
||||
match erase_mode {
|
||||
ScrollbackEraseMode::ScrollbackOnly => {
|
||||
self.terminal.borrow_mut().erase_scrollback();
|
||||
self.terminal.lock().erase_scrollback();
|
||||
}
|
||||
ScrollbackEraseMode::ScrollbackAndViewport => {
|
||||
self.terminal.borrow_mut().erase_scrollback_and_viewport();
|
||||
self.terminal.lock().erase_scrollback_and_viewport();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -435,7 +438,7 @@ impl termwiz::terminal::Terminal for TermWizTerminal {
|
||||
pub fn allocate(
|
||||
size: TerminalSize,
|
||||
config: Arc<dyn TerminalConfiguration + Send + Sync>,
|
||||
) -> (TermWizTerminal, Rc<dyn Pane>) {
|
||||
) -> (TermWizTerminal, Arc<dyn Pane>) {
|
||||
let render_pipe = Pipe::new().expect("Pipe creation not to fail");
|
||||
|
||||
let (input_tx, input_rx) = channel();
|
||||
@ -461,7 +464,7 @@ pub fn allocate(
|
||||
let pane = TermWizTerminalPane::new(domain_id, size, input_tx, render_pipe.read, Some(config));
|
||||
|
||||
// Add the tab to the mux so that the output is processed
|
||||
let pane: Rc<dyn Pane> = Rc::new(pane);
|
||||
let pane: Arc<dyn Pane> = Arc::new(pane);
|
||||
|
||||
let mux = Mux::get().unwrap();
|
||||
mux.add_pane(&pane).expect("to be able to add pane to mux");
|
||||
@ -530,7 +533,7 @@ pub async fn run<
|
||||
|
||||
let pane =
|
||||
TermWizTerminalPane::new(domain.domain_id(), size, input_tx, render_rx, term_config);
|
||||
let pane: Rc<dyn Pane> = Rc::new(pane);
|
||||
let pane: Arc<dyn Pane> = Arc::new(pane);
|
||||
|
||||
let tab = Rc::new(Tab::new(&size));
|
||||
tab.assign_pane(&pane);
|
||||
|
@ -5,12 +5,11 @@ use crate::tmux_commands::{ListAllPanes, TmuxCommand};
|
||||
use crate::{Mux, MuxWindowBuilder};
|
||||
use async_trait::async_trait;
|
||||
use filedescriptor::FileDescriptor;
|
||||
use parking_lot::{Condvar, Mutex};
|
||||
use portable_pty::CommandBuilder;
|
||||
use std::cell::RefCell;
|
||||
use std::collections::{HashMap, HashSet, VecDeque};
|
||||
use std::io::Write;
|
||||
use std::rc::Rc;
|
||||
use std::sync::{Arc, Condvar, Mutex};
|
||||
use std::sync::Arc;
|
||||
use termwiz::tmux_cc::*;
|
||||
use wezterm_term::TerminalSize;
|
||||
|
||||
@ -55,12 +54,12 @@ pub(crate) type TmuxCmdQueue = VecDeque<Box<dyn TmuxCommand>>;
|
||||
pub(crate) struct TmuxDomainState {
|
||||
pub pane_id: PaneId, // ID of the original pane
|
||||
pub domain_id: DomainId, // ID of TmuxDomain
|
||||
state: RefCell<State>,
|
||||
state: Mutex<State>,
|
||||
pub cmd_queue: Arc<Mutex<TmuxCmdQueue>>,
|
||||
pub gui_window: RefCell<Option<MuxWindowBuilder>>,
|
||||
pub gui_tabs: RefCell<Vec<TmuxTab>>,
|
||||
pub remote_panes: RefCell<HashMap<TmuxPaneId, RefTmuxRemotePane>>,
|
||||
pub tmux_session: RefCell<Option<TmuxSessionId>>,
|
||||
pub gui_window: Mutex<Option<MuxWindowBuilder>>,
|
||||
pub gui_tabs: Mutex<Vec<TmuxTab>>,
|
||||
pub remote_panes: Mutex<HashMap<TmuxPaneId, RefTmuxRemotePane>>,
|
||||
pub tmux_session: Mutex<Option<TmuxSessionId>>,
|
||||
}
|
||||
|
||||
pub struct TmuxDomain {
|
||||
@ -70,18 +69,18 @@ pub struct TmuxDomain {
|
||||
impl TmuxDomainState {
|
||||
pub fn advance(&self, events: Box<Vec<Event>>) {
|
||||
for event in events.iter() {
|
||||
let state = *self.state.borrow();
|
||||
let state = *self.state.lock();
|
||||
log::info!("tmux: {:?} in state {:?}", event, state);
|
||||
match event {
|
||||
Event::Guarded(response) => match state {
|
||||
State::WaitForInitialGuard => {
|
||||
*self.state.borrow_mut() = State::Idle;
|
||||
*self.state.lock() = State::Idle;
|
||||
}
|
||||
State::WaitingForResponse => {
|
||||
let mut cmd_queue = self.cmd_queue.as_ref().lock().unwrap();
|
||||
let mut cmd_queue = self.cmd_queue.as_ref().lock();
|
||||
let cmd = cmd_queue.pop_front().unwrap();
|
||||
let domain_id = self.domain_id;
|
||||
*self.state.borrow_mut() = State::Idle;
|
||||
*self.state.lock() = State::Idle;
|
||||
let resp = response.clone();
|
||||
promise::spawn::spawn(async move {
|
||||
if let Err(err) = cmd.process_result(domain_id, &resp) {
|
||||
@ -93,9 +92,9 @@ impl TmuxDomainState {
|
||||
State::Idle => {}
|
||||
},
|
||||
Event::Output { pane, text } => {
|
||||
let pane_map = self.remote_panes.borrow_mut();
|
||||
let pane_map = self.remote_panes.lock();
|
||||
if let Some(ref_pane) = pane_map.get(pane) {
|
||||
let mut tmux_pane = ref_pane.lock().unwrap();
|
||||
let mut tmux_pane = ref_pane.lock();
|
||||
if let Err(err) = tmux_pane.output_write.write_all(text.as_bytes()) {
|
||||
log::error!("Failed to write tmux data to output: {:#}", err);
|
||||
}
|
||||
@ -107,15 +106,15 @@ impl TmuxDomainState {
|
||||
self.create_gui_window();
|
||||
}
|
||||
Event::SessionChanged { session, name: _ } => {
|
||||
*self.tmux_session.borrow_mut() = Some(*session);
|
||||
*self.tmux_session.lock() = Some(*session);
|
||||
log::info!("tmux session changed:{}", session);
|
||||
}
|
||||
Event::Exit { reason: _ } => {
|
||||
let mut pane_map = self.remote_panes.borrow_mut();
|
||||
let mut pane_map = self.remote_panes.lock();
|
||||
for (_, v) in pane_map.iter_mut() {
|
||||
let remote_pane = v.lock().unwrap();
|
||||
let remote_pane = v.lock();
|
||||
let (lock, condvar) = &*remote_pane.active_lock;
|
||||
let mut released = lock.lock().unwrap();
|
||||
let mut released = lock.lock();
|
||||
*released = true;
|
||||
condvar.notify_all();
|
||||
}
|
||||
@ -125,8 +124,8 @@ impl TmuxDomainState {
|
||||
}
|
||||
|
||||
// send pending commands to tmux
|
||||
let cmd_queue = self.cmd_queue.as_ref().lock().unwrap();
|
||||
if *self.state.borrow() == State::Idle && !cmd_queue.is_empty() {
|
||||
let cmd_queue = self.cmd_queue.as_ref().lock();
|
||||
if *self.state.lock() == State::Idle && !cmd_queue.is_empty() {
|
||||
TmuxDomainState::schedule_send_next_command(self.domain_id);
|
||||
}
|
||||
}
|
||||
@ -134,10 +133,10 @@ impl TmuxDomainState {
|
||||
/// send next command at the front of cmd_queue.
|
||||
/// must be called inside main thread
|
||||
fn send_next_command(&self) {
|
||||
if *self.state.borrow() != State::Idle {
|
||||
if *self.state.lock() != State::Idle {
|
||||
return;
|
||||
}
|
||||
let cmd_queue = self.cmd_queue.as_ref().lock().unwrap();
|
||||
let cmd_queue = self.cmd_queue.as_ref().lock();
|
||||
if let Some(first) = cmd_queue.front() {
|
||||
let cmd = first.get_command();
|
||||
log::info!("sending cmd {:?}", cmd);
|
||||
@ -146,7 +145,7 @@ impl TmuxDomainState {
|
||||
let mut writer = pane.writer();
|
||||
let _ = write!(writer, "{}", cmd);
|
||||
}
|
||||
*self.state.borrow_mut() = State::WaitingForResponse;
|
||||
*self.state.lock() = State::WaitingForResponse;
|
||||
}
|
||||
}
|
||||
|
||||
@ -165,12 +164,12 @@ impl TmuxDomainState {
|
||||
|
||||
/// create a standalone window for tmux tabs
|
||||
pub fn create_gui_window(&self) {
|
||||
if self.gui_window.borrow().is_none() {
|
||||
if self.gui_window.lock().is_none() {
|
||||
let mux = Mux::get().expect("should be call at main thread");
|
||||
let window_builder = mux.new_empty_window(None /* TODO: pass session here */);
|
||||
log::info!("Tmux create window id {}", window_builder.window_id);
|
||||
{
|
||||
let mut window_id = self.gui_window.borrow_mut();
|
||||
let mut window_id = self.gui_window.lock();
|
||||
*window_id = Some(window_builder); // keep the builder so it won't be purged
|
||||
}
|
||||
};
|
||||
@ -180,19 +179,18 @@ impl TmuxDomainState {
|
||||
impl TmuxDomain {
|
||||
pub fn new(pane_id: PaneId) -> Self {
|
||||
let domain_id = alloc_domain_id();
|
||||
// let parser = RefCell::new(Parser::new());
|
||||
let mut cmd_queue = VecDeque::<Box<dyn TmuxCommand>>::new();
|
||||
cmd_queue.push_back(Box::new(ListAllPanes));
|
||||
let inner = Arc::new(TmuxDomainState {
|
||||
domain_id,
|
||||
pane_id,
|
||||
// parser,
|
||||
state: RefCell::new(State::WaitForInitialGuard),
|
||||
state: Mutex::new(State::WaitForInitialGuard),
|
||||
cmd_queue: Arc::new(Mutex::new(cmd_queue)),
|
||||
gui_window: RefCell::new(None),
|
||||
gui_tabs: RefCell::new(Vec::default()),
|
||||
remote_panes: RefCell::new(HashMap::default()),
|
||||
tmux_session: RefCell::new(None),
|
||||
gui_window: Mutex::new(None),
|
||||
gui_tabs: Mutex::new(Vec::default()),
|
||||
remote_panes: Mutex::new(HashMap::default()),
|
||||
tmux_session: Mutex::new(None),
|
||||
});
|
||||
|
||||
Self { inner }
|
||||
@ -210,7 +208,7 @@ impl Domain for TmuxDomain {
|
||||
_size: TerminalSize,
|
||||
_command: Option<CommandBuilder>,
|
||||
_command_dir: Option<String>,
|
||||
) -> anyhow::Result<Rc<dyn Pane>> {
|
||||
) -> anyhow::Result<Arc<dyn Pane>> {
|
||||
anyhow::bail!("Spawn_pane not yet implemented for TmuxDomain");
|
||||
}
|
||||
|
||||
|
@ -6,12 +6,13 @@ use crate::tmux::{TmuxDomain, TmuxDomainState, TmuxRemotePane, TmuxTab};
|
||||
use crate::tmux_pty::{TmuxChild, TmuxPty};
|
||||
use crate::{Mux, Pane};
|
||||
use anyhow::{anyhow, Context};
|
||||
use parking_lot::{Condvar, Mutex};
|
||||
use portable_pty::{MasterPty, PtySize};
|
||||
use std::collections::HashSet;
|
||||
use std::fmt::{Debug, Write};
|
||||
use std::io::Write as _;
|
||||
use std::rc::Rc;
|
||||
use std::sync::{Arc, Condvar, Mutex};
|
||||
use std::sync::Arc;
|
||||
use termwiz::tmux_cc::*;
|
||||
use wezterm_term::TerminalSize;
|
||||
|
||||
@ -37,7 +38,7 @@ pub(crate) struct PaneItem {
|
||||
impl TmuxDomainState {
|
||||
/// check if a PaneItem received from ListAllPanes has been attached
|
||||
fn check_pane_attached(&self, target: &PaneItem) -> bool {
|
||||
let pane_list = self.gui_tabs.borrow();
|
||||
let pane_list = self.gui_tabs.lock();
|
||||
let local_tab = match pane_list
|
||||
.iter()
|
||||
.find(|&x| x.tmux_window_id == target.window_id)
|
||||
@ -60,7 +61,7 @@ impl TmuxDomainState {
|
||||
/// after we create a tab for a remote pane, save its ID into the
|
||||
/// TmuxPane-TmuxPane tree, so we can ref it later.
|
||||
fn add_attached_pane(&self, target: &PaneItem, tab_id: &TabId) -> anyhow::Result<()> {
|
||||
let mut pane_list = self.gui_tabs.borrow_mut();
|
||||
let mut pane_list = self.gui_tabs.lock();
|
||||
let local_tab = match pane_list
|
||||
.iter_mut()
|
||||
.find(|x| x.tmux_window_id == target.window_id)
|
||||
@ -92,7 +93,7 @@ impl TmuxDomainState {
|
||||
// 2) create pane if not exist
|
||||
// 3) fetch scroll buffer if new created
|
||||
// 4) update pane state if exist
|
||||
let current_session = self.tmux_session.borrow().unwrap_or(0);
|
||||
let current_session = self.tmux_session.lock().unwrap_or(0);
|
||||
for pane in panes.iter() {
|
||||
if pane.session_id != current_session || self.check_pane_attached(&pane) {
|
||||
continue;
|
||||
@ -118,7 +119,7 @@ impl TmuxDomainState {
|
||||
}));
|
||||
|
||||
{
|
||||
let mut pane_map = self.remote_panes.borrow_mut();
|
||||
let mut pane_map = self.remote_panes.lock();
|
||||
pane_map.insert(pane.pane_id, ref_pane.clone());
|
||||
}
|
||||
|
||||
@ -150,7 +151,7 @@ impl TmuxDomainState {
|
||||
Box::new(writer.clone()),
|
||||
);
|
||||
|
||||
let local_pane: Rc<dyn Pane> = Rc::new(LocalPane::new(
|
||||
let local_pane: Arc<dyn Pane> = Arc::new(LocalPane::new(
|
||||
local_pane_id,
|
||||
terminal,
|
||||
Box::new(child),
|
||||
@ -164,7 +165,7 @@ impl TmuxDomainState {
|
||||
tab.assign_pane(&local_pane);
|
||||
|
||||
self.create_gui_window();
|
||||
let mut gui_window = self.gui_window.borrow_mut();
|
||||
let mut gui_window = self.gui_window.lock();
|
||||
let gui_window_id = match gui_window.as_mut() {
|
||||
Some(x) => x,
|
||||
None => {
|
||||
@ -178,7 +179,6 @@ impl TmuxDomainState {
|
||||
|
||||
self.cmd_queue
|
||||
.lock()
|
||||
.unwrap()
|
||||
.push_back(Box::new(CapturePane(pane.pane_id)));
|
||||
TmuxDomainState::schedule_send_next_command(self.domain_id);
|
||||
|
||||
@ -314,9 +314,9 @@ impl TmuxCommand for CapturePane {
|
||||
// capturep contents returned from guarded lines which always contain a tailing '\n'
|
||||
let unescaped = &unescaped[0..unescaped.len().saturating_sub(1)].replace("\n", "\r\n");
|
||||
|
||||
let pane_map = tmux_domain.inner.remote_panes.borrow();
|
||||
let pane_map = tmux_domain.inner.remote_panes.lock();
|
||||
if let Some(pane) = pane_map.get(&self.0) {
|
||||
let mut pane = pane.lock().expect("Grant lock of tmux cmd queue failed");
|
||||
let mut pane = pane.lock();
|
||||
pane.output_write
|
||||
.write_all(unescaped.as_bytes())
|
||||
.context("writing capture pane result to output")?;
|
||||
|
@ -2,9 +2,10 @@ use crate::tmux::{RefTmuxRemotePane, TmuxCmdQueue, TmuxDomainState};
|
||||
use crate::tmux_commands::{Resize, SendKeys};
|
||||
use crate::DomainId;
|
||||
use filedescriptor::FileDescriptor;
|
||||
use parking_lot::{Condvar, Mutex};
|
||||
use portable_pty::{Child, ChildKiller, ExitStatus, MasterPty};
|
||||
use std::io::{Read, Write};
|
||||
use std::sync::{Arc, Condvar, Mutex};
|
||||
use std::sync::Arc;
|
||||
|
||||
/// A local tmux pane(tab) based on a tmux pty
|
||||
#[derive(Debug)]
|
||||
@ -24,11 +25,11 @@ struct TmuxPtyWriter {
|
||||
impl Write for TmuxPtyWriter {
|
||||
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
|
||||
let pane_id = {
|
||||
let pane_lock = self.master_pane.lock().unwrap();
|
||||
let pane_lock = self.master_pane.lock();
|
||||
pane_lock.pane_id
|
||||
};
|
||||
log::trace!("pane:{}, content:{:?}", &pane_id, buf);
|
||||
let mut cmd_queue = self.cmd_queue.lock().unwrap();
|
||||
let mut cmd_queue = self.cmd_queue.lock();
|
||||
cmd_queue.push_back(Box::new(SendKeys {
|
||||
pane: pane_id,
|
||||
keys: buf.to_vec(),
|
||||
@ -45,11 +46,11 @@ impl Write for TmuxPtyWriter {
|
||||
impl Write for TmuxPty {
|
||||
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
|
||||
let pane_id = {
|
||||
let pane_lock = self.master_pane.lock().unwrap();
|
||||
let pane_lock = self.master_pane.lock();
|
||||
pane_lock.pane_id
|
||||
};
|
||||
log::trace!("pane:{}, content:{:?}", &pane_id, buf);
|
||||
let mut cmd_queue = self.cmd_queue.lock().unwrap();
|
||||
let mut cmd_queue = self.cmd_queue.lock();
|
||||
cmd_queue.push_back(Box::new(SendKeys {
|
||||
pane: pane_id,
|
||||
keys: buf.to_vec(),
|
||||
@ -74,10 +75,10 @@ impl Child for TmuxChild {
|
||||
}
|
||||
|
||||
fn wait(&mut self) -> std::io::Result<portable_pty::ExitStatus> {
|
||||
let (lock, var) = &*self.active_lock;
|
||||
let mut released = lock.lock().unwrap();
|
||||
let &(ref lock, ref var) = &*self.active_lock;
|
||||
let mut released = lock.lock();
|
||||
while !*released {
|
||||
released = var.wait(released).unwrap();
|
||||
var.wait(&mut released);
|
||||
}
|
||||
return Ok(ExitStatus::with_exit_code(0));
|
||||
}
|
||||
@ -123,14 +124,14 @@ impl ChildKiller for TmuxChild {
|
||||
|
||||
impl MasterPty for TmuxPty {
|
||||
fn resize(&self, size: portable_pty::PtySize) -> Result<(), anyhow::Error> {
|
||||
let mut cmd_queue = self.cmd_queue.lock().unwrap();
|
||||
let mut cmd_queue = self.cmd_queue.lock();
|
||||
cmd_queue.push_back(Box::new(Resize { size }));
|
||||
TmuxDomainState::schedule_send_next_command(self.domain_id);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn get_size(&self) -> Result<portable_pty::PtySize, anyhow::Error> {
|
||||
let pane = self.master_pane.lock().unwrap();
|
||||
let pane = self.master_pane.lock();
|
||||
Ok(portable_pty::PtySize {
|
||||
rows: pane.pane_height as u16,
|
||||
cols: pane.pane_width as u16,
|
||||
|
@ -131,7 +131,7 @@ impl Default for NewlineCanon {
|
||||
/// The configuration can be changed at runtime; provided that the implementation
|
||||
/// increments the generation counter appropriately, the changes will be detected
|
||||
/// and applied at the next appropriate opportunity.
|
||||
pub trait TerminalConfiguration: std::fmt::Debug {
|
||||
pub trait TerminalConfiguration: std::fmt::Debug + Send + Sync {
|
||||
/// Returns a generation counter for the active
|
||||
/// configuration. If the implementation may be
|
||||
/// changed at runtime, it must increment the generation
|
||||
|
@ -10,7 +10,7 @@ pub enum ClipboardSelection {
|
||||
PrimarySelection,
|
||||
}
|
||||
|
||||
pub trait Clipboard {
|
||||
pub trait Clipboard: Send + Sync {
|
||||
fn set_contents(
|
||||
&self,
|
||||
selection: ClipboardSelection,
|
||||
@ -28,7 +28,7 @@ impl Clipboard for Box<dyn Clipboard> {
|
||||
}
|
||||
}
|
||||
|
||||
pub trait DeviceControlHandler {
|
||||
pub trait DeviceControlHandler: Send + Sync {
|
||||
fn handle_device_control(&mut self, _control: termwiz::escape::DeviceControlMode);
|
||||
}
|
||||
|
||||
@ -61,11 +61,11 @@ pub enum Alert {
|
||||
OutputSinceFocusLost,
|
||||
}
|
||||
|
||||
pub trait AlertHandler {
|
||||
pub trait AlertHandler: Send + Sync {
|
||||
fn alert(&mut self, alert: Alert);
|
||||
}
|
||||
|
||||
pub trait DownloadHandler {
|
||||
pub trait DownloadHandler: Send + Sync {
|
||||
fn save_to_downloads(&self, name: Option<String>, data: Vec<u8>);
|
||||
}
|
||||
|
||||
@ -132,7 +132,7 @@ impl Terminal {
|
||||
/// are answerback responses to a number of escape sequences.
|
||||
pub fn new(
|
||||
size: TerminalSize,
|
||||
config: Arc<dyn TerminalConfiguration>,
|
||||
config: Arc<dyn TerminalConfiguration + Send + Sync>,
|
||||
term_program: &str,
|
||||
term_version: &str,
|
||||
// writing to the writer sends data to input of the pty
|
||||
|
@ -1,5 +1,6 @@
|
||||
use crate::input::*;
|
||||
use crate::TerminalState;
|
||||
use std::io::Write;
|
||||
use termwiz::input::{KeyCodeEncodeModes, KeyboardEncoding};
|
||||
|
||||
impl TerminalState {
|
||||
|
@ -6,6 +6,7 @@ use ::image::{
|
||||
};
|
||||
use anyhow::Context;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::io::Write;
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
use termwiz::escape::apc::{
|
||||
|
@ -7,6 +7,7 @@ use crate::config::{BidiMode, NewlineCanon};
|
||||
use log::debug;
|
||||
use num_traits::ToPrimitive;
|
||||
use std::collections::HashMap;
|
||||
use std::io::{BufWriter, Write};
|
||||
use std::sync::mpsc::{channel, Sender};
|
||||
use std::sync::Arc;
|
||||
use terminfo::{Database, Value};
|
||||
@ -350,7 +351,7 @@ pub struct TerminalState {
|
||||
term_program: String,
|
||||
term_version: String,
|
||||
|
||||
writer: Box<dyn std::io::Write>,
|
||||
writer: BufWriter<ThreadedWriter>,
|
||||
|
||||
image_cache: lru::LruCache<[u8; 32], Arc<ImageData>>,
|
||||
sixel_scrolls_right: bool,
|
||||
@ -498,7 +499,7 @@ impl TerminalState {
|
||||
term_version: &str,
|
||||
writer: Box<dyn std::io::Write + Send>,
|
||||
) -> TerminalState {
|
||||
let writer = Box::new(ThreadedWriter::new(writer));
|
||||
let writer = BufWriter::new(ThreadedWriter::new(writer));
|
||||
let seqno = 1;
|
||||
let screen = ScreenOrAlt::new(size, &config, seqno, config.bidi_mode());
|
||||
|
||||
@ -559,7 +560,7 @@ impl TerminalState {
|
||||
current_dir: None,
|
||||
term_program: term_program.to_string(),
|
||||
term_version: term_version.to_string(),
|
||||
writer: Box::new(std::io::BufWriter::new(writer)),
|
||||
writer,
|
||||
image_cache: lru::LruCache::new(16),
|
||||
user_vars: HashMap::new(),
|
||||
kitty_img: Default::default(),
|
||||
|
@ -2,6 +2,7 @@ use crate::input::*;
|
||||
use crate::terminalstate::MouseEncoding;
|
||||
use crate::TerminalState;
|
||||
use anyhow::bail;
|
||||
use std::io::Write;
|
||||
|
||||
impl TerminalState {
|
||||
/// Encode a coordinate value using X10 encoding or Utf8 encoding.
|
||||
|
@ -8,6 +8,7 @@ use log::{debug, error};
|
||||
use num_traits::FromPrimitive;
|
||||
use ordered_float::NotNan;
|
||||
use std::fmt::Write;
|
||||
use std::io::Write as _;
|
||||
use std::ops::{Deref, DerefMut};
|
||||
use termwiz::cell::{grapheme_column_width, Cell, CellAttributes, SemanticType};
|
||||
use termwiz::escape::csi::{
|
||||
|
@ -9,21 +9,20 @@ mod csi;
|
||||
// mod selection; FIXME: port to render layer
|
||||
use crate::color::ColorPalette;
|
||||
use k9::assert_equal as assert_eq;
|
||||
use std::cell::RefCell;
|
||||
use std::sync::Arc;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use termwiz::escape::csi::{Edit, EraseInDisplay, EraseInLine};
|
||||
use termwiz::escape::{OneBased, OperatingSystemCommand, CSI};
|
||||
use termwiz::surface::{CursorShape, CursorVisibility, SequenceNo, SEQ_ZERO};
|
||||
|
||||
#[derive(Debug)]
|
||||
struct LocalClip {
|
||||
clip: RefCell<Option<String>>,
|
||||
clip: Mutex<Option<String>>,
|
||||
}
|
||||
|
||||
impl LocalClip {
|
||||
fn new() -> Self {
|
||||
Self {
|
||||
clip: RefCell::new(None),
|
||||
clip: Mutex::new(None),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -34,7 +33,7 @@ impl Clipboard for LocalClip {
|
||||
_selection: ClipboardSelection,
|
||||
clip: Option<String>,
|
||||
) -> anyhow::Result<()> {
|
||||
*self.clip.borrow_mut() = clip;
|
||||
*self.clip.lock().unwrap() = clip;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
@ -27,6 +27,7 @@ mux = { path = "../mux" }
|
||||
# https://github.com/sfackler/rust-openssl/pull/1578
|
||||
# https://github.com/wez/libssh-rs/blob/main/libssh-rs-sys/Cargo.toml
|
||||
openssl = "=0.10.38"
|
||||
parking_lot = "0.12"
|
||||
portable-pty = { path = "../pty", features = ["serde_support"]}
|
||||
promise = { path = "../promise" }
|
||||
rangeset = { path = "../rangeset" }
|
||||
|
@ -460,7 +460,7 @@ impl ClientDomain {
|
||||
// removed it from the mux. Let's add it back, but
|
||||
// with a new id.
|
||||
inner.remove_old_pane_mapping(entry.pane_id);
|
||||
let pane: Rc<dyn Pane> = Rc::new(ClientPane::new(
|
||||
let pane: Arc<dyn Pane> = Arc::new(ClientPane::new(
|
||||
&inner,
|
||||
entry.tab_id,
|
||||
entry.pane_id,
|
||||
@ -472,7 +472,7 @@ impl ClientDomain {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
let pane: Rc<dyn Pane> = Rc::new(ClientPane::new(
|
||||
let pane: Arc<dyn Pane> = Arc::new(ClientPane::new(
|
||||
&inner,
|
||||
entry.tab_id,
|
||||
entry.pane_id,
|
||||
@ -592,7 +592,7 @@ impl Domain for ClientDomain {
|
||||
_size: TerminalSize,
|
||||
_command: Option<CommandBuilder>,
|
||||
_command_dir: Option<String>,
|
||||
) -> anyhow::Result<Rc<dyn Pane>> {
|
||||
) -> anyhow::Result<Arc<dyn Pane>> {
|
||||
anyhow::bail!("spawn_pane not implemented for ClientDomain")
|
||||
}
|
||||
|
||||
@ -623,7 +623,7 @@ impl Domain for ClientDomain {
|
||||
|
||||
inner.record_remote_to_local_window_mapping(result.window_id, window);
|
||||
|
||||
let pane: Rc<dyn Pane> = Rc::new(ClientPane::new(
|
||||
let pane: Arc<dyn Pane> = Arc::new(ClientPane::new(
|
||||
&inner,
|
||||
result.tab_id,
|
||||
result.pane_id,
|
||||
@ -648,7 +648,7 @@ impl Domain for ClientDomain {
|
||||
tab_id: TabId,
|
||||
pane_id: PaneId,
|
||||
split_request: SplitRequest,
|
||||
) -> anyhow::Result<Rc<dyn Pane>> {
|
||||
) -> anyhow::Result<Arc<dyn Pane>> {
|
||||
let inner = self
|
||||
.inner()
|
||||
.ok_or_else(|| anyhow!("domain is not attached"))?;
|
||||
@ -685,7 +685,7 @@ impl Domain for ClientDomain {
|
||||
})
|
||||
.await?;
|
||||
|
||||
let pane: Rc<dyn Pane> = Rc::new(ClientPane::new(
|
||||
let pane: Arc<dyn Pane> = Arc::new(ClientPane::new(
|
||||
&inner,
|
||||
result.tab_id,
|
||||
result.pane_id,
|
||||
@ -702,7 +702,7 @@ impl Domain for ClientDomain {
|
||||
None => anyhow::bail!("invalid pane id {}", pane_id),
|
||||
};
|
||||
|
||||
tab.split_and_insert(pane_index, split_request, Rc::clone(&pane))
|
||||
tab.split_and_insert(pane_index, split_request, Arc::clone(&pane))
|
||||
.ok();
|
||||
|
||||
mux.add_pane(&pane)?;
|
||||
|
@ -13,12 +13,12 @@ use mux::pane::{
|
||||
use mux::renderable::{RenderableDimensions, StableCursorPosition};
|
||||
use mux::tab::TabId;
|
||||
use mux::{Mux, MuxNotification};
|
||||
use parking_lot::{MappedMutexGuard, Mutex, MutexGuard};
|
||||
use rangeset::RangeSet;
|
||||
use ratelim::RateLimiter;
|
||||
use std::cell::{RefCell, RefMut};
|
||||
use std::cell::RefCell;
|
||||
use std::collections::{BTreeMap, HashMap};
|
||||
use std::ops::Range;
|
||||
use std::rc::Rc;
|
||||
use std::sync::Arc;
|
||||
use termwiz::input::KeyEvent;
|
||||
use termwiz::surface::SequenceNo;
|
||||
@ -34,14 +34,14 @@ pub struct ClientPane {
|
||||
local_pane_id: PaneId,
|
||||
pub remote_pane_id: PaneId,
|
||||
pub remote_tab_id: TabId,
|
||||
pub renderable: RefCell<RenderableState>,
|
||||
palette: RefCell<ColorPalette>,
|
||||
writer: RefCell<PaneWriter>,
|
||||
mouse: Rc<RefCell<MouseState>>,
|
||||
clipboard: RefCell<Option<Arc<dyn Clipboard>>>,
|
||||
mouse_grabbed: RefCell<bool>,
|
||||
ignore_next_kill: RefCell<bool>,
|
||||
user_vars: RefCell<HashMap<String, String>>,
|
||||
pub renderable: Mutex<RenderableState>,
|
||||
palette: Mutex<ColorPalette>,
|
||||
writer: Mutex<PaneWriter>,
|
||||
mouse: Arc<Mutex<MouseState>>,
|
||||
clipboard: Mutex<Option<Arc<dyn Clipboard>>>,
|
||||
mouse_grabbed: Mutex<bool>,
|
||||
ignore_next_kill: Mutex<bool>,
|
||||
user_vars: Mutex<HashMap<String, String>>,
|
||||
}
|
||||
|
||||
impl ClientPane {
|
||||
@ -58,7 +58,7 @@ impl ClientPane {
|
||||
remote_pane_id,
|
||||
};
|
||||
|
||||
let mouse = Rc::new(RefCell::new(MouseState::new(
|
||||
let mouse = Arc::new(Mutex::new(MouseState::new(
|
||||
remote_pane_id,
|
||||
client.client.clone(),
|
||||
)));
|
||||
@ -96,27 +96,27 @@ impl ClientPane {
|
||||
remote_pane_id,
|
||||
local_pane_id,
|
||||
remote_tab_id,
|
||||
renderable: RefCell::new(render),
|
||||
writer: RefCell::new(writer),
|
||||
palette: RefCell::new(palette),
|
||||
clipboard: RefCell::new(None),
|
||||
mouse_grabbed: RefCell::new(false),
|
||||
ignore_next_kill: RefCell::new(false),
|
||||
user_vars: RefCell::new(HashMap::new()),
|
||||
renderable: Mutex::new(render),
|
||||
writer: Mutex::new(writer),
|
||||
palette: Mutex::new(palette),
|
||||
clipboard: Mutex::new(None),
|
||||
mouse_grabbed: Mutex::new(false),
|
||||
ignore_next_kill: Mutex::new(false),
|
||||
user_vars: Mutex::new(HashMap::new()),
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn process_unilateral(&self, pdu: Pdu) -> anyhow::Result<()> {
|
||||
match pdu {
|
||||
Pdu::GetPaneRenderChangesResponse(mut delta) => {
|
||||
*self.mouse_grabbed.borrow_mut() = delta.mouse_grabbed;
|
||||
*self.mouse_grabbed.lock() = delta.mouse_grabbed;
|
||||
|
||||
let bonus_lines = std::mem::take(&mut delta.bonus_lines);
|
||||
let client = { Arc::clone(&self.renderable.borrow().inner.borrow().client) };
|
||||
let client = { Arc::clone(&self.renderable.lock().inner.borrow().client) };
|
||||
let bonus_lines = hydrate_lines(client, delta.pane_id, bonus_lines).await;
|
||||
|
||||
self.renderable
|
||||
.borrow()
|
||||
.lock()
|
||||
.inner
|
||||
.borrow_mut()
|
||||
.apply_changes_to_surface(delta, bonus_lines);
|
||||
@ -125,7 +125,7 @@ impl ClientPane {
|
||||
clipboard,
|
||||
selection,
|
||||
..
|
||||
}) => match self.clipboard.borrow().as_ref() {
|
||||
}) => match self.clipboard.lock().as_ref() {
|
||||
Some(clip) => {
|
||||
log::debug!(
|
||||
"Pdu::SetClipboard pane={} remote={} {:?} {:?}",
|
||||
@ -141,7 +141,7 @@ impl ClientPane {
|
||||
}
|
||||
},
|
||||
Pdu::SetPalette(SetPalette { palette, .. }) => {
|
||||
*self.palette.borrow_mut() = palette;
|
||||
*self.palette.lock() = palette;
|
||||
let mux = Mux::get().unwrap();
|
||||
mux.notify(MuxNotification::Alert {
|
||||
pane_id: self.local_pane_id,
|
||||
@ -152,9 +152,7 @@ impl ClientPane {
|
||||
let mux = Mux::get().unwrap();
|
||||
match &alert {
|
||||
Alert::SetUserVar { name, value } => {
|
||||
self.user_vars
|
||||
.borrow_mut()
|
||||
.insert(name.clone(), value.clone());
|
||||
self.user_vars.lock().insert(name.clone(), value.clone());
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
@ -165,7 +163,7 @@ impl ClientPane {
|
||||
}
|
||||
Pdu::PaneRemoved(PaneRemoved { pane_id }) => {
|
||||
log::trace!("remote pane {} has been removed", pane_id);
|
||||
self.renderable.borrow().inner.borrow_mut().dead = true;
|
||||
self.renderable.lock().inner.borrow_mut().dead = true;
|
||||
let mux = Mux::get().unwrap();
|
||||
mux.prune_dead_windows();
|
||||
|
||||
@ -188,7 +186,7 @@ impl ClientPane {
|
||||
/// from where they left off.
|
||||
/// It isn't perfect.
|
||||
pub fn ignore_next_kill(&self) {
|
||||
*self.ignore_next_kill.borrow_mut() = true;
|
||||
*self.ignore_next_kill.lock() = true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -199,7 +197,7 @@ impl Pane for ClientPane {
|
||||
}
|
||||
|
||||
fn get_metadata(&self) -> Value {
|
||||
let renderable = self.renderable.borrow();
|
||||
let renderable = self.renderable.lock();
|
||||
let inner = renderable.inner.borrow();
|
||||
|
||||
let mut map: BTreeMap<Value, Value> = BTreeMap::new();
|
||||
@ -216,11 +214,11 @@ impl Pane for ClientPane {
|
||||
}
|
||||
|
||||
fn get_cursor_position(&self) -> StableCursorPosition {
|
||||
self.renderable.borrow().get_cursor_position()
|
||||
self.renderable.lock().get_cursor_position()
|
||||
}
|
||||
|
||||
fn get_dimensions(&self) -> RenderableDimensions {
|
||||
self.renderable.borrow().get_dimensions()
|
||||
self.renderable.lock().get_dimensions()
|
||||
}
|
||||
|
||||
fn with_lines_mut(&self, lines: Range<StableRowIndex>, with_lines: &mut dyn WithPaneLines) {
|
||||
@ -236,7 +234,7 @@ impl Pane for ClientPane {
|
||||
}
|
||||
|
||||
fn get_lines(&self, lines: Range<StableRowIndex>) -> (StableRowIndex, Vec<Line>) {
|
||||
self.renderable.borrow().get_lines(lines)
|
||||
self.renderable.lock().get_lines(lines)
|
||||
}
|
||||
|
||||
fn get_logical_lines(&self, lines: Range<StableRowIndex>) -> Vec<LogicalLine> {
|
||||
@ -244,7 +242,7 @@ impl Pane for ClientPane {
|
||||
}
|
||||
|
||||
fn get_current_seqno(&self) -> SequenceNo {
|
||||
self.renderable.borrow().get_current_seqno()
|
||||
self.renderable.lock().get_current_seqno()
|
||||
}
|
||||
|
||||
fn get_changed_since(
|
||||
@ -252,15 +250,15 @@ impl Pane for ClientPane {
|
||||
lines: Range<StableRowIndex>,
|
||||
seqno: SequenceNo,
|
||||
) -> RangeSet<StableRowIndex> {
|
||||
self.renderable.borrow().get_changed_since(lines, seqno)
|
||||
self.renderable.lock().get_changed_since(lines, seqno)
|
||||
}
|
||||
|
||||
fn set_clipboard(&self, clipboard: &Arc<dyn Clipboard>) {
|
||||
self.clipboard.borrow_mut().replace(Arc::clone(clipboard));
|
||||
self.clipboard.lock().replace(Arc::clone(clipboard));
|
||||
}
|
||||
|
||||
fn get_title(&self) -> String {
|
||||
let renderable = self.renderable.borrow();
|
||||
let renderable = self.renderable.lock();
|
||||
let inner = renderable.inner.borrow();
|
||||
inner.title.clone()
|
||||
}
|
||||
@ -269,7 +267,7 @@ impl Pane for ClientPane {
|
||||
let client = Arc::clone(&self.client);
|
||||
let remote_pane_id = self.remote_pane_id;
|
||||
self.renderable
|
||||
.borrow()
|
||||
.lock()
|
||||
.inner
|
||||
.borrow_mut()
|
||||
.predict_from_paste(text);
|
||||
@ -285,11 +283,7 @@ impl Pane for ClientPane {
|
||||
.await
|
||||
})
|
||||
.detach();
|
||||
self.renderable
|
||||
.borrow()
|
||||
.inner
|
||||
.borrow_mut()
|
||||
.update_last_send();
|
||||
self.renderable.lock().inner.borrow_mut().update_last_send();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -297,12 +291,15 @@ impl Pane for ClientPane {
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
fn writer(&self) -> RefMut<dyn std::io::Write> {
|
||||
self.writer.borrow_mut()
|
||||
fn writer(&self) -> MappedMutexGuard<dyn std::io::Write> {
|
||||
MutexGuard::map(self.writer.lock(), |writer| {
|
||||
let w: &mut dyn std::io::Write = writer;
|
||||
w
|
||||
})
|
||||
}
|
||||
|
||||
fn set_zoomed(&self, zoomed: bool) {
|
||||
let render = self.renderable.borrow();
|
||||
let render = self.renderable.lock();
|
||||
let mut inner = render.inner.borrow_mut();
|
||||
let client = Arc::clone(&self.client);
|
||||
let remote_pane_id = self.remote_pane_id;
|
||||
@ -324,7 +321,7 @@ impl Pane for ClientPane {
|
||||
}
|
||||
|
||||
fn resize(&self, size: TerminalSize) -> anyhow::Result<()> {
|
||||
let render = self.renderable.borrow();
|
||||
let render = self.renderable.lock();
|
||||
let mut inner = render.inner.borrow_mut();
|
||||
|
||||
let cols = size.cols as usize;
|
||||
@ -381,7 +378,7 @@ impl Pane for ClientPane {
|
||||
fn key_down(&self, key: KeyCode, mods: KeyModifiers) -> anyhow::Result<()> {
|
||||
let input_serial;
|
||||
{
|
||||
let renderable = self.renderable.borrow();
|
||||
let renderable = self.renderable.lock();
|
||||
let mut inner = renderable.inner.borrow_mut();
|
||||
inner.input_serial = InputSerial::now();
|
||||
input_serial = inner.input_serial;
|
||||
@ -403,11 +400,7 @@ impl Pane for ClientPane {
|
||||
.await
|
||||
})
|
||||
.detach();
|
||||
self.renderable
|
||||
.borrow()
|
||||
.inner
|
||||
.borrow_mut()
|
||||
.update_last_send();
|
||||
self.renderable.lock().inner.borrow_mut().update_last_send();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -417,7 +410,7 @@ impl Pane for ClientPane {
|
||||
}
|
||||
|
||||
fn kill(&self) {
|
||||
let mut ignore = self.ignore_next_kill.borrow_mut();
|
||||
let mut ignore = self.ignore_next_kill.lock();
|
||||
if *ignore {
|
||||
*ignore = false;
|
||||
return;
|
||||
@ -482,27 +475,23 @@ impl Pane for ClientPane {
|
||||
// status, but killing the pane prevents the server
|
||||
// side from sending us further data.
|
||||
// <https://github.com/wez/wezterm/issues/1752>
|
||||
self.renderable.borrow().inner.borrow_mut().dead = true;
|
||||
self.renderable.lock().inner.borrow_mut().dead = true;
|
||||
}
|
||||
|
||||
fn mouse_event(&self, event: MouseEvent) -> anyhow::Result<()> {
|
||||
self.mouse.borrow_mut().append(event);
|
||||
if MouseState::next(Rc::clone(&self.mouse)) {
|
||||
self.renderable
|
||||
.borrow()
|
||||
.inner
|
||||
.borrow_mut()
|
||||
.update_last_send();
|
||||
self.mouse.lock().append(event);
|
||||
if MouseState::next(Arc::clone(&self.mouse)) {
|
||||
self.renderable.lock().inner.borrow_mut().update_last_send();
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn is_dead(&self) -> bool {
|
||||
self.renderable.borrow().inner.borrow().dead
|
||||
self.renderable.lock().inner.borrow().dead
|
||||
}
|
||||
|
||||
fn palette(&self) -> ColorPalette {
|
||||
self.palette.borrow().clone()
|
||||
self.palette.lock().clone()
|
||||
}
|
||||
|
||||
fn domain_id(&self) -> DomainId {
|
||||
@ -510,7 +499,7 @@ impl Pane for ClientPane {
|
||||
}
|
||||
|
||||
fn is_mouse_grabbed(&self) -> bool {
|
||||
*self.mouse_grabbed.borrow()
|
||||
*self.mouse_grabbed.lock()
|
||||
}
|
||||
|
||||
fn is_alt_screen_active(&self) -> bool {
|
||||
@ -519,7 +508,7 @@ impl Pane for ClientPane {
|
||||
}
|
||||
|
||||
fn get_current_working_dir(&self) -> Option<Url> {
|
||||
self.renderable.borrow().inner.borrow().working_dir.clone()
|
||||
self.renderable.lock().inner.borrow().working_dir.clone()
|
||||
}
|
||||
|
||||
fn focus_changed(&self, focused: bool) {
|
||||
@ -555,7 +544,7 @@ impl Pane for ClientPane {
|
||||
}
|
||||
|
||||
fn copy_user_vars(&self) -> HashMap<String, String> {
|
||||
self.user_vars.borrow().clone()
|
||||
self.user_vars.lock().clone()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,10 +1,10 @@
|
||||
use crate::client::Client;
|
||||
use codec::*;
|
||||
use mux::tab::TabId;
|
||||
use std::cell::RefCell;
|
||||
use parking_lot::Mutex;
|
||||
use std::collections::VecDeque;
|
||||
use std::rc::Rc;
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
use std::sync::Arc;
|
||||
use wezterm_term::{MouseButton, MouseEvent, MouseEventKind};
|
||||
|
||||
pub struct MouseState {
|
||||
@ -64,12 +64,12 @@ impl MouseState {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn next(state: Rc<RefCell<Self>>) -> bool {
|
||||
let mut mouse = state.borrow_mut();
|
||||
pub fn next(state: Arc<Mutex<Self>>) -> bool {
|
||||
let mut mouse = state.lock();
|
||||
if let Some(event) = mouse.pop() {
|
||||
let client = mouse.client.clone();
|
||||
|
||||
let state = Rc::clone(&state);
|
||||
let state = Arc::clone(&state);
|
||||
mouse.pending.store(true, Ordering::SeqCst);
|
||||
let remote_pane_id = mouse.remote_pane_id;
|
||||
|
||||
@ -82,11 +82,11 @@ impl MouseState {
|
||||
.await
|
||||
.ok();
|
||||
|
||||
let mouse = state.borrow_mut();
|
||||
let mouse = state.lock();
|
||||
mouse.pending.store(false, Ordering::SeqCst);
|
||||
drop(mouse);
|
||||
|
||||
Self::next(Rc::clone(&state));
|
||||
Self::next(Arc::clone(&state));
|
||||
Ok::<(), anyhow::Error>(())
|
||||
})
|
||||
.detach();
|
||||
|
@ -540,7 +540,7 @@ impl RenderableInner {
|
||||
.get_pane(local_pane_id)
|
||||
.ok_or_else(|| anyhow!("no such tab {}", local_pane_id))?;
|
||||
if let Some(client_tab) = pane.downcast_ref::<ClientPane>() {
|
||||
let renderable = client_tab.renderable.borrow_mut();
|
||||
let renderable = client_tab.renderable.lock();
|
||||
let mut inner = renderable.inner.borrow_mut();
|
||||
|
||||
match result {
|
||||
@ -621,7 +621,7 @@ impl RenderableInner {
|
||||
.get_pane(local_pane_id)
|
||||
.ok_or_else(|| anyhow!("no such tab {}", local_pane_id))?;
|
||||
if let Some(client_tab) = tab.downcast_ref::<ClientPane>() {
|
||||
let renderable = client_tab.renderable.borrow_mut();
|
||||
let renderable = client_tab.renderable.lock();
|
||||
let mut inner = renderable.inner.borrow_mut();
|
||||
|
||||
inner.dead = !alive;
|
||||
|
@ -67,6 +67,7 @@ mux = { path = "../mux" }
|
||||
mux-lua = { path = "../lua-api-crates/mux" }
|
||||
open = "3.0"
|
||||
ordered-float = "3.0"
|
||||
parking_lot = "0.12"
|
||||
portable-pty = { path = "../pty", features = ["serde_support"]}
|
||||
promise = { path = "../promise" }
|
||||
pulldown-cmark = "0.9"
|
||||
|
@ -12,12 +12,11 @@ use mux::pane::{
|
||||
use mux::renderable::*;
|
||||
use mux::tab::TabId;
|
||||
use ordered_float::NotNan;
|
||||
use parking_lot::{MappedMutexGuard, Mutex};
|
||||
use rangeset::RangeSet;
|
||||
use std::cell::{RefCell, RefMut};
|
||||
use std::collections::HashMap;
|
||||
use std::ops::Range;
|
||||
use std::rc::Rc;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
use termwiz::cell::{Cell, CellAttributes};
|
||||
use termwiz::color::AnsiColor;
|
||||
@ -38,8 +37,8 @@ lazy_static::lazy_static! {
|
||||
const SEARCH_CHUNK_SIZE: StableRowIndex = 1000;
|
||||
|
||||
pub struct CopyOverlay {
|
||||
delegate: Rc<dyn Pane>,
|
||||
render: RefCell<CopyRenderable>,
|
||||
delegate: Arc<dyn Pane>,
|
||||
render: Mutex<CopyRenderable>,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
@ -57,7 +56,7 @@ struct Jump {
|
||||
|
||||
struct CopyRenderable {
|
||||
cursor: StableCursorPosition,
|
||||
delegate: Rc<dyn Pane>,
|
||||
delegate: Arc<dyn Pane>,
|
||||
start: Option<SelectionCoordinate>,
|
||||
selection_mode: SelectionMode,
|
||||
viewport: Option<StableRowIndex>,
|
||||
@ -109,9 +108,9 @@ pub struct CopyModeParams {
|
||||
impl CopyOverlay {
|
||||
pub fn with_pane(
|
||||
term_window: &TermWindow,
|
||||
pane: &Rc<dyn Pane>,
|
||||
pane: &Arc<dyn Pane>,
|
||||
params: CopyModeParams,
|
||||
) -> anyhow::Result<Rc<dyn Pane>> {
|
||||
) -> anyhow::Result<Arc<dyn Pane>> {
|
||||
let mut cursor = pane.get_cursor_position();
|
||||
cursor.shape = termwiz::surface::CursorShape::SteadyBlock;
|
||||
cursor.visibility = CursorVisibility::Visible;
|
||||
@ -129,7 +128,7 @@ impl CopyOverlay {
|
||||
let mut render = CopyRenderable {
|
||||
cursor,
|
||||
window,
|
||||
delegate: Rc::clone(pane),
|
||||
delegate: Arc::clone(pane),
|
||||
start: None,
|
||||
viewport: term_window.get_viewport(pane.pane_id()),
|
||||
results: vec![],
|
||||
@ -143,7 +142,6 @@ impl CopyOverlay {
|
||||
pattern: if params.pattern.is_empty() {
|
||||
SAVED_PATTERN
|
||||
.lock()
|
||||
.unwrap()
|
||||
.get(&tab_id)
|
||||
.map(|p| p.clone())
|
||||
.unwrap_or(params.pattern)
|
||||
@ -163,14 +161,14 @@ impl CopyOverlay {
|
||||
render.dirty_results.add(search_row);
|
||||
render.update_search();
|
||||
|
||||
Ok(Rc::new(CopyOverlay {
|
||||
delegate: Rc::clone(pane),
|
||||
render: RefCell::new(render),
|
||||
Ok(Arc::new(CopyOverlay {
|
||||
delegate: Arc::clone(pane),
|
||||
render: Mutex::new(render),
|
||||
}))
|
||||
}
|
||||
|
||||
pub fn get_params(&self) -> CopyModeParams {
|
||||
let render = self.render.borrow();
|
||||
let render = self.render.lock();
|
||||
CopyModeParams {
|
||||
pattern: render.pattern.clone(),
|
||||
editing_search: render.editing_search,
|
||||
@ -178,7 +176,7 @@ impl CopyOverlay {
|
||||
}
|
||||
|
||||
pub fn apply_params(&self, params: CopyModeParams) {
|
||||
let mut render = self.render.borrow_mut();
|
||||
let mut render = self.render.lock();
|
||||
render.editing_search = params.editing_search;
|
||||
if render.pattern != params.pattern {
|
||||
render.pattern = params.pattern;
|
||||
@ -189,7 +187,7 @@ impl CopyOverlay {
|
||||
}
|
||||
|
||||
pub fn viewport_changed(&self, viewport: Option<StableRowIndex>) {
|
||||
let mut render = self.render.borrow_mut();
|
||||
let mut render = self.render.lock();
|
||||
if render.viewport != viewport {
|
||||
if let Some(last) = render.last_bar_pos.take() {
|
||||
render.dirty_results.add(last);
|
||||
@ -271,7 +269,7 @@ impl CopyRenderable {
|
||||
let state = term_window.pane_state(pane_id);
|
||||
if let Some(overlay) = state.overlay.as_ref() {
|
||||
if let Some(copy_overlay) = overlay.pane.downcast_ref::<CopyOverlay>() {
|
||||
let mut r = copy_overlay.render.borrow_mut();
|
||||
let mut r = copy_overlay.render.lock();
|
||||
if cookie == r.typing_cookie {
|
||||
r.update_search();
|
||||
}
|
||||
@ -297,7 +295,6 @@ impl CopyRenderable {
|
||||
|
||||
SAVED_PATTERN
|
||||
.lock()
|
||||
.unwrap()
|
||||
.insert(self.tab_id, self.pattern.clone());
|
||||
|
||||
let bar_pos = self.compute_search_row();
|
||||
@ -305,7 +302,7 @@ impl CopyRenderable {
|
||||
self.last_result_seqno = self.delegate.get_current_seqno();
|
||||
|
||||
if !self.pattern.is_empty() {
|
||||
let pane: Rc<dyn Pane> = self.delegate.clone();
|
||||
let pane: Arc<dyn Pane> = self.delegate.clone();
|
||||
let window = self.window.clone();
|
||||
let pattern = self.pattern.clone();
|
||||
let dims = pane.get_dimensions();
|
||||
@ -330,7 +327,7 @@ impl CopyRenderable {
|
||||
let state = term_window.pane_state(pane_id);
|
||||
if let Some(overlay) = state.overlay.as_ref() {
|
||||
if let Some(copy_overlay) = overlay.pane.downcast_ref::<CopyOverlay>() {
|
||||
let mut r = copy_overlay.render.borrow_mut();
|
||||
let mut r = copy_overlay.render.lock();
|
||||
r.processed_search_chunk(pattern, results.take().unwrap(), range);
|
||||
}
|
||||
}
|
||||
@ -375,7 +372,7 @@ impl CopyRenderable {
|
||||
}
|
||||
|
||||
// Search next chunk
|
||||
let pane: Rc<dyn Pane> = self.delegate.clone();
|
||||
let pane: Arc<dyn Pane> = self.delegate.clone();
|
||||
let window = self.window.clone();
|
||||
let end = range.start;
|
||||
let range = end
|
||||
@ -397,7 +394,7 @@ impl CopyRenderable {
|
||||
let state = term_window.pane_state(pane_id);
|
||||
if let Some(overlay) = state.overlay.as_ref() {
|
||||
if let Some(copy_overlay) = overlay.pane.downcast_ref::<CopyOverlay>() {
|
||||
let mut r = copy_overlay.render.borrow_mut();
|
||||
let mut r = copy_overlay.render.lock();
|
||||
r.processed_search_chunk(pattern, results.take().unwrap(), range);
|
||||
}
|
||||
}
|
||||
@ -1025,7 +1022,7 @@ impl Pane for CopyOverlay {
|
||||
|
||||
fn send_paste(&self, text: &str) -> anyhow::Result<()> {
|
||||
// paste into the search bar
|
||||
let mut r = self.render.borrow_mut();
|
||||
let mut r = self.render.lock();
|
||||
r.pattern.push_str(text);
|
||||
r.schedule_update_search();
|
||||
Ok(())
|
||||
@ -1035,7 +1032,7 @@ impl Pane for CopyOverlay {
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
fn writer(&self) -> RefMut<dyn std::io::Write> {
|
||||
fn writer(&self) -> MappedMutexGuard<dyn std::io::Write> {
|
||||
self.delegate.writer()
|
||||
}
|
||||
|
||||
@ -1048,7 +1045,7 @@ impl Pane for CopyOverlay {
|
||||
}
|
||||
|
||||
fn key_down(&self, key: KeyCode, mods: KeyModifiers) -> anyhow::Result<()> {
|
||||
let mut render = self.render.borrow_mut();
|
||||
let mut render = self.render.lock();
|
||||
if let Some(jump) = render.pending_jump.take() {
|
||||
match (key, mods) {
|
||||
(KeyCode::Char(c), KeyModifiers::NONE)
|
||||
@ -1093,7 +1090,7 @@ impl Pane for CopyOverlay {
|
||||
|
||||
fn perform_assignment(&self, assignment: &KeyAssignment) -> PerformAssignmentResult {
|
||||
use CopyModeAssignment::*;
|
||||
let mut render = self.render.borrow_mut();
|
||||
let mut render = self.render.lock();
|
||||
if render.pending_jump.is_some() {
|
||||
// Block key assignments until key_down is called
|
||||
// and resolves the next state
|
||||
@ -1190,7 +1187,7 @@ impl Pane for CopyOverlay {
|
||||
}
|
||||
|
||||
fn get_cursor_position(&self) -> StableCursorPosition {
|
||||
let renderer = self.render.borrow();
|
||||
let renderer = self.render.lock();
|
||||
if renderer.editing_search {
|
||||
// place in the search box
|
||||
StableCursorPosition {
|
||||
@ -1232,8 +1229,8 @@ impl Pane for CopyOverlay {
|
||||
fn with_lines_mut(&self, lines: Range<StableRowIndex>, with_lines: &mut dyn WithPaneLines) {
|
||||
// Take care to access self.delegate methods here before we get into
|
||||
// calling into its own with_lines_mut to avoid a runtime
|
||||
// borrow erro!
|
||||
let mut renderer = self.render.borrow_mut();
|
||||
// lock erro!
|
||||
let mut renderer = self.render.lock();
|
||||
if self.delegate.get_current_seqno() > renderer.last_result_seqno {
|
||||
renderer.update_search();
|
||||
}
|
||||
@ -1351,7 +1348,7 @@ impl Pane for CopyOverlay {
|
||||
}
|
||||
|
||||
fn get_lines(&self, lines: Range<StableRowIndex>) -> (StableRowIndex, Vec<Line>) {
|
||||
let mut renderer = self.render.borrow_mut();
|
||||
let mut renderer = self.render.lock();
|
||||
if self.delegate.get_current_seqno() > renderer.last_result_seqno {
|
||||
renderer.update_search();
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ pub fn start_overlay<T, F>(
|
||||
tab: &Rc<Tab>,
|
||||
func: F,
|
||||
) -> (
|
||||
Rc<dyn Pane>,
|
||||
Arc<dyn Pane>,
|
||||
Pin<Box<dyn std::future::Future<Output = anyhow::Result<T>>>>,
|
||||
)
|
||||
where
|
||||
@ -54,10 +54,10 @@ where
|
||||
|
||||
pub fn start_overlay_pane<T, F>(
|
||||
term_window: &TermWindow,
|
||||
pane: &Rc<dyn Pane>,
|
||||
pane: &Arc<dyn Pane>,
|
||||
func: F,
|
||||
) -> (
|
||||
Rc<dyn Pane>,
|
||||
Arc<dyn Pane>,
|
||||
Pin<Box<dyn std::future::Future<Output = anyhow::Result<T>>>>,
|
||||
)
|
||||
where
|
||||
|
@ -7,11 +7,10 @@ use mux::pane::{
|
||||
ForEachPaneLogicalLine, LogicalLine, Pane, PaneId, Pattern, SearchResult, WithPaneLines,
|
||||
};
|
||||
use mux::renderable::*;
|
||||
use parking_lot::{MappedMutexGuard, Mutex};
|
||||
use rangeset::RangeSet;
|
||||
use std::cell::{RefCell, RefMut};
|
||||
use std::collections::HashMap;
|
||||
use std::ops::Range;
|
||||
use std::rc::Rc;
|
||||
use std::sync::Arc;
|
||||
use termwiz::cell::{Cell, CellAttributes};
|
||||
use termwiz::color::AnsiColor;
|
||||
@ -148,8 +147,8 @@ mod alphabet_test {
|
||||
}
|
||||
|
||||
pub struct QuickSelectOverlay {
|
||||
renderer: RefCell<QuickSelectRenderable>,
|
||||
delegate: Rc<dyn Pane>,
|
||||
renderer: Mutex<QuickSelectRenderable>,
|
||||
delegate: Arc<dyn Pane>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
@ -159,7 +158,7 @@ struct MatchResult {
|
||||
}
|
||||
|
||||
struct QuickSelectRenderable {
|
||||
delegate: Rc<dyn Pane>,
|
||||
delegate: Arc<dyn Pane>,
|
||||
/// The text that the user entered
|
||||
pattern: Pattern,
|
||||
/// The most recently queried set of matches
|
||||
@ -186,9 +185,9 @@ struct QuickSelectRenderable {
|
||||
impl QuickSelectOverlay {
|
||||
pub fn with_pane(
|
||||
term_window: &TermWindow,
|
||||
pane: &Rc<dyn Pane>,
|
||||
pane: &Arc<dyn Pane>,
|
||||
args: &QuickSelectArguments,
|
||||
) -> Rc<dyn Pane> {
|
||||
) -> Arc<dyn Pane> {
|
||||
let viewport = term_window.get_viewport(pane.pane_id());
|
||||
let dims = pane.get_dimensions();
|
||||
|
||||
@ -228,7 +227,7 @@ impl QuickSelectOverlay {
|
||||
|
||||
let window = term_window.window.clone().unwrap();
|
||||
let mut renderer = QuickSelectRenderable {
|
||||
delegate: Rc::clone(pane),
|
||||
delegate: Arc::clone(pane),
|
||||
pattern,
|
||||
selection: "".to_string(),
|
||||
results: vec![],
|
||||
@ -249,14 +248,14 @@ impl QuickSelectOverlay {
|
||||
renderer.dirty_results.add(search_row);
|
||||
renderer.update_search(true);
|
||||
|
||||
Rc::new(QuickSelectOverlay {
|
||||
renderer: RefCell::new(renderer),
|
||||
delegate: Rc::clone(pane),
|
||||
Arc::new(QuickSelectOverlay {
|
||||
renderer: Mutex::new(renderer),
|
||||
delegate: Arc::clone(pane),
|
||||
})
|
||||
}
|
||||
|
||||
pub fn viewport_changed(&self, viewport: Option<StableRowIndex>) {
|
||||
let mut render = self.renderer.borrow_mut();
|
||||
let mut render = self.renderer.lock();
|
||||
if render.viewport != viewport {
|
||||
if let Some(last) = render.last_bar_pos.take() {
|
||||
render.dirty_results.add(last);
|
||||
@ -287,7 +286,7 @@ impl Pane for QuickSelectOverlay {
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
fn writer(&self) -> RefMut<dyn std::io::Write> {
|
||||
fn writer(&self) -> MappedMutexGuard<dyn std::io::Write> {
|
||||
self.delegate.writer()
|
||||
}
|
||||
|
||||
@ -301,12 +300,12 @@ impl Pane for QuickSelectOverlay {
|
||||
|
||||
fn key_down(&self, key: KeyCode, mods: KeyModifiers) -> anyhow::Result<()> {
|
||||
match (key, mods) {
|
||||
(KeyCode::Escape, KeyModifiers::NONE) => self.renderer.borrow().close(),
|
||||
(KeyCode::Escape, KeyModifiers::NONE) => self.renderer.lock().close(),
|
||||
(KeyCode::UpArrow, KeyModifiers::NONE)
|
||||
| (KeyCode::Enter, KeyModifiers::NONE)
|
||||
| (KeyCode::Char('p'), KeyModifiers::CTRL) => {
|
||||
// Move to prior match
|
||||
let mut r = self.renderer.borrow_mut();
|
||||
let mut r = self.renderer.lock();
|
||||
if let Some(cur) = r.result_pos.as_ref() {
|
||||
let prior = if *cur > 0 {
|
||||
cur - 1
|
||||
@ -320,7 +319,7 @@ impl Pane for QuickSelectOverlay {
|
||||
// Skip this page of matches and move up to the first match from
|
||||
// the prior page.
|
||||
let dims = self.delegate.get_dimensions();
|
||||
let mut r = self.renderer.borrow_mut();
|
||||
let mut r = self.renderer.lock();
|
||||
if let Some(cur) = r.result_pos {
|
||||
let top = r.viewport.unwrap_or(dims.physical_top);
|
||||
let prior = top - dims.viewport_rows as isize;
|
||||
@ -339,7 +338,7 @@ impl Pane for QuickSelectOverlay {
|
||||
// Skip this page of matches and move down to the first match from
|
||||
// the next page.
|
||||
let dims = self.delegate.get_dimensions();
|
||||
let mut r = self.renderer.borrow_mut();
|
||||
let mut r = self.renderer.lock();
|
||||
if let Some(cur) = r.result_pos {
|
||||
let top = r.viewport.unwrap_or(dims.physical_top);
|
||||
let bottom = top + dims.viewport_rows as isize;
|
||||
@ -353,7 +352,7 @@ impl Pane for QuickSelectOverlay {
|
||||
}
|
||||
(KeyCode::DownArrow, KeyModifiers::NONE) | (KeyCode::Char('n'), KeyModifiers::CTRL) => {
|
||||
// Move to next match
|
||||
let mut r = self.renderer.borrow_mut();
|
||||
let mut r = self.renderer.lock();
|
||||
if let Some(cur) = r.result_pos.as_ref() {
|
||||
let next = if *cur + 1 >= r.results.len() {
|
||||
0
|
||||
@ -365,7 +364,7 @@ impl Pane for QuickSelectOverlay {
|
||||
}
|
||||
(KeyCode::Char(c), KeyModifiers::NONE) | (KeyCode::Char(c), KeyModifiers::SHIFT) => {
|
||||
// Type to add to the selection
|
||||
let mut r = self.renderer.borrow_mut();
|
||||
let mut r = self.renderer.lock();
|
||||
r.selection.push(c);
|
||||
let lowered = r.selection.to_lowercase();
|
||||
let paste = lowered != r.selection;
|
||||
@ -376,12 +375,12 @@ impl Pane for QuickSelectOverlay {
|
||||
}
|
||||
(KeyCode::Backspace, KeyModifiers::NONE) => {
|
||||
// Backspace to edit the selection
|
||||
let mut r = self.renderer.borrow_mut();
|
||||
let mut r = self.renderer.lock();
|
||||
r.selection.pop();
|
||||
}
|
||||
(KeyCode::Char('u'), KeyModifiers::CTRL) => {
|
||||
// CTRL-u to clear the selection
|
||||
let mut r = self.renderer.borrow_mut();
|
||||
let mut r = self.renderer.lock();
|
||||
r.selection.clear();
|
||||
}
|
||||
_ => {}
|
||||
@ -431,7 +430,7 @@ impl Pane for QuickSelectOverlay {
|
||||
|
||||
fn get_cursor_position(&self) -> StableCursorPosition {
|
||||
// move to the search box
|
||||
let renderer = self.renderer.borrow();
|
||||
let renderer = self.renderer.lock();
|
||||
StableCursorPosition {
|
||||
x: 8 + wezterm_term::unicode_column_width(&renderer.selection, None),
|
||||
y: renderer.compute_search_row(),
|
||||
@ -450,7 +449,7 @@ impl Pane for QuickSelectOverlay {
|
||||
seqno: SequenceNo,
|
||||
) -> RangeSet<StableRowIndex> {
|
||||
let mut dirty = self.delegate.get_changed_since(lines.clone(), seqno);
|
||||
dirty.add_set(&self.renderer.borrow().dirty_results);
|
||||
dirty.add_set(&self.renderer.lock().dirty_results);
|
||||
dirty.intersection_with_range(lines)
|
||||
}
|
||||
|
||||
@ -468,7 +467,7 @@ impl Pane for QuickSelectOverlay {
|
||||
}
|
||||
|
||||
fn with_lines_mut(&self, lines: Range<StableRowIndex>, with_lines: &mut dyn WithPaneLines) {
|
||||
let mut renderer = self.renderer.borrow_mut();
|
||||
let mut renderer = self.renderer.lock();
|
||||
// Take care to access self.delegate methods here before we get into
|
||||
// calling into its own with_lines_mut to avoid a runtime
|
||||
// borrow erro!
|
||||
@ -579,7 +578,7 @@ impl Pane for QuickSelectOverlay {
|
||||
}
|
||||
|
||||
fn get_lines(&self, lines: Range<StableRowIndex>) -> (StableRowIndex, Vec<Line>) {
|
||||
let mut renderer = self.renderer.borrow_mut();
|
||||
let mut renderer = self.renderer.lock();
|
||||
renderer.check_for_resize();
|
||||
let dims = self.get_dimensions();
|
||||
|
||||
@ -791,7 +790,7 @@ impl QuickSelectRenderable {
|
||||
self.dirty_results.add(bar_pos);
|
||||
|
||||
if !self.pattern.is_empty() {
|
||||
let pane: Rc<dyn Pane> = self.delegate.clone();
|
||||
let pane: Arc<dyn Pane> = self.delegate.clone();
|
||||
let window = self.window.clone();
|
||||
let pattern = self.pattern.clone();
|
||||
let scope = self.args.scope_lines;
|
||||
@ -814,7 +813,7 @@ impl QuickSelectRenderable {
|
||||
if let Some(search_overlay) =
|
||||
overlay.pane.downcast_ref::<QuickSelectOverlay>()
|
||||
{
|
||||
let mut r = search_overlay.renderer.borrow_mut();
|
||||
let mut r = search_overlay.renderer.lock();
|
||||
r.results = results.take().unwrap();
|
||||
r.recompute_results();
|
||||
let num_results = r.results.len();
|
||||
|
@ -3,7 +3,7 @@ use crate::TermWindow;
|
||||
use config::keyassignment::{ClipboardCopyDestination, ClipboardPasteSource};
|
||||
use mux::pane::Pane;
|
||||
use mux::Mux;
|
||||
use std::rc::Rc;
|
||||
use std::sync::Arc;
|
||||
use window::{Clipboard, WindowOps};
|
||||
|
||||
impl TermWindow {
|
||||
@ -23,7 +23,7 @@ impl TermWindow {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn paste_from_clipboard(&mut self, pane: &Rc<dyn Pane>, clipboard: ClipboardPasteSource) {
|
||||
pub fn paste_from_clipboard(&mut self, pane: &Arc<dyn Pane>, clipboard: ClipboardPasteSource) {
|
||||
let pane_id = pane.pane_id();
|
||||
log::trace!(
|
||||
"paste_from_clipboard in pane {} {:?}",
|
||||
|
@ -4,7 +4,7 @@ use anyhow::Context;
|
||||
use config::keyassignment::{KeyAssignment, KeyTableEntry};
|
||||
use mux::pane::{Pane, PerformAssignmentResult};
|
||||
use smol::Timer;
|
||||
use std::rc::Rc;
|
||||
use std::sync::Arc;
|
||||
use std::time::{Duration, Instant};
|
||||
use termwiz::input::KeyboardEncoding;
|
||||
|
||||
@ -218,7 +218,7 @@ enum OnlyKeyBindings {
|
||||
}
|
||||
|
||||
impl super::TermWindow {
|
||||
fn encode_win32_input(&self, pane: &Rc<dyn Pane>, key: &KeyEvent) -> Option<String> {
|
||||
fn encode_win32_input(&self, pane: &Arc<dyn Pane>, key: &KeyEvent) -> Option<String> {
|
||||
if !self.config.allow_win32_input_mode
|
||||
|| pane.get_keyboard_encoding() != KeyboardEncoding::Win32
|
||||
{
|
||||
@ -229,7 +229,7 @@ impl super::TermWindow {
|
||||
|
||||
fn lookup_key(
|
||||
&mut self,
|
||||
pane: &Rc<dyn Pane>,
|
||||
pane: &Arc<dyn Pane>,
|
||||
keycode: &KeyCode,
|
||||
mods: Modifiers,
|
||||
only_key_bindings: OnlyKeyBindings,
|
||||
@ -257,7 +257,7 @@ impl super::TermWindow {
|
||||
|
||||
fn process_key(
|
||||
&mut self,
|
||||
pane: &Rc<dyn Pane>,
|
||||
pane: &Arc<dyn Pane>,
|
||||
context: &dyn WindowOps,
|
||||
keycode: &KeyCode,
|
||||
raw_modifiers: Modifiers,
|
||||
|
@ -176,7 +176,7 @@ pub struct SemanticZoneCache {
|
||||
}
|
||||
|
||||
pub struct OverlayState {
|
||||
pub pane: Rc<dyn Pane>,
|
||||
pub pane: Arc<dyn Pane>,
|
||||
key_table_state: KeyTableState,
|
||||
}
|
||||
|
||||
@ -1466,7 +1466,7 @@ impl TermWindow {
|
||||
}
|
||||
}
|
||||
|
||||
fn check_for_dirty_lines_and_invalidate_selection(&mut self, pane: &Rc<dyn Pane>) {
|
||||
fn check_for_dirty_lines_and_invalidate_selection(&mut self, pane: &Arc<dyn Pane>) {
|
||||
let dims = pane.get_dimensions();
|
||||
let viewport = self
|
||||
.get_viewport(pane.pane_id())
|
||||
@ -2095,7 +2095,7 @@ impl TermWindow {
|
||||
}
|
||||
|
||||
/// Returns the Prompt semantic zones
|
||||
fn get_semantic_prompt_zones(&mut self, pane: &Rc<dyn Pane>) -> &[StableRowIndex] {
|
||||
fn get_semantic_prompt_zones(&mut self, pane: &Arc<dyn Pane>) -> &[StableRowIndex] {
|
||||
let mut cache = self
|
||||
.semantic_zones
|
||||
.entry(pane.pane_id())
|
||||
@ -2222,7 +2222,7 @@ impl TermWindow {
|
||||
|
||||
pub fn perform_key_assignment(
|
||||
&mut self,
|
||||
pane: &Rc<dyn Pane>,
|
||||
pane: &Arc<dyn Pane>,
|
||||
assignment: &KeyAssignment,
|
||||
) -> anyhow::Result<PerformAssignmentResult> {
|
||||
use KeyAssignment::*;
|
||||
@ -2764,7 +2764,7 @@ impl TermWindow {
|
||||
Ok(PerformAssignmentResult::Handled)
|
||||
}
|
||||
|
||||
fn do_open_link_at_mouse_cursor(&self, pane: &Rc<dyn Pane>) {
|
||||
fn do_open_link_at_mouse_cursor(&self, pane: &Arc<dyn Pane>) {
|
||||
// They clicked on a link, so let's open it!
|
||||
// We need to ensure that we spawn the `open` call outside of the context
|
||||
// of our window loop; on Windows it can cause a panic due to
|
||||
@ -2967,22 +2967,22 @@ impl TermWindow {
|
||||
self.window.as_ref().unwrap().invalidate();
|
||||
}
|
||||
|
||||
fn maybe_scroll_to_bottom_for_input(&mut self, pane: &Rc<dyn Pane>) {
|
||||
fn maybe_scroll_to_bottom_for_input(&mut self, pane: &Arc<dyn Pane>) {
|
||||
if self.config.scroll_to_bottom_on_input {
|
||||
self.scroll_to_bottom(pane);
|
||||
}
|
||||
}
|
||||
|
||||
fn scroll_to_top(&mut self, pane: &Rc<dyn Pane>) {
|
||||
fn scroll_to_top(&mut self, pane: &Arc<dyn Pane>) {
|
||||
let dims = pane.get_dimensions();
|
||||
self.set_viewport(pane.pane_id(), Some(dims.scrollback_top), dims);
|
||||
}
|
||||
|
||||
fn scroll_to_bottom(&mut self, pane: &Rc<dyn Pane>) {
|
||||
fn scroll_to_bottom(&mut self, pane: &Arc<dyn Pane>) {
|
||||
self.pane_state(pane.pane_id()).viewport = None;
|
||||
}
|
||||
|
||||
fn get_active_pane_no_overlay(&self) -> Option<Rc<dyn Pane>> {
|
||||
fn get_active_pane_no_overlay(&self) -> Option<Arc<dyn Pane>> {
|
||||
let mux = Mux::get().unwrap();
|
||||
mux.get_active_tab_for_window(self.mux_window_id)
|
||||
.and_then(|tab| tab.get_active_pane())
|
||||
@ -2994,7 +2994,7 @@ impl TermWindow {
|
||||
/// then that will be returned instead. Otherwise, if the pane has
|
||||
/// an active overlay (such as search or copy mode) then that will
|
||||
/// be returned.
|
||||
pub fn get_active_pane_or_overlay(&self) -> Option<Rc<dyn Pane>> {
|
||||
pub fn get_active_pane_or_overlay(&self) -> Option<Arc<dyn Pane>> {
|
||||
let mux = Mux::get().unwrap();
|
||||
let tab = match mux.get_active_tab_for_window(self.mux_window_id) {
|
||||
Some(tab) => tab,
|
||||
@ -3116,7 +3116,7 @@ impl TermWindow {
|
||||
let mut panes = tab.iter_panes();
|
||||
for p in &mut panes {
|
||||
if let Some(overlay) = self.pane_state(p.pane.pane_id()).overlay.as_ref() {
|
||||
p.pane = Rc::clone(&overlay.pane);
|
||||
p.pane = Arc::clone(&overlay.pane);
|
||||
}
|
||||
}
|
||||
panes
|
||||
@ -3177,7 +3177,7 @@ impl TermWindow {
|
||||
window.notify(TermWindowNotif::CancelOverlayForPane(pane_id));
|
||||
}
|
||||
|
||||
pub fn assign_overlay_for_pane(&mut self, pane_id: PaneId, pane: Rc<dyn Pane>) {
|
||||
pub fn assign_overlay_for_pane(&mut self, pane_id: PaneId, pane: Arc<dyn Pane>) {
|
||||
self.cancel_overlay_for_pane(pane_id);
|
||||
self.pane_state(pane_id).overlay.replace(OverlayState {
|
||||
pane,
|
||||
@ -3186,7 +3186,7 @@ impl TermWindow {
|
||||
self.update_title();
|
||||
}
|
||||
|
||||
pub fn assign_overlay(&mut self, tab_id: TabId, overlay: Rc<dyn Pane>) {
|
||||
pub fn assign_overlay(&mut self, tab_id: TabId, overlay: Arc<dyn Pane>) {
|
||||
self.cancel_overlay_for_tab(tab_id, None);
|
||||
self.tab_state(tab_id).overlay.replace(OverlayState {
|
||||
pane: overlay,
|
||||
@ -3195,7 +3195,7 @@ impl TermWindow {
|
||||
self.update_title();
|
||||
}
|
||||
|
||||
fn resolve_search_pattern(&self, pattern: Pattern, pane: &Rc<dyn Pane>) -> MuxPattern {
|
||||
fn resolve_search_pattern(&self, pattern: Pattern, pane: &Arc<dyn Pane>) -> MuxPattern {
|
||||
match pattern {
|
||||
Pattern::CaseSensitiveString(s) => MuxPattern::CaseSensitiveString(s),
|
||||
Pattern::CaseInSensitiveString(s) => MuxPattern::CaseInSensitiveString(s),
|
||||
|
@ -12,7 +12,6 @@ use mux::tab::SplitDirection;
|
||||
use mux::Mux;
|
||||
use std::convert::TryInto;
|
||||
use std::ops::Sub;
|
||||
use std::rc::Rc;
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
use termwiz::hyperlink::Hyperlink;
|
||||
@ -347,7 +346,7 @@ impl super::TermWindow {
|
||||
fn mouse_event_ui_item(
|
||||
&mut self,
|
||||
item: UIItem,
|
||||
pane: Rc<dyn Pane>,
|
||||
pane: Arc<dyn Pane>,
|
||||
_y: i64,
|
||||
event: MouseEvent,
|
||||
context: &dyn WindowOps,
|
||||
@ -453,7 +452,7 @@ impl super::TermWindow {
|
||||
pub fn mouse_event_above_scroll_thumb(
|
||||
&mut self,
|
||||
_item: UIItem,
|
||||
pane: Rc<dyn Pane>,
|
||||
pane: Arc<dyn Pane>,
|
||||
event: MouseEvent,
|
||||
context: &dyn WindowOps,
|
||||
) {
|
||||
@ -478,7 +477,7 @@ impl super::TermWindow {
|
||||
pub fn mouse_event_below_scroll_thumb(
|
||||
&mut self,
|
||||
_item: UIItem,
|
||||
pane: Rc<dyn Pane>,
|
||||
pane: Arc<dyn Pane>,
|
||||
event: MouseEvent,
|
||||
context: &dyn WindowOps,
|
||||
) {
|
||||
@ -503,7 +502,7 @@ impl super::TermWindow {
|
||||
pub fn mouse_event_scroll_thumb(
|
||||
&mut self,
|
||||
item: UIItem,
|
||||
_pane: Rc<dyn Pane>,
|
||||
_pane: Arc<dyn Pane>,
|
||||
event: MouseEvent,
|
||||
context: &dyn WindowOps,
|
||||
) {
|
||||
@ -534,7 +533,7 @@ impl super::TermWindow {
|
||||
|
||||
fn mouse_event_terminal(
|
||||
&mut self,
|
||||
mut pane: Rc<dyn Pane>,
|
||||
mut pane: Arc<dyn Pane>,
|
||||
position: ClickPosition,
|
||||
event: MouseEvent,
|
||||
context: &dyn WindowOps,
|
||||
@ -569,7 +568,7 @@ impl super::TermWindow {
|
||||
mux.get_active_tab_for_window(self.mux_window_id)
|
||||
.map(|tab| tab.set_active_idx(pos.index));
|
||||
|
||||
pane = Rc::clone(&pos.pane);
|
||||
pane = Arc::clone(&pos.pane);
|
||||
is_click_to_focus_pane = true;
|
||||
}
|
||||
WMEK::Move => {
|
||||
@ -578,7 +577,7 @@ impl super::TermWindow {
|
||||
mux.get_active_tab_for_window(self.mux_window_id)
|
||||
.map(|tab| tab.set_active_idx(pos.index));
|
||||
|
||||
pane = Rc::clone(&pos.pane);
|
||||
pane = Arc::clone(&pos.pane);
|
||||
context.invalidate();
|
||||
}
|
||||
}
|
||||
@ -586,7 +585,7 @@ impl super::TermWindow {
|
||||
WMEK::VertWheel(_) => {
|
||||
// Let wheel events route to the hovered pane,
|
||||
// even if it doesn't have focus
|
||||
pane = Rc::clone(&pos.pane);
|
||||
pane = Arc::clone(&pos.pane);
|
||||
context.invalidate();
|
||||
}
|
||||
}
|
||||
|
@ -244,7 +244,7 @@ pub struct RenderScreenLineOpenGLParams<'a> {
|
||||
pub palette: &'a ColorPalette,
|
||||
pub dims: &'a RenderableDimensions,
|
||||
pub config: &'a ConfigHandle,
|
||||
pub pane: Option<&'a Rc<dyn Pane>>,
|
||||
pub pane: Option<&'a Arc<dyn Pane>>,
|
||||
|
||||
pub white_space: TextureRect,
|
||||
pub filled_box: TextureRect,
|
||||
@ -299,7 +299,7 @@ pub struct ComputeCellFgBgParams<'a> {
|
||||
pub cursor_bg: LinearRgba,
|
||||
pub cursor_is_default_color: bool,
|
||||
pub cursor_border_color: LinearRgba,
|
||||
pub pane: Option<&'a Rc<dyn Pane>>,
|
||||
pub pane: Option<&'a Arc<dyn Pane>>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
@ -461,7 +461,7 @@ impl super::TermWindow {
|
||||
|
||||
fn get_intensity_if_bell_target_ringing(
|
||||
&self,
|
||||
pane: &Rc<dyn Pane>,
|
||||
pane: &Arc<dyn Pane>,
|
||||
config: &ConfigHandle,
|
||||
target: VisualBellTarget,
|
||||
) -> Option<f32> {
|
||||
@ -2183,7 +2183,7 @@ impl super::TermWindow {
|
||||
&mut self,
|
||||
layers: &mut TripleLayerQuadAllocator,
|
||||
split: &PositionedSplit,
|
||||
pane: &Rc<dyn Pane>,
|
||||
pane: &Arc<dyn Pane>,
|
||||
) -> anyhow::Result<()> {
|
||||
let palette = pane.palette();
|
||||
let foreground = palette.split.to_linear();
|
||||
|
@ -2,7 +2,7 @@ use crate::selection::{Selection, SelectionCoordinate, SelectionMode, SelectionR
|
||||
use ::window::WindowOps;
|
||||
use mux::pane::{Pane, PaneId};
|
||||
use std::cell::RefMut;
|
||||
use std::rc::Rc;
|
||||
use std::sync::Arc;
|
||||
use termwiz::surface::Line;
|
||||
use wezterm_term::StableRowIndex;
|
||||
|
||||
@ -12,7 +12,7 @@ impl super::TermWindow {
|
||||
}
|
||||
|
||||
/// Returns the selection region as a series of Line
|
||||
pub fn selection_lines(&self, pane: &Rc<dyn Pane>) -> Vec<Line> {
|
||||
pub fn selection_lines(&self, pane: &Arc<dyn Pane>) -> Vec<Line> {
|
||||
let mut result = vec![];
|
||||
|
||||
let rectangular = self.selection(pane.pane_id()).rectangular;
|
||||
@ -63,7 +63,7 @@ impl super::TermWindow {
|
||||
}
|
||||
|
||||
/// Returns the selection text only
|
||||
pub fn selection_text(&self, pane: &Rc<dyn Pane>) -> String {
|
||||
pub fn selection_text(&self, pane: &Arc<dyn Pane>) -> String {
|
||||
let mut s = String::new();
|
||||
let rectangular = self.selection(pane.pane_id()).rectangular;
|
||||
if let Some(sel) = self
|
||||
@ -109,14 +109,14 @@ impl super::TermWindow {
|
||||
s
|
||||
}
|
||||
|
||||
pub fn clear_selection(&mut self, pane: &Rc<dyn Pane>) {
|
||||
pub fn clear_selection(&mut self, pane: &Arc<dyn Pane>) {
|
||||
let mut selection = self.selection(pane.pane_id());
|
||||
selection.clear();
|
||||
selection.seqno = pane.get_current_seqno();
|
||||
self.window.as_ref().unwrap().invalidate();
|
||||
}
|
||||
|
||||
pub fn extend_selection_at_mouse_cursor(&mut self, mode: SelectionMode, pane: &Rc<dyn Pane>) {
|
||||
pub fn extend_selection_at_mouse_cursor(&mut self, mode: SelectionMode, pane: &Arc<dyn Pane>) {
|
||||
self.selection(pane.pane_id()).seqno = pane.get_current_seqno();
|
||||
let (position, y) = match self.pane_state(pane.pane_id()).mouse_terminal_coords {
|
||||
Some(coords) => coords,
|
||||
@ -240,7 +240,7 @@ impl super::TermWindow {
|
||||
self.window.as_ref().unwrap().invalidate();
|
||||
}
|
||||
|
||||
pub fn select_text_at_mouse_cursor(&mut self, mode: SelectionMode, pane: &Rc<dyn Pane>) {
|
||||
pub fn select_text_at_mouse_cursor(&mut self, mode: SelectionMode, pane: &Arc<dyn Pane>) {
|
||||
let (x, y) = match self.pane_state(pane.pane_id()).mouse_terminal_coords {
|
||||
Some(coords) => (coords.0.column, coords.1),
|
||||
None => return,
|
||||
|
@ -9,7 +9,6 @@ use mux::tab::TabId;
|
||||
use mux::Mux;
|
||||
use promise::spawn::spawn_into_main_thread;
|
||||
use std::collections::HashMap;
|
||||
use std::rc::Rc;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::time::Instant;
|
||||
use termwiz::surface::SequenceNo;
|
||||
@ -51,7 +50,7 @@ pub(crate) struct PerPane {
|
||||
impl PerPane {
|
||||
fn compute_changes(
|
||||
&mut self,
|
||||
pane: &Rc<dyn Pane>,
|
||||
pane: &Arc<dyn Pane>,
|
||||
force_with_input_serial: Option<InputSerial>,
|
||||
) -> Option<GetPaneRenderChangesResponse> {
|
||||
let mut changed = false;
|
||||
@ -139,7 +138,7 @@ impl PerPane {
|
||||
}
|
||||
|
||||
fn maybe_push_pane_changes(
|
||||
pane: &Rc<dyn Pane>,
|
||||
pane: &Arc<dyn Pane>,
|
||||
sender: PduSender,
|
||||
per_pane: Arc<Mutex<PerPane>>,
|
||||
) -> anyhow::Result<()> {
|
||||
|
Loading…
Reference in New Issue
Block a user