From 5b84b6dfc94ab8e06ae13e5743f103be9e2c0944 Mon Sep 17 00:00:00 2001 From: Wez Furlong Date: Sun, 24 Feb 2019 08:36:59 -0800 Subject: [PATCH] start moving some host functions to guicommon; clipboard first --- src/gliumwindows.rs | 51 ++++++++------------------------------ src/guicommon/host.rs | 57 +++++++++++++++++++++++++++++++++++++++++++ src/guicommon/mod.rs | 1 + src/xwindows/xwin.rs | 28 +++++++-------------- 4 files changed, 77 insertions(+), 60 deletions(-) create mode 100644 src/guicommon/host.rs diff --git a/src/gliumwindows.rs b/src/gliumwindows.rs index 148232c69..965cabacf 100644 --- a/src/gliumwindows.rs +++ b/src/gliumwindows.rs @@ -3,13 +3,13 @@ use crate::config::Config; use crate::failure::Error; use crate::font::FontConfiguration; +use crate::guicommon::host::{HostHelper, HostImpl}; use crate::guicommon::tabs::{Tab, TabId, Tabs}; use crate::guicommon::window::{Dimensions, TerminalWindow}; use crate::guiloop::glutinloop::GuiEventLoop; use crate::guiloop::SessionTerminated; use crate::opengl::render::Renderer; use crate::{spawn_window_impl, Child, MasterPty}; -use clipboard::{ClipboardContext, ClipboardProvider}; use glium; use glium::glutin::dpi::{LogicalPosition, LogicalSize, PhysicalPosition, PhysicalSize}; use glium::glutin::{self, ElementState, MouseCursor}; @@ -29,13 +29,12 @@ use winit::os::macos::WindowExt; /// other state. struct TabHost<'a> { pty: &'a mut MasterPty, - host: &'a mut Host, + host: &'a mut HostImpl, } struct Host { event_loop: Rc, display: glium::Display, - clipboard: Clipboard, window_position: Option, /// if is_some, holds position to be restored after exiting /// fullscreen mode. @@ -44,37 +43,7 @@ struct Host { fonts: Rc, } -/// macOS gets unhappy if we set up the clipboard too early, -/// so we use this to defer it until we use it -#[derive(Default)] -struct Clipboard { - clipboard: Option, -} - -impl Clipboard { - fn clipboard(&mut self) -> Result<&mut ClipboardContext, Error> { - if self.clipboard.is_none() { - self.clipboard = Some(ClipboardContext::new().map_err(|e| format_err!("{}", e))?); - } - Ok(self.clipboard.as_mut().unwrap()) - } - - pub fn get_clipboard(&mut self) -> Result { - self.clipboard()? - .get_contents() - .map_err(|e| format_err!("{}", e)) - } - - pub fn set_clipboard(&mut self, clip: Option) -> Result<(), Error> { - self.clipboard()? - .set_contents(clip.unwrap_or_else(|| "".into())) - .map_err(|e| format_err!("{}", e))?; - // Request the clipboard contents we just set; on some systems - // if we copy and paste in wezterm, the clipboard isn't visible - // to us again until the second call to get_clipboard. - self.get_clipboard().map(|_| ()) - } -} +impl HostHelper for Host {} impl<'a> term::TerminalHost for TabHost<'a> { fn writer(&mut self) -> &mut Write { @@ -88,11 +57,11 @@ impl<'a> term::TerminalHost for TabHost<'a> { } fn get_clipboard(&mut self) -> Result { - self.host.clipboard.get_clipboard() + self.host.get_clipboard() } fn set_clipboard(&mut self, clip: Option) -> Result<(), Error> { - self.host.clipboard.set_clipboard(clip) + self.host.set_clipboard(clip) } fn set_title(&mut self, _title: &str) { @@ -102,8 +71,8 @@ impl<'a> term::TerminalHost for TabHost<'a> { } fn toggle_full_screen(&mut self) { - let window = self.host.display.gl_window(); if let Some(pos) = self.host.is_fullscreen.take() { + let window = self.host.display.gl_window(); // Use simple fullscreen mode on macos, as wez personally // prefers the faster transition to/from this mode than // the Lion+ slow transition to a new Space. This could @@ -120,6 +89,7 @@ impl<'a> term::TerminalHost for TabHost<'a> { // on Linux. self.host.is_fullscreen = self.host.window_position.take(); + let window = self.host.display.gl_window(); #[cfg(target_os = "macos")] window.set_simple_fullscreen(true); #[cfg(not(target_os = "macos"))] @@ -196,7 +166,7 @@ impl<'a> term::TerminalHost for TabHost<'a> { } pub struct GliumTerminalWindow { - host: Host, + host: HostImpl, event_loop: Rc, config: Rc, fonts: Rc, @@ -336,15 +306,14 @@ impl GliumTerminalWindow { }; let window_position = display.gl_window().get_position(); - let host = Host { + let host = HostImpl::new(Host { event_loop: Rc::clone(event_loop), display, - clipboard: Clipboard::default(), window_position, is_fullscreen: None, config: Rc::clone(config), fonts: Rc::clone(fonts), - }; + }); host.display.gl_window().set_cursor(MouseCursor::Text); diff --git a/src/guicommon/host.rs b/src/guicommon/host.rs new file mode 100644 index 000000000..bdf1aef14 --- /dev/null +++ b/src/guicommon/host.rs @@ -0,0 +1,57 @@ +use clipboard::{ClipboardContext, ClipboardProvider}; +use failure::Error; +use std::ops::{Deref, DerefMut}; + +pub trait HostHelper { +} + +pub struct HostImpl { + helper: H, + /// macOS gets unhappy if we set up the clipboard too early, + /// so we use an Option to defer it until we use it + clipboard: Option, +} + +impl HostImpl { + pub fn new(helper: H) -> Self { + Self { + helper, + clipboard: None, + } + } + + fn clipboard(&mut self) -> Result<&mut ClipboardContext, Error> { + if self.clipboard.is_none() { + self.clipboard = Some(ClipboardContext::new().map_err(|e| format_err!("{}", e))?); + } + Ok(self.clipboard.as_mut().unwrap()) + } + + pub fn get_clipboard(&mut self) -> Result { + self.clipboard()? + .get_contents() + .map_err(|e| format_err!("{}", e)) + } + + pub fn set_clipboard(&mut self, clip: Option) -> Result<(), Error> { + self.clipboard()? + .set_contents(clip.unwrap_or_else(|| "".into())) + .map_err(|e| format_err!("{}", e))?; + // Request the clipboard contents we just set; on some systems + // if we copy and paste in wezterm, the clipboard isn't visible + // to us again until the second call to get_clipboard. + self.get_clipboard().map(|_| ()) + } +} + +impl Deref for HostImpl { + type Target = H; + fn deref(&self) -> &H { + &self.helper + } +} +impl DerefMut for HostImpl { + fn deref_mut(&mut self) -> &mut H { + &mut self.helper + } +} diff --git a/src/guicommon/mod.rs b/src/guicommon/mod.rs index 68d1d4179..16e470131 100644 --- a/src/guicommon/mod.rs +++ b/src/guicommon/mod.rs @@ -1,2 +1,3 @@ +pub mod host; pub mod tabs; pub mod window; diff --git a/src/xwindows/xwin.rs b/src/xwindows/xwin.rs index 2d09d482c..9c96e4036 100644 --- a/src/xwindows/xwin.rs +++ b/src/xwindows/xwin.rs @@ -4,12 +4,12 @@ use super::xkeysyms; use super::{Connection, Window}; use crate::config::Config; use crate::font::FontConfiguration; +use crate::guicommon::host::{HostHelper, HostImpl}; use crate::guicommon::tabs::{Tab, TabId, Tabs}; use crate::guicommon::window::{Dimensions, TerminalWindow}; use crate::guiloop::x11::{GuiEventLoop, WindowId}; use crate::guiloop::SessionTerminated; use crate::MasterPty; -use clipboard::{ClipboardContext, ClipboardProvider}; use failure::Error; use futures; use std::cell::RefMut; @@ -24,20 +24,21 @@ use xcb; /// other state. struct TabHost<'a> { pty: &'a mut MasterPty, - host: &'a mut Host, + host: &'a mut HostImpl, } /// Holds most of the information we need to implement `TerminalHost` struct Host { window: Window, - clipboard: ClipboardContext, event_loop: Rc, fonts: Rc, config: Rc, } +impl HostHelper for Host {} + pub struct X11TerminalWindow { - host: Host, + host: HostImpl, conn: Rc, fonts: Rc, renderer: Renderer, @@ -78,21 +79,11 @@ impl<'a> term::TerminalHost for TabHost<'a> { } fn get_clipboard(&mut self) -> Result { - self.host - .clipboard - .get_contents() - .map_err(|e| format_err!("{}", e)) + self.host.get_clipboard() } fn set_clipboard(&mut self, clip: Option) -> Result<(), Error> { - self.host - .clipboard - .set_contents(clip.unwrap_or_else(|| "".into())) - .map_err(|e| format_err!("{}", e)) - // Request the clipboard contents we just set; on some systems - // if we copy and paste in wezterm, the clipboard isn't visible - // to us again until the second call to get_clipboard. - .and_then(|_| self.get_clipboard().map(|_| ())) + self.host.set_clipboard(clip) } fn set_title(&mut self, _title: &str) { @@ -266,13 +257,12 @@ impl X11TerminalWindow { let window = Window::new(&event_loop.conn, width, height)?; window.set_title("wezterm"); - let host = Host { + let host = HostImpl::new(Host { window, - clipboard: ClipboardContext::new().map_err(|e| format_err!("{}", e))?, event_loop: Rc::clone(event_loop), config: Rc::clone(config), fonts: Rc::clone(fonts), - }; + }); let renderer = Renderer::new(&host.window, width, height, fonts, palette)?; let cell_height = cell_height.ceil() as usize;