xcb: Fix drag and drop to applications like Emacs and Chromium.
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>
This commit is contained in:
parent
072f5b513e
commit
269fdbdd2b
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user