Drag&Drop

On Odysseus’s homepage you can drag and drop the links in order to reorder them. This is implemented using html5sortable, which in turn wraps HTML5’s drag & drop events whilst moving a placeholder element to always be under the cursor but within the list.

Today I want to describe how WebKitGTK implements those events.

And maybe I’ll also describe how GTK and (for simplicity) Weston implements drag & drop.

WebCore (the page sandbox)

WebKit’s “EventHandler” receives the “dragged” events from outside the sandbox, and will translate mouse moveds into dragging gestures if not otherwise handled. If the hovered element is not supported for drag, then it becomes a selection gesture.

Once it’s figured out which element to dispatch the drags to it dispatches the event to the “DragController”, which implements all the built on behaviours for drag & drop and dispatches the rest to the DOM.

WebKitGTK

In the WebKitGTK (other “ports” differ) sandbox, those drag&drop events are received by the embedding widget, and dispatched to the page via WebKitGTK’s “DragAndDropHandler” which handles conversion between the WebKit and GTK APIs.

Then when the DragController inside the sandbox wants to initiate a drag and drop gesture, it messages WebKitGTK’s PageClientImpl, which just forwards on to the DragAndDropHandler and resets a click count.

GTK

GTK’s drag&drop events are triggered in gtkdnd.c, which receives events from a shallow wrapper around the X11, Wayland, etc protocols and dispatches them to the correct widget (traversing up the widget tree from the leaf until it finds a drop target) and highlights it as such.

The events are received from the window manager alongside all others to be dispatched (in this case to gtkdnd.c) by gtk_main_do_event(). And requests to start dragging are forwarded on to the window manager.

Weston/Wayland

So far I’ve dug through two layers (WebKit and GTK) pushing the logic of drag and drop off onto someone else. So I don’t have to deal with any more layers, I’ll now describe how Weston handles the request to start a drag operation.

And once we’ve propagated the logic up to that level, drag and drop essentially just becomes a simple matter of switching to some temporary event handlers (for either touch or mouse/keyboard depending on the input state) and notifying the apps of any movement/change.