|  |  | @ -306,12 +306,14 @@ static GLboolean createWindow(_GLFWwindow* window, | 
			
		
	
		
		
			
				
					
					|  |  |  |         XISelectEvents(_glfw.x11.display, window->x11.handle, &eventmask, 1); |  |  |  |         XISelectEvents(_glfw.x11.display, window->x11.handle, &eventmask, 1); | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     // Enable Xdnd
 |  |  |  |     if (_glfw.x11.XdndAware) | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     if(_glfw.x11.XdndAware!=None) |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     { |  |  |  |     { | 
			
		
	
		
		
			
				
					
					|  |  |  |     	//Announce XDND support
 |  |  |  |         // Announce support for XDND version 5 and below
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		Atom version=5; |  |  |  | 
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		XChangeProperty(_glfw.x11.display, window->x11.handle, _glfw.x11.XdndAware, XA_ATOM, 32, PropModeReplace, (unsigned char*)&version, 1); |  |  |  |         const Atom version = 5; | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         XChangeProperty(_glfw.x11.display, window->x11.handle, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                         _glfw.x11.XdndAware, XA_ATOM, 32, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                         PropModeReplace, (unsigned char*) &version, 1); | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     _glfwPlatformSetWindowTitle(window, wndconfig->title); |  |  |  |     _glfwPlatformSetWindowTitle(window, wndconfig->title); | 
			
		
	
	
		
		
			
				
					|  |  | @ -716,10 +718,9 @@ static void processEvent(XEvent *event) | 
			
		
	
		
		
			
				
					
					|  |  |  |             } |  |  |  |             } | 
			
		
	
		
		
			
				
					
					|  |  |  |             else if (event->xclient.message_type == _glfw.x11.XdndEnter) |  |  |  |             else if (event->xclient.message_type == _glfw.x11.XdndEnter) | 
			
		
	
		
		
			
				
					
					|  |  |  |             { |  |  |  |             { | 
			
		
	
		
		
			
				
					
					|  |  |  |             	// Xdnd Enter: the drag&drop event has started in the window,
 |  |  |  |                 // Xdnd Enter: the drag&drop event has started in the window, we
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |             	// we could be getting the type and possible conversions here
 |  |  |  |                 // could be getting the type and possible conversions here but
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |             	// but since we use always string conversion we don't need
 |  |  |  |                 // since we use always string conversion we don't need it
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |             	// it
 |  |  |  |  | 
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |             } |  |  |  |             } | 
			
		
	
		
		
			
				
					
					|  |  |  |             else if (event->xclient.message_type == _glfw.x11.XdndDrop) |  |  |  |             else if (event->xclient.message_type == _glfw.x11.XdndDrop) | 
			
		
	
		
		
			
				
					
					|  |  |  |             { |  |  |  |             { | 
			
		
	
	
		
		
			
				
					|  |  | @ -731,45 +732,43 @@ static void processEvent(XEvent *event) | 
			
		
	
		
		
			
				
					
					|  |  |  |                                   _glfw.x11.UTF8_STRING, |  |  |  |                                   _glfw.x11.UTF8_STRING, | 
			
		
	
		
		
			
				
					
					|  |  |  |                                   _glfw.x11.XdndSelection, |  |  |  |                                   _glfw.x11.XdndSelection, | 
			
		
	
		
		
			
				
					
					|  |  |  |                                   window->x11.handle, CurrentTime); |  |  |  |                                   window->x11.handle, CurrentTime); | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             } |  |  |  |             } | 
			
		
	
		
		
			
				
					
					|  |  |  |             else if (event->xclient.message_type == _glfw.x11.XdndLeave) |  |  |  |             else if (event->xclient.message_type == _glfw.x11.XdndLeave) | 
			
		
	
		
		
			
				
					
					|  |  |  |             { |  |  |  |             { | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             } |  |  |  |             } | 
			
		
	
		
		
			
				
					
					|  |  |  |             else if (event->xclient.message_type == _glfw.x11.XdndPosition) |  |  |  |             else if (event->xclient.message_type == _glfw.x11.XdndPosition) | 
			
		
	
		
		
			
				
					
					|  |  |  |             { |  |  |  |             { | 
			
		
	
		
		
			
				
					
					|  |  |  |                 // Xdnd Position: get coordinates of the mouse inside the window
 |  |  |  |                 // Xdnd Position: get coordinates of the mouse inside the window
 | 
			
		
	
		
		
			
				
					
					|  |  |  |                 // and update the mouse position
 |  |  |  |                 // and update the mouse position
 | 
			
		
	
		
		
			
				
					
					|  |  |  |             	int absX = (event->xclient.data.l[2]>>16) & 0xFFFF; |  |  |  |                 const int absX = (event->xclient.data.l[2] >> 16) & 0xFFFF; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |             	int absY = (event->xclient.data.l[2]) & 0xFFFF; |  |  |  |                 const int absY = (event->xclient.data.l[2]) & 0xFFFF; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |             	int x; |  |  |  |                 int x, y; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |             	int y; |  |  |  |  | 
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |                 _glfwPlatformGetWindowPos(window, &x, &y); |  |  |  |                 _glfwPlatformGetWindowPos(window, &x, &y); | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 _glfwInputCursorMotion(window, absX - x, absY - y); |  |  |  |                 _glfwInputCursorMotion(window, absX - x, absY - y); | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |                 // Xdnd: reply with an XDND status message
 |  |  |  |                 // Xdnd: reply with an XDND status message
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 				XClientMessageEvent m; |  |  |  |                 XEvent reply; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 				memset(&m, sizeof(m), 0); |  |  |  |                 memset(&reply, sizeof(reply), 0); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 				m.type = ClientMessage; |  |  |  | 
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 				m.display = event->xclient.display; |  |  |  |                 reply.type = ClientMessage; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 				m.window = event->xclient.data.l[0]; |  |  |  |                 reply.xclient.window = event->xclient.data.l[0]; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 				m.message_type = _glfw.x11.XdndStatus; |  |  |  |                 reply.xclient.message_type = _glfw.x11.XdndStatus; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 				m.format=32; |  |  |  |                 reply.xclient.format = 32; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 				m.data.l[0] = window->x11.handle; |  |  |  |                 reply.xclient.data.l[0] = window->x11.handle; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 				m.data.l[1] = 1; // Always accept the dnd with no rectangle
 |  |  |  |                 reply.xclient.data.l[1] = 1; // Always accept the dnd with no rectangle
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 				m.data.l[2] = 0; // Specify an empty rectangle
 |  |  |  |                 reply.xclient.data.l[2] = 0; // Specify an empty rectangle
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 				m.data.l[3] = 0; |  |  |  |                 reply.xclient.data.l[3] = 0; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 				m.data.l[4] = _glfw.x11.XdndActionCopy; // We only accept copying
 |  |  |  |                 reply.xclient.data.l[4] = _glfw.x11.XdndActionCopy; // We only accept copying
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 				XSendEvent(_glfw.x11.display, event->xclient.data.l[0], False, NoEventMask, (XEvent*)&m); |  |  |  |                 XSendEvent(_glfw.x11.display, window->x11.handle, | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                            False, NoEventMask, &reply); | 
			
		
	
		
		
			
				
					
					|  |  |  |                 XFlush(_glfw.x11.display); |  |  |  |                 XFlush(_glfw.x11.display); | 
			
		
	
		
		
			
				
					
					|  |  |  |             } |  |  |  |             } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |             break; |  |  |  |             break; | 
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |         case SelectionNotify: |  |  |  |         case SelectionNotify: | 
			
		
	
		
		
			
				
					
					|  |  |  |         { |  |  |  |         { | 
			
		
	
		
		
			
				
					
					|  |  |  |             if (event->xselection.property != None) |  |  |  |             if (event->xselection.property != None) | 
			
		
	
	
		
		
			
				
					|  |  | @ -777,23 +776,27 @@ static void processEvent(XEvent *event) | 
			
		
	
		
		
			
				
					
					|  |  |  |                 // Xdnd: got a selection notification from the conversion
 |  |  |  |                 // Xdnd: got a selection notification from the conversion
 | 
			
		
	
		
		
			
				
					
					|  |  |  |                 // we asked for, get the data and finish the d&d event
 |  |  |  |                 // we asked for, get the data and finish the d&d event
 | 
			
		
	
		
		
			
				
					
					|  |  |  |                 char* data; |  |  |  |                 char* data; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |                 free(_glfw.x11.xdnd.string); |  |  |  |                 free(_glfw.x11.xdnd.string); | 
			
		
	
		
		
			
				
					
					|  |  |  |                 _glfw.x11.xdnd.string = NULL; |  |  |  |                 _glfw.x11.xdnd.string = NULL; | 
			
		
	
		
		
			
				
					
					|  |  |  | 				int result = _glfwGetWindowProperty(event->xselection.requestor, |  |  |  | 
 | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 const int result = _glfwGetWindowProperty(event->xselection.requestor, | 
			
		
	
		
		
			
				
					
					|  |  |  |                                                           event->xselection.property, |  |  |  |                                                           event->xselection.property, | 
			
		
	
		
		
			
				
					
					|  |  |  |                                                           event->xselection.target, |  |  |  |                                                           event->xselection.target, | 
			
		
	
		
		
			
				
					
					|  |  |  |                                                           (unsigned char**) &data); |  |  |  |                                                           (unsigned char**) &data); | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 				if(result){ |  |  |  |                 if (result) | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 					// nautilus seems to add a \r at the end of the paths
 |  |  |  |                 { | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                     // Nautilus seems to add a \r at the end of the paths
 | 
			
		
	
		
		
			
				
					
					|  |  |  |                     // remove it so paths can be directly used
 |  |  |  |                     // remove it so paths can be directly used
 | 
			
		
	
		
		
			
				
					
					|  |  |  |                     _glfw.x11.xdnd.string = malloc(strlen(data)); |  |  |  |                     _glfw.x11.xdnd.string = malloc(strlen(data)); | 
			
		
	
		
		
			
				
					
					|  |  |  |                     char *to = _glfw.x11.xdnd.string; |  |  |  |                     char *to = _glfw.x11.xdnd.string; | 
			
		
	
		
		
			
				
					
					|  |  |  |                     const char *from = data; |  |  |  |                     const char *from = data; | 
			
		
	
		
		
			
				
					
					|  |  |  |                     const char *current = strchr(from, '\r'); |  |  |  |                     const char *current = strchr(from, '\r'); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |                     while (current) |  |  |  |                     while (current) | 
			
		
	
		
		
			
				
					
					|  |  |  |                     { |  |  |  |                     { | 
			
		
	
		
		
			
				
					
					|  |  |  | 						int charsToCopy = current - from; |  |  |  |                         const int charsToCopy = current - from; | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |                         memcpy(to, from, (size_t) charsToCopy); |  |  |  |                         memcpy(to, from, (size_t) charsToCopy); | 
			
		
	
		
		
			
				
					
					|  |  |  |                         to += charsToCopy; |  |  |  |                         to += charsToCopy; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
	
		
		
			
				
					|  |  | @ -801,37 +804,33 @@ static void processEvent(XEvent *event) | 
			
		
	
		
		
			
				
					
					|  |  |  |                         current = strchr(from, '\r'); |  |  |  |                         current = strchr(from, '\r'); | 
			
		
	
		
		
			
				
					
					|  |  |  |                     } |  |  |  |                     } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 					size_t remaining = strlen(from); |  |  |  |                     const size_t remaining = strlen(from); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |                     memcpy(to, from, remaining); |  |  |  |                     memcpy(to, from, remaining); | 
			
		
	
		
		
			
				
					
					|  |  |  |                     to += remaining; |  |  |  |                     to += remaining; | 
			
		
	
		
		
			
				
					
					|  |  |  |                     *to = 0; |  |  |  |                     *to = 0; | 
			
		
	
		
		
			
				
					
					|  |  |  |                 } |  |  |  |                 } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 				XClientMessageEvent m; |  |  |  |                 XEvent reply; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 				memset(&m, sizeof(m), 0); |  |  |  |                 memset(&reply, sizeof(reply), 0); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 				m.type = ClientMessage; |  |  |  |                 reply.type = ClientMessage; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 				m.display = _glfw.x11.display; |  |  |  |                 reply.xclient.window = _glfw.x11.xdnd.sourceWindow; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 				m.window = _glfw.x11.xdnd.sourceWindow; |  |  |  |                 reply.xclient.message_type = _glfw.x11.XdndFinished; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 				m.message_type = _glfw.x11.XdndFinished; |  |  |  |                 reply.xclient.format = 32; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 				m.format=32; |  |  |  |                 reply.xclient.data.l[0] = window->x11.handle; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 				m.data.l[0] = window->x11.handle; |  |  |  |                 reply.xclient.data.l[1] = result; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 				m.data.l[1] = result; |  |  |  |                 reply.xclient.data.l[2] = _glfw.x11.XdndActionCopy; // We only ever copy
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 				m.data.l[2] = _glfw.x11.XdndActionCopy; //We only ever copy.
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 				// Reply that all is well.
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 				XSendEvent(_glfw.x11.display, _glfw.x11.xdnd.sourceWindow, False, NoEventMask, (XEvent*)&m); |  |  |  |  | 
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 // Reply that all is well
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 XSendEvent(_glfw.x11.display, _glfw.x11.xdnd.sourceWindow, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                            False, NoEventMask, &reply); | 
			
		
	
		
		
			
				
					
					|  |  |  |                 XSync(_glfw.x11.display, False); |  |  |  |                 XSync(_glfw.x11.display, False); | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 XFree(data); |  |  |  |                 XFree(data); | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |                 if (result) |  |  |  |                 if (result) | 
			
		
	
		
		
			
				
					
					|  |  |  | 				{ |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                     _glfwInputDrop(window, _glfw.x11.xdnd.string); |  |  |  |                     _glfwInputDrop(window, _glfw.x11.xdnd.string); | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 				} |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             } |  |  |  |             } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |             break; |  |  |  |             break; | 
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
	
		
		
			
				
					|  |  | 
 |