Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: winit dnd #119

Merged
merged 3 commits into from
Mar 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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, 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 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, 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, stable)

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, beta)

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 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 (macOS-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

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

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 @@
>,
) {
}

/// 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 @@
.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::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 @@
/// 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 @@
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 @@
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
Loading