From affb62514a0ac738626ffcc4a761d79b1f2602b7 Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Mon, 29 Apr 2013 20:54:42 +0200 Subject: [PATCH] Cleanup of clipboard manager work. --- src/x11_clipboard.c | 103 ++++++++++++++++++++++---------------------- src/x11_platform.h | 3 +- src/x11_window.c | 30 +++---------- 3 files changed, 60 insertions(+), 76 deletions(-) diff --git a/src/x11_clipboard.c b/src/x11_clipboard.c index 1e568222..133efdfc 100644 --- a/src/x11_clipboard.c +++ b/src/x11_clipboard.c @@ -49,14 +49,9 @@ static Bool isSelectionMessage(Display* display, XEvent* event, XPointer pointer return False; } - -////////////////////////////////////////////////////////////////////////// -////// GLFW internal API ////// -////////////////////////////////////////////////////////////////////////// - -// Set the specified property to the contents of the requested selection +// Set the specified property to the selection converted to the requested target // -Atom _glfwWriteSelection(XSelectionRequestEvent* request) +static Atom writeTargetToProperty(const XSelectionRequestEvent* request) { int i; const Atom formats[] = { _glfw.x11.UTF8_STRING, @@ -67,6 +62,7 @@ Atom _glfwWriteSelection(XSelectionRequestEvent* request) if (request->property == None) { // The requestor is a legacy client (ICCCM section 2.2) + // We don't support legacy clients, so fail here return None; } @@ -145,8 +141,8 @@ Atom _glfwWriteSelection(XSelectionRequestEvent* request) if (request->target == _glfw.x11.SAVE_TARGETS) { - // Conversion by clients to SAVE_TARGETS should be treated like - // a side-effect target without side effects + // The request is a check whether we support SAVE_TARGETS + // It should be handled as a no-op side effect target XChangeProperty(_glfw.x11.display, request->requestor, @@ -160,6 +156,8 @@ Atom _glfwWriteSelection(XSelectionRequestEvent* request) return request->property; } + // Conversion to a data target was requested + for (i = 0; i < formatCount; i++) { if (request->target == formats[i]) @@ -179,29 +177,42 @@ Atom _glfwWriteSelection(XSelectionRequestEvent* request) } } + // The requested target is not supported + return None; } -// Save clipboard data to clipboard manager -// + +////////////////////////////////////////////////////////////////////////// +////// GLFW internal API ////// +////////////////////////////////////////////////////////////////////////// + +void _glfwHandleSelectionClear(XEvent* event) +{ + free(_glfw.x11.selection.string); + _glfw.x11.selection.string = NULL; +} + +void _glfwHandleSelectionRequest(XEvent* event) +{ + const XSelectionRequestEvent* request = &event->xselectionrequest; + + XEvent response; + memset(&response, 0, sizeof(response)); + + response.xselection.property = writeTargetToProperty(request); + response.xselection.type = SelectionNotify; + response.xselection.display = request->display; + response.xselection.requestor = request->requestor; + response.xselection.selection = request->selection; + response.xselection.target = request->target; + response.xselection.time = request->time; + + XSendEvent(_glfw.x11.display, request->requestor, False, 0, &response); +} + void _glfwPushSelectionToManager(_GLFWwindow* window) { - XEvent request; - - if (XGetSelectionOwner(_glfw.x11.display, _glfw.x11.CLIPBOARD) != - window->x11.handle) - { - // This window does not own the clipboard selection - return; - } - - if (XGetSelectionOwner(_glfw.x11.display, _glfw.x11.CLIPBOARD_MANAGER) == - None) - { - // There is no running clipboard manager - return; - } - XConvertSelection(_glfw.x11.display, _glfw.x11.CLIPBOARD_MANAGER, _glfw.x11.SAVE_TARGETS, @@ -211,42 +222,31 @@ void _glfwPushSelectionToManager(_GLFWwindow* window) for (;;) { - if (!XCheckIfEvent(_glfw.x11.display, &request, isSelectionMessage, NULL)) + XEvent event; + + if (!XCheckIfEvent(_glfw.x11.display, &event, isSelectionMessage, NULL)) continue; - switch (request.type) + switch (event.type) { case SelectionRequest: - { - XEvent response; - memset(&response, 0, sizeof(response)); - - response.xselection.property = _glfwWriteSelection(&request.xselectionrequest); - response.xselection.type = SelectionNotify; - response.xselection.display = request.xselectionrequest.display; - response.xselection.requestor = request.xselectionrequest.requestor; - response.xselection.selection = request.xselectionrequest.selection; - response.xselection.target = request.xselectionrequest.target; - response.xselection.time = request.xselectionrequest.time; - - XSendEvent(_glfw.x11.display, - request.xselectionrequest.requestor, - False, 0, &response); - + _glfwHandleSelectionRequest(&event); break; - } case SelectionClear: - { - free(_glfw.x11.selection.string); - _glfw.x11.selection.string = NULL; + _glfwHandleSelectionClear(&event); break; - } case SelectionNotify: { - if (request.xselection.target == _glfw.x11.SAVE_TARGETS) + 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; } @@ -255,7 +255,6 @@ void _glfwPushSelectionToManager(_GLFWwindow* window) } - ////////////////////////////////////////////////////////////////////////// ////// GLFW platform API ////// ////////////////////////////////////////////////////////////////////////// diff --git a/src/x11_platform.h b/src/x11_platform.h index d97f9b0c..14f89f83 100644 --- a/src/x11_platform.h +++ b/src/x11_platform.h @@ -237,7 +237,8 @@ void _glfwTerminateJoysticks(void); long _glfwKeySym2Unicode(KeySym keysym); // Clipboard handling -Atom _glfwWriteSelection(XSelectionRequestEvent* request); +void _glfwHandleSelectionClear(XEvent* event); +void _glfwHandleSelectionRequest(XEvent* event); void _glfwPushSelectionToManager(_GLFWwindow* window); // Window support diff --git a/src/x11_window.c b/src/x11_window.c index c68becea..596d0f06 100644 --- a/src/x11_window.c +++ b/src/x11_window.c @@ -719,33 +719,13 @@ static void processEvent(XEvent *event) case SelectionClear: { - // The ownership of the clipboard selection was lost - - free(_glfw.x11.selection.string); - _glfw.x11.selection.string = NULL; + _glfwHandleSelectionClear(event); break; } case SelectionRequest: { - // The contents of the clipboard selection was requested - - XSelectionRequestEvent* request = &event->xselectionrequest; - - XEvent response; - memset(&response, 0, sizeof(response)); - - response.xselection.property = _glfwWriteSelection(request); - response.xselection.type = SelectionNotify; - response.xselection.display = request->display; - response.xselection.requestor = request->requestor; - response.xselection.selection = request->selection; - response.xselection.target = request->target; - response.xselection.time = request->time; - - XSendEvent(_glfw.x11.display, - request->requestor, - False, 0, &response); + _glfwHandleSelectionRequest(event); break; } @@ -904,7 +884,11 @@ void _glfwPlatformDestroyWindow(_GLFWwindow* window) if (window->x11.handle) { - _glfwPushSelectionToManager(window); + if (window->x11.handle == + XGetSelectionOwner(_glfw.x11.display, _glfw.x11.CLIPBOARD)) + { + _glfwPushSelectionToManager(window); + } XDeleteContext(_glfw.x11.display, window->x11.handle, _glfw.x11.context); XUnmapWindow(_glfw.x11.display, window->x11.handle);