diff --git a/src/frontend/guicommon/localtab.rs b/src/frontend/guicommon/localtab.rs index 909cfba6e..554f7c425 100644 --- a/src/frontend/guicommon/localtab.rs +++ b/src/frontend/guicommon/localtab.rs @@ -1,3 +1,4 @@ +use crate::mux::domain::DomainId; use crate::mux::renderable::Renderable; use crate::mux::tab::{alloc_tab_id, Tab, TabId}; use failure::Error; @@ -11,6 +12,7 @@ pub struct LocalTab { terminal: RefCell, process: RefCell>, pty: RefCell>, + domain_id: DomainId, } impl Tab for LocalTab { @@ -85,16 +87,26 @@ impl Tab for LocalTab { fn palette(&self) -> ColorPalette { self.terminal.borrow().palette().clone() } + + fn domain_id(&self) -> DomainId { + self.domain_id + } } impl LocalTab { - pub fn new(terminal: Terminal, process: Box, pty: Box) -> Self { + pub fn new( + terminal: Terminal, + process: Box, + pty: Box, + domain_id: DomainId, + ) -> Self { let tab_id = alloc_tab_id(); Self { tab_id, terminal: RefCell::new(terminal), process: RefCell::new(process), pty: RefCell::new(pty), + domain_id, } } } diff --git a/src/mux/domain.rs b/src/mux/domain.rs index 0b701605c..2946bb0b2 100644 --- a/src/mux/domain.rs +++ b/src/mux/domain.rs @@ -16,21 +16,38 @@ use portable_pty::{PtySize, PtySystem}; use std::rc::Rc; use std::sync::Arc; +static DOMAIN_ID: ::std::sync::atomic::AtomicUsize = ::std::sync::atomic::AtomicUsize::new(0); +pub type DomainId = usize; + +pub fn alloc_domain_id() -> DomainId { + DOMAIN_ID.fetch_add(1, ::std::sync::atomic::Ordering::Relaxed) +} + pub trait Domain { /// Spawn a new command within this domain fn spawn(&self, size: PtySize, command: Option) -> Result, Error>; + + /// Returns the domain id, which is useful for obtaining + /// a handle on the domain later. + fn domain_id(&self) -> DomainId; } pub struct LocalDomain { pty_system: Box, config: Arc, + id: DomainId, } impl LocalDomain { pub fn new(config: &Arc) -> Result { let config = Arc::clone(config); let pty_system = config.pty.get()?; - Ok(Self { pty_system, config }) + let id = alloc_domain_id(); + Ok(Self { + pty_system, + config, + id, + }) } } @@ -51,10 +68,14 @@ impl Domain for LocalDomain { self.config.hyperlink_rules.clone(), ); - let tab: Rc = Rc::new(LocalTab::new(terminal, child, master)); + let tab: Rc = Rc::new(LocalTab::new(terminal, child, master, self.id)); Mux::get().unwrap().add_tab(&tab)?; Ok(tab) } + + fn domain_id(&self) -> DomainId { + self.id + } } diff --git a/src/mux/mod.rs b/src/mux/mod.rs index 24dfc86c0..f5bc663f7 100644 --- a/src/mux/mod.rs +++ b/src/mux/mod.rs @@ -21,13 +21,14 @@ pub mod window; use crate::mux::tab::{Tab, TabId}; use crate::mux::window::{Window, WindowId}; -use domain::Domain; +use domain::{Domain, DomainId}; pub struct Mux { tabs: RefCell>>, windows: RefCell>, config: Arc, default_domain: Arc, + domains: RefCell>>, } fn read_from_tab_pty(tab_id: TabId, mut reader: Box) { @@ -106,11 +107,15 @@ thread_local! { impl Mux { pub fn new(config: &Arc, default_domain: &Arc) -> Self { + let mut domains = HashMap::new(); + domains.insert(default_domain.domain_id(), Arc::clone(default_domain)); + Self { tabs: RefCell::new(HashMap::new()), windows: RefCell::new(HashMap::new()), config: Arc::clone(config), default_domain: Arc::clone(default_domain), + domains: RefCell::new(domains), } } @@ -118,6 +123,18 @@ impl Mux { &self.default_domain } + #[allow(dead_code)] + pub fn get_domain(&self, id: DomainId) -> Option> { + self.domains.borrow().get(&id).cloned() + } + + #[allow(dead_code)] + pub fn add_domain(&self, domain: &Arc) { + self.domains + .borrow_mut() + .insert(domain.domain_id(), Arc::clone(domain)); + } + pub fn config(&self) -> &Arc { &self.config } diff --git a/src/mux/tab.rs b/src/mux/tab.rs index 95b2bd8ea..11e73ac65 100644 --- a/src/mux/tab.rs +++ b/src/mux/tab.rs @@ -1,3 +1,4 @@ +use crate::mux::domain::DomainId; use crate::mux::renderable::Renderable; use failure::Error; use std::cell::RefMut; @@ -30,4 +31,5 @@ pub trait Tab { fn advance_bytes(&self, buf: &[u8], host: &mut dyn TerminalHost); fn is_dead(&self) -> bool; fn palette(&self) -> ColorPalette; + fn domain_id(&self) -> DomainId; }