98 lines
3.7 KiB
Diff
98 lines
3.7 KiB
Diff
|
From 269fdbdd2bedda5f5eacb751224d3a3fc3eed5bc Mon Sep 17 00:00:00 2001
|
|||
|
From: Urs Fleisch <ufleisch@users.sourceforge.net>
|
|||
|
Date: Fri, 26 Feb 2016 17:46:09 +0100
|
|||
|
Subject: [PATCH] xcb: Fix drag and drop to applications like Emacs and
|
|||
|
Chromium.
|
|||
|
MIME-Version: 1.0
|
|||
|
Content-Type: text/plain; charset=UTF-8
|
|||
|
Content-Transfer-Encoding: 8bit
|
|||
|
|
|||
|
Drops without matching time stamp do not work. I have fixed the issue by
|
|||
|
reanimating the findXdndAwareParent() function (adapted to XCB) and
|
|||
|
using it to find a matching transaction if all else fails.
|
|||
|
|
|||
|
Task-number: QTBUG-45812
|
|||
|
Change-Id: Ibca15bbab02ccf2f25280418e9edf36972ebf9a0
|
|||
|
Reviewed-by: Błażej Szczygieł <spaz16@wp.pl>
|
|||
|
Reviewed-by: Dmitry Shachnev <mitya57@gmail.com>
|
|||
|
Reviewed-by: Shawn Rutledge <shawn.rutledge@theqtcompany.com>
|
|||
|
---
|
|||
|
src/plugins/platforms/xcb/qxcbdrag.cpp | 55 +++++++++++++++++++++++++++-------
|
|||
|
1 file changed, 44 insertions(+), 11 deletions(-)
|
|||
|
|
|||
|
diff --git a/src/plugins/platforms/xcb/qxcbdrag.cpp b/src/plugins/platforms/xcb/qxcbdrag.cpp
|
|||
|
index f5cc873..f1428d0 100644
|
|||
|
--- a/src/plugins/platforms/xcb/qxcbdrag.cpp
|
|||
|
+++ b/src/plugins/platforms/xcb/qxcbdrag.cpp
|
|||
|
@@ -1072,6 +1072,40 @@ void QXcbDrag::cancel()
|
|||
|
send_leave();
|
|||
|
}
|
|||
|
|
|||
|
+// find an ancestor with XdndAware on it
|
|||
|
+static xcb_window_t findXdndAwareParent(QXcbConnection *c, xcb_window_t window)
|
|||
|
+{
|
|||
|
+ xcb_window_t target = 0;
|
|||
|
+ forever {
|
|||
|
+ // check if window has XdndAware
|
|||
|
+ xcb_get_property_cookie_t gpCookie = Q_XCB_CALL(
|
|||
|
+ xcb_get_property(c->xcb_connection(), false, window,
|
|||
|
+ c->atom(QXcbAtom::XdndAware), XCB_GET_PROPERTY_TYPE_ANY, 0, 0));
|
|||
|
+ xcb_get_property_reply_t *gpReply = xcb_get_property_reply(
|
|||
|
+ c->xcb_connection(), gpCookie, 0);
|
|||
|
+ bool aware = gpReply && gpReply->type != XCB_NONE;
|
|||
|
+ free(gpReply);
|
|||
|
+ if (aware) {
|
|||
|
+ target = window;
|
|||
|
+ break;
|
|||
|
+ }
|
|||
|
+
|
|||
|
+ // try window's parent
|
|||
|
+ xcb_query_tree_cookie_t qtCookie = Q_XCB_CALL(
|
|||
|
+ xcb_query_tree_unchecked(c->xcb_connection(), window));
|
|||
|
+ xcb_query_tree_reply_t *qtReply = xcb_query_tree_reply(
|
|||
|
+ c->xcb_connection(), qtCookie, NULL);
|
|||
|
+ if (!qtReply)
|
|||
|
+ break;
|
|||
|
+ xcb_window_t root = qtReply->root;
|
|||
|
+ xcb_window_t parent = qtReply->parent;
|
|||
|
+ free(qtReply);
|
|||
|
+ if (window == root)
|
|||
|
+ break;
|
|||
|
+ window = parent;
|
|||
|
+ }
|
|||
|
+ return target;
|
|||
|
+}
|
|||
|
|
|||
|
void QXcbDrag::handleSelectionRequest(const xcb_selection_request_event_t *event)
|
|||
|
{
|
|||
|
@@ -1099,17 +1133,16 @@ void QXcbDrag::handleSelectionRequest(const xcb_selection_request_event_t *event
|
|||
|
// xcb_convert_selection() that we sent the XdndDrop event to.
|
|||
|
at = findTransactionByWindow(event->requestor);
|
|||
|
}
|
|||
|
-// if (at == -1 && event->time == XCB_CURRENT_TIME) {
|
|||
|
-// // previous Qt versions always requested the data on a child of the target window
|
|||
|
-// // using CurrentTime... but it could be asking for either drop data or the current drag's data
|
|||
|
-// Window target = findXdndAwareParent(event->requestor);
|
|||
|
-// if (target) {
|
|||
|
-// if (current_target && current_target == target)
|
|||
|
-// at = -2;
|
|||
|
-// else
|
|||
|
-// at = findXdndDropTransactionByWindow(target);
|
|||
|
-// }
|
|||
|
-// }
|
|||
|
+
|
|||
|
+ if (at == -1 && event->time == XCB_CURRENT_TIME) {
|
|||
|
+ xcb_window_t target = findXdndAwareParent(connection(), event->requestor);
|
|||
|
+ if (target) {
|
|||
|
+ if (current_target == target)
|
|||
|
+ at = -2;
|
|||
|
+ else
|
|||
|
+ at = findTransactionByWindow(target);
|
|||
|
+ }
|
|||
|
+ }
|
|||
|
}
|
|||
|
|
|||
|
QDrag *transactionDrag = 0;
|
|||
|
--
|
|||
|
2.7.1
|