mirror of
https://github.com/wez/wezterm.git
synced 2024-12-24 13:52:55 +03:00
Implement paste
This commit is contained in:
parent
41eeddb7a1
commit
5d6e7c4f98
@ -1,4 +1,7 @@
|
||||
use anyhow::{anyhow, Error};
|
||||
use filedescriptor::{FileDescriptor, Pipe};
|
||||
use smithay_client_toolkit as toolkit;
|
||||
use std::os::fd::AsRawFd;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use toolkit::reexports::client::protocol::wl_data_offer::WlDataOffer;
|
||||
|
||||
@ -25,6 +28,20 @@ impl CopyAndPaste {
|
||||
Arc::new(Mutex::new(Default::default()))
|
||||
}
|
||||
|
||||
pub(super) fn get_clipboard_data(
|
||||
&mut self,
|
||||
_clipboard: Clipboard,
|
||||
) -> anyhow::Result<FileDescriptor> {
|
||||
// TODO; primary selection
|
||||
let offer = self
|
||||
.data_offer
|
||||
.as_ref()
|
||||
.ok_or_else(|| anyhow!("no data offer"))?;
|
||||
let pipe = Pipe::new().map_err(Error::msg)?;
|
||||
offer.receive(TEXT_MIME_TYPE.to_string(), pipe.write.as_raw_fd());
|
||||
Ok(pipe.read)
|
||||
}
|
||||
|
||||
pub(super) fn set_clipboard_data(&mut self, _clipboard: Clipboard, data: String) {
|
||||
// TODO: primary selection
|
||||
|
||||
|
@ -1,6 +1,5 @@
|
||||
use std::fs::File;
|
||||
use std::io::Write;
|
||||
use std::os::fd::{AsRawFd, FromRawFd, IntoRawFd, OwnedFd};
|
||||
use std::os::fd::{AsRawFd, FromRawFd, IntoRawFd};
|
||||
|
||||
use anyhow::bail;
|
||||
use filedescriptor::FileDescriptor;
|
||||
@ -86,6 +85,7 @@ impl DataOfferHandler for WaylandState {
|
||||
}
|
||||
}
|
||||
|
||||
// Ignore drag and drop events
|
||||
fn source_actions(
|
||||
&mut self,
|
||||
_conn: &wayland_client::Connection,
|
||||
@ -93,7 +93,6 @@ impl DataOfferHandler for WaylandState {
|
||||
_offer: &mut smithay_client_toolkit::data_device_manager::data_offer::DragOffer,
|
||||
_actions: wayland_client::protocol::wl_data_device_manager::DndAction,
|
||||
) {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn selected_action(
|
||||
@ -103,7 +102,6 @@ impl DataOfferHandler for WaylandState {
|
||||
_offer: &mut smithay_client_toolkit::data_device_manager::data_offer::DragOffer,
|
||||
_actions: wayland_client::protocol::wl_data_device_manager::DndAction,
|
||||
) {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
@ -143,9 +141,10 @@ impl DataSourceHandler for WaylandState {
|
||||
&mut self,
|
||||
_conn: &wayland_client::Connection,
|
||||
_qh: &wayland_client::QueueHandle<Self>,
|
||||
_source: &wayland_client::protocol::wl_data_source::WlDataSource,
|
||||
source: &wayland_client::protocol::wl_data_source::WlDataSource,
|
||||
) {
|
||||
todo!()
|
||||
self.copy_paste_source.take();
|
||||
source.destroy();
|
||||
}
|
||||
|
||||
fn dnd_dropped(
|
||||
|
@ -24,7 +24,6 @@ use wayland_client::globals::GlobalList;
|
||||
use wayland_client::protocol::wl_keyboard::WlKeyboard;
|
||||
use wayland_client::protocol::wl_output::WlOutput;
|
||||
use wayland_client::protocol::wl_pointer::WlPointer;
|
||||
use wayland_client::protocol::wl_seat::WlSeat;
|
||||
use wayland_client::protocol::wl_surface::WlSurface;
|
||||
use wayland_client::{delegate_dispatch, Connection, QueueHandle};
|
||||
|
||||
|
@ -1,15 +1,18 @@
|
||||
use std::any::Any;
|
||||
use std::cell::{RefCell, RefMut};
|
||||
use std::convert::TryInto;
|
||||
use std::io::Read;
|
||||
use std::os::fd::AsRawFd;
|
||||
use std::rc::Rc;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::time::{Duration, Instant};
|
||||
|
||||
use anyhow::anyhow;
|
||||
use anyhow::{anyhow, bail};
|
||||
use async_io::Timer;
|
||||
use async_trait::async_trait;
|
||||
use config::ConfigHandle;
|
||||
use promise::Future;
|
||||
use filedescriptor::FileDescriptor;
|
||||
use promise::{Future, Promise};
|
||||
use raw_window_handle::{
|
||||
HasRawDisplayHandle, HasRawWindowHandle, RawDisplayHandle, RawWindowHandle,
|
||||
WaylandDisplayHandle, WaylandWindowHandle,
|
||||
@ -362,8 +365,35 @@ impl WindowOps for WaylandWindow {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn get_clipboard(&self, _clipboard: Clipboard) -> Future<String> {
|
||||
todo!()
|
||||
fn get_clipboard(&self, clipboard: Clipboard) -> Future<String> {
|
||||
let mut promise = Promise::new();
|
||||
let future = promise.get_future().unwrap();
|
||||
let promise = Arc::new(Mutex::new(promise));
|
||||
WaylandConnection::with_window_inner(self.0, move |inner| {
|
||||
let read = inner
|
||||
.copy_and_paste
|
||||
.lock()
|
||||
.unwrap()
|
||||
.get_clipboard_data(clipboard)?;
|
||||
let promise = Arc::clone(&promise);
|
||||
std::thread::spawn(move || {
|
||||
let mut promise = promise.lock().unwrap();
|
||||
match read_pipe_with_timeout(read) {
|
||||
Ok(result) => {
|
||||
// Normalize the text to unix line endings, otherwise
|
||||
// copying from eg: firefox inserts a lot of blank
|
||||
// lines, and that is super annoying.
|
||||
promise.ok(result.replace("\r\n", "\n"));
|
||||
}
|
||||
Err(e) => {
|
||||
log::error!("while reading clipboard: {}", e);
|
||||
promise.err(anyhow!("{}", e));
|
||||
}
|
||||
};
|
||||
});
|
||||
Ok(())
|
||||
});
|
||||
future
|
||||
}
|
||||
|
||||
fn set_clipboard(&self, clipboard: Clipboard, text: String) {
|
||||
@ -387,6 +417,37 @@ pub(crate) struct PendingEvent {
|
||||
pub(crate) window_state: Option<WindowState>,
|
||||
}
|
||||
|
||||
pub(crate) fn read_pipe_with_timeout(mut file: FileDescriptor) -> anyhow::Result<String> {
|
||||
let mut result = Vec::new();
|
||||
|
||||
file.set_non_blocking(true)?;
|
||||
let mut pfd = libc::pollfd {
|
||||
fd: file.as_raw_fd(),
|
||||
events: libc::POLLIN,
|
||||
revents: 0,
|
||||
};
|
||||
|
||||
let mut buf = [0u8; 8192];
|
||||
|
||||
loop {
|
||||
if unsafe { libc::poll(&mut pfd, 1, 3000) == 1 } {
|
||||
match file.read(&mut buf) {
|
||||
Ok(size) if size == 0 => {
|
||||
break;
|
||||
}
|
||||
Ok(size) => {
|
||||
result.extend_from_slice(&buf[..size]);
|
||||
}
|
||||
Err(e) => bail!("error reading from pipe: {}", e),
|
||||
}
|
||||
} else {
|
||||
bail!("timed out reading from pipe");
|
||||
}
|
||||
}
|
||||
|
||||
Ok(String::from_utf8(result)?)
|
||||
}
|
||||
|
||||
pub struct WaylandWindowInner {
|
||||
// window_id: usize,
|
||||
pub(crate) events: WindowEventSender,
|
||||
|
Loading…
Reference in New Issue
Block a user