diff --git a/src/frontend/glium/glutinloop.rs b/src/frontend/glium/glutinloop.rs index 09bad0577..1b33e6aad 100644 --- a/src/frontend/glium/glutinloop.rs +++ b/src/frontend/glium/glutinloop.rs @@ -1,5 +1,5 @@ use crate::config::Config; -use crate::font::{FontConfiguration, FontSystemSelection}; +use crate::font::FontConfiguration; use crate::frontend::glium::window::GliumTerminalWindow; use crate::frontend::guicommon::window::TerminalWindow; use crate::frontend::FrontEnd; @@ -9,7 +9,6 @@ use failure::{bail, Error}; use glium; use glium::glutin::EventsLoopProxy; use glium::glutin::WindowId; -use portable_pty::PtySize; use promise::{Executor, Future, SpawnFunc}; use std::cell::RefCell; use std::collections::HashMap; @@ -95,7 +94,6 @@ pub struct GuiEventLoop { gui_rx: Receiver, gui_thread_sends: RefCell>, tick_rx: Receiver<()>, - mux: Rc, } const TICK_INTERVAL: Duration = Duration::from_millis(50); @@ -156,7 +154,7 @@ impl FrontEnd for GlutinFrontEnd { } impl GuiEventLoop { - pub fn new(mux: &Rc) -> Result { + pub fn new(_mux: &Rc) -> Result { let event_loop = glium::glutin::EventsLoop::new(); let (gui_tx, gui_rx) = GuiSender::new(event_loop.create_proxy()); @@ -182,7 +180,6 @@ impl GuiEventLoop { tick_rx, event_loop: RefCell::new(event_loop), windows: Rc::new(RefCell::new(Default::default())), - mux: Rc::clone(mux), }) } @@ -206,35 +203,6 @@ impl GuiEventLoop { }) } - fn do_spawn_new_window( - &self, - config: &Arc, - fonts: &Rc, - ) -> Result<(), Error> { - let tab = self.mux.default_domain().spawn(PtySize::default(), None)?; - let events = Self::get().expect("to be called on gui thread"); - let window = GliumTerminalWindow::new(&events, &fonts, &config, &tab)?; - - events.add_window(window) - } - - pub fn schedule_spawn_new_window(&self, config: &Arc) { - let config = Arc::clone(config); - Future::with_executor( - GlutinGuiExecutor { - tx: self.gui_tx.clone(), - }, - move || { - let myself = Self::get().expect("to be called on gui thread"); - let fonts = Rc::new(FontConfiguration::new( - Arc::clone(&config), - FontSystemSelection::get_default(), - )); - myself.do_spawn_new_window(&config, &fonts) - }, - ); - } - pub fn with_window Result<(), Error>>( &self, window_id: WindowId, diff --git a/src/frontend/glium/window.rs b/src/frontend/glium/window.rs index 11019f97c..65ec9a892 100644 --- a/src/frontend/glium/window.rs +++ b/src/frontend/glium/window.rs @@ -29,7 +29,6 @@ struct Host { /// if is_some, holds position to be restored after exiting /// fullscreen mode. is_fullscreen: Option, - config: Arc, } impl HostHelper for Host { @@ -71,7 +70,6 @@ impl HostHelper for Host { pub struct GliumTerminalWindow { host: HostImpl, - event_loop: Rc, config: Arc, fonts: Rc, renderer: Renderer, @@ -227,7 +225,6 @@ impl GliumTerminalWindow { display, window_position, is_fullscreen: None, - config: Arc::clone(config), }); host.display.gl_window().set_cursor(MouseCursor::Text); @@ -241,7 +238,6 @@ impl GliumTerminalWindow { Ok(GliumTerminalWindow { host, - event_loop: Rc::clone(event_loop), config: Arc::clone(config), fonts: Rc::clone(fonts), renderer, @@ -632,11 +628,6 @@ impl GliumTerminalWindow { // debug!("event {:?} -> {:?}", event, key); match event.state { ElementState::Pressed => { - if mods == KeyModifiers::SUPER && key == KeyCode::Char('n') { - self.event_loop.schedule_spawn_new_window(&self.host.config); - return Ok(()); - } - if self.host.process_gui_shortcuts(&*tab, mods, key)? { return Ok(()); } diff --git a/src/frontend/guicommon/host.rs b/src/frontend/guicommon/host.rs index 704e9749b..37327ab5f 100644 --- a/src/frontend/guicommon/host.rs +++ b/src/frontend/guicommon/host.rs @@ -1,11 +1,14 @@ use super::window::TerminalWindow; -use crate::frontend::gui_executor; +use crate::font::{FontConfiguration, FontSystemSelection}; +use crate::frontend::{front_end, gui_executor}; use crate::mux::tab::{Tab, TabId}; use crate::mux::Mux; use clipboard::{ClipboardContext, ClipboardProvider}; use failure::{format_err, Error}; +use portable_pty::PtySize; use promise::Future; use std::ops::{Deref, DerefMut}; +use std::rc::Rc; use std::sync::{Arc, Mutex}; use term::{KeyCode, KeyModifiers}; use termwiz::hyperlink::Hyperlink; @@ -95,6 +98,20 @@ impl HostImpl { self.get_clipboard().map(|_| ()) } + pub fn spawn_new_window(&mut self) { + Future::with_executor(gui_executor().unwrap(), move || { + let mux = Mux::get().unwrap(); + let fonts = Rc::new(FontConfiguration::new( + Arc::clone(mux.config()), + FontSystemSelection::get_default(), + )); + let tab = mux.default_domain().spawn(PtySize::default(), None)?; + let front_end = front_end().expect("to be called on gui thread"); + front_end.spawn_new_window(mux.config(), &fonts, &tab)?; + Ok(()) + }); + } + pub fn process_gui_shortcuts( &mut self, tab: &Tab, @@ -106,6 +123,11 @@ impl HostImpl { return Ok(true); } + if mods == KeyModifiers::SUPER && key == KeyCode::Char('n') { + self.spawn_new_window(); + return Ok(true); + } + if mods == KeyModifiers::ALT && (key == KeyCode::Char('\r') || key == KeyCode::Char('\n') || key == KeyCode::Enter) { diff --git a/src/frontend/mod.rs b/src/frontend/mod.rs index fe7957b47..4458e1087 100644 --- a/src/frontend/mod.rs +++ b/src/frontend/mod.rs @@ -6,6 +6,7 @@ use failure::{format_err, Error}; use lazy_static::lazy_static; use promise::Executor; use serde_derive::*; +use std::cell::RefCell; use std::rc::Rc; use std::sync::{Arc, Mutex}; @@ -38,6 +39,9 @@ impl Default for FrontEndSelection { lazy_static! { static ref EXECUTOR: Mutex>> = Mutex::new(None); } +thread_local! { + static FRONT_END: RefCell>> = RefCell::new(None); +} pub fn gui_executor() -> Option> { let locked = EXECUTOR.lock().unwrap(); @@ -47,6 +51,16 @@ pub fn gui_executor() -> Option> { } } +pub fn front_end() -> Option> { + let mut res = None; + FRONT_END.with(|f| { + if let Some(me) = &*f.borrow() { + res = Some(Rc::clone(me)); + } + }); + res +} + impl FrontEndSelection { pub fn try_new(self, mux: &Rc) -> Result, Error> { let front_end = match self { @@ -60,6 +74,7 @@ impl FrontEndSelection { }?; EXECUTOR.lock().unwrap().replace(front_end.gui_executor()); + FRONT_END.with(|f| *f.borrow_mut() = Some(Rc::clone(&front_end))); Ok(front_end) } diff --git a/src/frontend/xwindows/x11loop.rs b/src/frontend/xwindows/x11loop.rs index 22ab2989d..2cebe536b 100644 --- a/src/frontend/xwindows/x11loop.rs +++ b/src/frontend/xwindows/x11loop.rs @@ -215,23 +215,6 @@ impl GuiEventLoop { events.add_window(window) } - pub fn schedule_spawn_new_window(&self, config: &Arc) { - let config = Arc::clone(config); - Future::with_executor( - X11GuiExecutor { - tx: self.gui_tx.clone(), - }, - move || { - let myself = Self::get().expect("to be called on gui thread"); - let fonts = Rc::new(FontConfiguration::new( - Arc::clone(&config), - FontSystemSelection::get_default(), - )); - myself.do_spawn_new_window(&config, &fonts) - }, - ); - } - pub fn add_window(&self, window: X11TerminalWindow) -> Result<(), Error> { let window_id = window.window_id(); diff --git a/src/frontend/xwindows/xwin.rs b/src/frontend/xwindows/xwin.rs index 74318955c..16346c8b5 100644 --- a/src/frontend/xwindows/xwin.rs +++ b/src/frontend/xwindows/xwin.rs @@ -202,13 +202,6 @@ impl X11TerminalWindow { None => return Ok(()), }; if let Some((code, mods)) = self.decode_key(key_press) { - if mods == KeyModifiers::SUPER && code == KeyCode::Char('n') { - self.host - .event_loop - .schedule_spawn_new_window(&self.host.config); - return Ok(()); - } - if self.host.process_gui_shortcuts(&*tab, mods, code)? { return Ok(()); }