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

factor out clipboard bits as a trait

This will make it easier to plug in macos support later.
This commit is contained in:
Wez Furlong 2018-02-22 22:53:50 -08:00
parent 315d9732c9
commit 4878aef542
4 changed files with 75 additions and 32 deletions

View File

@ -1,2 +1,35 @@
use failure::Error;
mod none;
#[cfg(target_os = "macos")]
pub use self::none::NoClipboard as Clipboard;
#[cfg(all(unix, not(target_os = "macos")))]
pub mod x11;
mod x11;
#[cfg(all(unix, not(target_os = "macos")))]
pub use self::x11::Clipboard;
use wakeup::Wakeup;
/// A fragment of the clipboard data received from another
/// app during paste.
#[derive(Debug)]
pub enum Paste {
/// The whole content of the paste is available
All(String),
/// Someone else now owns the selection. You should
/// clear the selection locally.
Cleared,
/// The clipboard window has initialized successfully
Running,
}
/// Abstracts away system specific clipboard implementation details.
pub trait ClipboardImpl {
fn new(wakeup: Wakeup) -> Result<Self, Error>
where
Self: Sized;
fn set_clipboard(&self, text: Option<String>) -> Result<(), Error>;
fn get_clipboard(&self) -> Result<String, Error>;
}

21
src/clipboard/none.rs Normal file
View File

@ -0,0 +1,21 @@
use clipboard::ClipboardImpl;
use failure::Error;
use wakeup::Wakeup;
/// A no-op clipboard implementation
#[allow(dead_code)]
pub struct NoClipboard {}
impl ClipboardImpl for NoClipboard {
fn new(_wakeup: Wakeup) -> Result<Self, Error> {
Ok(Self {})
}
fn set_clipboard(&self, _text: Option<String>) -> Result<(), Error> {
Ok(())
}
fn get_clipboard(&self) -> Result<String, Error> {
Ok("".into())
}
}

View File

@ -9,18 +9,7 @@ use wakeup::{Wakeup, WakeupMsg};
use xcb;
use xcb_util;
/// A fragment of the clipboard data received from another
/// app during paste.
#[derive(Debug)]
pub enum Paste {
/// The whole content of the paste is available
All(String),
/// Someone else now owns the selection. You should
/// clear the selection locally.
Cleared,
/// The clipboard window has initialized successfully
Running,
}
use clipboard::{ClipboardImpl, Paste};
#[derive(Debug)]
enum ClipRequest {
@ -33,7 +22,7 @@ enum ClipRequest {
Terminate,
}
struct ClipboardImpl {
struct Inner {
/// if we own the clipboard, here's its string content
owned: Option<String>,
receiver: Receiver<ClipRequest>,
@ -47,7 +36,7 @@ struct ClipboardImpl {
wakeup: Wakeup,
}
impl ClipboardImpl {
impl Inner {
fn new(
receiver: Receiver<ClipRequest>,
sender: Sender<Paste>,
@ -95,7 +84,7 @@ impl ClipboardImpl {
).request_check()?;
}
Ok(ClipboardImpl {
Ok(Inner {
conn,
owned: None,
receiver,
@ -334,13 +323,13 @@ pub struct Clipboard {
clip_thread: JoinHandle<()>,
}
impl Clipboard {
impl ClipboardImpl for Clipboard {
/// Create a new clipboard instance. `ping` is
pub fn new(wakeup: Wakeup) -> Result<Self, Error> {
fn new(wakeup: Wakeup) -> Result<Self, Error> {
let (sender_clip, receiver_clip) = channel();
let (sender_paste, receiver_paste) = channel();
let clip_thread = thread::spawn(move || {
match ClipboardImpl::new(receiver_clip, sender_paste, wakeup) {
match Inner::new(receiver_clip, sender_paste, wakeup) {
Ok(mut clip) => clip.clip_thread(),
Err(err) => eprintln!("failed to init clipboard window: {:?}", err),
}
@ -360,11 +349,22 @@ impl Clipboard {
}
/// Tell X that we own the selection and its contents are `text`
pub fn set_clipboard(&self, text: Option<String>) -> Result<(), Error> {
fn set_clipboard(&self, text: Option<String>) -> Result<(), Error> {
self.sender.send(ClipRequest::SetClipboard(text))?;
Ok(())
}
/// Blocks until the clipboard contents have been retrieved
fn get_clipboard(&self) -> Result<String, Error> {
self.request_clipboard()?;
match self.receiver().recv_timeout(Duration::from_secs(10)) {
Ok(Paste::All(result)) => return Ok(result),
Ok(Paste::Cleared) => return Ok("".into()),
other @ _ => bail!("unexpected result while waiting for paste: {:?}", other),
}
}
}
impl Clipboard {
/// Ask the selection owner for the clipboard contents.
/// The contents will be delivered asynchronously via
/// the receiver.
@ -376,16 +376,6 @@ impl Clipboard {
pub fn receiver(&self) -> &Receiver<Paste> {
&self.receiver
}
/// Blocks until the clipboard contents have been retrieved
pub fn get_clipboard(&self) -> Result<String, Error> {
self.request_clipboard()?;
match self.receiver().recv_timeout(Duration::from_secs(10)) {
Ok(Paste::All(result)) => return Ok(result),
Ok(Paste::Cleared) => return Ok("".into()),
other @ _ => bail!("unexpected result while waiting for paste: {:?}", other),
}
}
}
impl Drop for Clipboard {

View File

@ -1,7 +1,7 @@
//! Generic system dependent windows via glium+glutin
#![allow(dead_code)]
use clipboard::x11::Clipboard;
use clipboard::{Clipboard, ClipboardImpl, Paste};
use failure::Error;
use font::FontConfiguration;
use glium::{self, glutin};
@ -468,7 +468,6 @@ impl TerminalWindow {
}
fn process_clipboard(&mut self) -> Result<(), Error> {
use clipboard::x11::Paste;
match self.host.clipboard.receiver().try_recv() {
Ok(Paste::Cleared) => {
self.terminal.clear_selection();