From f5c2e6374b9f6c39a2e535f7282c7d7160591ba6 Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Tue, 15 Sep 2009 19:46:01 +0200 Subject: Implemented the SAVE_TARGET in QClipboard on X11 Added support for the simpliest SAVE_TARGET mechanizm allowing us to work nicely with clipboard managers, so that when Qt application that owns the clipboard exits we delegate the content to the clipboard manager if there is one. The current implementation doesn't specify which targets to give to the manager, so it will try to fetch as much as possible. Also, right now we do not support the TARGET_SIZES target, meaning that the manager doesn't know how much data it is going to fetch, so it will try to fetch everything even if it can take a lot of time. Reviewed-by: Bradley T. Hughes --- src/gui/kernel/qapplication_x11.cpp | 2 ++ src/gui/kernel/qclipboard_x11.cpp | 25 ++++++++++++++++++++++++- src/gui/kernel/qt_x11_p.h | 2 ++ 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/src/gui/kernel/qapplication_x11.cpp b/src/gui/kernel/qapplication_x11.cpp index 601cd11..bbce438 100644 --- a/src/gui/kernel/qapplication_x11.cpp +++ b/src/gui/kernel/qapplication_x11.cpp @@ -190,10 +190,12 @@ static const char * x11_atomnames = { "TARGETS\0" "MULTIPLE\0" "TIMESTAMP\0" + "SAVE_TARGETS\0" "CLIP_TEMPORARY\0" "_QT_SELECTION\0" "_QT_CLIPBOARD_SENTINEL\0" "_QT_SELECTION_SENTINEL\0" + "CLIPBOARD_MANAGER\0" "RESOURCE_MANAGER\0" diff --git a/src/gui/kernel/qclipboard_x11.cpp b/src/gui/kernel/qclipboard_x11.cpp index b2f682b..5495bfe 100644 --- a/src/gui/kernel/qclipboard_x11.cpp +++ b/src/gui/kernel/qclipboard_x11.cpp @@ -787,6 +787,7 @@ static Atom send_targets_selection(QClipboardData *d, Window window, Atom proper types.append(ATOM(TARGETS)); types.append(ATOM(MULTIPLE)); types.append(ATOM(TIMESTAMP)); + types.append(ATOM(SAVE_TARGETS)); XChangeProperty(X11->display, window, property, XA_ATOM, 32, PropModeReplace, (uchar *) types.data(), types.size()); @@ -911,8 +912,30 @@ bool QClipboard::event(QEvent *e) XEvent *xevent = (XEvent *)(((QClipboardEvent *)e)->data()); Display *dpy = X11->display; - if (!xevent) + if (!xevent) { + // That means application exits and we need to give clipboard + // content to the clipboard manager. + // First we check if there is a clipboard manager. + if (XGetSelectionOwner(X11->display, ATOM(CLIPBOARD_MANAGER)) == XNone) + return true; + + Window ownerId = owner->internalWinId(); + Q_ASSERT(ownerId); + // we delete the property so the manager saves all TARGETS. + XDeleteProperty(X11->display, ownerId, ATOM(_QT_SELECTION)); + XConvertSelection(X11->display, ATOM(CLIPBOARD_MANAGER), ATOM(SAVE_TARGETS), + ATOM(_QT_SELECTION), ownerId, X11->time); + XSync(dpy, false); + + XEvent event; + // waiting until the clipboard manager fetches the content. + if (!X11->clipboardWaitForEvent(ownerId, SelectionNotify, &event, 10000)) { + qWarning("QClipboard: Unable to receive an event from the " + "clipboard manager in a reasonable time"); + } + return true; + } switch (xevent->type) { diff --git a/src/gui/kernel/qt_x11_p.h b/src/gui/kernel/qt_x11_p.h index 1b02ed3..61acbac 100644 --- a/src/gui/kernel/qt_x11_p.h +++ b/src/gui/kernel/qt_x11_p.h @@ -544,10 +544,12 @@ struct QX11Data TARGETS, MULTIPLE, TIMESTAMP, + SAVE_TARGETS, CLIP_TEMPORARY, _QT_SELECTION, _QT_CLIPBOARD_SENTINEL, _QT_SELECTION_SENTINEL, + CLIPBOARD_MANAGER, RESOURCE_MANAGER, -- cgit v0.12