From 75a2fc72aad6482bd8147afccfcd9b48fc9f6d89 Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Thu, 22 May 2014 11:40:08 +0200 Subject: [PATCH] Avoid virtual calls in constructors. QWaylandWindow::setGeometry() is a virtual call and internally it would call windowType() which is pure virtual, so calling it from the constructor won't work. Instead, set geometry explicitly from the constructor and call setGeometry() on setVisible(true). This also merges it so we send one expose event (with correct x/y offset) on geometry change + show. Change-Id: I1d21664c982005c60c8d73740e43b3a463bac4a8 Reviewed-by: Giulio Camuffo --- .../platforms/wayland/qwaylandwindow.cpp | 35 +++++++++++-------- .../platforms/wayland/qwaylandwindow_p.h | 1 + 2 files changed, 21 insertions(+), 15 deletions(-) diff --git a/src/plugins/platforms/wayland/qwaylandwindow.cpp b/src/plugins/platforms/wayland/qwaylandwindow.cpp index f51100a54b1..216c2551df6 100644 --- a/src/plugins/platforms/wayland/qwaylandwindow.cpp +++ b/src/plugins/platforms/wayland/qwaylandwindow.cpp @@ -120,7 +120,7 @@ QWaylandWindow::QWaylandWindow(QWindow *window) } setWindowFlags(window->flags()); - setGeometry(window->geometry()); + setGeometry_helper(window->geometry()); setWindowStateInternal(window->windowState()); handleContentOrientationChange(window->contentOrientation()); } @@ -186,7 +186,7 @@ void QWaylandWindow::setWindowIcon(const QIcon &icon) mWindowDecoration->update(); } -void QWaylandWindow::setGeometry(const QRect &rect) +void QWaylandWindow::setGeometry_helper(const QRect &rect) { QPlatformWindow::setGeometry(QRect(rect.x(), rect.y(), qBound(window()->minimumWidth(), rect.width(), window()->maximumWidth()), @@ -194,15 +194,25 @@ void QWaylandWindow::setGeometry(const QRect &rect) if (shellSurface() && window()->transientParent() && window()->type() != Qt::Popup) shellSurface()->updateTransientParent(window()->transientParent()); +} - if (mWindowDecoration && window()->isVisible()) - mWindowDecoration->update(); +void QWaylandWindow::setGeometry(const QRect &rect) +{ + setGeometry_helper(rect); - if (mResizeAfterSwap && windowType() == Egl) - mResizeDirty = true; - else - QWindowSystemInterface::handleGeometryChange(window(), geometry()); - QWindowSystemInterface::handleExposeEvent(window(), QRegion(geometry())); + if (window()->isVisible()) { + if (mWindowDecoration) + mWindowDecoration->update(); + + if (mResizeAfterSwap && windowType() == Egl && mSentInitialResize) + mResizeDirty = true; + else + QWindowSystemInterface::handleGeometryChange(window(), geometry()); + + QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(), geometry().size())); + + mSentInitialResize = true; + } } void QWaylandWindow::setVisible(bool visible) @@ -217,12 +227,7 @@ void QWaylandWindow::setVisible(bool visible) mShellSurface->setPopup(transientParent(), mMouseDevice, mMouseSerial); } - if (!mSentInitialResize) { - QWindowSystemInterface::handleGeometryChange(window(), geometry()); - mSentInitialResize = true; - } - - QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(), geometry().size())); + setGeometry(window()->geometry()); // Don't flush the events here, or else the newly visible window may start drawing, but since // there was no frame before it will be stuck at the waitForFrameSync() in // QWaylandShmBackingStore::beginPaint(). diff --git a/src/plugins/platforms/wayland/qwaylandwindow_p.h b/src/plugins/platforms/wayland/qwaylandwindow_p.h index fe6f319087b..ce89e3d6b98 100644 --- a/src/plugins/platforms/wayland/qwaylandwindow_p.h +++ b/src/plugins/platforms/wayland/qwaylandwindow_p.h @@ -207,6 +207,7 @@ protected: private: bool setWindowStateInternal(Qt::WindowState flags); + void setGeometry_helper(const QRect &rect); void handleMouseEventWithDecoration(QWaylandInputDevice *inputDevice, ulong timestamp,