dnd: cross-client motion/drop handler with MIME type routing
This commit is contained in:
parent
b278d6491d
commit
adf79141b2
|
|
@ -5579,6 +5579,22 @@ handle_drag_motion(struct wl_listener *listener, void *data)
|
|||
struct wlr_drag_motion_event *ev = data;
|
||||
(void)listener;
|
||||
(void)ev;
|
||||
|
||||
if (!wl_current_drag)
|
||||
return;
|
||||
|
||||
/* Hit-test at current pointer position */
|
||||
struct wl_frame_buf *fb = frame_buf_hit(wl_state.pointer_x,
|
||||
wl_state.pointer_y);
|
||||
if (fb && fb->id >= 0x20000000) {
|
||||
/* Over a WINGs view — look up view and its DND procs */
|
||||
extern struct W_View *W_GetViewForWindow(unsigned long id);
|
||||
struct W_View *top = W_GetViewForWindow((unsigned long)fb->id);
|
||||
if (top && top->dragDestinationProcs) {
|
||||
/* Convert MIME types from wlr_data_source to WMArray */
|
||||
/* (For now, just acknowledge the view exists) */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -5587,8 +5603,70 @@ handle_drag_drop(struct wl_listener *listener, void *data)
|
|||
struct wlr_drag_drop_event *ev = data;
|
||||
(void)listener;
|
||||
wwarning("wl_backend: external DND drop");
|
||||
if (wl_current_drag && wl_current_drag->source)
|
||||
wlr_data_source_dnd_drop(wl_current_drag->source);
|
||||
|
||||
if (!wl_current_drag || !wl_current_drag->source)
|
||||
return;
|
||||
|
||||
struct wlr_data_source *src = wl_current_drag->source;
|
||||
|
||||
/* Hit-test to find the drop target */
|
||||
struct wl_frame_buf *fb = frame_buf_hit(wl_state.pointer_x,
|
||||
wl_state.pointer_y);
|
||||
if (fb && fb->id >= 0x20000000) {
|
||||
/* Over a WINGs view — read data and deliver */
|
||||
extern struct W_View *W_GetViewForWindow(unsigned long id);
|
||||
struct W_View *top = W_GetViewForWindow((unsigned long)fb->id);
|
||||
if (top && top->dragDestinationProcs &&
|
||||
top->dragDestinationProcs->performDragOperation) {
|
||||
|
||||
/* Build array of MIME type strings from data source */
|
||||
WMArray *mimeTypes = WMCreateArray(WMGetArrayItemCount(
|
||||
(WMArray*)&src->mime_types));
|
||||
char **mime_ptr;
|
||||
wl_array_for_each(mime_ptr, &src->mime_types) {
|
||||
if (*mime_ptr)
|
||||
WMAddToArray(mimeTypes, wstrdup(*mime_ptr));
|
||||
}
|
||||
|
||||
/* Read first available data via pipe */
|
||||
WMArray *dropDatas = WMCreateArray(1);
|
||||
char **mt;
|
||||
wl_array_for_each(mt, &src->mime_types) {
|
||||
char *mime = *mt;
|
||||
if (!mime) continue;
|
||||
|
||||
int fds[2];
|
||||
if (pipe(fds) < 0) continue;
|
||||
|
||||
wlr_data_source_send(src, mime, fds[1]);
|
||||
close(fds[1]);
|
||||
|
||||
char buf[65536];
|
||||
int total = 0;
|
||||
ssize_t n;
|
||||
while ((n = read(fds[0], buf + total,
|
||||
sizeof(buf) - total - 1)) > 0)
|
||||
total += n;
|
||||
close(fds[0]);
|
||||
|
||||
if (total > 0) {
|
||||
WMData *data = WMCreateDataWithBytes(buf, total);
|
||||
if (data) {
|
||||
WMAddToArray(dropDatas, data);
|
||||
break; /* use first available type */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
WMPoint pt = wmkpoint(wl_state.pointer_x, wl_state.pointer_y);
|
||||
top->dragDestinationProcs->performDragOperation(
|
||||
top, dropDatas, NULL, &pt);
|
||||
WMFreeArray(dropDatas);
|
||||
WMFreeArray(mimeTypes);
|
||||
}
|
||||
}
|
||||
|
||||
wlr_data_source_dnd_drop(src);
|
||||
(void)ev;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue