Skip to content

Commit

Permalink
feat: winit dnd
Browse files Browse the repository at this point in the history
  • Loading branch information
wash2 committed Mar 29, 2024
1 parent 1d9bb7f commit 4ad6c6c
Show file tree
Hide file tree
Showing 25 changed files with 950 additions and 77 deletions.
31 changes: 24 additions & 7 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,22 @@ multi-window = ["iced_winit?/multi-window"]
# Enables the advanced module
advanced = []
# Enables the `accesskit` accessibility library
a11y = ["iced_accessibility", "iced_core/a11y", "iced_widget/a11y", "iced_winit?/a11y", "iced_sctk?/a11y"]
a11y = [
"iced_accessibility",
"iced_core/a11y",
"iced_widget/a11y",
"iced_winit?/a11y",
"iced_sctk?/a11y",
]
# Enables the winit shell. Conflicts with `wayland` and `glutin`.
winit = ["iced_winit", "iced_accessibility?/accesskit_winit"]
# Enables the sctk shell. Conflicts with `winit` and `glutin`.
wayland = ["iced_sctk", "iced_widget/wayland", "iced_accessibility?/accesskit_unix", "iced_core/wayland"]
wayland = [
"iced_sctk",
"iced_widget/wayland",
"iced_accessibility?/accesskit_unix",
"iced_core/wayland",
]
# Enables clipboard for iced_sctk
wayland-clipboard = ["iced_sctk?/clipboard"]

Expand All @@ -75,6 +86,8 @@ iced_accessibility.workspace = true
iced_accessibility.optional = true
thiserror.workspace = true
window_clipboard.workspace = true
mime.workspace = true
dnd.workspace = true

image.workspace = true
image.optional = true
Expand All @@ -94,7 +107,7 @@ members = [
"winit",
"examples/*",
"accessibility",
"sctk"
"sctk",
]
exclude = ["examples/integration"]

Expand Down Expand Up @@ -158,7 +171,7 @@ qrcode = { version = "0.12", default-features = false }
raw-window-handle = "0.6"
resvg = "0.37"
rustc-hash = "1.0"
sctk = { package = "smithay-client-toolkit", git = "https://github.com/smithay/client-toolkit", rev = "2e9bf9f" }
sctk = { package = "smithay-client-toolkit", git = "https://github.com/smithay/client-toolkit", rev = "3bed072" }
smol = "1.0"
smol_str = "0.2"
softbuffer = { git = "https://github.com/pop-os/softbuffer", tag = "cosmic-4.0" }
Expand All @@ -172,13 +185,17 @@ xxhash-rust = { version = "0.8", features = ["xxh3"] }
unicode-segmentation = "1.0"
wasm-bindgen-futures = "0.4"
wasm-timer = "0.2"
wayland-protocols = { version = "0.31.0", features = [ "staging"]}
wayland-protocols = { version = "0.31.0", features = ["staging"] }
web-sys = "0.3"
web-time = "0.2"
# wgpu = "0.19"
# Newer wgpu commit that fixes Vulkan backend on Nvidia
wgpu = { git = "https://github.com/gfx-rs/wgpu", rev = "20fda69" }
winapi = "0.3"
window_clipboard = { git = "https://github.com/pop-os/window_clipboard.git", tag = "pop-mime-types" }
# window_clipboard = { path = "../window_clipboard" }
window_clipboard = { git = "https://github.com/pop-os/window_clipboard.git", tag = "pop-dnd" }
dnd = { git = "https://github.com/pop-os/window_clipboard.git", tag = "pop-dnd" }
mime = { git = "https://github.com/pop-os/window_clipboard.git", tag = "pop-dnd" }
# window_clipboard = { path = "../window_clipboard" }
# dnd = { path = "../window_clipboard/dnd" }
# mime = { path = "../window_clipboard/mime" }
winit = { git = "https://github.com/pop-os/winit.git", branch = "winit-0.29" }
2 changes: 2 additions & 0 deletions core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ thiserror.workspace = true
web-time.workspace = true
xxhash-rust.workspace = true
window_clipboard.workspace = true
dnd.workspace = true
mime.workspace = true

sctk.workspace = true
sctk.optional = true
Expand Down
85 changes: 84 additions & 1 deletion core/src/clipboard.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
//! Access the clipboard.
use window_clipboard::mime::{self, AllowedMimeTypes, ClipboardStoreData};
use std::{any::Any, borrow::Cow, sync::Arc};

Check warning on line 3 in core/src/clipboard.rs

View workflow job for this annotation

