1
1
mirror of https://github.com/wez/wezterm.git synced 2024-12-01 00:35:46 +03:00

extract some gui running code

This breaks the x11 flavor of the build for the moment.
This commit is contained in:
Wez Furlong 2019-02-19 21:57:12 -08:00
parent 4ab73ebb2c
commit ee06d34b18
4 changed files with 133 additions and 69 deletions

View File

@ -3,7 +3,8 @@
use crate::config::Config;
use crate::failure::Error;
use crate::font::FontConfiguration;
use crate::guiloop::{GuiEventLoop, SessionTerminated};
use crate::guiloop::glutinloop::GuiEventLoop;
use crate::guiloop::SessionTerminated;
use crate::opengl::render::Renderer;
use crate::opengl::textureatlas::OutOfTextureSpace;
use crate::Child;

View File

@ -1,7 +1,12 @@
use crate::config::Config;
use crate::font::FontConfiguration;
use crate::futurecore;
use crate::gliumwindows;
pub use crate::gliumwindows::TerminalWindow;
use crate::guiloop::SessionTerminated;
#[cfg(unix)]
use crate::sigchld;
use crate::{Child, MasterPty};
use failure::Error;
use futures::future;
use glium;
@ -15,11 +20,6 @@ use std::sync::mpsc::{self, Receiver, SyncSender, TryRecvError};
use std::thread;
use std::time::{Duration, SystemTime};
use crate::futurecore;
use crate::gliumwindows;
#[cfg(unix)]
use crate::sigchld;
#[derive(Clone)]
pub struct GuiSender<T: Send> {
tx: SyncSender<T>,
@ -83,7 +83,91 @@ pub struct GuiEventLoop {
const TICK_INTERVAL: Duration = Duration::from_millis(50);
const MAX_POLL_LOOP_DURATION: Duration = Duration::from_millis(500);
impl super::GuiSystem for GuiEventLoop {}
pub struct GlutinGuiSystem {
event_loop: Rc<GuiEventLoop>,
}
use super::GuiSystem;
impl GlutinGuiSystem {
pub fn new() -> Result<Rc<GuiSystem>, Error> {
let event_loop = Rc::new(GuiEventLoop::new()?);
Ok(Rc::new(Self { event_loop }))
}
fn process_spawn(
&self,
config: &Rc<Config>,
fonts: &Rc<FontConfiguration>,
) -> Result<(), Error> {
loop {
match self.event_loop.spawn_rx.try_recv() {
Ok(SpawnRequest::Window) => {
crate::spawn_window(&*self, None, config, fonts)?;
}
Ok(SpawnRequest::Tab(_window_id)) => {
eprintln!("Spawning tabs is not yet implemented for glutin");
}
Err(TryRecvError::Empty) => return Ok(()),
Err(err) => bail!("sigchld_rx disconnected {:?}", err),
}
}
}
}
impl GuiSystem for GlutinGuiSystem {
/// Run the event loop. Does not return until there is either a fatal
/// error, or until there are no more windows left to manage.
fn run_forever(
&self,
config: &Rc<crate::config::Config>,
fontconfig: &Rc<crate::font::FontConfiguration>,
) -> Result<(), Error> {
// This convoluted run() signature is present because of this issue:
// https://github.com/tomaka/winit/issues/413
let myself = &self.event_loop;
loop {
myself.process_futures();
// Check the window count; if after processing the futures there
// are no windows left, then we are done.
{
let windows = myself.windows.borrow();
if windows.by_id.is_empty() {
debug!("No more windows; done!");
return Ok(());
}
}
myself.run_event_loop()?;
myself.process_poll()?;
self.process_spawn(config, fontconfig)?;
#[cfg(unix)]
myself.process_sigchld()?;
myself.process_tick()?;
}
}
fn spawn_new_window(
&self,
terminal: term::Terminal,
master: MasterPty,
child: Child,
config: &Rc<crate::config::Config>,
fontconfig: &Rc<crate::font::FontConfiguration>,
) -> Result<(), Error> {
let window = TerminalWindow::new(
&self.event_loop,
terminal,
master,
child,
fontconfig,
config,
)?;
self.event_loop.add_window(window)
}
}
impl GuiEventLoop {
pub fn new() -> Result<Self, Error> {
@ -336,52 +420,4 @@ impl GuiEventLoop {
}
}
}
fn process_spawn(
myself: &Rc<Self>,
config: &Rc<Config>,
fonts: &Rc<FontConfiguration>,
) -> Result<(), Error> {
loop {
match myself.spawn_rx.try_recv() {
Ok(SpawnRequest::Window) => {
crate::spawn_window(myself, None, config, fonts)?;
}
Ok(SpawnRequest::Tab(_window_id)) => {
eprintln!("Spawning tabs is not yet implemented for glutin");
}
Err(TryRecvError::Empty) => return Ok(()),
Err(err) => bail!("sigchld_rx disconnected {:?}", err),
}
}
}
/// Run the event loop. Does not return until there is either a fatal
/// error, or until there are no more windows left to manage.
pub fn run(
myself: &Rc<Self>,
config: &Rc<Config>,
fonts: &Rc<FontConfiguration>,
) -> Result<(), Error> {
loop {
myself.process_futures();
// Check the window count; if after processing the futures there
// are no windows left, then we are done.
{
let windows = myself.windows.borrow();
if windows.by_id.is_empty() {
debug!("No more windows; done!");
return Ok(());
}
}
myself.run_event_loop()?;
myself.process_poll()?;
Self::process_spawn(myself, config, fonts)?;
#[cfg(unix)]
myself.process_sigchld()?;
myself.process_tick()?;
}
}
}

View File

@ -1,5 +1,9 @@
use super::ExitStatus;
use crate::config::Config;
use crate::font::FontConfiguration;
use crate::{Child, MasterPty};
use failure::Error;
use std::rc::Rc;
#[derive(Debug, Deserialize, Clone, Copy)]
pub enum GuiSelection {
@ -19,10 +23,36 @@ impl Default for GuiSelection {
}
}
pub trait GuiSystem {}
impl GuiSelection {
pub fn new(&self) -> Result<Rc<GuiSystem>, Error> {
match self {
GuiSelection::Glutin => glutinloop::GlutinGuiSystem::new(),
GuiSelection::X11 => {
//#[cfg!(all(unix, not(target_os = "macos")))]
bail!("X11 not compiled in");
}
}
}
}
#[cfg(any(windows, feature = "force-glutin", target_os = "macos"))]
mod glutinloop;
pub trait GuiSystem {
fn run_forever(
&self,
config: &Rc<Config>,
fontconfig: &Rc<FontConfiguration>,
) -> Result<(), Error>;
fn spawn_new_window(
&self,
terminal: term::Terminal,
master: MasterPty,
child: Child,
config: &Rc<Config>,
fontconfig: &Rc<FontConfiguration>,
) -> Result<(), Error>;
}
pub mod glutinloop;
#[cfg(any(windows, feature = "force-glutin", target_os = "macos"))]
pub use self::glutinloop::{GuiEventLoop, GuiSender, TerminalWindow, WindowId};

View File

@ -24,7 +24,7 @@ mod opengl;
mod gliumwindows;
mod guiloop;
use crate::guiloop::{GuiEventLoop, TerminalWindow};
use crate::guiloop::GuiSystem;
mod font;
use crate::font::FontConfiguration;
@ -105,17 +105,16 @@ fn main() -> Result<(), Error> {
None
};
let event_loop = Rc::new(GuiEventLoop::new()?);
let guitype = guiloop::GuiSelection::default();
spawn_window(&event_loop, cmd, &config, &fontconfig)?;
// This convoluted run() signature is present because of this issue:
// https://github.com/tomaka/winit/issues/413
GuiEventLoop::run(&event_loop, &config, &fontconfig)?;
Ok(())
let gui = guitype.new()?;
spawn_window(&*gui, cmd, &config, &fontconfig)?;
gui.run_forever(&config, &fontconfig)
}
fn spawn_window(
event_loop: &Rc<GuiEventLoop>,
gui: &GuiSystem,
cmd: Option<Vec<&std::ffi::OsStr>>,
config: &Rc<config::Config>,
fontconfig: &Rc<FontConfiguration>,
@ -163,7 +162,5 @@ fn spawn_window(
config.hyperlink_rules.clone(),
);
let window = TerminalWindow::new(event_loop, terminal, master, child, fontconfig, config)?;
event_loop.add_window(window)
gui.spawn_new_window(terminal, master, child, config, fontconfig)
}