-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New drag and drop API #4571
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
Open
eira-fransham
wants to merge
103
commits into
rust-windowing:master
Choose a base branch
from
slint-ui:drag-n-drop
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
New drag and drop API #4571
Changes from 20 commits
Commits
Show all changes
103 commits
Select commit
Hold shift + click to select a range
c8fe672
Wayland: support basic Drag&Drop
SludgePhD 809ae2c
Address clippy lints
SludgePhD 31a4de1
Use `make_wid` to simplify code
SludgePhD 9d88e5e
Also emit all appropriate cursor events
SludgePhD 2b0dd48
Read the pipe without blocking
SludgePhD 2687654
Follow style
SludgePhD d95dd41
Address clippy lint
SludgePhD 60749aa
Fix parsing of CRLF-delimited lines
SludgePhD 2c15c5e
Fix merge conflicts in Cargo.toml
eira-fransham ccd7116
Fix merge conflicts in `platform_impl`, start implementing data trans…
eira-fransham ccaff27
Fix cargo fmt
eira-fransham d8fa184
Convert to use new data transfer system
eira-fransham 3c01cb8
Add plaintext + URI helpers, remove MIME
eira-fransham b7fcfe0
Add more documentation
eira-fransham 2234a27
Fix drag-and-drop on X11
eira-fransham 8d3111b
Fix use of `XDndStatus`
eira-fransham e867501
Change comment
eira-fransham 4dc8f6f
Fix conversion from type hint to "real" type
eira-fransham 1fec92c
Fill out type hints for X11
eira-fransham 61ab9c8
Fix transferring text and add an example
eira-fransham fb7779e
WIP: Implement drag-and-drop for AppKit using new API
eira-fransham 98106b8
Remove `DataTransferEvent`
eira-fransham 2e99f38
Implement dnd for appkit
eira-fransham 1c5a76a
Fix `registerForDraggedTypes` on macOS
eira-fransham 0e6bbf6
Fix clippy on macOS
eira-fransham 9a058cb
Fix clippy
eira-fransham fbccd66
Fix 1.85 compat
eira-fransham d4b9c49
Taplo fmt
eira-fransham d00d415
X11 clippy
eira-fransham e52cae1
Explain `regsisterForDraggedTypes` usage
eira-fransham 47dd3cf
Fix clippy issue
eira-fransham 03eb54a
Small changes
eira-fransham a439436
Fix compilation issue
eira-fransham 0c94650
WIP: Implement for Windows
eira-fransham fb92e36
X11 cleanup
eira-fransham aaa006a
X11 cleanup
eira-fransham 72ed878
Fix clippy warnings, make `wait_for_data` X11-internal
eira-fransham 1a6b0dd
Remove `wait_for_data` from appkit
eira-fransham fc55406
WIP: win32
eira-fransham 4f22d27
Simpler API
eira-fransham ea24514
`drop_handler`->`dnd`
eira-fransham 8028fc8
Fix unused Cow import
eira-fransham 42c4ccf
Use `OsString` for paths
eira-fransham 798c79b
WIP: Implement for Wayland
eira-fransham 9966b83
Fix appkit
eira-fransham f3eec15
Fix clippy warnings, fix on wayland
eira-fransham 3a2231f
WIP: Initiate drag
eira-fransham 74a3383
WIP: Initiate drag
eira-fransham 9f48597
WIP: Initiate drag
eira-fransham 5d28920
WIP: Initiate drag
eira-fransham 75ffbf5
Initiate drag on Wayland
eira-fransham 4596833
Fix icon on drag
eira-fransham 4d92ce5
Allow switching on requested type, allowing the application to be gen…
eira-fransham cce666a
Complete win32 drag-and-drop by reading dropped data
tronical 708962e
Use the actual copied length when reading dropped file paths
tronical 649ad6f
Receive PNG image drops on win32
tronical 5fb6208
Accept drops on win32 via set_valid_actions
tronical eb7792c
Update win32 for new set_valid_actions signature
eira-fransham ed9e71d
Fix nitpicks
eira-fransham e99836b
Fix invalid panic over FFI boundary
eira-fransham 41e1f5f
Fmt
eira-fransham b5375a9
WIP: Initiate drag on macOS
eira-fransham 340c2cb
Initiate drag on macOS
eira-fransham 098af43
Remove `cancel_drag`
eira-fransham b8e3eba
Fix buggy drag visuals
eira-fransham ea394ea
Clippy warnings
eira-fransham fcababb
Clippy warnings
eira-fransham 54f695e
Fix comment formatting
eira-fransham 3a4bb3d
Fix `DndActionMask` on macOS
eira-fransham 16f2102
Initiate drags from win32 windows
tronical 1e1c579
Emit DragLeft when the drop was rejected
tronical 353fb87
Pair COM Release with an Acquire fence before drop
tronical dfd05ae
Implement DragIcon on win32
tronical 2c6d5c5
fixup! Implement DragIcon on win32
tronical e4f341d
fixup! Implement DragIcon on win32
tronical 463d72f
fixup! Implement DragIcon on win32
tronical f058957
fixup! Pair COM Release with an Acquire fence before drop
tronical bf5bcc1
fixup! Implement DragIcon on win32
tronical e35894d
fixup! Initiate drags from win32 windows
tronical b8ebe98
fixup! Initiate drags from win32 windows
tronical 0b5b9b3
fixup! Initiate drags from win32 windows
tronical d8b2bab
fixup! Implement DragIcon on win32
tronical e1293a1
Plaintext is UTF-8 on Wayland
eira-fransham 5e7d943
Merge branch 'drag-n-drop' into simon/win32-drag
eira-fransham 2884d74
fixup! Initiate drags from win32 windows
tronical 58ca72b
fixup! Implement DragIcon on win32
tronical 8bce692
Fix dragging file paths on Windows
eira-fransham b5535e2
Format
eira-fransham e5ee07f
Merge pull request #3 from slint-ui/simon/win32-drag
eira-fransham 5804690
Fix KDE not sending dropped event if data is not fetched
eira-fransham fc21fad
Respond to PR feedback
eira-fransham 6f4a843
Respond to PR feedback
eira-fransham 5978feb
Make Wayland transfer ID more consistent
eira-fransham f5d6ba3
Talkback to drag source when drag is completed, properly handle opera…
eira-fransham 1a50668
Wayland drag talkback (TODO: re-format)
eira-fransham 87decff
Format
eira-fransham af93270
Fix CI
eira-fransham 948fce7
Taplo fmt
eira-fransham 01a5ce2
Fix macOS
eira-fransham e98cdfd
Fix internal drag-and-drop on Windows, implement outgoing drag ended …
eira-fransham 971e5f8
Remove explicit internal drag functionality (only available on Waylan…
eira-fransham 9e3fd5d
`new_window`->`register_window`
eira-fransham e608cea
Remove unused import
eira-fransham File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,175 @@ | ||
| //! Types related to data transfer, used for clipboard and drag-and-drop. | ||
| //! | ||
| //! This module contains types and traits implementing cross-application data transfer. | ||
| //! While the precise implementation depends on platform, there are a set of types which | ||
| //! can be safely transferred between applications on all platforms (see [`TypeHint`]). | ||
| //! | ||
| //! On all platforms, the process looks something like this: | ||
| //! | ||
| //! - A data transfer advertises a set of types which the data can be interpreted as | ||
| //! - For example, if you copy or drag text from a web page, the browser may advertise the text | ||
| //! formatted using HTML, the text formatted as RTF, and the text with all formatting removed | ||
| //! simultaneously. | ||
| //! - An application receiving a data transfer chooses one or more types that it understands and | ||
| //! requests the data in those formats (in practice, it will usually only request a single | ||
| //! format). | ||
| //! - The source application converts the data stored in its memory to the requested format and | ||
| //! asynchronously sends it to the target application | ||
| //! | ||
| //! On some platforms, the data is sometimes available synchronously, but all platforms have at | ||
| //! least some method of sending the data asynchronously and some types of data that may _only_ be | ||
| //! sent using the asynchronous interface. Because of this, the API in winit must be asynchronous. | ||
| //! | ||
| //! The flow for a user application that implements drag-and-drop would look something like this: | ||
| //! | ||
| //! - The application receives a [`DragEnter`](crate::event::WindowEvent::DragEnter) event. This | ||
| //! event supplies a [`DataTransferId`] which can be used to request information or operations on | ||
| //! the dragged data by using methods on [`Window`](crate::window::Window). | ||
| //! - As the drag operation continues, the window will receive | ||
| //! [`DragMoved`](crate::event::WindowEvent::DragEnter) events. | ||
| //! - While `DragMoved` events are being received, the receiving application may mark the data as | ||
| //! being accepted or rejected. This will update the OS/compositor to display the correct UI to | ||
| //! the user. Accepting does not "finalize" the drag operation, nor does rejecting cancel it. | ||
| //! - At any point during this operation, the receiving application may request either the available | ||
| //! types or even the data being transferred. This may be useful in cases where the application | ||
| //! wants to preload the data. For example, an image editor may want to display the image on the | ||
| //! canvas during the drag operation. | ||
| //! - When the user tries to drop the data onto the window, that window will receive a | ||
| //! [`DragDropped`](crate::event::WindowEvent::DragDropped) event. In general, the receiving | ||
| //! application should assume that calling [`reject_drag`](crate::window::Window::reject_drag) | ||
| //! after `DragDropped` is received ends the lifecycle of the data transfer. | ||
| //! | ||
| //! If platform-dependent behavior is required, a platform may define internal types | ||
| //! implementing the traits in this module, which can then be accessed in an application | ||
| //! using the methods defined on [`dyn AsAny`]. See each platform's documentation for details. | ||
|
|
||
| use std::fmt::{self, Debug}; | ||
| use std::io; | ||
|
|
||
| use crate::as_any::AsAny; | ||
|
|
||
| /// Unique identifier for a data transfer. | ||
| #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] | ||
| pub struct DataTransferId(i64); | ||
|
|
||
| impl DataTransferId { | ||
| /// Convert the [`DataTransferId`] into the underlying integer. | ||
| /// | ||
| /// This is useful if you need to pass the ID across an FFI boundary, or store it in an atomic. | ||
| pub const fn into_raw(self) -> i64 { | ||
| self.0 | ||
| } | ||
|
|
||
| /// Construct a [`DataTransferId`] from the underlying integer. | ||
| /// | ||
| /// This should only be called with integers returned from [`DataTransferId::into_raw`]. | ||
| pub const fn from_raw(id: i64) -> Self { | ||
| Self(id) | ||
| } | ||
| } | ||
|
|
||
| /// The set of types supported cross-platform. | ||
| #[derive(Debug, Copy, Clone, PartialEq, Eq)] | ||
| pub enum TypeHint { | ||
| /// Plain UTF-8 text (see [`TypedData::try_as_plaintext`]). | ||
| /// | ||
| /// **Note for platform implementations**: this hint is _only_ for UTF-8 text. If the platform | ||
| /// returns plaintext in some format other than UTF-8 by default, a [`TypedData`] | ||
| /// implementation marked with this type hint should convert to UTF-8. | ||
| Plaintext, | ||
| /// A list of URIs in the format defined by the `text/uri-list` MIME type, encoded as UTF-8 (see | ||
| /// [`TypedData::try_as_uris`]). | ||
| /// | ||
| /// **Note for platform implementations**: this hint is _only_ for URIs encoded precisely in the | ||
| /// format specified above. If the platform uses a different format, a [`TypedData`] | ||
| /// implementation marked with this type hint should convert to that format. | ||
| UriList, | ||
| /// A HTML-formatted string | ||
| Html, | ||
| /// An RTF-formatted string | ||
| Rtf, | ||
| /// Audio | ||
| Audio { | ||
| /// An optional hint for the encoding of the supplied bytes, specified using the standard | ||
| /// file extension for that audio format, lowercase and without the leading `.`. | ||
| extension_hint: Option<&'static str>, | ||
| }, | ||
| /// Image data | ||
| Image { | ||
| /// An optional hint for the encoding of the supplied bytes, specified using the standard | ||
| /// file extension for that audio format, lowercase and without the leading `.`. | ||
| extension_hint: Option<&'static str>, | ||
| }, | ||
| } | ||
|
|
||
| /// The type of a data transfer. | ||
| /// | ||
| /// [`hint`](TransferType::hint) can be called to get the type in | ||
| /// a cross-platform format (see [`TypeHint`]) | ||
| pub trait TransferType: AsAny + Send + Sync + fmt::Debug { | ||
| /// Get the cross-platform representation of this type. | ||
| /// | ||
| /// If this returns `None`, then this is a platform-dependent type that has no cross-platform | ||
| /// equivalent. | ||
| fn hint(&self) -> Option<TypeHint>; | ||
| } | ||
|
|
||
| impl TransferType for TypeHint { | ||
| fn hint(&self) -> Option<TypeHint> { | ||
| Some(*self) | ||
| } | ||
| } | ||
|
|
||
| impl_dyn_casting!(TransferType); | ||
|
|
||
| /// Data that has been fetched from a data transfer | ||
| pub trait TypedData: AsAny + Send + Sync + fmt::Debug { | ||
| /// The type of this `TypedData`. | ||
| fn type_(&self) -> &dyn TransferType; | ||
|
|
||
| /// If this value is readable as bytes, return a reader than can be used to read those bytes. | ||
| fn try_read(&mut self) -> Option<Box<dyn io::BufRead + '_>>; | ||
|
|
||
| /// Read this value as a list of URIs. | ||
| /// | ||
| /// If this value is not readable as URIs, return `None`. | ||
| /// | ||
| /// The format of the returned URIs is simply a vector of strings. No validation is done | ||
| /// to ensure that the URIs are valid or in the format | ||
| fn try_as_uris(&mut self) -> Option<Vec<String>>; | ||
|
|
||
| /// Read this value as a plain text string. | ||
| /// | ||
| /// If this value is not readable as a string, return `None`. | ||
| fn try_as_string(&mut self) -> Option<String>; | ||
| } | ||
|
|
||
| impl_dyn_casting!(TypedData); | ||
|
|
||
| /// Metadata about a data transfer. This does not allow actually receiving data, as that is an | ||
| /// asynchronous operation. To fetch the data from the source application, see | ||
| /// [`Window::fetch_data_transfer`](crate::window::Window::fetch_data_transfer) | ||
| /// and [`WindowEvent::DataTransferResult`](crate::event::WindowEvent::DataTransferResult). | ||
| pub trait DataTransfer: AsAny + Send + Sync + fmt::Debug { | ||
| /// Display the list of all available types. | ||
| /// | ||
| /// This is useful if more-complex type matching is required, but for most cases | ||
| /// [`has_type`](DataTransfer::has_type) should be used. | ||
| // TODO: We should be able to do `&dyn TransferType`, but some implementation details in | ||
| // the platforms make that unnecessarily difficult right now. Specifically, use of `RwLock`. | ||
| fn available_types(&self) -> Vec<Box<dyn TransferType>>; | ||
|
|
||
| /// Check if the supplied type is provided by this [`DataTransfer`]. | ||
| /// | ||
| /// Supplying a [`TypeHint`] as the type is supported on all platforms, but if some | ||
| /// platform-specific type is required then that platform's implementation of `TransferType` can | ||
| /// be used. | ||
| fn has_type(&self, type_: &dyn TransferType) -> bool { | ||
| let available_types = self.available_types(); | ||
| type_.hint().is_some_and(|hint| { | ||
| available_types.iter().any(|haystack| haystack.hint() == Some(hint)) | ||
| }) | ||
| } | ||
| } | ||
|
|
||
| impl_dyn_casting!(DataTransfer); | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.