xdnd code that i can't really test but i think it might work?

This commit is contained in:
IoIxD 2026-09-14 16:45:58 -07:00
commit 4bdbfffb78
2 changed files with 71 additions and 21 deletions

View file

@ -53,7 +53,7 @@ struct _MwLLX11 {
Atom xdnd_aware; Atom xdnd_aware;
int xdnd_source; int xdnd_source;
unsigned char xdnd_version; unsigned char xdnd_version;
int format; int xdnd_format;
XIM xim; XIM xim;
XIC xic; XIC xic;

View file

@ -451,8 +451,7 @@ static MwLL MwLLCreateImpl(MwLL parent, int x, int y, int width, int height) {
r->x11.xdnd_text_plain = XInternAtom(r->x11.display, "text/plain", False); r->x11.xdnd_text_plain = XInternAtom(r->x11.display, "text/plain", False);
r->x11.xdnd_aware = XInternAtom(r->x11.display, "XdndAware", False); r->x11.xdnd_aware = XInternAtom(r->x11.display, "XdndAware", False);
r->x11.xdnd_version = 5; r->x11.xdnd_version = 5;
r->x11.format = None; r->x11.xdnd_format = None;
XChangeProperty(r->x11.display, r->x11.window, r->x11.xdnd_aware, 4, 32, PropModeReplace, &r->x11.xdnd_version, 1);
r->x11.clipboard_pending = 0; r->x11.clipboard_pending = 0;
@ -797,20 +796,17 @@ static void MwLLNextEventImpl(MwLL handle) {
if( if(
ev.xclient.message_type == handle->x11.xdnd_enter || ev.xclient.message_type == handle->x11.xdnd_enter ||
ev.xclient.message_type == handle->x11.xdnd_selection || ev.xclient.message_type == handle->x11.xdnd_position ||
ev.xclient.message_type == handle->x11.xdnd_drop) { ev.xclient.message_type == handle->x11.xdnd_drop) {
char* name = XGetAtomName(handle->x11.display, ev.xclient.message_type); char* name = XGetAtomName(handle->x11.display, ev.xclient.message_type);
printf("%s\n", name);
if(ev.xclient.message_type == handle->x11.xdnd_enter) { if(ev.xclient.message_type == handle->x11.xdnd_enter) {
Bool list = ev.xclient.data.l[1] & 1; Bool list = ev.xclient.data.l[1] & 1;
int version = ev.xclient.data.l[1] >> 24; int version = ev.xclient.data.l[1] >> 24;
unsigned long count = 0; unsigned long count = 0;
unsigned char* formats = NULL; unsigned char* formats = NULL;
handle->x11.xdnd_source = ev.xclient.data.l[0];
unsigned long i; unsigned long i;
handle->x11.xdnd_source = ev.xclient.data.l[0];
if(list) { if(list) {
Atom actualType; Atom actualType;
int32_t actualFormat; int32_t actualFormat;
@ -841,7 +837,8 @@ static void MwLLNextEventImpl(MwLL handle) {
for(i = 0; i < count; i++) { for(i = 0; i < count; i++) {
if(formats[i] == handle->x11.xdnd_text_uri_list || formats[i] == handle->x11.xdnd_text_plain) { if(formats[i] == handle->x11.xdnd_text_uri_list || formats[i] == handle->x11.xdnd_text_plain) {
handle->x11.format = formats[i]; handle->x11.xdnd_format = formats[i];
printf("format %d\n", handle->x11.xdnd_format);
break; break;
} }
} }
@ -850,20 +847,30 @@ static void MwLLNextEventImpl(MwLL handle) {
XFree(formats); XFree(formats);
} }
} }
if(ev.xclient.message_type == handle->x11.xdnd_selection && handle->x11.xdnd_version >= 5) { if(ev.xclient.message_type == handle->x11.xdnd_position && handle->x11.xdnd_version >= 5) {
XEvent reply; XEvent reply;
reply.xclient.message_type = handle->x11.xdnd_status; reply.xclient.message_type = handle->x11.xdnd_status;
if(handle->x11.format) { if(handle->x11.xdnd_format) {
reply.xclient.data.l[1] = 1; reply.xclient.data.l[1] = 1;
if(handle->x11.xdnd_version >= 2) if(handle->x11.xdnd_version >= 2) reply.xclient.data.l[4] = handle->x11.xdnd_action_copy;
reply.xclient.data.l[4] = handle->x11.xdnd_action_copy;
} }
XSendEvent(handle->x11.display, handle->x11.xdnd_source, False, NoEventMask, &reply); XSendEvent(handle->x11.display, handle->x11.xdnd_source, False, NoEventMask, &reply);
XFlush(handle->x11.display); XFlush(handle->x11.display);
} }
if(ev.xclient.message_type == handle->x11.xdnd_drop && handle->x11.xdnd_version >= 5) { if(ev.xclient.message_type == handle->x11.xdnd_drop && handle->x11.xdnd_version >= 5) {
printf("whar\n"); Time time = CurrentTime;
if(handle->x11.xdnd_version >= 1)
time = ev.xclient.data.l[2];
if(handle->x11.xdnd_format) {
XConvertSelection((Display*)handle->x11.display,
handle->x11.xdnd_selection,
handle->x11.xdnd_format,
handle->x11.xdnd_selection,
(Window)handle->x11.window,
time);
}
} }
XFree(name); XFree(name);
@ -973,7 +980,51 @@ static void MwLLNextEventImpl(MwLL handle) {
{ {
handle->x11.clipboard_pending = 0; handle->x11.clipboard_pending = 0;
if(ev.xselection.property != None) { if(ev.xselection.property == handle->x11.xdnd_selection) {
XEvent reply;
char* data;
unsigned long result;
Atom actualType;
int32_t actualFormat;
unsigned long bytesAfter;
XGetWindowProperty(handle->x11.display,
ev.xselection.requestor, ev.xselection.property,
0, LONG_MAX, False, ev.xselection.target,
&actualType, &actualFormat, &result, &bytesAfter,
(unsigned char**)&data);
if(result == 0)
break;
/* !! untested lmao !! */
printf("File(s) dropped: %s\n", data);
if(strstr(data, "\n")) {
char* data_ptr = data;
while(data_ptr) {
if(strstr(data_ptr, "file://")) {
MwLLDispatch(handle, drag_and_drop, data_ptr + sizeof("file://") - 1);
} else {
MwLLDispatch(handle, drag_and_drop, data_ptr);
}
data_ptr = strstr(data, "\n");
}
} else {
MwLLDispatch(handle, drag_and_drop, data);
}
if(data)
XFree(data);
if(handle->x11.xdnd_version >= 2) {
reply.xclient.message_type = handle->x11.xdnd_finished;
reply.xclient.data.l[1] = result;
reply.xclient.data.l[2] = handle->x11.xdnd_action_copy;
XSendEvent((Display*)handle->x11.display, handle->x11.xdnd_source, False, NoEventMask, &reply);
XFlush((Display*)handle->x11.display);
}
} else if(ev.xselection.property != None) {
Atom type; Atom type;
int format; int format;
unsigned long nitems, after, size; unsigned long nitems, after, size;
@ -1010,7 +1061,6 @@ static void MwLLNextEventImpl(MwLL handle) {
free(buf); free(buf);
} }
} }
XDeleteProperty(handle->x11.display, handle->x11.window, handle->x11.selection); XDeleteProperty(handle->x11.display, handle->x11.window, handle->x11.selection);
} }
} break; } break;
@ -1492,7 +1542,7 @@ static void MwLLGetScreenSizeImpl(MwLL handle, MwRect* rect) {
} }
static void MwLLSetupDragAndDropImpl(MwLL handle) { static void MwLLSetupDragAndDropImpl(MwLL handle) {
(void)handle; XChangeProperty(handle->x11.display, handle->x11.window, handle->x11.xdnd_aware, 4, 32, PropModeReplace, &handle->x11.xdnd_version, 1);
} }
static void MwLLBeginStateChangeImpl(MwLL handle) { static void MwLLBeginStateChangeImpl(MwLL handle) {