diff --git a/src/x11_init.c b/src/x11_init.c index eed9f5a28..cd3f5bfdb 100644 --- a/src/x11_init.c +++ b/src/x11_init.c @@ -546,14 +546,11 @@ static GLboolean initExtensions(void) _glfw.x11.XdndEnter = XInternAtom(_glfw.x11.display, "XdndEnter", False); _glfw.x11.XdndPosition = XInternAtom(_glfw.x11.display, "XdndPosition", False); _glfw.x11.XdndStatus = XInternAtom(_glfw.x11.display, "XdndStatus", False); - _glfw.x11.XdndTypeList = XInternAtom(_glfw.x11.display, "XdndTypeList", False); _glfw.x11.XdndActionCopy = XInternAtom(_glfw.x11.display, "XdndActionCopy", False); _glfw.x11.XdndDrop = XInternAtom(_glfw.x11.display, "XdndDrop", False); _glfw.x11.XdndLeave = XInternAtom(_glfw.x11.display, "XdndLeave", False); _glfw.x11.XdndFinished = XInternAtom(_glfw.x11.display, "XdndFinished", False); _glfw.x11.XdndSelection = XInternAtom(_glfw.x11.display, "XdndSelection", False); - _glfw.x11.XdndProxy = XInternAtom(_glfw.x11.display, "XdndProxy", False); - _glfw.x11.XA_TARGETS = XInternAtom(_glfw.x11.display, "TARGETS", False); _glfw.x11.xdnd.string = NULL; _glfw.x11.xdnd.type1 = NULL; _glfw.x11.xdnd.type2 = NULL; diff --git a/src/x11_platform.h b/src/x11_platform.h index 71a0febc1..70a9d5d1a 100644 --- a/src/x11_platform.h +++ b/src/x11_platform.h @@ -127,14 +127,11 @@ typedef struct _GLFWlibraryX11 Atom XdndEnter; Atom XdndPosition; Atom XdndStatus; - Atom XdndTypeList; Atom XdndActionCopy; Atom XdndDrop; Atom XdndLeave; Atom XdndFinished; Atom XdndSelection; - Atom XdndProxy; - Atom XA_TARGETS; struct{ Window sourceWindow; char* string; diff --git a/src/x11_window.c b/src/x11_window.c index 247d2c188..c2aa7b69c 100644 --- a/src/x11_window.c +++ b/src/x11_window.c @@ -701,6 +701,11 @@ static void processEvent(XEvent *event) event); } + +#define xdndEnter_sourceWindow(evt) ( (evt)->data.l[0]) +#define xdndEnter_version(evt) ( (evt)->data.l[1] >> 24) +#define xdndEnter_hasThreeTypes(evt) (((evt)->xclient.data.l[1] & 0x1UL) == 0) +#define xdndEnter_typeAt(evt, idx) ( (evt)->xclient.data.l[2 + (idx)]) else if(event->xclient.message_type == _glfw.x11.XdndEnter) { // Xdnd Enter: the drag&drop event has started in the window, @@ -714,20 +719,11 @@ static void processEvent(XEvent *event) // the window, ask to convert the selection _glfw.x11.xdnd.sourceWindow = event->xclient.data.l[0]; - - const Atom formats[] = { _glfw.x11.UTF8_STRING, - _glfw.x11.COMPOUND_STRING, - XA_STRING }; - const int formatCount = sizeof(formats) / sizeof(formats[0]); - int i; - - for(i=0;ix11.handle, CurrentTime); - } + XConvertSelection(_glfw.x11.display, + _glfw.x11.XdndSelection, + _glfw.x11.UTF8_STRING, + _glfw.x11.XdndSelection, + window->x11.handle, CurrentTime); } else if(event->xclient.message_type == _glfw.x11.XdndLeave) @@ -765,7 +761,6 @@ static void processEvent(XEvent *event) XSendEvent(_glfw.x11.display, event->xclient.data.l[0], False, NoEventMask, (XEvent*)&m); XFlush(_glfw.x11.display); - } break; @@ -778,13 +773,36 @@ static void processEvent(XEvent *event) // Xdnd: got a selection notification from the conversion // we asked for, get the data and finish the d&d event char* data; - _glfwGetWindowProperty(event->xselection.requestor, + free(_glfw.x11.xdnd.string); + _glfw.x11.xdnd.string = NULL; + int result = _glfwGetWindowProperty(event->xselection.requestor, event->xselection.property, event->xselection.target, (unsigned char**) &data); - free(_glfw.x11.xdnd.string); - _glfw.x11.xdnd.string = strdup(data); + if(result){ + // nautilus seems to add a \r at the end of the paths + // remove it so paths can be directly used + _glfw.x11.xdnd.string = malloc(strlen(data)); + char *to = _glfw.x11.xdnd.string; + const char *from = data; + const char *current = strchr(from, '\r'); + while(current) + { + int charsToCopy = current - from; + memcpy(to, from, (size_t)charsToCopy); + to += charsToCopy; + + from = current+1; + current = strchr(from, '\r'); + } + + size_t remaining = strlen(from); + + memcpy(to, from, remaining); + to += remaining; + *to = 0; + } XClientMessageEvent m; memset(&m, sizeof(m), 0); @@ -794,7 +812,7 @@ static void processEvent(XEvent *event) m.message_type = _glfw.x11.XdndFinished; m.format=32; m.data.l[0] = window->x11.handle; - m.data.l[1] = 1; + m.data.l[1] = result; m.data.l[2] = _glfw.x11.XdndActionCopy; //We only ever copy. // Reply that all is well. @@ -804,7 +822,7 @@ static void processEvent(XEvent *event) XFree(data); - _glfwInputDrop(window,_glfw.x11.xdnd.string); + if(result) _glfwInputDrop(window,_glfw.x11.xdnd.string); } break; }