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

Rework DnD #2615

Open
wants to merge 21 commits into
base: master
Choose a base branch
from
Open

Conversation

amrbashir
Copy link
Contributor

@amrbashir amrbashir commented Jan 3, 2023

  • Tested on all platforms changed
    • Windows
    • macOS
    • X11
  • Added an entry to CHANGELOG.md if knowledge of this change could be valuable to users
  • Updated documentation to reflect any user-facing changes, including notes of platform-specific behavior
  • Created or updated an example program if it would help users understand this functionality
  • Updated feature matrix, if new features were added or implemented

@kchibisov
Copy link
Member

Could you elaborate why this is needed? Don't you get pointer motion events during DnD? It's just strange that we have 2 sources of pointer events during dnd with that.

@kchibisov
Copy link
Member

This is also a breaking change.

@amrbashir
Copy link
Contributor Author

Could you elaborate why this is needed? Don't you get pointer motion events during DnD? It's just strange that we have 2 sources of pointer events during dnd with that.

You get the cursor event only right before the DroppedFile event happens but not while HoveredFile, also there has been reports that it sometimes fire after the DroppedFile (Can't reproduce but see #1550 (comment)). Adding the cursor position to these events removes the need to sync with other events.

Copy link
Member

@kchibisov kchibisov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to ensure, have you tested the X11 part of it? (I just can't do that myself, but I guess that you can easily do that with any file manager)

src/event.rs Outdated Show resolved Hide resolved
src/event.rs Outdated Show resolved Hide resolved
@kchibisov kchibisov mentioned this pull request Jan 17, 2023
11 tasks
@amrbashir
Copy link
Contributor Author

I haven't tested X11 nor macOS but I can test X11 later today.

@amrbashir
Copy link
Contributor Author

Alright, X11 should be fine now. The returned coordinates were root window coordinates so I had to translate them before dispatching the event.

Copy link
Member

@kchibisov kchibisov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's a bit more clear which events.

CHANGELOG.md Outdated Show resolved Hide resolved
Copy link
Member

@madsmtm madsmtm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree that it makes sense to have for DroppedFile, but not so sure about HoveredFile? It seems like, for that to be useful, you'd have to receive the event continuously (which you at least don't on macOS)

src/platform_impl/macos/window_delegate.rs Outdated Show resolved Hide resolved
@kchibisov
Copy link
Member

but not so sure about HoveredFile? It seems like, for that to be useful, you'd have to receive the event continuously (which you at least don't on macOS)

That would strange, I'd assume you can know that you're over some element while doing drag and drop? Maybe the event is sent via some side channel, so we should plumb it to hovered?

@amrbashir
Copy link
Contributor Author

but not so sure about HoveredFile? It seems like, for that to be useful, you'd have to receive the event continuously (which you at least don't on macOS)

It is the same behavior on Windows and Linux too, the event is emitted only once upon entering the window.

Copy link
Member

@madsmtm madsmtm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

macOS impl tested and approved from my side.

It is the same behavior on Windows and Linux too, the event is emitted only once upon entering the window.

HoveredFile.position still doesn't really make sense to me, perhaps we should instead just emit two events CursorMoved { position } + HoveredFile { path } (or the other way around, if that's better)?

Adding the cursor position to these events removes the need to sync with other events.

(Though I do believe you when you say it's useful, I don't use the API myself, so it's not a blocker for me).

@madsmtm madsmtm added the S - enhancement Wouldn't this be the coolest? label Jan 21, 2023
@amrbashir
Copy link
Contributor Author

The thing is that winit should send either CursorMoved or Hovered event, it shouldn't send both at the same time.

why not both? if the OS sends them both, I think winit should pass that through as well

@madsmtm
Copy link
Member

madsmtm commented Jan 29, 2023

do you get any cursor events when moving drag and drop over the window, don't you get CurserMoved?

Nope, you get neither WindowEvent::CursorMoved nor DeviceEvent::MouseMotion.

But it seems you can opt-in to getting updates about the current drag operation, so one could probably implement a DragHover event on macOS.


Should we consider postponing this PR to 0.29? It seems like there's still quite some work to do figuring out the desired design (and implementing it, and testing it).

@kchibisov
Copy link
Member

why not both? if the OS sends them both, I think winit should pass that through as well

I guess using both will also work, I'm just afraid of the potential collisions and such, since DND mouse movements shouldn't update mouse cursor. But I guess on most systems the event data is separate already.

I'm not sure I like Hovered as a name, maybe DragMoved will be better.

@kchibisov
Copy link
Member

Should we consider postponing this PR to 0.29? It seems like there's still quite some work to do figuring out the desired design (and implementing it, and testing it).

We may do so if it'll be the only PR left.

@amrbashir amrbashir changed the title Add cursor position to DroppedFile and HoveredFile events Rework DnD Feb 11, 2023
@amrbashir
Copy link
Contributor Author

I'm not sure I like Hovered as a name, maybe DragMoved will be better.

I went with DragOver since it could be triggered even if the mouse hasn't moved.

@dhardy
Copy link
Contributor

dhardy commented Feb 12, 2023

Use of CursorMotion sounds problematic: what happens if the event source is touch not mouse?

Ah, so it pairs with some API to set DND zones?

I much prefer the API in this PR (just send the coordinates).


The current API (i.e. this PR) seems fine except maybe one thing: it clones a Vec<PathBuf> on each cursor motion. Is this sensible over, maybe dyn AsRef<Path> or some such?

Also the API should be clear on whether CursorMotion, Touch etc. may still be received during DnD.


Edit: clarify that "current API = this PR"

@amrbashir
Copy link
Contributor Author

The current API seems fine except maybe one thing: it clones a Vec<PathBuf> on each cursor motion. Is this sensible over, maybe dyn AsRef<Path> or some such?

Using dyn AsRef<Path> would require manual implementation for the Debug trait and would need to either remove the PartialEq derive or implement it manually so I don't think it is worth it.

I initially had DragOver only emit the drag location without paths, since DragEnter emits the paths and it will be re emitted on DragDrop but I added just to show it is possible and if it is desired behavior or not.

@dhardy
Copy link
Contributor

dhardy commented Feb 13, 2023

Using dyn AsRef would require manual implementation ...

Rust doesn't support multi-trait objects (yet) but you can do this:

pub trait HasPath: Debug + PartialEq + Eq + AsRef<Path> {}

But this is somewhat irrelevant in my opinion. Do we want to lock winit into an API which copies a bunch of paths on every mouse movement? Or is it irrelevant since all platforms re-send those on each movement anyway?

@amrbashir
Copy link
Contributor Author

Do we want to lock winit into an API which copies a bunch of paths on every mouse movement? Or is it irrelevant since all platforms re-send those on each movement anyway?

Only Windows doesn't send it on each movement, x11 and macOS do.

@madsmtm
Copy link
Member

madsmtm commented Feb 19, 2023

I think I'd prefer to just leave paths out of DragOver - if you need to do something with the paths while they're being dragged you can just store it yourself from DragEnter.

And maybe even remove it from DragDrop? Can the dragged items change while they're being dragged? (Or should we leave it in for ease-of-use?)

@amrbashir
Copy link
Contributor Author

And maybe even remove it from DragDrop? Can the dragged items change while they're being dragged? (Or should we leave it in for ease-of-use?)

I doubt that it can change but I'd say keep it for ease-of-use

@amrbashir
Copy link
Contributor Author

@kchibisov It is been a while, and now that I have some time to work on this and fix conflicts, do you think this rework should land soon?

@geom3trik
Copy link

Is this PR still compatible with the recent winit API changes or does it need updating?

@valadaptive
Copy link

It's very frustrating to see PRs languish and become outdated due to API reworks. This solves an issue (#1550) that has been linked to by several users of other UI frameworks and GUI apps who keep running into it again and again. I would offer to help push this over the finish line, but I have no idea if it would even be looked at or bikeshed to death again and become unmergeable due to conflicts.

Imagine my frustration when I had to go to a third-party repo (iced)'s issues list to see that this PR even existed (it's not mentioned anywhere in #1550) and has been sitting here unmerged for almost two years while its creator has diligently responded to every request made by the maintainers.

@kchibisov
Copy link
Member

You can open a PR with the new proposed events, with impl only for one backend and see how it works with the recent pointer API rework.

I myself don't have issues with the suggested design, since it's mostly about dropping into your window, starting drag is not really possible from winit and it'll require the same work as e.g. clipboard APIs. Though, it's not that much.

@amrbashir
Copy link
Contributor Author

amrbashir commented Oct 30, 2024

I will see If I can update this PR once again when I have some time.

For starting a drag operation, there is drag-rs which can handle that, see https://github.com/crabnebula-dev/drag-rs/blob/v2/examples/winit/src/main.rs for an example with winit so this PR is mainly for events of dragging into the window.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
I - BREAKING CHANGE S - api Design and usability S - enhancement Wouldn't this be the coolest?
Development

Successfully merging this pull request may close these issues.

6 participants