From 4d15f393a76cfcc4d54f311884fedac5bf0f72ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 22 Mar 2018 14:54:43 +0100 Subject: [PATCH] Move default implementation of update requests to QPlatformWindow Change-Id: I4cbb8d2023068288e298ab21f5cd8bc258825c77 Reviewed-by: Simon Hausmann --- src/gui/kernel/qguiapplication.cpp | 17 ++++---- src/gui/kernel/qguiapplication_p.h | 2 +- src/gui/kernel/qplatformwindow.cpp | 42 ++++++++++++------- src/gui/kernel/qplatformwindow.h | 2 +- src/gui/kernel/qplatformwindow_p.h | 2 + src/gui/kernel/qwindow.cpp | 13 ------ src/gui/kernel/qwindow_p.h | 2 - .../platforms/windows/qwindowswindow.cpp | 4 +- .../platforms/windows/qwindowswindow.h | 2 +- src/plugins/platforms/xcb/qxcbwindow.cpp | 4 +- src/plugins/platforms/xcb/qxcbwindow.h | 2 +- src/widgets/kernel/qapplication.cpp | 6 ++- 12 files changed, 51 insertions(+), 47 deletions(-) diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index 22f4cdeaa3d..d1655da4780 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -1754,8 +1754,11 @@ int QGuiApplication::exec() */ bool QGuiApplication::notify(QObject *object, QEvent *event) { - if (object->isWindowType()) - QGuiApplicationPrivate::sendQWindowEventToQPlatformWindow(static_cast(object), event); + if (object->isWindowType()) { + if (QGuiApplicationPrivate::sendQWindowEventToQPlatformWindow(static_cast(object), event)) + return true; // Platform plugin ate the event + } + return QCoreApplication::notify(object, event); } @@ -1777,18 +1780,18 @@ bool QGuiApplication::compressEvent(QEvent *event, QObject *receiver, QPostEvent return QCoreApplication::compressEvent(event, receiver, postedEvents); } -void QGuiApplicationPrivate::sendQWindowEventToQPlatformWindow(QWindow *window, QEvent *event) +bool QGuiApplicationPrivate::sendQWindowEventToQPlatformWindow(QWindow *window, QEvent *event) { if (!window) - return; + return false; QPlatformWindow *platformWindow = window->handle(); if (!platformWindow) - return; + return false; // spontaneous events come from the platform integration already, we don't need to send the events back if (event->spontaneous()) - return; + return false; // let the platform window do any handling it needs to as well - platformWindow->windowEvent(event); + return platformWindow->windowEvent(event); } bool QGuiApplicationPrivate::processNativeEvent(QWindow *window, const QByteArray &eventType, void *message, long *result) diff --git a/src/gui/kernel/qguiapplication_p.h b/src/gui/kernel/qguiapplication_p.h index 243cbde8af4..fb7dda10a96 100644 --- a/src/gui/kernel/qguiapplication_p.h +++ b/src/gui/kernel/qguiapplication_p.h @@ -173,7 +173,7 @@ public: static bool processNativeEvent(QWindow *window, const QByteArray &eventType, void *message, long *result); - static void sendQWindowEventToQPlatformWindow(QWindow *window, QEvent *event); + static bool sendQWindowEventToQPlatformWindow(QWindow *window, QEvent *event); static inline Qt::Alignment visualAlignment(Qt::LayoutDirection direction, Qt::Alignment alignment) { diff --git a/src/gui/kernel/qplatformwindow.cpp b/src/gui/kernel/qplatformwindow.cpp index 9fe68bd5648..e83f76fb067 100644 --- a/src/gui/kernel/qplatformwindow.cpp +++ b/src/gui/kernel/qplatformwindow.cpp @@ -461,14 +461,26 @@ bool QPlatformWindow::setWindowModified(bool modified) /*! Reimplement this method to be able to do any platform specific event - handling. All events for window() are passed to this function before being - sent to QWindow::event(). + handling. All non-synthetic events for window() are passed to this + function before being sent to QWindow::event(). - The default implementation is empty and does nothing with \a event. + Return true if the event should not be passed on to the QWindow. + + Subclasses should always call the base class implementation. */ -void QPlatformWindow::windowEvent(QEvent *event) +bool QPlatformWindow::windowEvent(QEvent *event) { - Q_UNUSED(event); + Q_D(QPlatformWindow); + + if (event->type() == QEvent::Timer) { + if (static_cast(event)->timerId() == d->updateTimer.timerId()) { + d->updateTimer.stop(); + deliverUpdateRequest(); + return true; + } + } + + return false; } /*! @@ -734,18 +746,16 @@ QRect QPlatformWindow::initialGeometry(const QWindow *w, */ void QPlatformWindow::requestUpdate() { - static int timeout = -1; - if (timeout == -1) { - bool ok = false; - timeout = qEnvironmentVariableIntValue("QT_QPA_UPDATE_IDLE_TIME", &ok); - if (!ok) - timeout = 5; - } + Q_D(QPlatformWindow); - QWindow *w = window(); - QWindowPrivate *wp = qt_window_private(w); - Q_ASSERT(wp->updateTimer == 0); - wp->updateTimer = w->startTimer(timeout, Qt::PreciseTimer); + static int updateInterval = []() { + bool ok = false; + int customUpdateInterval = qEnvironmentVariableIntValue("QT_QPA_UPDATE_IDLE_TIME", &ok); + return ok ? customUpdateInterval : 5; + }(); + + Q_ASSERT(!d->updateTimer.isActive()); + d->updateTimer.start(updateInterval, Qt::PreciseTimer, window()); } /*! diff --git a/src/gui/kernel/qplatformwindow.h b/src/gui/kernel/qplatformwindow.h index 2b353959c74..1590a10554c 100644 --- a/src/gui/kernel/qplatformwindow.h +++ b/src/gui/kernel/qplatformwindow.h @@ -127,7 +127,7 @@ public: virtual bool setWindowModified(bool modified); - virtual void windowEvent(QEvent *event); + virtual bool windowEvent(QEvent *event); virtual bool startSystemResize(const QPoint &pos, Qt::Corner corner); virtual bool startSystemMove(const QPoint &pos); diff --git a/src/gui/kernel/qplatformwindow_p.h b/src/gui/kernel/qplatformwindow_p.h index 62ecd61d9ef..00dae9334c8 100644 --- a/src/gui/kernel/qplatformwindow_p.h +++ b/src/gui/kernel/qplatformwindow_p.h @@ -52,6 +52,7 @@ // #include +#include #include QT_BEGIN_NAMESPACE @@ -60,6 +61,7 @@ class QPlatformWindowPrivate { public: QRect rect; + QBasicTimer updateTimer; }; QT_END_NAMESPACE diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp index 0a41196b5bb..ef00ce5adc2 100644 --- a/src/gui/kernel/qwindow.cpp +++ b/src/gui/kernel/qwindow.cpp @@ -2328,19 +2328,6 @@ bool QWindow::event(QEvent *ev) break; #endif - case QEvent::Timer: { - Q_D(QWindow); - if (static_cast(ev)->timerId() == d->updateTimer) { - killTimer(d->updateTimer); - d->updateTimer = 0; - if (d->platformWindow) - d->platformWindow->deliverUpdateRequest(); - } else { - QObject::event(ev); - } - break; - } - case QEvent::PlatformSurface: { if ((static_cast(ev))->surfaceEventType() == QPlatformSurfaceEvent::SurfaceAboutToBeDestroyed) { #ifndef QT_NO_OPENGL diff --git a/src/gui/kernel/qwindow_p.h b/src/gui/kernel/qwindow_p.h index adc9414b0fb..745ff2e46ff 100644 --- a/src/gui/kernel/qwindow_p.h +++ b/src/gui/kernel/qwindow_p.h @@ -97,7 +97,6 @@ public: , modality(Qt::NonModal) , blockedByModalWindow(false) , updateRequestPending(false) - , updateTimer(0) , transientParent(0) , topLevelScreen(0) #ifndef QT_NO_CURSOR @@ -192,7 +191,6 @@ public: bool blockedByModalWindow; bool updateRequestPending; - int updateTimer; QPointer transientParent; QPointer topLevelScreen; diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index f1762146ecf..552c4c0f5c9 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -2048,7 +2048,7 @@ void QWindowsWindow::setExStyle(unsigned s) const SetWindowLongPtr(m_data.hwnd, GWL_EXSTYLE, s); } -void QWindowsWindow::windowEvent(QEvent *event) +bool QWindowsWindow::windowEvent(QEvent *event) { switch (event->type()) { case QEvent::WindowBlocked: // Blocked by another modal window. @@ -2064,6 +2064,8 @@ void QWindowsWindow::windowEvent(QEvent *event) default: break; } + + return QPlatformWindow::windowEvent(event); } void QWindowsWindow::propagateSizeHints() diff --git a/src/plugins/platforms/windows/qwindowswindow.h b/src/plugins/platforms/windows/qwindowswindow.h index fe2518e3297..68e0617b196 100644 --- a/src/plugins/platforms/windows/qwindowswindow.h +++ b/src/plugins/platforms/windows/qwindowswindow.h @@ -252,7 +252,7 @@ public: void raise() override { raise_sys(); } void lower() override { lower_sys(); } - void windowEvent(QEvent *event) override; + bool windowEvent(QEvent *event) override; void propagateSizeHints() override; static bool handleGeometryChangingMessage(MSG *message, const QWindow *qWindow, const QMargins &marginsDp); diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index 01eb88eea72..d757e2dbf88 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -2587,7 +2587,7 @@ bool QXcbWindow::setMouseGrabEnabled(bool grab) return result; } -void QXcbWindow::windowEvent(QEvent *event) +bool QXcbWindow::windowEvent(QEvent *event) { switch (event->type()) { case QEvent::FocusIn: @@ -2613,7 +2613,7 @@ void QXcbWindow::windowEvent(QEvent *event) default: break; } - QPlatformWindow::windowEvent(event); + return QPlatformWindow::windowEvent(event); } bool QXcbWindow::startSystemResize(const QPoint &pos, Qt::Corner corner) diff --git a/src/plugins/platforms/xcb/qxcbwindow.h b/src/plugins/platforms/xcb/qxcbwindow.h index edfee1f5749..bdfe3c4e9e0 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.h +++ b/src/plugins/platforms/xcb/qxcbwindow.h @@ -105,7 +105,7 @@ public: QSurfaceFormat format() const override; - void windowEvent(QEvent *event) override; + bool windowEvent(QEvent *event) override; bool startSystemResize(const QPoint &pos, Qt::Corner corner) override; bool startSystemMove(const QPoint &pos) override; diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp index 122d94d152f..c316c03a440 100644 --- a/src/widgets/kernel/qapplication.cpp +++ b/src/widgets/kernel/qapplication.cpp @@ -2952,8 +2952,10 @@ bool QApplication::notify(QObject *receiver, QEvent *e) d->checkReceiverThread(receiver); #endif - if (receiver->isWindowType()) - QGuiApplicationPrivate::sendQWindowEventToQPlatformWindow(static_cast(receiver), e); + if (receiver->isWindowType()) { + if (QGuiApplicationPrivate::sendQWindowEventToQPlatformWindow(static_cast(receiver), e)) + return true; // Platform plugin ate the event + } if(e->spontaneous()) { // Capture the current mouse and keyboard states. Doing so here is