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

introduce mux Domain concept

All locations that were setting up ptys now do so via the
Domain concept.  We still need a way to set up a persistent
global domain.
This commit is contained in:
Wez Furlong 2019-03-26 08:22:16 -07:00
parent 7b8a989e10
commit f642bd56d6
7 changed files with 90 additions and 56 deletions

View File

@ -64,6 +64,17 @@ pub struct PtySize {
pub pixel_height: u16,
}
impl Default for PtySize {
fn default() -> Self {
PtySize {
rows: 24,
cols: 80,
pixel_width: 0,
pixel_height: 0,
}
}
}
/// Represents the master/control end of the pty
pub trait MasterPty: std::io::Write {
/// Inform the kernel and thus the child process that the window resized.

View File

@ -215,7 +215,7 @@ impl GuiEventLoop {
config: &Arc<Config>,
fonts: &Rc<FontConfiguration>,
) -> Result<(), Error> {
let tab = spawn_tab(&config, None)?;
let tab = spawn_tab(&config)?; // FIXME: Domain
self.mux.add_tab(self.gui_executor(), &tab)?;
let events = Self::get().expect("to be called on gui thread");
let window = GliumTerminalWindow::new(&events, &fonts, &config, &tab)?;

View File

@ -1,6 +1,6 @@
use crate::config::Config;
use crate::font::FontConfiguration;
use crate::frontend::guicommon::localtab::LocalTab;
use crate::mux::domain::{Domain, LocalDomain};
use crate::mux::tab::{Tab, TabId};
use crate::mux::window::WindowId;
use crate::mux::Mux;
@ -8,7 +8,7 @@ use crate::opengl::render::Renderer;
use crate::opengl::textureatlas::OutOfTextureSpace;
use failure::{format_err, Error};
use glium;
use portable_pty::{PtySize, PtySystemSelection};
use portable_pty::PtySize;
use std::rc::Rc;
use std::sync::Arc;
@ -157,35 +157,23 @@ pub trait TerminalWindow {
fn spawn_tab(&mut self) -> Result<TabId, Error> {
let config = self.config();
let domain = LocalDomain::new(config)?; // FIXME: Domain
let dims = self.get_dimensions();
let rows = (dims.height as usize + 1) / dims.cell_height;
let cols = (dims.width as usize + 1) / dims.cell_width;
let pty_sys = PtySystemSelection::default().get()?;
let (pty, slave) = pty_sys.openpty(PtySize {
let size = PtySize {
rows: rows as u16,
cols: cols as u16,
pixel_width: dims.width,
pixel_height: dims.height,
})?;
let cmd = config.build_prog(None)?;
};
let process = slave.spawn_command(cmd)?;
eprintln!("spawned: {:?}", process);
let mux = Mux::get().unwrap();
let terminal = term::Terminal::new(
rows,
cols,
config.scrollback_lines.unwrap_or(3500),
config.hyperlink_rules.clone(),
);
let tab: Rc<Tab> = Rc::new(LocalTab::new(terminal, process, pty));
let tab = domain.spawn(size, None)?;
let tab_id = tab.tab_id();
let mux = Mux::get().unwrap();
let len = {
let mut window = mux

View File

@ -213,7 +213,7 @@ impl GuiEventLoop {
config: &Arc<Config>,
fonts: &Rc<FontConfiguration>,
) -> Result<(), Error> {
let tab = spawn_tab(&config, None)?;
let tab = spawn_tab(&config)?; // FIXME: Domain
self.mux.add_tab(self.gui_executor(), &tab)?;
let events = Self::get().expect("to be called on gui thread");
let window = X11TerminalWindow::new(&events, &fonts, &config, &tab)?;

View File

@ -15,10 +15,11 @@ mod frontend;
mod mux;
mod opengl;
mod server;
use crate::frontend::guicommon::localtab::LocalTab;
use crate::frontend::{FrontEnd, FrontEndSelection};
use crate::mux::domain::{Domain, LocalDomain};
use crate::mux::tab::Tab;
use crate::mux::Mux;
use portable_pty::cmdbuilder::CommandBuilder;
mod font;
use crate::font::{FontConfiguration, FontSystemSelection};
@ -118,7 +119,10 @@ fn run_terminal_gui(config: Arc<config::Config>, opts: &StartCommand) -> Result<
let fontconfig = Rc::new(FontConfiguration::new(Arc::clone(&config), font_system));
let cmd = if !opts.prog.is_empty() {
Some(opts.prog.iter().map(|x| x.as_os_str()).collect())
let argv: Vec<&std::ffi::OsStr> = opts.prog.iter().map(|x| x.as_os_str()).collect();
let mut builder = CommandBuilder::new(&argv[0]);
builder.args(&argv[1..]);
Some(builder)
} else {
None
};
@ -129,7 +133,9 @@ fn run_terminal_gui(config: Arc<config::Config>, opts: &StartCommand) -> Result<
let front_end = opts.front_end.unwrap_or(config.front_end);
let gui = front_end.try_new(&mux)?;
spawn_window(&mux, &*gui, cmd, &fontconfig)?;
let domain = LocalDomain::new(&config)?;
spawn_window(&mux, &domain, &*gui, cmd, &fontconfig)?;
gui.run_forever()
}
@ -185,45 +191,19 @@ fn main() -> Result<(), Error> {
}
}
fn spawn_tab(
config: &Arc<config::Config>,
cmd: Option<Vec<&std::ffi::OsStr>>,
) -> Result<Rc<Tab>, Error> {
let cmd = config.build_prog(cmd)?;
let initial_cols = 80u16;
let initial_rows = 24u16;
let initial_pixel_width = 0;
let initial_pixel_height = 0;
let pty_sys = config.pty.get()?;
let (master, slave) = pty_sys.openpty(PtySize {
rows: initial_rows,
cols: initial_cols,
pixel_width: initial_pixel_width,
pixel_height: initial_pixel_height,
})?;
let child = slave.spawn_command(cmd)?;
eprintln!("spawned: {:?}", child);
let terminal = term::Terminal::new(
initial_rows as usize,
initial_cols as usize,
config.scrollback_lines.unwrap_or(3500),
config.hyperlink_rules.clone(),
);
Ok(Rc::new(LocalTab::new(terminal, child, master)))
fn spawn_tab(config: &Arc<config::Config>) -> Result<Rc<Tab>, Error> {
let domain = LocalDomain::new(config)?;
domain.spawn(PtySize::default(), None)
}
fn spawn_window(
mux: &Rc<Mux>,
domain: &Domain,
gui: &FrontEnd,
cmd: Option<Vec<&std::ffi::OsStr>>,
cmd: Option<CommandBuilder>,
fontconfig: &Rc<FontConfiguration>,
) -> Result<(), Error> {
let tab = spawn_tab(mux.config(), cmd)?;
let tab = domain.spawn(PtySize::default(), cmd)?;
mux.add_tab(gui.gui_executor(), &tab)?;
gui.spawn_new_window(mux.config(), &fontconfig, &tab)

54
src/mux/domain.rs Normal file
View File

@ -0,0 +1,54 @@
//! A Domain represents an instance of a multiplexer.
//! For example, the gui frontend has its own domain,
//! and we can connect to a domain hosted by a mux server
//! that may be local, running "remotely" inside a WSL
//! container or actually remote, running on the other end
//! of an ssh session somewhere.
use crate::config::Config;
use crate::frontend::guicommon::localtab::LocalTab;
use crate::mux::tab::Tab;
use failure::Error;
use portable_pty::cmdbuilder::CommandBuilder;
use portable_pty::{PtySize, PtySystem};
use std::rc::Rc;
use std::sync::Arc;
pub trait Domain {
/// Spawn a new command within this domain
fn spawn(&self, size: PtySize, command: Option<CommandBuilder>) -> Result<Rc<Tab>, Error>;
}
pub struct LocalDomain {
pty_system: Box<PtySystem>,
config: Arc<Config>,
}
impl LocalDomain {
pub fn new(config: &Arc<Config>) -> Result<Self, Error> {
let config = Arc::clone(config);
let pty_system = config.pty.get()?;
Ok(Self { pty_system, config })
}
}
impl Domain for LocalDomain {
fn spawn(&self, size: PtySize, command: Option<CommandBuilder>) -> Result<Rc<Tab>, Error> {
let cmd = match command {
Some(c) => c,
None => self.config.build_prog(None)?,
};
let (master, slave) = self.pty_system.openpty(size)?;
let child = slave.spawn_command(cmd)?;
eprintln!("spawned: {:?}", child);
let terminal = term::Terminal::new(
size.rows as usize,
size.cols as usize,
self.config.scrollback_lines.unwrap_or(3500),
self.config.hyperlink_rules.clone(),
);
Ok(Rc::new(LocalTab::new(terminal, child, master)))
}
}

View File

@ -12,6 +12,7 @@ use std::thread;
use term::TerminalHost;
use termwiz::hyperlink::Hyperlink;
pub mod domain;
pub mod renderable;
pub mod tab;
pub mod window;