WINGs/wview_wl: implement internal DnD for Wayland
Implement wl_drag_begin as a simple internal drag-and-drop state machine for WINGs-to-WINGs drag operations (color wells, text widgets). On button press, waits for motion to confirm drag intent, then enters a drag loop tracking the cursor. On release, finds the view under the cursor and if it has drag destination procs + matching types, fetches data from the source and calls performDragOperation on the destination. This handles same-process DnD without needing wl_data_device protocol.
This commit is contained in:
parent
1c96a93ac8
commit
a438713b92
|
|
@ -555,7 +555,69 @@ static void wl_balloon_draw(void *vctx, W_View *view, int x, int y,
|
|||
|
||||
static void wl_drag_begin(void *vctx, W_View *view, WMEvent *event)
|
||||
{
|
||||
(void)vctx; (void)view; (void)event;
|
||||
W_Screen *scr = (W_Screen *)vctx;
|
||||
if (!view->dragSourceProcs || event->type != WME_BUTTON_PRESS)
|
||||
return;
|
||||
|
||||
/* Wait for motion to confirm drag */
|
||||
WMEvent ev;
|
||||
WMMaskEvent(scr, ButtonMotionMask | ButtonReleaseMask, &ev);
|
||||
if (ev.type != WME_MOTION)
|
||||
return;
|
||||
|
||||
if (view->dragSourceProcs->beganDrag) {
|
||||
WMPoint pt = wmkpoint(ev.u.motion.x_root, ev.u.motion.y_root);
|
||||
view->dragSourceProcs->beganDrag(view, &pt);
|
||||
}
|
||||
|
||||
/* Drag loop */
|
||||
W_View *destView = NULL;
|
||||
Bool deposited = False;
|
||||
int done = 0;
|
||||
|
||||
while (!done) {
|
||||
WMMaskEvent(scr, ButtonMotionMask | ButtonReleaseMask, &ev);
|
||||
switch (ev.type) {
|
||||
case WME_MOTION:
|
||||
/* Find view under cursor */
|
||||
{
|
||||
W_View *top = scr->rootView;
|
||||
int mx = ev.u.motion.x_root;
|
||||
int my = ev.u.motion.y_root;
|
||||
destView = W_FindViewAtPoint(top, mx, my);
|
||||
}
|
||||
break;
|
||||
|
||||
case WME_BUTTON_RELEASE:
|
||||
if (destView && destView->dragDestinationProcs &&
|
||||
destView->droppableTypes && view->dragSourceProcs->dropDataTypes) {
|
||||
WMArray *types = view->dragSourceProcs->dropDataTypes(view);
|
||||
WMArray *dropData = WMCreateArray(WMGetArrayItemCount(types));
|
||||
int i;
|
||||
for (i = 0; i < WMGetArrayItemCount(types); i++) {
|
||||
char *type = WMGetFromArray(types, i);
|
||||
WMData *data = view->dragSourceProcs->fetchDragData(view, type);
|
||||
if (data)
|
||||
WMAddToArray(dropData, data);
|
||||
}
|
||||
if (WMGetArrayItemCount(dropData) > 0 &&
|
||||
destView->dragDestinationProcs->performDragOperation) {
|
||||
WMPoint pt = wmkpoint(ev.u.button.x_root, ev.u.button.y_root);
|
||||
destView->dragDestinationProcs->performDragOperation(
|
||||
destView, dropData, NULL, &pt);
|
||||
deposited = True;
|
||||
}
|
||||
WMFreeArray(dropData);
|
||||
}
|
||||
done = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (view->dragSourceProcs->endedDrag) {
|
||||
WMPoint pt = wmkpoint(ev.u.button.x_root, ev.u.button.y_root);
|
||||
view->dragSourceProcs->endedDrag(view, &pt, deposited);
|
||||
}
|
||||
}
|
||||
|
||||
static void wl_flush(void *vctx)
|
||||
|
|
|
|||
Loading…
Reference in New Issue