1
1
mirror of https://github.com/wez/wezterm.git synced 2024-12-26 14:54:16 +03:00

more plumbing to route window events

This commit is contained in:
Wez Furlong 2018-03-01 21:33:49 -08:00
parent 44694fec95
commit 6e98b10027
6 changed files with 37 additions and 41 deletions

View File

@ -1,4 +1,5 @@
use failure::Error;
use glium::glutin::WindowId;
mod none;
#[cfg(target_os = "macos")]
@ -27,7 +28,7 @@ pub enum Paste {
/// Abstracts away system specific clipboard implementation details.
pub trait ClipboardImpl {
fn new(wakeup: Wakeup) -> Result<Self, Error>
fn new(wakeup: Wakeup, window_id: WindowId) -> Result<Self, Error>
where
Self: Sized;
fn set_clipboard(&self, text: Option<String>) -> Result<(), Error>;

View File

@ -1,5 +1,6 @@
use clipboard::{ClipboardImpl, Paste};
use failure::Error;
use glium::glutin::WindowId;
use std::sync::mpsc::{channel, Receiver, Sender};
use wakeup::Wakeup;
@ -11,7 +12,7 @@ pub struct NoClipboard {
}
impl ClipboardImpl for NoClipboard {
fn new(_wakeup: Wakeup) -> Result<Self, Error> {
fn new(_wakeup: Wakeup, _window_id: WindowId) -> Result<Self, Error> {
let (sender, receiver) = channel();
Ok(Self { sender, receiver })
}

View File

@ -2,6 +2,7 @@
//! Check out https://tronche.com/gui/x/icccm/sec-2.html for some deep and complex
//! background on what's happening in here.
use failure::{self, Error};
use glium::glutin::WindowId;
use mio::{Events, Poll, PollOpt, Ready, Token};
use mio::unix::EventedFd;
use mio_extras::channel::{channel as mio_channel, Receiver as MioReceiver, Sender as MioSender};
@ -38,6 +39,7 @@ struct Inner {
atom_targets: xcb::Atom,
atom_clipboard: xcb::Atom,
wakeup: Wakeup,
wakeup_window_id: WindowId,
}
impl Inner {
@ -45,6 +47,7 @@ impl Inner {
receiver: MioReceiver<ClipRequest>,
sender: Sender<Paste>,
wakeup: Wakeup,
wakeup_window_id: WindowId,
) -> Result<Self, Error> {
let (conn, screen) = xcb::Connection::connect(None)?;
@ -99,17 +102,18 @@ impl Inner {
atom_targets,
atom_clipboard,
wakeup,
wakeup_window_id,
})
}
fn send(&mut self, packet: Paste) -> Result<(), Error> {
match self.sender.send(packet) {
Ok(_) => {
self.wakeup.send(WakeupMsg::Paste)?;
self.wakeup.send(WakeupMsg::Paste(self.wakeup_window_id))?;
Ok(())
}
Err(err) => {
self.wakeup.send(WakeupMsg::Paste)?;
self.wakeup.send(WakeupMsg::Paste(self.wakeup_window_id))?;
bail!("clipboard: error sending to channel: {:?}", err);
}
}
@ -390,11 +394,11 @@ pub struct Clipboard {
impl ClipboardImpl for Clipboard {
/// Create a new clipboard instance. `ping` is
fn new(wakeup: Wakeup) -> Result<Self, Error> {
fn new(wakeup: Wakeup, window_id: WindowId) -> Result<Self, Error> {
let (sender_clip, receiver_clip) = mio_channel();
let (sender_paste, receiver_paste) = channel();
let clip_thread = thread::spawn(move || {
match Inner::new(receiver_clip, sender_paste, wakeup) {
match Inner::new(receiver_clip, sender_paste, wakeup, window_id) {
Ok(mut clip) => clip.clip_thread(),
Err(err) => eprintln!("failed to init clipboard window: {:?}", err),
}

View File

@ -14,13 +14,12 @@ use std::io::{Read, Write};
use std::process::Child;
use std::process::Command;
use std::rc::Rc;
use std::sync::mpsc::Receiver;
use term::{self, Terminal};
use term::{MouseButton, MouseEventKind};
use term::KeyCode;
use term::KeyModifiers;
use term::hyperlink::Hyperlink;
use wakeup::{Wakeup, WakeupMsg};
use wakeup::Wakeup;
struct Host {
display: glium::Display,
@ -65,7 +64,6 @@ pub struct TerminalWindow {
process: Child,
last_mouse_coords: (f64, f64),
last_modifiers: KeyModifiers,
wakeup_receiver: Receiver<WakeupMsg>,
window_position: Option<(i32, i32)>,
/// is is_some, holds position to be restored after exiting
/// fullscreen mode.
@ -76,7 +74,6 @@ impl TerminalWindow {
pub fn new(
event_loop: &glutin::EventsLoop,
wakeup: Wakeup,
wakeup_receiver: Receiver<WakeupMsg>,
width: u16,
height: u16,
terminal: Terminal,
@ -102,11 +99,12 @@ impl TerminalWindow {
.with_srgb(true);
let display =
glium::Display::new(window, context, &event_loop).map_err(|e| format_err!("{:?}", e))?;
let window_id = display.gl_window().id();
let host = Host {
display,
pty,
clipboard: Clipboard::new(wakeup)?,
clipboard: Clipboard::new(wakeup, window_id)?,
};
host.display.gl_window().set_cursor(MouseCursor::Text);
@ -127,7 +125,6 @@ impl TerminalWindow {
process,
last_mouse_coords: (0.0, 0.0),
last_modifiers: Default::default(),
wakeup_receiver,
window_position,
is_fullscreen: None,
})
@ -561,26 +558,12 @@ impl TerminalWindow {
} => {
self.paint()?;
}
Event::Awakened => loop {
match self.wakeup_receiver.try_recv() {
Ok(WakeupMsg::PtyReadable) => self.try_read_pty()?,
Ok(WakeupMsg::SigChld) => self.test_for_child_exit()?,
Ok(WakeupMsg::Paint) => if self.terminal.has_dirty_lines() {
self.paint()?;
},
Ok(WakeupMsg::Paste) => self.process_clipboard()?,
Err(_) => break,
}
},
Event::Suspended(suspended) => {
eprintln!("Suspended {:?}", suspended);
}
_ => {}
}
Ok(())
}
fn process_clipboard(&mut self) -> Result<(), Error> {
pub fn process_clipboard(&mut self) -> Result<(), Error> {
match self.host.clipboard.try_get_paste() {
Ok(Some(Paste::Cleared)) => {
self.terminal.clear_selection();

View File

@ -101,7 +101,6 @@ fn run_glium(
let window = gliumwindows::TerminalWindow::new(
&events_loop,
wakeup.clone(),
wakeup_receiver,
initial_pixel_width,
initial_pixel_height,
terminal,
@ -154,7 +153,7 @@ fn run_glium(
Ok(_) => for event in &events {
if event.token() == Token(0) && event.readiness().is_readable() {
wakeup
.send(WakeupMsg::PtyReadable)
.send(WakeupMsg::PtyReadable(window_id))
.expect("failed to wakeup gui thread");
}
},
@ -181,15 +180,23 @@ fn run_glium(
glium::glutin::ControlFlow::Continue
}
},
Event::Awakened => match windows_by_id
.get_mut(&window_id)
.unwrap()
.dispatch_event(event)
{
Ok(_) => glium::glutin::ControlFlow::Continue,
Err(err) => {
eprintln!("{:?}", err);
glium::glutin::ControlFlow::Break
Event::Awakened => loop {
match wakeup_receiver.try_recv() {
Ok(WakeupMsg::PtyReadable(window_id)) => {
windows_by_id.get_mut(&window_id).map(|w| w.try_read_pty());
}
Ok(WakeupMsg::SigChld) => for (_, window) in windows_by_id.iter_mut() {
window.test_for_child_exit().unwrap();
},
Ok(WakeupMsg::Paint) => for (_, window) in windows_by_id.iter_mut() {
window.paint_if_needed().unwrap();
},
Ok(WakeupMsg::Paste(window_id)) => {
windows_by_id
.get_mut(&window_id)
.map(|w| w.process_clipboard());
}
Err(_) => return glium::glutin::ControlFlow::Continue,
}
},
_ => glium::glutin::ControlFlow::Continue,

View File

@ -1,13 +1,13 @@
use failure::Error;
use glium::glutin::EventsLoopProxy;
use glium::glutin::{EventsLoopProxy, WindowId};
use std::sync::mpsc::{channel, Receiver, Sender};
#[derive(Debug)]
pub enum WakeupMsg {
PtyReadable,
PtyReadable(WindowId),
SigChld,
Paint,
Paste,
Paste(WindowId),
}
#[derive(Clone)]