GitHub Actions / widget

unused import: `borrow::Cow`

Check warning on line 3 in core/src/clipboard.rs

View workflow job for this annotation

GitHub Actions / all

unused import: `borrow::Cow`

Check failure on line 3 in core/src/clipboard.rs

View workflow job for this annotation

GitHub Actions / all (macOS-latest, stable)

unused import: `borrow::Cow`

Check failure on line 3 in core/src/clipboard.rs

View workflow job for this annotation

GitHub Actions / all (ubuntu-latest, beta)

unused import: `borrow::Cow`

Check warning on line 3 in core/src/clipboard.rs

View workflow job for this annotation

GitHub Actions / all

unused import: `borrow::Cow`

Check warning on line 3 in core/src/clipboard.rs

View workflow job for this annotation

GitHub Actions / widget

unused import: `borrow::Cow`

Check warning on line 3 in core/src/clipboard.rs

View workflow job for this annotation

GitHub Actions / all

unused import: `borrow::Cow`

Check failure on line 3 in core/src/clipboard.rs

View workflow job for this annotation

GitHub Actions / all (ubuntu-latest, stable)

unused import: `borrow::Cow`

Check failure on line 3 in core/src/clipboard.rs

View workflow job for this annotation

GitHub Actions / all (macOS-latest, stable)

unused import: `borrow::Cow`

Check failure on line 3 in core/src/clipboard.rs

View workflow job for this annotation

GitHub Actions / all (ubuntu-latest, beta)

unused import: `borrow::Cow`

Check failure on line 3 in core/src/clipboard.rs

View workflow job for this annotation

GitHub Actions / all (macOS-latest, beta)

unused import: `borrow::Cow`

Check warning on line 3 in core/src/clipboard.rs

View workflow job for this annotation

GitHub Actions / all

unused import: `borrow::Cow`

use dnd::{DndAction, DndDestinationRectangle, DndSurface};
use mime::{self, AllowedMimeTypes, AsMimeTypes, ClipboardStoreData};

Check failure on line 6 in core/src/clipboard.rs

View workflow job for this annotation

GitHub Actions / all (ubuntu-latest, beta)

the item `mime` is imported redundantly

Check failure on line 6 in core/src/clipboard.rs

View workflow job for this annotation

GitHub Actions / all (ubuntu-latest, beta)

the item `mime` is imported redundantly

Check failure on line 6 in core/src/clipboard.rs

View workflow job for this annotation

GitHub Actions / all (macOS-latest, beta)

the item `mime` is imported redundantly

use crate::{widget::tree::State, window, Element};

/// A buffer for short-term storage and transfer within and between
/// applications.
Expand Down Expand Up @@ -51,6 +56,61 @@ pub trait Clipboard {
>,
) {
}

/// Starts a DnD operation.
fn register_dnd_destination(
&self,
_surface: DndSurface,
_rectangles: Vec<DndDestinationRectangle>,
) {
}

/// Set the final action for the DnD operation.
/// Only should be done if it is requested.
fn set_action(&self, _action: DndAction) {}

/// Registers Dnd destinations
fn start_dnd(
&self,
_internal: bool,
_source_surface: Option<DndSource>,
_icon_surface: Option<Box<dyn Any>>,
_content: Box<dyn AsMimeTypes + Send + 'static>,
_actions: DndAction,
) {
}

/// Ends a DnD operation.
fn end_dnd(&self) {}

/// Consider using [`peek_dnd`] instead
/// Peeks the data on the DnD with a specific mime type.
/// Will return an error if there is no ongoing DnD operation.
fn peek_dnd(&self, _mime: String) -> Option<(Vec<u8>, String)> {
None
}
}

/// Starts a DnD operation.
/// icon surface is a tuple of the icon element and optionally the icon element state.
pub fn start_dnd<T: 'static, R: 'static, M: 'static>(
clipboard: &mut dyn Clipboard,
internal: bool,
source_surface: Option<DndSource>,
icon_surface: Option<(Element<'static, M, T, R>, State)>,
content: Box<dyn AsMimeTypes + Send + 'static>,
actions: DndAction,
) {
clipboard.start_dnd(
internal,
source_surface,
icon_surface.map(|i| {
let i: Box<dyn Any> = Box::new(Arc::new(i));
i
}),
content,
actions,
);
}

/// A null implementation of the [`Clipboard`] trait.
Expand Down Expand Up @@ -82,3 +142,26 @@ pub fn read_primary_data<T: AllowedMimeTypes>(
.read_data(T::allowed().into())
.and_then(|data| T::try_from(data).ok())
}

