Expand description
External (OS) drag-and-drop service.
Lets a window accept drops that originate outside the application —
files dragged from the file manager, or text / URLs dragged from another
app — and feed them into the same drag pipeline used for in-app drags
(teksilo_core::WidgetTree::begin_external_drag et al.).
Three concerns are separated, mirroring crate::file_dialog:
- Trait surface —
ExternalDndBackendis the swappable platform abstraction. A backend registers itself as the OS drop target for a window and, for each phase of a drag, posts anExternalDndEventPayloadthroughteksilo_core::AppEventPoster::post_external. - Handle —
ExternalDndHandleis the per-app service registered in app-state. It owns the backend and the per-window registration guards.teksilo-appcallsExternalDndHandle::attachwhen a window is created andExternalDndHandle::detachwhen it closes. - Event delivery —
teksilo-apppicks the payload up in itsAppEvent::Externalarm, routes it to the originating window’sWidgetTree, and calls the matching*_external_dragmethod.
§Why raw platform backends
winit’s DroppedFile / HoveredFile events carry no cursor position,
support files only, and are unimplemented on Wayland. A drop-zone widget
placed inside a layout needs the drop position to hit-test which zone
received the drop, so the real backends sit below winit on the raw
platform APIs (OLE IDropTarget on Windows, NSDraggingDestination on
macOS, wl_data_device on Wayland, XDND on X11), all of which provide
position and arbitrary data formats. NoopExternalDndBackend is left for
targets with no drop-target implementation at all.
§Threading
The macOS and Windows drop targets deliver their callbacks on the UI
thread; the Wayland and X11 backends run a dedicated per-window dispatch
thread on their own protocol connection. Either way the payload is routed
through teksilo_core::AppEventPoster::post_external (the same channel as
file dialogs) so the borrow of the window’s tree happens in one
well-defined place in the event loop rather than re-entrantly inside a
platform callback — and so a backend thread never touches the tree at all.
Structs§
- External
DndEvent Payload - Boxed inside
AppEvent::Externalwhen a backend reports a drag phase.teksilo-app’s app-event handler downcasts to this type and routes theExternalDragEventto the originating window’sWidgetTree. - External
DndHandle - Per-app external-drag service. Registered in app-state by
TeksiloAppBuilder::install_external_dnd;teksilo-appcallsSelf::attach/Self::detachfrom its window lifecycle hooks. Cloneable; clones share the same backend and guard map. - Memory
DndGuard - Guard that removes the window’s attachment record on drop, so
ExternalDndHandle::detachis observable in tests viaMemoryExternalDndBackend::attached_windows. - Memory
External DndBackend - In-memory backend for headless tests. Records the
(window_id, poster)of each attached window so a test can synthesize OS drag phases viaSelf::emit, which posts anExternalDndEventPayloadexactly as a real backend would. Cloneable — clones share the same recording, so a test can keep a clone after handing one toExternalDndHandle::new. - Noop
DndGuard - A guard that does nothing on drop. Used by
NoopExternalDndBackendand by backends whose registration needs no explicit teardown. - Noop
External DndBackend - Backend that registers nothing and never emits events. Used on X11 and any
target without a raw drop-target implementation. External OS drops simply
don’t fire; a
DropZonewidget stays usable via its keyboard “Browse…” fallback button. - Outbound
OsDrag Request - Posted by a backend whose outbound (app → OS) drag is blocking (Windows
OLE
DoDragDropruns its own modal message loop) so it can be run OUTSIDE the in-app event dispatch that started it.ExternalDndGuard::begin_dragstashes the payload, posts this, and returnstrue;teksilo-app’sAppEvent::Externalarm downcasts it and callsExternalDndHandle::run_pending_outbound_dragon the next loop turn — a point where no window is borrowed out of the manager, mirroring how inbound drag events route through the poster rather than re-entrantly inside a platform callback. Non-blocking backends (macOS / Wayland) never post this.
Enums§
- External
Drag Event - One phase of an external (OS) drag over a window. Positions are in the window’s logical coordinate space (top-left origin), already converted from the platform’s native coordinates.
Traits§
- External
DndBackend - Swappable external-drag backend. One backend instance serves the whole
app;
Self::attachis called once per window. - External
DndGuard - RAII guard for one window’s OS drop-target registration. Dropping it
revokes the registration (e.g.
RevokeDragDropon Windows, unregistering the dragging destination on macOS, destroying thewl_data_devicelistener on Wayland). Backends return a boxed guard fromExternalDndBackend::attach;ExternalDndHandleholds it for the lifetime of the window.
Functions§
- default_
backend - The default external-drag backend for the current target.