iOS: Take advantage of new synchronous API for QPA event delivery
By using the SynchronousDelivery specialization instead of flushing all window system events, we remove the risk of flushing an event that was added without our knowledge. For example, QGuiApplicationPrivate::processMouseEvent() used to prepend a mouse move event to the QPA queue, which is why we had a check for QWidgetWindow when flushing geometry changes. processMouseEvent no longer sends the move event via the QPA queue, so that's no longer an issue, but if it were to be reintroduced, we wouldn't need to check for QWidgetWindow, as we're not flushing all events anymore. Change-Id: Ib346ea9501cd88ddda6c2137981d3eb0922192a0 Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io> Reviewed-by: Simon Hausmann <simon.hausmann@qt.io> Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io>
This commit is contained in:
parent
815341dbec
commit
d8c72f4154
@ -165,11 +165,11 @@ void QWindowSystemInterface::handleEnterLeaveEvent(QWindow *enter, QWindow *leav
|
|||||||
handleEnterEvent(enter, local, global);
|
handleEnterEvent(enter, local, global);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QWindowSystemInterface::handleWindowActivated(QWindow *tlw, Qt::FocusReason r)
|
QT_DEFINE_QPA_EVENT_HANDLER(void, handleWindowActivated, QWindow *tlw, Qt::FocusReason r)
|
||||||
{
|
{
|
||||||
QWindowSystemInterfacePrivate::ActivatedWindowEvent *e =
|
QWindowSystemInterfacePrivate::ActivatedWindowEvent *e =
|
||||||
new QWindowSystemInterfacePrivate::ActivatedWindowEvent(tlw, r);
|
new QWindowSystemInterfacePrivate::ActivatedWindowEvent(tlw, r);
|
||||||
QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
|
QWindowSystemInterfacePrivate::handleWindowSystemEvent<Delivery>(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QWindowSystemInterface::handleWindowStateChanged(QWindow *tlw, Qt::WindowState newState)
|
void QWindowSystemInterface::handleWindowStateChanged(QWindow *tlw, Qt::WindowState newState)
|
||||||
@ -197,10 +197,25 @@ void QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationState
|
|||||||
/*!
|
/*!
|
||||||
If \a oldRect is null, Qt will use the previously reported geometry instead.
|
If \a oldRect is null, Qt will use the previously reported geometry instead.
|
||||||
*/
|
*/
|
||||||
void QWindowSystemInterface::handleGeometryChange(QWindow *tlw, const QRect &newRect, const QRect &oldRect)
|
QT_DEFINE_QPA_EVENT_HANDLER(void, handleGeometryChange, QWindow *tlw, const QRect &newRect, const QRect &oldRect)
|
||||||
{
|
{
|
||||||
QWindowSystemInterfacePrivate::GeometryChangeEvent *e = new QWindowSystemInterfacePrivate::GeometryChangeEvent(tlw, QHighDpi::fromNativePixels(newRect, tlw), QHighDpi::fromNativePixels(oldRect, tlw));
|
QWindowSystemInterfacePrivate::GeometryChangeEvent *e = new QWindowSystemInterfacePrivate::GeometryChangeEvent(tlw, QHighDpi::fromNativePixels(newRect, tlw), QHighDpi::fromNativePixels(oldRect, tlw));
|
||||||
QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
|
QWindowSystemInterfacePrivate::handleWindowSystemEvent<Delivery>(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
QWindowSystemInterfacePrivate::ExposeEvent::ExposeEvent(QWindow *window, const QRegion ®ion)
|
||||||
|
: WindowSystemEvent(Expose)
|
||||||
|
, window(window)
|
||||||
|
, isExposed(window && window->handle() ? window->handle()->isExposed() : false)
|
||||||
|
, region(region)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
QT_DEFINE_QPA_EVENT_HANDLER(void, handleExposeEvent, QWindow *tlw, const QRegion ®ion)
|
||||||
|
{
|
||||||
|
QWindowSystemInterfacePrivate::ExposeEvent *e =
|
||||||
|
new QWindowSystemInterfacePrivate::ExposeEvent(tlw, QHighDpi::fromNativeLocalExposedRegion(region, tlw));
|
||||||
|
QWindowSystemInterfacePrivate::handleWindowSystemEvent<Delivery>(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QWindowSystemInterface::handleCloseEvent(QWindow *tlw, bool *accepted)
|
void QWindowSystemInterface::handleCloseEvent(QWindow *tlw, bool *accepted)
|
||||||
@ -405,15 +420,6 @@ void QWindowSystemInterface::handleWheelEvent(QWindow *tlw, ulong timestamp, con
|
|||||||
QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
|
QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
QWindowSystemInterfacePrivate::ExposeEvent::ExposeEvent(QWindow *window, const QRegion ®ion)
|
|
||||||
: WindowSystemEvent(Expose)
|
|
||||||
, window(window)
|
|
||||||
, isExposed(window && window->handle() ? window->handle()->isExposed() : false)
|
|
||||||
, region(region)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
int QWindowSystemInterfacePrivate::windowSystemEventsQueued()
|
int QWindowSystemInterfacePrivate::windowSystemEventsQueued()
|
||||||
{
|
{
|
||||||
return windowSystemEventQueue.count();
|
return windowSystemEventQueue.count();
|
||||||
@ -596,20 +602,20 @@ QT_DEFINE_QPA_EVENT_HANDLER(void, handleTouchEvent, QWindow *tlw, ulong timestam
|
|||||||
QWindowSystemInterfacePrivate::handleWindowSystemEvent<Delivery>(e);
|
QWindowSystemInterfacePrivate::handleWindowSystemEvent<Delivery>(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QWindowSystemInterface::handleTouchCancelEvent(QWindow *w, QTouchDevice *device,
|
QT_DEFINE_QPA_EVENT_HANDLER(void, handleTouchCancelEvent, QWindow *w, QTouchDevice *device,
|
||||||
Qt::KeyboardModifiers mods)
|
Qt::KeyboardModifiers mods)
|
||||||
{
|
{
|
||||||
unsigned long time = QWindowSystemInterfacePrivate::eventTime.elapsed();
|
unsigned long time = QWindowSystemInterfacePrivate::eventTime.elapsed();
|
||||||
handleTouchCancelEvent(w, time, device, mods);
|
handleTouchCancelEvent<Delivery>(w, time, device, mods);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QWindowSystemInterface::handleTouchCancelEvent(QWindow *w, ulong timestamp, QTouchDevice *device,
|
QT_DEFINE_QPA_EVENT_HANDLER(void, handleTouchCancelEvent, QWindow *w, ulong timestamp, QTouchDevice *device,
|
||||||
Qt::KeyboardModifiers mods)
|
Qt::KeyboardModifiers mods)
|
||||||
{
|
{
|
||||||
QWindowSystemInterfacePrivate::TouchEvent *e =
|
QWindowSystemInterfacePrivate::TouchEvent *e =
|
||||||
new QWindowSystemInterfacePrivate::TouchEvent(w, timestamp, QEvent::TouchCancel, device,
|
new QWindowSystemInterfacePrivate::TouchEvent(w, timestamp, QEvent::TouchCancel, device,
|
||||||
QList<QTouchEvent::TouchPoint>(), mods);
|
QList<QTouchEvent::TouchPoint>(), mods);
|
||||||
QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
|
QWindowSystemInterfacePrivate::handleWindowSystemEvent<Delivery>(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QWindowSystemInterface::handleScreenOrientationChange(QScreen *screen, Qt::ScreenOrientation orientation)
|
void QWindowSystemInterface::handleScreenOrientationChange(QScreen *screen, Qt::ScreenOrientation orientation)
|
||||||
@ -646,13 +652,6 @@ void QWindowSystemInterface::handleThemeChange(QWindow *tlw)
|
|||||||
QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
|
QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QWindowSystemInterface::handleExposeEvent(QWindow *tlw, const QRegion ®ion)
|
|
||||||
{
|
|
||||||
QWindowSystemInterfacePrivate::ExposeEvent *e =
|
|
||||||
new QWindowSystemInterfacePrivate::ExposeEvent(tlw, QHighDpi::fromNativeLocalExposedRegion(region, tlw));
|
|
||||||
QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
void QWindowSystemInterface::deferredFlushWindowSystemEvents(QEventLoop::ProcessEventsFlags flags)
|
void QWindowSystemInterface::deferredFlushWindowSystemEvents(QEventLoop::ProcessEventsFlags flags)
|
||||||
{
|
{
|
||||||
Q_ASSERT(QThread::currentThread() == QGuiApplication::instance()->thread());
|
Q_ASSERT(QThread::currentThread() == QGuiApplication::instance()->thread());
|
||||||
|
@ -150,11 +150,19 @@ public:
|
|||||||
template<typename Delivery = QWindowSystemInterface::DefaultDelivery>
|
template<typename Delivery = QWindowSystemInterface::DefaultDelivery>
|
||||||
static void handleTouchEvent(QWindow *w, ulong timestamp, QTouchDevice *device,
|
static void handleTouchEvent(QWindow *w, ulong timestamp, QTouchDevice *device,
|
||||||
const QList<struct TouchPoint> &points, Qt::KeyboardModifiers mods = Qt::NoModifier);
|
const QList<struct TouchPoint> &points, Qt::KeyboardModifiers mods = Qt::NoModifier);
|
||||||
|
template<typename Delivery = QWindowSystemInterface::DefaultDelivery>
|
||||||
static void handleTouchCancelEvent(QWindow *w, QTouchDevice *device, Qt::KeyboardModifiers mods = Qt::NoModifier);
|
static void handleTouchCancelEvent(QWindow *w, QTouchDevice *device, Qt::KeyboardModifiers mods = Qt::NoModifier);
|
||||||
|
template<typename Delivery = QWindowSystemInterface::DefaultDelivery>
|
||||||
static void handleTouchCancelEvent(QWindow *w, ulong timestamp, QTouchDevice *device, Qt::KeyboardModifiers mods = Qt::NoModifier);
|
static void handleTouchCancelEvent(QWindow *w, ulong timestamp, QTouchDevice *device, Qt::KeyboardModifiers mods = Qt::NoModifier);
|
||||||
|
|
||||||
// rect is relative to parent
|
// rect is relative to parent
|
||||||
|
template<typename Delivery = QWindowSystemInterface::DefaultDelivery>
|
||||||
static void handleGeometryChange(QWindow *w, const QRect &newRect, const QRect &oldRect = QRect());
|
static void handleGeometryChange(QWindow *w, const QRect &newRect, const QRect &oldRect = QRect());
|
||||||
|
|
||||||
|
// region is in local coordinates, do not confuse with geometry which is parent-relative
|
||||||
|
template<typename Delivery = QWindowSystemInterface::DefaultDelivery>
|
||||||
|
static void handleExposeEvent(QWindow *tlw, const QRegion ®ion);
|
||||||
|
|
||||||
static void handleCloseEvent(QWindow *w, bool *accepted = Q_NULLPTR);
|
static void handleCloseEvent(QWindow *w, bool *accepted = Q_NULLPTR);
|
||||||
|
|
||||||
template<typename Delivery = QWindowSystemInterface::DefaultDelivery>
|
template<typename Delivery = QWindowSystemInterface::DefaultDelivery>
|
||||||
@ -162,6 +170,7 @@ public:
|
|||||||
template<typename Delivery = QWindowSystemInterface::DefaultDelivery>
|
template<typename Delivery = QWindowSystemInterface::DefaultDelivery>
|
||||||
static void handleLeaveEvent(QWindow *w);
|
static void handleLeaveEvent(QWindow *w);
|
||||||
static void handleEnterLeaveEvent(QWindow *enter, QWindow *leave, const QPointF &local = QPointF(), const QPointF& global = QPointF());
|
static void handleEnterLeaveEvent(QWindow *enter, QWindow *leave, const QPointF &local = QPointF(), const QPointF& global = QPointF());
|
||||||
|
template<typename Delivery = QWindowSystemInterface::DefaultDelivery>
|
||||||
static void handleWindowActivated(QWindow *w, Qt::FocusReason r = Qt::OtherFocusReason);
|
static void handleWindowActivated(QWindow *w, Qt::FocusReason r = Qt::OtherFocusReason);
|
||||||
|
|
||||||
static void handleWindowStateChanged(QWindow *w, Qt::WindowState newState);
|
static void handleWindowStateChanged(QWindow *w, Qt::WindowState newState);
|
||||||
@ -169,9 +178,6 @@ public:
|
|||||||
|
|
||||||
static void handleApplicationStateChanged(Qt::ApplicationState newState, bool forcePropagate = false);
|
static void handleApplicationStateChanged(Qt::ApplicationState newState, bool forcePropagate = false);
|
||||||
|
|
||||||
// region is in local coordinates, do not confuse with geometry which is parent-relative
|
|
||||||
static void handleExposeEvent(QWindow *tlw, const QRegion ®ion);
|
|
||||||
|
|
||||||
#ifndef QT_NO_DRAGANDDROP
|
#ifndef QT_NO_DRAGANDDROP
|
||||||
// Drag and drop. These events are sent immediately.
|
// Drag and drop. These events are sent immediately.
|
||||||
static QPlatformDragQtResponse handleDrag(QWindow *w, const QMimeData *dropData, const QPoint &p, Qt::DropActions supportedActions);
|
static QPlatformDragQtResponse handleDrag(QWindow *w, const QMimeData *dropData, const QPoint &p, Qt::DropActions supportedActions);
|
||||||
|
@ -164,8 +164,7 @@
|
|||||||
requestedGeometry : qt_window_private(m_qioswindow->window())->geometry;
|
requestedGeometry : qt_window_private(m_qioswindow->window())->geometry;
|
||||||
|
|
||||||
QWindow *window = m_qioswindow->window();
|
QWindow *window = m_qioswindow->window();
|
||||||
QWindowSystemInterface::handleGeometryChange(window, actualGeometry, previousGeometry);
|
QWindowSystemInterface::handleGeometryChange<QWindowSystemInterface::SynchronousDelivery>(window, actualGeometry, previousGeometry);
|
||||||
QWindowSystemInterface::flushWindowSystemEvents(window->inherits("QWidgetWindow") ? QEventLoop::ExcludeUserInputEvents : QEventLoop::AllEvents);
|
|
||||||
|
|
||||||
if (actualGeometry.size() != previousGeometry.size()) {
|
if (actualGeometry.size() != previousGeometry.size()) {
|
||||||
// Trigger expose event on resize
|
// Trigger expose event on resize
|
||||||
@ -197,8 +196,7 @@
|
|||||||
region = QRect(QPoint(), bounds);
|
region = QRect(QPoint(), bounds);
|
||||||
}
|
}
|
||||||
|
|
||||||
QWindowSystemInterface::handleExposeEvent(m_qioswindow->window(), region);
|
QWindowSystemInterface::handleExposeEvent<QWindowSystemInterface::SynchronousDelivery>(m_qioswindow->window(), region);
|
||||||
QWindowSystemInterface::flushWindowSystemEvents();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
@ -223,13 +221,10 @@
|
|||||||
|
|
||||||
qImDebug() << m_qioswindow->window() << "became first responder";
|
qImDebug() << m_qioswindow->window() << "became first responder";
|
||||||
|
|
||||||
if (qGuiApp->focusWindow() != m_qioswindow->window()) {
|
if (qGuiApp->focusWindow() != m_qioswindow->window())
|
||||||
QWindowSystemInterface::handleWindowActivated(m_qioswindow->window());
|
QWindowSystemInterface::handleWindowActivated<QWindowSystemInterface::SynchronousDelivery>(m_qioswindow->window());
|
||||||
QWindowSystemInterface::flushWindowSystemEvents();
|
else
|
||||||
} else {
|
qImDebug() << m_qioswindow->window() << "already active, not sending window activation";
|
||||||
qImDebug() << m_qioswindow->window()
|
|
||||||
<< "already active, not sending window activation";
|
|
||||||
}
|
|
||||||
|
|
||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
@ -264,10 +259,8 @@
|
|||||||
qImDebug() << m_qioswindow->window() << "resigned first responder";
|
qImDebug() << m_qioswindow->window() << "resigned first responder";
|
||||||
|
|
||||||
UIResponder *newResponder = FirstResponderCandidate::currentCandidate();
|
UIResponder *newResponder = FirstResponderCandidate::currentCandidate();
|
||||||
if ([self responderShouldTriggerWindowDeactivation:newResponder]) {
|
if ([self responderShouldTriggerWindowDeactivation:newResponder])
|
||||||
QWindowSystemInterface::handleWindowActivated(0);
|
QWindowSystemInterface::handleWindowActivated<QWindowSystemInterface::SynchronousDelivery>(0);
|
||||||
QWindowSystemInterface::flushWindowSystemEvents();
|
|
||||||
}
|
|
||||||
|
|
||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
@ -357,10 +350,8 @@
|
|||||||
|
|
||||||
- (void)sendTouchEventWithTimestamp:(ulong)timeStamp
|
- (void)sendTouchEventWithTimestamp:(ulong)timeStamp
|
||||||
{
|
{
|
||||||
// Send touch event synchronously
|
|
||||||
QIOSIntegration *iosIntegration = QIOSIntegration::instance();
|
QIOSIntegration *iosIntegration = QIOSIntegration::instance();
|
||||||
QWindowSystemInterface::handleTouchEvent(m_qioswindow->window(), timeStamp, iosIntegration->touchDevice(), m_activeTouches.values());
|
QWindowSystemInterface::handleTouchEvent<QWindowSystemInterface::SynchronousDelivery>(m_qioswindow->window(), timeStamp, iosIntegration->touchDevice(), m_activeTouches.values());
|
||||||
QWindowSystemInterface::flushWindowSystemEvents();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
|
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
|
||||||
@ -438,10 +429,8 @@
|
|||||||
|
|
||||||
NSTimeInterval timestamp = event ? event.timestamp : [[NSProcessInfo processInfo] systemUptime];
|
NSTimeInterval timestamp = event ? event.timestamp : [[NSProcessInfo processInfo] systemUptime];
|
||||||
|
|
||||||
// Send cancel touch event synchronously
|
|
||||||
QIOSIntegration *iosIntegration = static_cast<QIOSIntegration *>(QGuiApplicationPrivate::platformIntegration());
|
QIOSIntegration *iosIntegration = static_cast<QIOSIntegration *>(QGuiApplicationPrivate::platformIntegration());
|
||||||
QWindowSystemInterface::handleTouchCancelEvent(m_qioswindow->window(), ulong(timestamp * 1000), iosIntegration->touchDevice());
|
QWindowSystemInterface::handleTouchCancelEvent<QWindowSystemInterface::SynchronousDelivery>(m_qioswindow->window(), ulong(timestamp * 1000), iosIntegration->touchDevice());
|
||||||
QWindowSystemInterface::flushWindowSystemEvents();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (int)mapPressTypeToKey:(UIPress*)press
|
- (int)mapPressTypeToKey:(UIPress*)press
|
||||||
@ -464,14 +453,12 @@
|
|||||||
// When handling the event (for example, as a back button), both press and
|
// When handling the event (for example, as a back button), both press and
|
||||||
// release events must be handled accordingly.
|
// release events must be handled accordingly.
|
||||||
|
|
||||||
QScopedValueRollback<bool> syncRollback(QWindowSystemInterfacePrivate::synchronousWindowSystemEvents, true);
|
|
||||||
|
|
||||||
bool handled = false;
|
bool handled = false;
|
||||||
for (UIPress* press in presses) {
|
for (UIPress* press in presses) {
|
||||||
int key = [self mapPressTypeToKey:press];
|
int key = [self mapPressTypeToKey:press];
|
||||||
if (key == Qt::Key_unknown)
|
if (key == Qt::Key_unknown)
|
||||||
continue;
|
continue;
|
||||||
if (QWindowSystemInterface::handleKeyEvent(m_qioswindow->window(), type, key, Qt::NoModifier))
|
if (QWindowSystemInterface::handleKeyEvent<QWindowSystemInterface::SynchronousDelivery>(m_qioswindow->window(), type, key, Qt::NoModifier))
|
||||||
handled = true;
|
handled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user