/// Reads the current content of the primary [`Clipboard`].
pub fn peek_dnd<T: AllowedMimeTypes>(
clipboard: &mut dyn Clipboard,
mime: Option<String>,
) -> Option<T> {
let Some(mime) = mime.or_else(|| T::allowed().first().cloned().into())

Check warning on line 151 in core/src/clipboard.rs

View workflow job for this annotation

GitHub Actions / all

this `let...else` may be rewritten with the `?` operator

Check warning on line 151 in core/src/clipboard.rs

View workflow job for this annotation

GitHub Actions / all

useless conversion to the same type: `std::option::Option<std::string::String>`

Check warning on line 151 in core/src/clipboard.rs

View workflow job for this annotation

GitHub Actions / all

this `let...else` may be rewritten with the `?` operator

Check warning on line 151 in core/src/clipboard.rs

View workflow job for this annotation

GitHub Actions / all

useless conversion to the same type: `std::option::Option<std::string::String>`
else {
return None;
};
clipboard
.peek_dnd(mime)
.and_then(|data| T::try_from(data).ok())
}

/// Source of a DnD operation.
#[derive(Debug, Clone)]
pub enum DndSource {
/// A widget is the source of the DnD operation.
Widget(crate::id::Id),
/// A surface is the source of the DnD operation.
Surface(window::Id),
}
6 changes: 6 additions & 0 deletions core/src/event.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
//! Handle events of a user interface.
use dnd::DndEvent;
use dnd::DndSurface;

use crate::keyboard;
use crate::mouse;
use crate::touch;
Expand Down Expand Up @@ -33,6 +36,9 @@ pub enum Event {
iced_accessibility::accesskit::ActionRequest,
),

/// A DnD event.
Dnd(DndEvent<DndSurface>),

/// A platform specific event
PlatformSpecific(PlatformSpecific),
}
Expand Down
15 changes: 15 additions & 0 deletions core/src/widget/tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,21 @@ impl Tree {
}
}

/// Finds a widget state in the tree by its id.
pub fn find<'a>(&'a self, id: &Id) -> Option<&'a Tree> {
if self.id == Some(id.clone()) {
return Some(self);
}

for child in self.children.iter() {
if let Some(tree) = child.find(id) {
return Some(tree);
}
}

None
}

/// Reconciliates the current tree with the provided [`Widget`].
///
/// If the tag of the [`Widget`] matches the tag of the [`Tree`], then the
Expand Down
3 changes: 2 additions & 1 deletion runtime/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,5 @@ sctk.optional = true
thiserror.workspace = true
iced_accessibility.workspace = true
iced_accessibility.optional = true
window_clipboard.workspace = true
window_clipboard.workspace = true
dnd.workspace = true
8 changes: 8 additions & 0 deletions runtime/src/command/action.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use crate::font;
use crate::system;
use crate::window;

use dnd::DndAction;

Check warning on line 7 in runtime/src/command/action.rs

View workflow job for this annotation

GitHub Actions / widget

unused import: `dnd::DndAction`

Check warning on line 7 in runtime/src/command/action.rs

View workflow job for this annotation

GitHub Actions / all

unused import: `dnd::DndAction`

Check warning on line 7 in runtime/src/command/action.rs

View workflow job for this annotation

GitHub Actions / all

unused import: `dnd::DndAction`

Check warning on line 7 in runtime/src/command/action.rs

View workflow job for this annotation

GitHub Actions / widget

unused import: `dnd::DndAction`

Check warning on line 7 in runtime/src/command/action.rs

View workflow job for this annotation

GitHub Actions / all

unused import: `dnd::DndAction`

Check warning on line 7 in runtime/src/command/action.rs

View workflow job for this annotation

GitHub Actions / all

unused import: `dnd::DndAction`
use iced_futures::MaybeSend;

