Fix QGuiApplication::keyboardModifiers()

Make sure that the keybaord modifiers are maintained properly when
handling window system events.

Change-Id: Ie75cbe5eb509c29e3d2291694f2de509fbf3098a
Reviewed-by: Morten Johan Sørvig <morten.sorvig@nokia.com>
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@nokia.com>
bb10
Bradley T. Hughes 2012-03-22 17:43:25 +01:00 committed by Qt by Nokia
parent 37010812a2
commit b2363a935c
4 changed files with 84 additions and 21 deletions

View File

@ -1005,6 +1005,7 @@ void QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::Mo
}
QWindow *window = e->window.data();
modifier_buttons = e->modifiers;
if (!window)
window = QGuiApplication::topLevelAt(e->globalPos.toPoint());
@ -1107,6 +1108,7 @@ void QGuiApplicationPrivate::processWheelEvent(QWindowSystemInterfacePrivate::Wh
QPointF globalPoint = e->globalPos;
QGuiApplicationPrivate::lastCursorPosition = globalPoint;
modifier_buttons = e->modifiers;
QWindow *window = e->window.data();
@ -1123,6 +1125,7 @@ void QGuiApplicationPrivate::processWheelEvent(QWindowSystemInterfacePrivate::Wh
void QGuiApplicationPrivate::processKeyEvent(QWindowSystemInterfacePrivate::KeyEvent *e)
{
QWindow *window = e->window.data();
modifier_buttons = e->modifiers;
if (e->nullWindow)
window = QGuiApplication::activeWindow();
if (!window)
@ -1280,6 +1283,7 @@ Q_GUI_EXPORT bool operator==(const QGuiApplicationPrivate::ActiveTouchPointsKey
void QGuiApplicationPrivate::processTouchEvent(QWindowSystemInterfacePrivate::TouchEvent *e)
{
QGuiApplicationPrivate *d = self;
modifier_buttons = e->modifiers;
if (e->touchType == QEvent::TouchCancel) {
// The touch sequence has been canceled (e.g. by the compositor).

View File

@ -158,6 +158,8 @@ bool QWindowSystemInterface::tryHandleSynchronousShortcutEvent(QWindow *w, int k
bool QWindowSystemInterface::tryHandleSynchronousShortcutEvent(QWindow *w, ulong timestamp, int k, Qt::KeyboardModifiers mods,
const QString & text, bool autorep, ushort count)
{
QGuiApplicationPrivate::modifier_buttons = mods;
QKeyEvent qevent(QEvent::ShortcutOverride, k, mods, text, autorep, count);
qevent.setTimestamp(timestamp);
return QGuiApplicationPrivate::instance()->shortcutMap.tryShortcutEvent(w, &qevent);
@ -175,6 +177,8 @@ bool QWindowSystemInterface::tryHandleSynchronousExtendedShortcutEvent(QWindow *
quint32 nativeScanCode, quint32 nativeVirtualKey, quint32 nativeModifiers,
const QString &text, bool autorep, ushort count)
{
QGuiApplicationPrivate::modifier_buttons = mods;
QKeyEventEx qevent(QEvent::ShortcutOverride, k, mods, text, autorep, count, nativeScanCode, nativeVirtualKey, nativeModifiers);
qevent.setTimestamp(timestamp);
return QGuiApplicationPrivate::instance()->shortcutMap.tryShortcutEvent(w, &qevent);

View File

@ -3014,34 +3014,14 @@ bool QApplication::notify(QObject *receiver, QEvent *e)
// capture the current mouse/keyboard state
if(e->spontaneous()) {
if (e->type() == QEvent::KeyPress
|| e->type() == QEvent::KeyRelease) {
QKeyEvent *ke = static_cast<QKeyEvent*>(e);
QApplicationPrivate::modifier_buttons = ke->modifiers();
} else if(e->type() == QEvent::MouseButtonPress
if (e->type() == QEvent::MouseButtonPress
|| e->type() == QEvent::MouseButtonRelease) {
QMouseEvent *me = static_cast<QMouseEvent*>(e);
QApplicationPrivate::modifier_buttons = me->modifiers();
if(me->type() == QEvent::MouseButtonPress)
QApplicationPrivate::mouse_buttons |= me->button();
else
QApplicationPrivate::mouse_buttons &= ~me->button();
}
#if !defined(QT_NO_WHEELEVENT) || !defined(QT_NO_TABLETEVENT)
else if (false
# ifndef QT_NO_WHEELEVENT
|| e->type() == QEvent::Wheel
# endif
# ifndef QT_NO_TABLETEVENT
|| e->type() == QEvent::TabletMove
|| e->type() == QEvent::TabletPress
|| e->type() == QEvent::TabletRelease
# endif
) {
QInputEvent *ie = static_cast<QInputEvent*>(e);
QApplicationPrivate::modifier_buttons = ie->modifiers();
}
#endif // !QT_NO_WHEELEVENT || !QT_NO_TABLETEVENT
}
#ifndef QT_NO_GESTURES

View File

@ -55,6 +55,7 @@ private slots:
void topLevelWindows();
void abortQuitOnShow();
void changeFocusWindow();
void keyboardModifiers();
};
class DummyWindow : public QWindow
@ -239,6 +240,80 @@ void tst_QGuiApplication::changeFocusWindow()
QCOMPARE(window1.windowDuringFocusOut, &window2);
}
void tst_QGuiApplication::keyboardModifiers()
{
int argc = 0;
QGuiApplication app(argc, 0);
QWindow *window = new QWindow;
window->show();
QTest::qWaitForWindowShown(window);
QCOMPARE(QGuiApplication::keyboardModifiers(), Qt::NoModifier);
// mouse events
QPoint center = window->geometry().center();
QTest::mouseEvent(QTest::MousePress, window, Qt::LeftButton, Qt::NoModifier, center);
QCOMPARE(QGuiApplication::keyboardModifiers(), Qt::NoModifier);
QTest::mouseEvent(QTest::MouseRelease, window, Qt::LeftButton, Qt::NoModifier, center);
QCOMPARE(QGuiApplication::keyboardModifiers(), Qt::NoModifier);
QTest::mouseEvent(QTest::MousePress, window, Qt::RightButton, Qt::ControlModifier, center);
QCOMPARE(QGuiApplication::keyboardModifiers(), Qt::ControlModifier);
QTest::mouseEvent(QTest::MouseRelease, window, Qt::RightButton, Qt::ControlModifier, center);
QCOMPARE(QGuiApplication::keyboardModifiers(), Qt::ControlModifier);
// shortcut events
QWindowSystemInterface::tryHandleSynchronousShortcutEvent(window, Qt::Key_5, Qt::MetaModifier);
QCOMPARE(QGuiApplication::keyboardModifiers(), Qt::MetaModifier);
QWindowSystemInterface::tryHandleSynchronousShortcutEvent(window, Qt::Key_Period, Qt::NoModifier);
QCOMPARE(QGuiApplication::keyboardModifiers(), Qt::NoModifier);
QWindowSystemInterface::tryHandleSynchronousShortcutEvent(window, Qt::Key_0, Qt::ControlModifier);
QCOMPARE(QGuiApplication::keyboardModifiers(), Qt::ControlModifier);
// key events
QTest::keyEvent(QTest::Press, window, Qt::Key_C);
QCOMPARE(QGuiApplication::keyboardModifiers(), Qt::NoModifier);
QTest::keyEvent(QTest::Release, window, Qt::Key_C);
QCOMPARE(QGuiApplication::keyboardModifiers(), Qt::NoModifier);
QTest::keyEvent(QTest::Press, window, Qt::Key_U, Qt::ControlModifier);
QCOMPARE(QGuiApplication::keyboardModifiers(), Qt::ControlModifier);
QTest::keyEvent(QTest::Release, window, Qt::Key_U, Qt::ControlModifier);
QCOMPARE(QGuiApplication::keyboardModifiers(), Qt::ControlModifier);
QTest::keyEvent(QTest::Press, window, Qt::Key_T);
QCOMPARE(QGuiApplication::keyboardModifiers(), Qt::NoModifier);
QTest::keyEvent(QTest::Release, window, Qt::Key_T);
QCOMPARE(QGuiApplication::keyboardModifiers(), Qt::NoModifier);
QTest::keyEvent(QTest::Press, window, Qt::Key_E, Qt::ControlModifier);
QCOMPARE(QGuiApplication::keyboardModifiers(), Qt::ControlModifier);
QTest::keyEvent(QTest::Release, window, Qt::Key_E, Qt::ControlModifier);
QCOMPARE(QGuiApplication::keyboardModifiers(), Qt::ControlModifier);
// wheel events
QPoint global = window->mapToGlobal(center);
QPoint delta(0, 1);
QWindowSystemInterface::handleWheelEvent(window, center, global, delta, delta, Qt::NoModifier);
QWindowSystemInterface::sendWindowSystemEvents(app.eventDispatcher(), QEventLoop::AllEvents);
QCOMPARE(QGuiApplication::keyboardModifiers(), Qt::NoModifier);
QWindowSystemInterface::handleWheelEvent(window, center, global, delta, delta, Qt::AltModifier);
QWindowSystemInterface::sendWindowSystemEvents(app.eventDispatcher(), QEventLoop::AllEvents);
QCOMPARE(QGuiApplication::keyboardModifiers(), Qt::AltModifier);
QWindowSystemInterface::handleWheelEvent(window, center, global, delta, delta, Qt::ControlModifier);
QWindowSystemInterface::sendWindowSystemEvents(app.eventDispatcher(), QEventLoop::AllEvents);
QCOMPARE(QGuiApplication::keyboardModifiers(), Qt::ControlModifier);
// touch events
QList<const QTouchDevice *> touchDevices = QTouchDevice::devices();
if (!touchDevices.isEmpty()) {
QTouchDevice *touchDevice = const_cast<QTouchDevice *>(touchDevices.first());
QTest::touchEvent(window, touchDevice).press(1, center).release(1, center);
QCOMPARE(QGuiApplication::keyboardModifiers(), Qt::NoModifier);
}
window->close();
delete window;
}
QTEST_APPLESS_MAIN(tst_QGuiApplication)
#include "tst_qguiapplication.moc"