Fixes to the Xdnd code in xcb

Make sure we move the drag pixmap when required,
and readd some commented out code from Qt 4.x.

Change-Id: Ib4302b394f4ac7b966d0146267651b9c3860c62b
Reviewed-on: http://codereview.qt-project.org/5262
Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com>
Reviewed-by: Samuel Rødal <samuel.rodal@nokia.com>
This commit is contained in:
Lars Knoll 2011-09-20 18:11:39 +02:00 committed by Qt by Nokia
parent c9c33bd227
commit 4ed5f2600f
2 changed files with 63 additions and 61 deletions

View File

@ -217,6 +217,61 @@ translateCoordinates(QXcbConnection *c, xcb_window_t from, xcb_window_t to, int
return xcb_translate_coordinates_reply(c->xcb_connection(), cookie, 0);
}
xcb_window_t QXcbDrag::findRealWindow(const QPoint & pos, xcb_window_t w, int md)
{
if (w == QDragManager::self()->shapedPixmapWindow->handle()->winId())
return 0;
if (md) {
xcb_get_window_attributes_cookie_t cookie = xcb_get_window_attributes(xcb_connection(), w);
xcb_get_window_attributes_reply_t *reply = xcb_get_window_attributes_reply(xcb_connection(), cookie, 0);
if (!reply)
return 0;
if (reply->map_state != XCB_MAP_STATE_VIEWABLE)
return 0;
xcb_get_geometry_cookie_t gcookie = xcb_get_geometry(xcb_connection(), w);
xcb_get_geometry_reply_t *greply = xcb_get_geometry_reply(xcb_connection(), gcookie, 0);
if (reply && QRect(greply->x, greply->y, greply->width, greply->height).contains(pos)) {
{
xcb_get_property_cookie_t cookie =
Q_XCB_CALL(xcb_get_property(xcb_connection(), false, w, connection()->atom(QXcbAtom::XdndAware),
XCB_GET_PROPERTY_TYPE_ANY, 0, 0));
xcb_get_property_reply_t *reply = xcb_get_property_reply(xcb_connection(), cookie, 0);
bool isAware = reply && reply->type != XCB_NONE;
free(reply);
if (isAware)
return w;
}
xcb_query_tree_cookie_t cookie = xcb_query_tree (xcb_connection(), w);
xcb_query_tree_reply_t *reply = xcb_query_tree_reply(xcb_connection(), cookie, 0);
if (!reply)
return 0;
int nc = xcb_query_tree_children_length(reply);
xcb_window_t *c = xcb_query_tree_children(reply);
xcb_window_t r = 0;
for (uint i = nc; !r && i--;)
r = findRealWindow(pos - QPoint(greply->x, greply->y), c[i], md-1);
free(reply);
if (r)
return r;
// We didn't find a client window! Just use the
// innermost window.
// No children!
return w;
}
}
return 0;
}
void QXcbDrag::move(const QMouseEvent *me)
{
DEBUG() << "QDragManager::move enter";
@ -304,12 +359,12 @@ void QXcbDrag::move(const QMouseEvent *me)
target = translate->child;
free(translate);
}
// ####
// if (xdnd_data.deco && (!target || target == xdnd_data.deco->effectiveWinId())) {
// DNDDEBUG << "need to find real window";
// target = findRealWindow(globalPos, rootwin, 6);
// DNDDEBUG << "real window found" << QWidget::find(target) << target;
// }
if (!target || target == QDragManager::self()->shapedPixmapWindow->handle()->winId()) {
DNDDEBUG << "need to find real window";
target = findRealWindow(globalPos, rootwin, 6);
DNDDEBUG << "real window found" << target;
}
}
QXcbWindow *w = 0;
@ -406,9 +461,9 @@ void QXcbDrag::move(const QMouseEvent *me)
} else {
if (m->willDrop) {
m->willDrop = false;
m->updateCursor();
}
}
m->updateCursor();
DEBUG() << "QDragManager::move leave";
}
@ -1076,60 +1131,6 @@ void QXcbDrag::cancel()
current_target = 0;
}
#if 0
static
Window findRealWindow(const QPoint & pos, Window w, int md)
{
if (xdnd_data.deco && w == xdnd_data.deco->effectiveWinId())
return 0;
if (md) {
X11->ignoreBadwindow();
XWindowAttributes attr;
XGetWindowAttributes(X11->display, w, &attr);
if (X11->badwindow())
return 0;
if (attr.map_state == IsViewable
&& QRect(attr.x,attr.y,attr.width,attr.height).contains(pos)) {
{
Atom type = XNone;
int f;
unsigned long n, a;
unsigned char *data;
XGetWindowProperty(X11->display, w, ATOM(XdndAware), 0, 0, False,
AnyPropertyType, &type, &f,&n,&a,&data);
if (data) XFree(data);
if (type)
return w;
}
Window r, p;
Window* c;
uint nc;
if (XQueryTree(X11->display, w, &r, &p, &c, &nc)) {
r=0;
for (uint i=nc; !r && i--;) {
r = findRealWindow(pos-QPoint(attr.x,attr.y),
c[i], md-1);
}
XFree(c);
if (r)
return r;
// We didn't find a client window! Just use the
// innermost window.
}
// No children!
return w;
}
}
return 0;
}
#endif
void QXcbDrag::handleSelectionRequest(const xcb_selection_request_event_t *event)
{

View File

@ -151,6 +151,7 @@ private:
void restartDropExpiryTimer();
int findTransactionByWindow(xcb_window_t window);
int findTransactionByTime(xcb_timestamp_t timestamp);
xcb_window_t findRealWindow(const QPoint & pos, xcb_window_t w, int md);
};
QT_END_NAMESPACE