use std::borrow::Cow;
Expand Down Expand Up @@ -35,6 +36,9 @@ pub enum Action<T> {
/// Run a widget action.
Widget(Box<dyn widget::Operation<T>>),

/// Run a Dnd action.
Dnd(crate::dnd::DndAction<T>),

/// Load a font from its bytes.
LoadFont {
/// The bytes of the font to load.
Expand Down Expand Up @@ -78,6 +82,9 @@ impl<T> Action<T> {
Self::PlatformSpecific(action) => {
Action::PlatformSpecific(action.map(f))
}
Self::Dnd(a) => Action::Dnd(a.map(f)),
Action::LoadFont { bytes, tagger } => todo!(),

Check warning on line 86 in runtime/src/command/action.rs

View workflow job for this annotation

GitHub Actions / widget

unreachable pattern

Check warning on line 86 in runtime/src/command/action.rs

View workflow job for this annotation

GitHub Actions / widget

unused variable: `bytes`

Check warning on line 86 in runtime/src/command/action.rs

View workflow job for this annotation

GitHub Actions / widget

unused variable: `tagger`

Check warning on line 86 in runtime/src/command/action.rs

View workflow job for this annotation

GitHub Actions / all

unreachable pattern

Check warning on line 86 in runtime/src/command/action.rs

View workflow job for this annotation

GitHub Actions / all

unused variable: `bytes`

Check warning on line 86 in runtime/src/command/action.rs

View workflow job for this annotation

GitHub Actions / all

unused variable: `tagger`

Check warning on line 86 in runtime/src/command/action.rs

View workflow job for this annotation

GitHub Actions / all

unreachable pattern

Check warning on line 86 in runtime/src/command/action.rs

View workflow job for this annotation

GitHub Actions / all

unused variable: `bytes`

Check warning on line 86 in runtime/src/command/action.rs

View workflow job for this annotation

GitHub Actions / all

unused variable: `tagger`

Check warning on line 86 in runtime/src/command/action.rs

View workflow job for this annotation

GitHub Actions / widget

unreachable pattern

Check warning on line 86 in runtime/src/command/action.rs

View workflow job for this annotation

GitHub Actions / widget

unused variable: `bytes`

Check warning on line 86 in runtime/src/command/action.rs

View workflow job for this annotation

GitHub Actions / widget

unused variable: `tagger`

Check warning on line 86 in runtime/src/command/action.rs

View workflow job for this annotation

GitHub Actions / all

unreachable pattern

Check warning on line 86 in runtime/src/command/action.rs

View workflow job for this annotation

GitHub Actions / all

unused variable: `bytes`

Check warning on line 86 in runtime/src/command/action.rs

View workflow job for this annotation

GitHub Actions / all

unused variable: `tagger`

Check warning on line 86 in runtime/src/command/action.rs

View workflow job for this annotation

GitHub Actions / all

unreachable pattern

Check warning on line 86 in runtime/src/command/action.rs

View workflow job for this annotation

GitHub Actions / all

unused variable: `bytes`

Check warning on line 86 in runtime/src/command/action.rs

View workflow job for this annotation

GitHub Actions / all

unused variable: `tagger`
Action::PlatformSpecific(_) => todo!(),

Check warning on line 87 in runtime/src/command/action.rs

View workflow job for this annotation

GitHub Actions / widget

unreachable pattern

Check warning on line 87 in runtime/src/command/action.rs

View workflow job for this annotation

GitHub Actions / all

unreachable pattern

Check warning on line 87 in runtime/src/command/action.rs

View workflow job for this annotation

GitHub Actions / all

unreachable pattern

Check warning on line 87 in runtime/src/command/action.rs

View workflow job for this annotation

GitHub Actions / widget

unreachable pattern

Check warning on line 87 in runtime/src/command/action.rs

View workflow job for this annotation

GitHub Actions / all

unreachable pattern

Check warning on line 87 in runtime/src/command/action.rs

View workflow job for this annotation

GitHub Actions / all

unreachable pattern
}
}
}
Expand All @@ -99,6 +106,7 @@ impl<T> fmt::Debug for Action<T> {
Self::PlatformSpecific(action) => {
write!(f, "Action::PlatformSpecific({:?})", action)
}
Self::Dnd(action) => write!(f, "Action::Dnd"),

Check warning on line 109 in runtime/src/command/action.rs

View workflow job for this annotation

GitHub Actions / widget

unused variable: `action`

Check warning on line 109 in runtime/src/command/action.rs

View workflow job for this annotation

GitHub Actions / all

unused variable: `action`

Check warning on line 109 in runtime/src/command/action.rs

View workflow job for this annotation

GitHub Actions / all

unused variable: `action`

Check warning on line 109 in runtime/src/command/action.rs

View workflow job for this annotation

GitHub Actions / widget

unused variable: `action`

Check warning on line 109 in runtime/src/command/action.rs

View workflow job for this annotation

GitHub Actions / all

unused variable: `action`

Check warning on line 109 in runtime/src/command/action.rs

View workflow job for this annotation

GitHub Actions / all

unused variable: `action`
}
}
}
Loading

0 comments on commit 4ad6c6c

Please sign in to comment.