mirror of
https://github.com/glfw/glfw.git
synced 2025-10-02 21:00:57 +00:00
x11: fix d&d type conversions + remove \r in paths
This commit is contained in:
parent
9e9e75f331
commit
0322154670
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;i<formatCount;i++){
|
||||
XConvertSelection(_glfw.x11.display,
|
||||
_glfw.x11.XdndSelection,
|
||||
formats[i],
|
||||
_glfw.x11.XdndSelection,
|
||||
window->x11.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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user