From: Owen W. Taylor Date: Mon, 17 Oct 2011 21:27:43 +0000 (-0400) Subject: [PATCH] Fix logic for figuring out what ConfigureNotify positions can be trusted X-Git-Tag: archive/raspbian/4%4.8.7+dfsg-18+rpi1+deb10u1^2~63 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=b473c92afd7b4569721c6b2c930a5efb5db8ab18;p=qt4-x11.git [PATCH] Fix logic for figuring out what ConfigureNotify positions can be trusted When reading ahead in the queue for ConfigureNotify events, it's necessary to look for intermediate ReparentNotify events as well, since they will determine whether the position in the event can be trusted or not. Bug: https://bugreports.qt.nokia.com/browse/QTBUG-21900 Gbp-Pq: Name QTBUG-21900_Buttons_in_Qt_applications_not_clickable_when_run_under_gnome-shell.patch --- diff --git a/src/gui/kernel/qapplication_x11.cpp b/src/gui/kernel/qapplication_x11.cpp index 400b99d44..2e666ce83 100644 --- a/src/gui/kernel/qapplication_x11.cpp +++ b/src/gui/kernel/qapplication_x11.cpp @@ -819,6 +819,27 @@ static Bool qt_sync_request_scanner(Display*, XEvent *event, XPointer arg) #endif #endif // QT_NO_XSYNC +struct qt_configure_event_data +{ + WId window; + WId parent; +}; + +static Bool qt_configure_event_scanner(Display*, XEvent *event, XPointer arg) +{ + qt_configure_event_data *data = + reinterpret_cast(arg); + if (event->type == ConfigureNotify && + event->xconfigure.window == data->window) { + return true; + } else if (event->type == ReparentNotify && + event->xreparent.window == data->window) { + data->parent = event->xreparent.parent; + } + + return false; +} + static void qt_x11_create_intern_atoms() { const char *names[QX11Data::NAtoms]; @@ -5310,8 +5331,11 @@ bool QETWidget::translateConfigEvent(const XEvent *event) if (d->extra->compress_events) { // ConfigureNotify compression for faster opaque resizing XEvent otherEvent; - while (XCheckTypedWindowEvent(X11->display, internalWinId(), ConfigureNotify, - &otherEvent)) { + qt_configure_event_data configureData; + configureData.window = internalWinId(); + configureData.parent = d->topData()->parentWinId; + while (XCheckIfEvent(X11->display, &otherEvent, + &qt_configure_event_scanner, (XPointer)&configureData)) { if (qt_x11EventFilter(&otherEvent)) continue; @@ -5324,13 +5348,19 @@ bool QETWidget::translateConfigEvent(const XEvent *event) newSize.setWidth(otherEvent.xconfigure.width); newSize.setHeight(otherEvent.xconfigure.height); + trust = isVisible() + && (configureData.parent == XNone || + configureData.parent == QX11Info::appRootWindow()); + if (otherEvent.xconfigure.send_event || trust) { newCPos.rx() = otherEvent.xconfigure.x + otherEvent.xconfigure.border_width; newCPos.ry() = otherEvent.xconfigure.y + otherEvent.xconfigure.border_width; isCPos = true; - } + } else { + isCPos = false; + } } #ifndef QT_NO_XSYNC qt_sync_request_event_data sync_event; @@ -5343,9 +5373,14 @@ bool QETWidget::translateConfigEvent(const XEvent *event) } if (!isCPos) { - // we didn't get an updated position of the toplevel. - // either we haven't moved or there is a bug in the window manager. - // anyway, let's query the position to be certain. + // If the last configure event didn't have a trustable position, + // it's necessary to query, see ICCCM 4.24: + // + // Any real ConfigureNotify event on a top-level window implies + // that the window position on the root may have changed, even + // though the event reports that the window position in its + // parent is unchanged because the window may have been reparented. + int x, y; Window child; XTranslateCoordinates(X11->display, internalWinId(),