Introducing QWindow::requestUpdate().

Change-Id: I0e2a09b53459a56d90dcd9043e694b19e2d77a9e
Reviewed-by: Jørgen Lind <jorgen.lind@digia.com>
This commit is contained in:
Gunnar Sletta 2014-09-30 13:21:13 +02:00
parent 264fcd4eef
commit b3d2c867ed
5 changed files with 84 additions and 0 deletions

View File

@ -592,6 +592,36 @@ QRect QPlatformWindow::initialGeometry(const QWindow *w,
return rect;
}
/*!
Requests an QEvent::UpdateRequest event. The event will be
delivered to the QWindow.
QPlatformWindow subclasses can re-implement this function to
provide display refresh synchronized updates. The event
should be delivered using QWindowPrivate::deliverUpdateRequest()
to not get out of sync with the the internal state of QWindow.
The default implementation posts an UpdateRequest event to the
window after 5 ms. The additional time is there to give the event
loop a bit of idle time to gather system events.
*/
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;
}
QWindow *w = window();
QWindowPrivate *wp = (QWindowPrivate *) QObjectPrivate::get(w);
Q_ASSERT(wp->updateTimer == 0);
wp->updateTimer = w->startTimer(timeout, Qt::PreciseTimer);
}
/*!
\class QPlatformWindow
\since 4.8

View File

@ -129,6 +129,7 @@ public:
static QRect initialGeometry(const QWindow *w,
const QRect &initialGeometry, int defaultWidth, int defaultHeight);
virtual void requestUpdate();
protected:
static QString formatWindowTitle(const QString &title, const QString &separator);
QPlatformScreen *screenForGeometry(const QRect &newGeometry) const;

View File

@ -2043,12 +2043,56 @@ bool QWindow::event(QEvent *ev)
break;
#endif
case QEvent::Timer: {
Q_D(QWindow);
if (static_cast<QTimerEvent *>(ev)->timerId() == d->updateTimer) {
killTimer(d->updateTimer);
d->updateTimer = 0;
d->deliverUpdateRequest();
} else {
QObject::event(ev);
}
break;
}
default:
return QObject::event(ev);
}
return true;
}
void QWindowPrivate::deliverUpdateRequest()
{
Q_Q(QWindow);
updateRequestPending = false;
QEvent request(QEvent::UpdateRequest);
QCoreApplication::sendEvent(q, &request);
}
/*!
Schedules a QEvent::UpdateRequest event to be delivered to this window.
The event is delivered in sync with the display vsync on platforms
where this is possible. When driving animations, this function should
be called once after drawing has completed.
Calling this function multiple times will result in a single event
being delivered to the window.
Subclasses of QWindow should reimplement QWindow::event(), intercept
the event and call the application's rendering code, then call the
base class implementation.
*/
void QWindow::requestUpdate()
{
Q_D(QWindow);
if (d->updateRequestPending || !d->platformWindow)
return;
d->updateRequestPending = true;
d->platformWindow->requestUpdate();
}
/*!
Override this to handle key press events (\a ev).

View File

@ -286,6 +286,8 @@ public Q_SLOTS:
Q_REVISION(1) void alert(int msec);
Q_REVISION(3) void requestUpdate();
Q_SIGNALS:
void screenChanged(QScreen *screen);
void modalityChanged(Qt::WindowModality modality);

View File

@ -86,6 +86,8 @@ public:
, maximumSize(QWINDOWSIZE_MAX, QWINDOWSIZE_MAX)
, modality(Qt::NonModal)
, blockedByModalWindow(false)
, updateRequestPending(false)
, updateTimer(0)
, transientParent(0)
, topLevelScreen(0)
#ifndef QT_NO_CURSOR
@ -109,6 +111,8 @@ public:
void applyCursor();
#endif
void deliverUpdateRequest();
QPoint globalPosition() const {
Q_Q(const QWindow);
QPoint offset = q->position();
@ -162,6 +166,9 @@ public:
Qt::WindowModality modality;
bool blockedByModalWindow;
bool updateRequestPending;
int updateTimer;
QPointer<QWindow> transientParent;
QScreen *topLevelScreen;