diff --git a/src/x11_init.c b/src/x11_init.c index 666b42cc..c056456c 100644 --- a/src/x11_init.c +++ b/src/x11_init.c @@ -797,6 +797,12 @@ void _glfwPlatformTerminate(void) if (_glfw.x11.helperWindowHandle) { + if (XGetSelectionOwner(_glfw.x11.display, _glfw.x11.CLIPBOARD) == + _glfw.x11.helperWindowHandle) + { + _glfwPushSelectionToManagerX11(); + } + XDestroyWindow(_glfw.x11.display, _glfw.x11.helperWindowHandle); _glfw.x11.helperWindowHandle = None; } diff --git a/src/x11_platform.h b/src/x11_platform.h index c86944ba..9f23854f 100644 --- a/src/x11_platform.h +++ b/src/x11_platform.h @@ -295,4 +295,6 @@ void _glfwGrabErrorHandlerX11(void); void _glfwReleaseErrorHandlerX11(void); void _glfwInputErrorX11(int error, const char* message); +void _glfwPushSelectionToManagerX11(void); + #endif // _glfw3_x11_platform_h_ diff --git a/src/x11_window.c b/src/x11_window.c index 58fbaba6..2c4ade13 100644 --- a/src/x11_window.c +++ b/src/x11_window.c @@ -815,51 +815,6 @@ static void handleSelectionRequest(XEvent* event) XSendEvent(_glfw.x11.display, request->requestor, False, 0, &reply); } -static void pushSelectionToManager(_GLFWwindow* window) -{ - XConvertSelection(_glfw.x11.display, - _glfw.x11.CLIPBOARD_MANAGER, - _glfw.x11.SAVE_TARGETS, - None, - window->x11.handle, - CurrentTime); - - for (;;) - { - XEvent event; - - while (XCheckIfEvent(_glfw.x11.display, &event, isSelectionEvent, NULL)) - { - switch (event.type) - { - case SelectionRequest: - handleSelectionRequest(&event); - break; - - case SelectionClear: - handleSelectionClear(&event); - break; - - case SelectionNotify: - { - if (event.xselection.target == _glfw.x11.SAVE_TARGETS) - { - // This means one of two things; either the selection was - // not owned, which means there is no clipboard manager, or - // the transfer to the clipboard manager has completed - // In either case, it means we are done here - return; - } - - break; - } - } - } - - waitForEvent(NULL); - } -} - // Make the specified window and its video mode active on its monitor // static GLFWbool acquireMonitor(_GLFWwindow* window) @@ -1533,6 +1488,53 @@ unsigned long _glfwGetWindowPropertyX11(Window window, return itemCount; } +// Push contents of our selection to clipboard manager +// +void _glfwPushSelectionToManagerX11(void) +{ + XConvertSelection(_glfw.x11.display, + _glfw.x11.CLIPBOARD_MANAGER, + _glfw.x11.SAVE_TARGETS, + None, + _glfw.x11.helperWindowHandle, + CurrentTime); + + for (;;) + { + XEvent event; + + while (XCheckIfEvent(_glfw.x11.display, &event, isSelectionEvent, NULL)) + { + switch (event.type) + { + case SelectionRequest: + handleSelectionRequest(&event); + break; + + case SelectionClear: + handleSelectionClear(&event); + break; + + case SelectionNotify: + { + if (event.xselection.target == _glfw.x11.SAVE_TARGETS) + { + // This means one of two things; either the selection was + // not owned, which means there is no clipboard manager, or + // the transfer to the clipboard manager has completed + // In either case, it means we are done here + return; + } + + break; + } + } + } + + waitForEvent(NULL); + } +} + ////////////////////////////////////////////////////////////////////////// ////// GLFW platform API ////// @@ -1619,12 +1621,6 @@ void _glfwPlatformDestroyWindow(_GLFWwindow* window) if (window->x11.handle) { - if (XGetSelectionOwner(_glfw.x11.display, _glfw.x11.CLIPBOARD) == - window->x11.handle) - { - pushSelectionToManager(window); - } - XDeleteContext(_glfw.x11.display, window->x11.handle, _glfw.x11.context); XUnmapWindow(_glfw.x11.display, window->x11.handle); XDestroyWindow(_glfw.x11.display, window->x11.handle); @@ -2094,11 +2090,11 @@ void _glfwPlatformPostEmptyEvent(void) memset(&event, 0, sizeof(event)); event.type = ClientMessage; - event.xclient.window = _glfw.x11.helper; + event.xclient.window = _glfw.x11.helperWindowHandle; event.xclient.format = 32; // Data is 32-bit longs event.xclient.message_type = _glfw.x11.NULL_; - XSendEvent(_glfw.x11.display, _glfw.x11.helper, False, 0, &event); + XSendEvent(_glfw.x11.display, _glfw.x11.helperWindowHandle, False, 0, &event); XFlush(_glfw.x11.display); } @@ -2234,10 +2230,11 @@ void _glfwPlatformSetClipboardString(_GLFWwindow* window, const char* string) XSetSelectionOwner(_glfw.x11.display, _glfw.x11.CLIPBOARD, - window->x11.handle, CurrentTime); + _glfw.x11.helperWindowHandle, + CurrentTime); if (XGetSelectionOwner(_glfw.x11.display, _glfw.x11.CLIPBOARD) != - window->x11.handle) + _glfw.x11.helperWindowHandle) { _glfwInputError(GLFW_PLATFORM_ERROR, "X11: Failed to become owner of clipboard selection"); @@ -2252,8 +2249,8 @@ const char* _glfwPlatformGetClipboardString(_GLFWwindow* window) XA_STRING }; const size_t formatCount = sizeof(formats) / sizeof(formats[0]); - if (findWindowByHandle(XGetSelectionOwner(_glfw.x11.display, - _glfw.x11.CLIPBOARD))) + if (XGetSelectionOwner(_glfw.x11.display, _glfw.x11.CLIPBOARD) == + _glfw.x11.helperWindowHandle) { // Instead of doing a large number of X round-trips just to put this // string into a window property and then read it back, just return it @@ -2272,7 +2269,8 @@ const char* _glfwPlatformGetClipboardString(_GLFWwindow* window) _glfw.x11.CLIPBOARD, formats[i], _glfw.x11.GLFW_SELECTION, - window->x11.handle, CurrentTime); + _glfw.x11.helperWindowHandle, + CurrentTime); while (!XCheckTypedEvent(_glfw.x11.display, SelectionNotify, &event)) waitForEvent(NULL);