feat: dnd integration
This commit is contained in:
parent
c3e9e794b9
commit
228288dfdf
11 changed files with 589 additions and 14 deletions
102
src/dnd/mod.rs
Normal file
102
src/dnd/mod.rs
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
use std::borrow::Cow;
|
||||
|
||||
use ::dnd::{DndAction, DndDestinationRectangle, Sender};
|
||||
use dnd::DndSurface;
|
||||
use mime::{AllowedMimeTypes, AsMimeTypes};
|
||||
|
||||
pub trait DndProvider {
|
||||
/// Set up DnD operations for the Clipboard
|
||||
fn init_dnd(
|
||||
&self,
|
||||
_tx: Box<dyn dnd::Sender<DndSurface> + Send + Sync + 'static>,
|
||||
) {
|
||||
}
|
||||
|
||||
/// Start a DnD operation on the given surface with some data
|
||||
fn start_dnd<D: AsMimeTypes + Send + 'static>(
|
||||
&self,
|
||||
_internal: bool,
|
||||
_source_surface: DndSurface,
|
||||
_icon_surface: Option<DndSurface>,
|
||||
_content: D,
|
||||
_actions: DndAction,
|
||||
) {
|
||||
}
|
||||
|
||||
/// End the current DnD operation, if there is one
|
||||
fn end_dnd(&self) {}
|
||||
|
||||
/// Register a surface for receiving DnD offers
|
||||
/// Rectangles should be provided in order of decreasing priority.
|
||||
/// This method can be called multiple time for a single surface if the
|
||||
/// rectangles change.
|
||||
fn register_dnd_destination(
|
||||
&self,
|
||||
_surface: DndSurface,
|
||||
_rectangles: Vec<DndDestinationRectangle>,
|
||||
) {
|
||||
}
|
||||
|
||||
/// Set the final action after presenting the user with a choice
|
||||
fn set_action(&self, _action: DndAction) {}
|
||||
|
||||
/// Peek at the contents of a DnD offer
|
||||
fn peek_offer<D: AllowedMimeTypes + 'static>(
|
||||
&self,
|
||||
_mime_type: Cow<'static, str>,
|
||||
) -> std::io::Result<D> {
|
||||
Err(std::io::Error::new(
|
||||
std::io::ErrorKind::Other,
|
||||
"DnD not supported",
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
impl<C: DndProvider> DndProvider for crate::PlatformClipboard<C> {
|
||||
fn init_dnd(
|
||||
&self,
|
||||
tx: Box<dyn Sender<DndSurface> + Send + Sync + 'static>,
|
||||
) {
|
||||
self.raw.init_dnd(tx);
|
||||
}
|
||||
|
||||
fn start_dnd<D: AsMimeTypes + Send + 'static>(
|
||||
&self,
|
||||
internal: bool,
|
||||
source_surface: DndSurface,
|
||||
icon_surface: Option<DndSurface>,
|
||||
content: D,
|
||||
actions: DndAction,
|
||||
) {
|
||||
self.raw.start_dnd(
|
||||
internal,
|
||||
source_surface,
|
||||
icon_surface,
|
||||
content,
|
||||
actions,
|
||||
);
|
||||
}
|
||||
|
||||
fn end_dnd(&self) {
|
||||
self.raw.end_dnd();
|
||||
}
|
||||
|
||||
fn register_dnd_destination(
|
||||
&self,
|
||||
surface: DndSurface,
|
||||
rectangles: Vec<DndDestinationRectangle>,
|
||||
) {
|
||||
self.raw.register_dnd_destination(surface, rectangles);
|
||||
}
|
||||
|
||||
fn set_action(&self, action: DndAction) {
|
||||
self.raw.set_action(action);
|
||||
}
|
||||
|
||||
fn peek_offer<D: AllowedMimeTypes + 'static>(
|
||||
&self,
|
||||
mime_type: Cow<'static, str>,
|
||||
) -> std::io::Result<D> {
|
||||
self.raw.peek_offer::<D>(mime_type)
|
||||
}
|
||||
}
|
||||
|
|
@ -48,6 +48,8 @@ mod platform;
|
|||
#[path = "platform/dummy.rs"]
|
||||
mod platform;
|
||||
|
||||
mod dnd;
|
||||
|
||||
use mime::ClipboardStoreData;
|
||||
use raw_window_handle::HasDisplayHandle;
|
||||
use std::error::Error;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,14 @@
|
|||
use crate::{
|
||||
dnd::DndProvider,
|
||||
mime::{ClipboardLoadData, ClipboardStoreData},
|
||||
ClipboardProvider,
|
||||
};
|
||||
|
||||
use dnd::{DndAction, DndDestinationRectangle, DndSurface};
|
||||
use mime::{AllowedMimeTypes, AsMimeTypes};
|
||||
use raw_window_handle::{HasDisplayHandle, RawDisplayHandle};
|
||||
use std::error::Error;
|
||||
use std::{borrow::Cow, error::Error, sync::Arc};
|
||||
use wayland::DndSender;
|
||||
|
||||
pub use clipboard_wayland as wayland;
|
||||
pub use clipboard_x11 as x11;
|
||||
|
|
@ -125,6 +129,78 @@ impl ClipboardProvider for Clipboard {
|
|||
}
|
||||
}
|
||||
|
||||
impl DndProvider for Clipboard {
|
||||
fn init_dnd(
|
||||
&self,
|
||||
tx: Box<dyn dnd::Sender<DndSurface> + Send + Sync + 'static>,
|
||||
) {
|
||||
match self {
|
||||
Clipboard::Wayland(c) => c.init_dnd(DndSender(Arc::new(tx))),
|
||||
Clipboard::X11(_) => {}
|
||||
}
|
||||
}
|
||||
|
||||
fn start_dnd<D: AsMimeTypes + Send + 'static>(
|
||||
&self,
|
||||
internal: bool,
|
||||
source_surface: DndSurface,
|
||||
icon_surface: Option<DndSurface>,
|
||||
content: D,
|
||||
actions: DndAction,
|
||||
) {
|
||||
match self {
|
||||
Clipboard::Wayland(c) => c.start_dnd(
|
||||
internal,
|
||||
source_surface,
|
||||
icon_surface,
|
||||
content,
|
||||
actions,
|
||||
),
|
||||
Clipboard::X11(_) => {}
|
||||
}
|
||||
}
|
||||
|
||||
fn end_dnd(&self) {
|
||||
match self {
|
||||
Clipboard::Wayland(c) => c.end_dnd(),
|
||||
Clipboard::X11(_) => {}
|
||||
}
|
||||
}
|
||||
|
||||
fn register_dnd_destination(
|
||||
&self,
|
||||
surface: DndSurface,
|
||||
rectangles: Vec<DndDestinationRectangle>,
|
||||
) {
|
||||
match self {
|
||||
Clipboard::Wayland(c) => {
|
||||
c.register_dnd_destination(surface, rectangles)
|
||||
}
|
||||
Clipboard::X11(_) => {}
|
||||
}
|
||||
}
|
||||
|
||||
fn set_action(&self, action: DndAction) {
|
||||
match self {
|
||||
Clipboard::Wayland(c) => c.set_action(action),
|
||||
Clipboard::X11(_) => {}
|
||||
}
|
||||
}
|
||||
|
||||
fn peek_offer<D: AllowedMimeTypes + 'static>(
|
||||
&self,
|
||||
mime_type: Cow<'static, str>,
|
||||
) -> std::io::Result<D> {
|
||||
match self {
|
||||
Clipboard::Wayland(c) => c.peek_offer::<D>(mime_type),
|
||||
Clipboard::X11(_) => Err(std::io::Error::new(
|
||||
std::io::ErrorKind::Other,
|
||||
"DnD not supported",
|
||||
)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub unsafe fn connect<W: HasDisplayHandle>(
|
||||
window: &W,
|
||||
) -> Result<Clipboard, Box<dyn Error>> {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue