OS drag-and-drop file events on SDL - #922
Conversation
|
Thank you! I agree with the intention, we need to support this. I'm trying to figure out if we can reuse the cross-widget dragging facilities for this. That could unify the event handling code for drags no matter if they originated from inside dvui or outside. Thinking out loud: That would look like dvui having a well-known drag name, like "dvui.content". Does SDL let us know the type file/text during the drag, or only at the release?
I plan to explore this approach on this branch if that's ok. Any obvious problems with this? |
I think this is the right approach too.
At release. But it seems macOS Means populating the
Yes.
Yes
In short, probably not. I wouldn't do that. I dug into this a bit and gave up after getting into the internals of X11 and Wayland. X11 sends the dragging through So, I think it's best to just use
Yes.
I don't think you can view I'd say it's too risky to make these assumptions. (And I'd say I'm too lazy to thoroughly review X11/Wayland, macOS, and Windows code to determine this 😆) I admit I don't know if the DnD channels vs. others actually matters for dvui, so take it with a grain of salt.
Yeah. And multi-files is just
Could do that, but doesn't dvui prefer one event per input? That would also cut out state and allow users to run some code for each file drop separately (if users want/need).
By all means! I'm already using it, but I'd trust your code over mine. :) If you need me to test (Linux, macOS), let me know. |
SDL backend receives `SDL_EVENT_DROP_FILE` but it's logged and
discarded.
- added `Event.Drop` in `EventTypes`, like the `.mouse`, `.key`.
- it's of `Action` type.
- `.enter` = drag entered the window
- `.motion` = drag moved while hovering
- `.leave` = drag left or drop finished
- `.content` = content was dropped (one event per content)
- `p` (of type `dvui.Point.Physical`) is set for `.motion` and `.file`
The content can be a lot of stuff. SDL supports both file
(`SDL_EVENT_DROP_FILE`) and text (`SDL_EVENT_DROP_TEXT`), but other
systems might support much more. Across macOS NSPasteboard, Windows
IDataObject, and GTK/Qt, there might be file URLs, plain text, RTF,
HTML, images, URLs, app-defined custom types. So best to just separate
it to Content.
For now, Content only has the two types that SDL has. I'm not sure if in
the future it would be better to have backend-specific values or not.
Added `Window.addEventDrop(action, p)`.
Tried to provide implementations for both SDL2 and SDL3. In SDL3, we
need to translate the positions from window coordinates to physical
pixels with the same scale factor as mouse motion.
SDL2 has no hover tracking, so it just uses `.file`.
Can use it with:
for (dvui.events()) |*e| switch (e.evt) {
.drop => |d| switch (d.action) {
.enter, .motion => highlight = true,
.leave => highlight = false,
.file => |path| openOrAppendImport(path), // copy to keep it
},
else => {},
};
6d30400 to
d4f6b40
Compare
[I put all of this in the commit message too.]
SDL backend receives
SDL_EVENT_DROP_FILEbut it's logged and discarded.Event.DropinEventTypes, like the.mouse,.key.Actiontype..enter= drag entered the window.motion= drag moved while hovering.leave= drag left or drop finished.content= content was dropped (one event per content)p(of typedvui.Point.Physical) is set for.motionand.fileThe content can be a lot of stuff. SDL supports both file (
SDL_EVENT_DROP_FILE) and text (SDL_EVENT_DROP_TEXT), but other systems might support much more. Across macOS NSPasteboard, Windows IDataObject, and GTK/Qt, there might be file URLs, plain text, RTF, HTML, images, URLs, app-defined custom types. So best to just separate it to Content.For now, Content only has the two types that SDL has. I'm not sure if in the future it would be better to have backend-specific values or not.
Added
Window.addEventDrop(action, p).Tried to provide implementations for both SDL2 and SDL3. In SDL3, we need to translate the positions from window coordinates to physical pixels with the same scale factor as mouse motion.
SDL2 has no hover tracking, so it just uses
.file.Can use it with: