From 689c4009fb9be348f9137a9092b068e056a3d8b3 Mon Sep 17 00:00:00 2001 From: Albert Astals Cid Date: Thu, 5 Jan 2012 11:11:27 +0100 Subject: Check for the clipboard manager when looping due to app quiting One can be extremely unlucky and on session logout get this: * All apps are going down * A Qt app checks if the clipboard manager is there to yield its clipboard contents * The clipboard manager is still there * Then just after that check, the clipboard manager finishes because of the session end * This means the Qt app will loop for 5 seconds trying to yield its clipboard contents to a clipboard manager that is not there anymore Change-Id: Ia89670d4deb72f12e660a0d7aa5b2d212955d6fe Reviewed-by: Lars Knoll --- src/plugins/platforms/xcb/qxcbclipboard.cpp | 14 ++++++++++++-- src/plugins/platforms/xcb/qxcbclipboard.h | 2 +- 2 files changed, 13 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/plugins/platforms/xcb/qxcbclipboard.cpp b/src/plugins/platforms/xcb/qxcbclipboard.cpp index 3c3469a73b..24de78861f 100644 --- a/src/plugins/platforms/xcb/qxcbclipboard.cpp +++ b/src/plugins/platforms/xcb/qxcbclipboard.cpp @@ -208,7 +208,7 @@ QXcbClipboard::~QXcbClipboard() connection()->sync(); // waiting until the clipboard manager fetches the content. - if (!waitForClipboardEvent(m_owner, XCB_SELECTION_NOTIFY, 5000)) { + if (!waitForClipboardEvent(m_owner, XCB_SELECTION_NOTIFY, 5000, true)) { qWarning("QClipboard: Unable to receive an event from the " "clipboard manager in a reasonable time"); } @@ -726,7 +726,7 @@ namespace }; } -xcb_generic_event_t *QXcbClipboard::waitForClipboardEvent(xcb_window_t win, int type, int timeout) +xcb_generic_event_t *QXcbClipboard::waitForClipboardEvent(xcb_window_t win, int type, int timeout, bool checkManager) { QElapsedTimer timer; timer.start(); @@ -736,6 +736,16 @@ xcb_generic_event_t *QXcbClipboard::waitForClipboardEvent(xcb_window_t win, int if (e) return e; + if (checkManager) { + xcb_get_selection_owner_cookie_t cookie = xcb_get_selection_owner(xcb_connection(), atom(QXcbAtom::CLIPBOARD_MANAGER)); + xcb_get_selection_owner_reply_t *reply = xcb_get_selection_owner_reply(xcb_connection(), cookie, 0); + if (!reply || reply->owner == XCB_NONE) { + free(reply); + return 0; + } + free(reply); + } + // process other clipboard events, since someone is probably requesting data from us ClipboardEvent clipboard(connection()); e = connection()->checkEvent(clipboard); diff --git a/src/plugins/platforms/xcb/qxcbclipboard.h b/src/plugins/platforms/xcb/qxcbclipboard.h index 9debdcefbb..e9ddb70f8f 100644 --- a/src/plugins/platforms/xcb/qxcbclipboard.h +++ b/src/plugins/platforms/xcb/qxcbclipboard.h @@ -85,7 +85,7 @@ public: QByteArray getSelection(xcb_atom_t selection, xcb_atom_t target, xcb_atom_t property); private: - xcb_generic_event_t *waitForClipboardEvent(xcb_window_t win, int type, int timeout); + xcb_generic_event_t *waitForClipboardEvent(xcb_window_t win, int type, int timeout, bool needsManager = false); xcb_atom_t sendTargetsSelection(QMimeData *d, xcb_window_t window, xcb_atom_t property); xcb_atom_t sendSelection(QMimeData *d, xcb_atom_t target, xcb_window_t window, xcb_atom_t property); -- cgit v1.2.3