From 600ec57606ef0c02a51f9875e0a201ff71d09c19 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Wed, 24 Mar 2010 13:19:38 +0100 Subject: Autotest: added more tests to macnativeevents --- tests/auto/macnativeevents/expectedeventlist.cpp | 169 +++++++++ tests/auto/macnativeevents/expectedeventlist.h | 70 ++++ tests/auto/macnativeevents/macnativeevents.pro | 6 +- tests/auto/macnativeevents/nativeeventlist.cpp | 107 ++++++ tests/auto/macnativeevents/nativeeventlist.h | 81 +++++ tests/auto/macnativeevents/qnativeevents.cpp | 378 ++++++++++++++++++++ tests/auto/macnativeevents/qnativeevents.h | 228 ++++++++++++ tests/auto/macnativeevents/qnativeevents_mac.cpp | 382 +++++++++++++++++++++ tests/auto/macnativeevents/qnativeinput.cpp | 378 -------------------- tests/auto/macnativeevents/qnativeinput.h | 228 ------------ tests/auto/macnativeevents/qnativeinput_mac.cpp | 382 --------------------- tests/auto/macnativeevents/qnativeplayer.cpp | 139 -------- tests/auto/macnativeevents/qnativeplayer.h | 92 ----- tests/auto/macnativeevents/tst_macnativeevents.cpp | 124 ++++++- 14 files changed, 1534 insertions(+), 1230 deletions(-) create mode 100644 tests/auto/macnativeevents/expectedeventlist.cpp create mode 100644 tests/auto/macnativeevents/expectedeventlist.h create mode 100644 tests/auto/macnativeevents/nativeeventlist.cpp create mode 100644 tests/auto/macnativeevents/nativeeventlist.h create mode 100644 tests/auto/macnativeevents/qnativeevents.cpp create mode 100644 tests/auto/macnativeevents/qnativeevents.h create mode 100644 tests/auto/macnativeevents/qnativeevents_mac.cpp delete mode 100644 tests/auto/macnativeevents/qnativeinput.cpp delete mode 100644 tests/auto/macnativeevents/qnativeinput.h delete mode 100644 tests/auto/macnativeevents/qnativeinput_mac.cpp delete mode 100644 tests/auto/macnativeevents/qnativeplayer.cpp delete mode 100644 tests/auto/macnativeevents/qnativeplayer.h diff --git a/tests/auto/macnativeevents/expectedeventlist.cpp b/tests/auto/macnativeevents/expectedeventlist.cpp new file mode 100644 index 0000000..48cfe1f --- /dev/null +++ b/tests/auto/macnativeevents/expectedeventlist.cpp @@ -0,0 +1,169 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "expectedeventlist.h" +#include +#include +#include +#include + +ExpectedEventList::ExpectedEventList(QObject *target) + : QObject(target), eventCount(0) +{ + target->installEventFilter(this); +} + +ExpectedEventList::~ExpectedEventList() +{ + qDeleteAll(eventList); +} + +void ExpectedEventList::append(QEvent *e) +{ + eventList.append(e); + ++eventCount; +} + +void ExpectedEventList::timerEvent(QTimerEvent *) +{ + timer.stop(); + QAbstractEventDispatcher::instance()->interrupt(); +} + +bool ExpectedEventList::waitForAllEvents(int maxEventWaitTime) +{ + if (eventList.isEmpty()) + return true; + + int eventCount = eventList.size(); + timer.start(maxEventWaitTime, this); + + while (timer.isActive()) { + QCoreApplication::processEvents(QEventLoop::WaitForMoreEvents); + if (eventList.isEmpty()) + return true; + + if (eventCount < eventList.size()){ + eventCount = eventList.size(); + timer.start(maxEventWaitTime, this); + } + } + + int eventListNr = eventCount - eventList.size() + 1; + qWarning() << "Stopped waiting for expected event nr" << eventListNr; + return false; +} + +void ExpectedEventList::compareMouseEvents(QEvent *expected, QEvent *received) +{ + QMouseEvent *e1 = static_cast(expected); + QMouseEvent *e2 = static_cast(received); + if (e1->pos() == e2->pos() + && (e1->globalPos() == e2->globalPos()) + && (e1->button() == e2->button()) + && (e1->buttons() == e2->buttons()) + && (e1->modifiers() == e2->modifiers())) + return; // equal + + int eventListNr = eventCount - eventList.size(); + qWarning() << "Expected event" << eventListNr << "about to fail:"; + qWarning() << "Expected:" << e1; + qWarning() << "Received:" << e2; + QCOMPARE(e1->pos(), e2->pos()); + QCOMPARE(e1->globalPos(), e2->globalPos()); + QCOMPARE(e1->button(), e2->button()); + QCOMPARE(e1->buttons(), e2->buttons()); + QCOMPARE(e1->modifiers(), e2->modifiers()); +} + +void ExpectedEventList::compareKeyEvents(QEvent *event1, QEvent *event2) +{ + QKeyEvent *e1 = static_cast(event1); + QKeyEvent *e2 = static_cast(event2); + Q_UNUSED(e1); + Q_UNUSED(e2); +} + +bool ExpectedEventList::eventFilter(QObject *, QEvent *received) +{ + if (eventList.isEmpty()) + return false; + + QEvent *expected = eventList.first(); + if (expected->type() == received->type()) { + eventList.removeFirst(); + switch (received->type()) { + case QEvent::MouseButtonPress: + case QEvent::MouseButtonRelease: + case QEvent::MouseMove: + case QEvent::MouseButtonDblClick: + case QEvent::NonClientAreaMouseButtonPress: + case QEvent::NonClientAreaMouseButtonRelease: + case QEvent::NonClientAreaMouseButtonDblClick: + case QEvent::NonClientAreaMouseMove: { + compareMouseEvents(expected, received); + break; + } + case QEvent::KeyPress: { + break; + } + case QEvent::KeyRelease: { + break; + } + case QEvent::Resize: { + break; + } + case QEvent::WindowActivate: { + break; + } + case QEvent::WindowDeactivate: { + break; + } + default: + break; + } + if (eventList.isEmpty()) + QAbstractEventDispatcher::instance()->interrupt(); + } + + return false; +} + diff --git a/tests/auto/macnativeevents/expectedeventlist.h b/tests/auto/macnativeevents/expectedeventlist.h new file mode 100644 index 0000000..3bdbb67 --- /dev/null +++ b/tests/auto/macnativeevents/expectedeventlist.h @@ -0,0 +1,70 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef EVENTFILTER +#define EVENTFILTER + +#include +#include +#include +#include + +class ExpectedEventList : public QObject +{ + QList eventList; + QBasicTimer timer; + int eventCount; + void timerEvent(QTimerEvent *); + +public: + ExpectedEventList(QObject *target); + ~ExpectedEventList(); + void append(QEvent *e); + bool waitForAllEvents(int timeoutPerEvent = 2000); + bool eventFilter(QObject *obj, QEvent *event); + +private: + void compareMouseEvents(QEvent *event1, QEvent *event2); + void compareKeyEvents(QEvent *event1, QEvent *event2); +}; + +#endif + diff --git a/tests/auto/macnativeevents/macnativeevents.pro b/tests/auto/macnativeevents/macnativeevents.pro index a0293d4..af34942 100644 --- a/tests/auto/macnativeevents/macnativeevents.pro +++ b/tests/auto/macnativeevents/macnativeevents.pro @@ -8,9 +8,9 @@ DEPENDPATH += . INCLUDEPATH += . LIBS += -framework Carbon -HEADERS += qnativeinput.h qnativeplayer.h -SOURCES += qnativeinput.cpp qnativeplayer.cpp qnativeinput_mac.cpp - +HEADERS += qnativeevents.h nativeeventlist.h expectedeventlist.h +SOURCES += qnativeevents.cpp qnativeevents_mac.cpp +SOURCES += expectedeventlist.cpp nativeeventlist.cpp SOURCES += tst_macnativeevents.cpp requires(mac) diff --git a/tests/auto/macnativeevents/nativeeventlist.cpp b/tests/auto/macnativeevents/nativeeventlist.cpp new file mode 100644 index 0000000..614e9d0 --- /dev/null +++ b/tests/auto/macnativeevents/nativeeventlist.cpp @@ -0,0 +1,107 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "nativeeventlist.h" + +NativeEventList::NativeEventList(int defaultWaitMs) + : playbackMultiplier(1.0) + , currIndex(-1) + , wait(false) + , defaultWaitMs(defaultWaitMs) +{ +} + +NativeEventList::~NativeEventList() +{ + for (int i=0; i= eventList.size()){ + emit done(); + stop(); + return; + } + + int interval = eventList.at(currIndex).first; + QTimer::singleShot(interval * playbackMultiplier, this, SLOT(sendNextEvent())); +} + +void NativeEventList::append(QNativeEvent *event) +{ + eventList.append(QPair(defaultWaitMs, event)); +} + +void NativeEventList::append(int waitMs, QNativeEvent *event) +{ + eventList.append(QPair(waitMs, event)); +} + +void NativeEventList::append(int waitMs) +{ + eventList.append(QPair(waitMs, 0)); +} + +void NativeEventList::play(Playback playback) +{ + waitNextEvent(); + + wait = (playback == WaitUntilFinished); + while (wait) + QCoreApplication::processEvents(QEventLoop::WaitForMoreEvents); +} + +void NativeEventList::stop() +{ + wait = false; + QAbstractEventDispatcher::instance()->interrupt(); +} + diff --git a/tests/auto/macnativeevents/nativeeventlist.h b/tests/auto/macnativeevents/nativeeventlist.h new file mode 100644 index 0000000..886ab78 --- /dev/null +++ b/tests/auto/macnativeevents/nativeeventlist.h @@ -0,0 +1,81 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef Q_NATIVE_PLAYBACK +#define Q_NATIVE_PLAYBACK + +#include +#include "qnativeevents.h" + +class NativeEventList : public QObject +{ + Q_OBJECT; + + public: + enum Playback {ReturnImmediately, WaitUntilFinished}; + + NativeEventList(int defaultWaitMs = 20); + ~NativeEventList(); + + void append(QNativeEvent *event); + void append(int waitMs, QNativeEvent *event = 0); + void append(int waitMs); + + void play(Playback playback = WaitUntilFinished); + void stop(); + float playbackMultiplier; + +signals: + void done(); + +private slots: + void sendNextEvent(); + +private: + void waitNextEvent(); + + QList > eventList; + int currIndex; + bool wait; + int defaultWaitMs; +}; + +#endif diff --git a/tests/auto/macnativeevents/qnativeevents.cpp b/tests/auto/macnativeevents/qnativeevents.cpp new file mode 100644 index 0000000..cb4b82e --- /dev/null +++ b/tests/auto/macnativeevents/qnativeevents.cpp @@ -0,0 +1,378 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qnativeevents.h" + +QNativeInput::QNativeInput(bool subscribe) +{ + if (subscribe) + subscribeForNativeEvents(); +} + +QNativeInput::~QNativeInput() +{ + unsubscribeForNativeEvents(); +} + +void QNativeInput::notify(QNativeEvent *event) +{ + nativeEvent(event); +} + +void QNativeInput::nativeEvent(QNativeEvent *event) +{ + switch (event->id()){ + case QNativeMouseButtonEvent::eventId:{ + QNativeMouseButtonEvent *e = static_cast(event); + (e->clickCount > 0) ? nativeMousePressEvent(e) : nativeMouseReleaseEvent(e); + break; } + case QNativeMouseMoveEvent::eventId: + nativeMouseMoveEvent(static_cast(event)); + break; + case QNativeMouseDragEvent::eventId: + nativeMouseDragEvent(static_cast(event)); + break; + case QNativeMouseWheelEvent::eventId: + nativeMouseWheelEvent(static_cast(event)); + break; + case QNativeKeyEvent::eventId:{ + QNativeKeyEvent *e = static_cast(event); + e->press ? nativeKeyPressEvent(e) : nativeKeyReleaseEvent(e); + break; } + case QNativeModifierEvent::eventId: + nativeModifierEvent(static_cast(event)); + break; + default: + break; + } +} + +Qt::Native::Status QNativeInput::sendNativeEvent(const QNativeEvent &event, int pid) +{ + switch (event.id()){ + case QNativeMouseMoveEvent::eventId: + return sendNativeMouseMoveEvent(static_cast(event)); + case QNativeMouseButtonEvent::eventId: + return sendNativeMouseButtonEvent(static_cast(event)); + case QNativeMouseDragEvent::eventId: + return sendNativeMouseDragEvent(static_cast(event)); + case QNativeMouseWheelEvent::eventId: + return sendNativeMouseWheelEvent(static_cast(event)); + case QNativeKeyEvent::eventId: + return sendNativeKeyEvent(static_cast(event), pid); + case QNativeModifierEvent::eventId: + return sendNativeModifierEvent(static_cast(event)); + case QNativeEvent::eventId: + qWarning() << "Warning: Cannot send a pure native event. Use a sub class."; + default: + return Qt::Native::Failure; + } +} + +QNativeEvent::QNativeEvent(Qt::KeyboardModifiers modifiers) + : modifiers(modifiers){} + +QNativeMouseEvent::QNativeMouseEvent(QPoint pos, Qt::KeyboardModifiers modifiers) + : QNativeEvent(modifiers), globalPos(pos){} + +QNativeMouseMoveEvent::QNativeMouseMoveEvent(QPoint pos, Qt::KeyboardModifiers modifiers) + : QNativeMouseEvent(pos, modifiers){} + +QNativeMouseButtonEvent::QNativeMouseButtonEvent(QPoint globalPos, Qt::MouseButton button, int clickCount, Qt::KeyboardModifiers modifiers) + : QNativeMouseEvent(globalPos, modifiers), button(button), clickCount(clickCount){} + +QNativeMouseDragEvent::QNativeMouseDragEvent(QPoint globalPos, Qt::MouseButton button, Qt::KeyboardModifiers modifiers) + : QNativeMouseButtonEvent(globalPos, button, true, modifiers){} + +QNativeMouseWheelEvent::QNativeMouseWheelEvent(QPoint globalPos, int delta, Qt::KeyboardModifiers modifiers) + : QNativeMouseEvent(globalPos, modifiers), delta(delta){} + +QNativeKeyEvent::QNativeKeyEvent(int nativeKeyCode, bool press, Qt::KeyboardModifiers modifiers) + : QNativeEvent(modifiers), nativeKeyCode(nativeKeyCode), press(press), character(QChar()){} + +QNativeModifierEvent::QNativeModifierEvent(Qt::KeyboardModifiers modifiers, int nativeKeyCode) + : QNativeEvent(modifiers), nativeKeyCode(nativeKeyCode){} + +QNativeKeyEvent::QNativeKeyEvent(int nativeKeyCode, bool press, QChar character, Qt::KeyboardModifiers modifiers) + : QNativeEvent(modifiers), nativeKeyCode(nativeKeyCode), press(press), character(character){} + +static QString getButtonAsString(const QNativeMouseButtonEvent *e) +{ + switch (e->button){ + case Qt::LeftButton: + return "button = LeftButton"; + break; + case Qt::RightButton: + return "button = RightButton"; + break; + case Qt::MidButton: + return "button = MidButton"; + break; + default: + return "button = Other"; + break; + } +} + +static QString getModifiersAsString(const QNativeEvent *e) +{ + if (e->modifiers == 0) + return "modifiers = none"; + + QString tmp = "modifiers = "; + if (e->modifiers.testFlag(Qt::ShiftModifier)) + tmp += "Shift"; + if (e->modifiers.testFlag(Qt::ControlModifier)) + tmp += "Control"; + if (e->modifiers.testFlag(Qt::AltModifier)) + tmp += "Alt"; + if (e->modifiers.testFlag(Qt::MetaModifier)) + tmp += "Meta"; + return tmp; +} + +static QString getPosAsString(QPoint pos) +{ + return QString("QPoint(%1, %2)").arg(pos.x()).arg(pos.y()); +} + +static QString getBoolAsString(bool b) +{ + return b ? QString("true") : QString("false"); +} + +QString QNativeMouseMoveEvent::toString() const +{ + return QString("QNativeMouseMoveEvent(globalPos = %1 %2)").arg(getPosAsString(globalPos)) + .arg(getModifiersAsString(this)); +} + +QString QNativeMouseButtonEvent::toString() const +{ + return QString("QNativeMouseButtonEvent(globalPos = %1, %2, clickCount = %3, %4)").arg(getPosAsString(globalPos)) + .arg(getButtonAsString(this)).arg(clickCount).arg(getModifiersAsString(this)); +} + +QString QNativeMouseDragEvent::toString() const +{ + return QString("QNativeMouseDragEvent(globalPos = %1, %2, clickCount = %3, %4)").arg(getPosAsString(globalPos)) + .arg(getButtonAsString(this)).arg(clickCount).arg(getModifiersAsString(this)); +} + +QString QNativeMouseWheelEvent::toString() const +{ + return QString("QNativeMouseWheelEvent(globalPos = %1, delta = %2, %3)").arg(getPosAsString(globalPos)) + .arg(delta).arg(getModifiersAsString(this)); +} + +QString QNativeKeyEvent::toString() const +{ + return QString("QNativeKeyEvent(press = %1, native key code = %2, character = %3, %4)").arg(getBoolAsString(press)) + .arg(nativeKeyCode).arg(character.isPrint() ? character : QString("")) + .arg(getModifiersAsString(this)); +} + +QString QNativeModifierEvent::toString() const +{ + return QString("QNativeModifierEvent(%1, native key code = %2)").arg(getModifiersAsString(this)) + .arg(nativeKeyCode); +} + +QDebug operator<<(QDebug d, QNativeEvent *e) +{ + Q_UNUSED(e); + return d << e->toString(); +} + +QDebug operator<<(QDebug d, const QNativeEvent &e) +{ + Q_UNUSED(e); + return d << e.toString(); +} + +QTextStream &operator<<(QTextStream &s, QNativeEvent *e) +{ + return s << e->eventId << " " << e->modifiers << " QNativeEvent"; +} + +QTextStream &operator<<(QTextStream &s, QNativeMouseEvent *e) +{ + return s << e->eventId << " " << e->globalPos.x() << " " << e->globalPos.y() << " " << e->modifiers << " " << e->toString(); +} + +QTextStream &operator<<(QTextStream &s, QNativeMouseMoveEvent *e) +{ + return s << e->eventId << " " << e->globalPos.x() << " " << e->globalPos.y() << " " << e->modifiers << " " << e->toString(); +} + +QTextStream &operator<<(QTextStream &s, QNativeMouseButtonEvent *e) +{ + return s << e->eventId << " " << e->globalPos.x() << " " << e->globalPos.y() << " " << e->button + << " " << e->clickCount << " " << e->modifiers << " " << e->toString(); +} + +QTextStream &operator<<(QTextStream &s, QNativeMouseDragEvent *e) +{ + return s << e->eventId << " " << e->globalPos.x() << " " << e->globalPos.y() << " " << e->button << " " << e->clickCount + << " " << e->modifiers << " " << e->toString(); +} + +QTextStream &operator<<(QTextStream &s, QNativeMouseWheelEvent *e) +{ + return s << e->eventId << " " << e->globalPos.x() << " " << e->globalPos.y() << " " << e->delta + << " " << e->modifiers << " " << e->toString(); +} + +QTextStream &operator<<(QTextStream &s, QNativeKeyEvent *e) +{ + return s << e->eventId << " " << e->press << " " << e->nativeKeyCode << " " << e->character + << " " << e->modifiers << " " << e->toString(); +} + +QTextStream &operator<<(QTextStream &s, QNativeModifierEvent *e) +{ + return s << e->eventId << " " << e->modifiers << " " << e->nativeKeyCode << " " << e->toString(); +} + + + + +QTextStream &operator>>(QTextStream &s, QNativeMouseMoveEvent *e) +{ + // Skip reading eventId. + QString humanReadable; + int x, y, modifiers; + s >> x >> y >> modifiers >> humanReadable; + e->globalPos.setX(x); + e->globalPos.setY(y); + e->modifiers = Qt::KeyboardModifiers(modifiers); + return s; +} + +QTextStream &operator>>(QTextStream &s, QNativeMouseButtonEvent *e) +{ + // Skip reading eventId. + QString humanReadable; + int x, y, button, clickCount, modifiers; + s >> x >> y >> button >> clickCount >> modifiers >> humanReadable; + e->globalPos.setX(x); + e->globalPos.setY(y); + e->clickCount = clickCount; + e->modifiers = Qt::KeyboardModifiers(modifiers); + switch (button){ + case 1: + e->button = Qt::LeftButton; + break; + case 2: + e->button = Qt::RightButton; + break; + case 3: + e->button = Qt::MidButton; + break; + default: + e->button = Qt::NoButton; + break; + } + return s; +} + +QTextStream &operator>>(QTextStream &s, QNativeMouseDragEvent *e) +{ + // Skip reading eventId. + QString humanReadable; + int x, y, button, clickCount, modifiers; + s >> x >> y >> button >> clickCount >> modifiers >> humanReadable; + e->globalPos.setX(x); + e->globalPos.setY(y); + e->clickCount = clickCount; + e->modifiers = Qt::KeyboardModifiers(modifiers); + switch (button){ + case 1: + e->button = Qt::LeftButton; + break; + case 2: + e->button = Qt::RightButton; + break; + case 3: + e->button = Qt::MidButton; + break; + default: + e->button = Qt::NoButton; + break; + } + return s; +} + +QTextStream &operator>>(QTextStream &s, QNativeMouseWheelEvent *e) +{ + // Skip reading eventId. + QString humanReadable; + int x, y, modifiers; + s >> x >> y >> e->delta >> modifiers >> humanReadable; + e->globalPos.setX(x); + e->globalPos.setY(y); + e->modifiers = Qt::KeyboardModifiers(modifiers); + return s; +} + +QTextStream &operator>>(QTextStream &s, QNativeKeyEvent *e) +{ + // Skip reading eventId. + QString humanReadable; + int press, modifiers; + QString character; + s >> press >> e->nativeKeyCode >> character >> modifiers >> humanReadable; + e->press = bool(press); + e->character = character[0]; + e->modifiers = Qt::KeyboardModifiers(modifiers); + return s; +} + +QTextStream &operator>>(QTextStream &s, QNativeModifierEvent *e) +{ + // Skip reading eventId. + QString humanReadable; + int modifiers; + s >> modifiers >> e->nativeKeyCode >> humanReadable; + e->modifiers = Qt::KeyboardModifiers(modifiers); + return s; +} + diff --git a/tests/auto/macnativeevents/qnativeevents.h b/tests/auto/macnativeevents/qnativeevents.h new file mode 100644 index 0000000..a98e4e4 --- /dev/null +++ b/tests/auto/macnativeevents/qnativeevents.h @@ -0,0 +1,228 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef Q_NATIVE_INPUT +#define Q_NATIVE_INPUT + +#include + +namespace Qt { +namespace Native { + enum Status {Success, Failure}; +}} + +// ---------------------------------------------------------------------------- +// Declare a set of native events that can be used to communicate with +// client applications in an platform independent way +// ---------------------------------------------------------------------------- + +class QNativeEvent +{ +public: + static const int eventId = 1; + + QNativeEvent(Qt::KeyboardModifiers modifiers = Qt::NoModifier); + virtual ~QNativeEvent(){}; + virtual int id() const { return eventId; }; + virtual QString toString() const = 0; + Qt::KeyboardModifiers modifiers; // Yields for mouse events too. +}; + +class QNativeMouseEvent : public QNativeEvent { +public: + static const int eventId = 2; + + QNativeMouseEvent(){}; + QNativeMouseEvent(QPoint globalPos, Qt::KeyboardModifiers modifiers = Qt::NoModifier); + virtual ~QNativeMouseEvent(){}; + virtual int id() const { return eventId; }; + + QPoint globalPos; +}; + +class QNativeMouseMoveEvent : public QNativeMouseEvent { +public: + static const int eventId = 4; + + QNativeMouseMoveEvent(){}; + QNativeMouseMoveEvent(QPoint globalPos, Qt::KeyboardModifiers modifiers = Qt::NoModifier); + virtual ~QNativeMouseMoveEvent(){}; + virtual int id() const { return eventId; }; + virtual QString toString() const; +}; + +class QNativeMouseButtonEvent : public QNativeMouseEvent { +public: + static const int eventId = 8; + + QNativeMouseButtonEvent(){}; + QNativeMouseButtonEvent(QPoint globalPos, Qt::MouseButton button, int clickCount, Qt::KeyboardModifiers modifiers = Qt::NoModifier); + virtual ~QNativeMouseButtonEvent(){}; + virtual int id() const { return eventId; }; + virtual QString toString() const; + + Qt::MouseButton button; + int clickCount; +}; + +class QNativeMouseDragEvent : public QNativeMouseButtonEvent { +public: + static const int eventId = 16; + + QNativeMouseDragEvent(){}; + QNativeMouseDragEvent(QPoint globalPos, Qt::MouseButton button, Qt::KeyboardModifiers modifiers = Qt::NoModifier); + virtual ~QNativeMouseDragEvent(){}; + virtual int id() const { return eventId; }; + virtual QString toString() const; +}; + +class QNativeMouseWheelEvent : public QNativeMouseEvent { +public: + static const int eventId = 32; + + QNativeMouseWheelEvent(){}; + QNativeMouseWheelEvent(QPoint globalPos, int delta, Qt::KeyboardModifiers modifiers = Qt::NoModifier); + virtual ~QNativeMouseWheelEvent(){}; + virtual int id() const { return eventId; }; + virtual QString toString() const; + + int delta; +}; + +class QNativeKeyEvent : public QNativeEvent { + public: + static const int eventId = 64; + + QNativeKeyEvent(){}; + QNativeKeyEvent(int nativeKeyCode, bool press, Qt::KeyboardModifiers modifiers = Qt::NoModifier); + QNativeKeyEvent(int nativeKeyCode, bool press, QChar character, Qt::KeyboardModifiers modifiers); + virtual ~QNativeKeyEvent(){}; + virtual int id() const { return eventId; }; + virtual QString toString() const; + + int nativeKeyCode; + bool press; + QChar character; + + // Some Qt to Native mappings: + static int Key_A; + static int Key_B; + static int Key_C; + static int Key_1; + static int Key_Backspace; + static int Key_Enter; + static int Key_Del; +}; + +class QNativeModifierEvent : public QNativeEvent { +public: + static const int eventId = 128; + + QNativeModifierEvent(Qt::KeyboardModifiers modifiers = Qt::NoModifier, int nativeKeyCode = 0); + virtual ~QNativeModifierEvent(){}; + virtual int id() const { return eventId; }; + virtual QString toString() const; + + int nativeKeyCode; +}; + +// ---------------------------------------------------------------------------- +// Declare a set of related output / input functions for convenience: +// ---------------------------------------------------------------------------- + +QDebug operator<<(QDebug d, QNativeEvent *e); +QDebug operator<<(QDebug d, const QNativeEvent &e); + +QTextStream &operator<<(QTextStream &s, QNativeEvent *e); +QTextStream &operator<<(QTextStream &s, QNativeMouseEvent *e); +QTextStream &operator<<(QTextStream &s, QNativeMouseMoveEvent *e); +QTextStream &operator<<(QTextStream &s, QNativeMouseButtonEvent *e); +QTextStream &operator<<(QTextStream &s, QNativeMouseDragEvent *e); +QTextStream &operator<<(QTextStream &s, QNativeMouseWheelEvent *e); +QTextStream &operator<<(QTextStream &s, QNativeKeyEvent *e); +QTextStream &operator<<(QTextStream &s, QNativeModifierEvent *e); + +QTextStream &operator>>(QTextStream &s, QNativeMouseMoveEvent *e); +QTextStream &operator>>(QTextStream &s, QNativeMouseButtonEvent *e); +QTextStream &operator>>(QTextStream &s, QNativeMouseDragEvent *e); +QTextStream &operator>>(QTextStream &s, QNativeMouseWheelEvent *e); +QTextStream &operator>>(QTextStream &s, QNativeKeyEvent *e); +QTextStream &operator>>(QTextStream &s, QNativeModifierEvent *e); + +// ---------------------------------------------------------------------------- +// Declare the main class that is supposed to be sub-classed by components +// that are to receive native events +// ---------------------------------------------------------------------------- + +class QNativeInput +{ + public: + QNativeInput(bool subscribe = true); + virtual ~QNativeInput(); + + // Callback methods. Should be implemented by interested sub-classes: + void notify(QNativeEvent *event); + virtual void nativeEvent(QNativeEvent *event); + virtual void nativeMousePressEvent(QNativeMouseButtonEvent *){}; + virtual void nativeMouseReleaseEvent(QNativeMouseButtonEvent *){}; + virtual void nativeMouseMoveEvent(QNativeMouseMoveEvent *){}; + virtual void nativeMouseDragEvent(QNativeMouseDragEvent *){}; + virtual void nativeMouseWheelEvent(QNativeMouseWheelEvent *){}; + virtual void nativeKeyPressEvent(QNativeKeyEvent *){}; + virtual void nativeKeyReleaseEvent(QNativeKeyEvent *){}; + virtual void nativeModifierEvent(QNativeModifierEvent *){}; + + // The following methods will differ in implementation from OS to OS: + static Qt::Native::Status sendNativeMouseButtonEvent(const QNativeMouseButtonEvent &event); + static Qt::Native::Status sendNativeMouseMoveEvent(const QNativeMouseMoveEvent &event); + static Qt::Native::Status sendNativeMouseDragEvent(const QNativeMouseDragEvent &event); + static Qt::Native::Status sendNativeMouseWheelEvent(const QNativeMouseWheelEvent &event); + static Qt::Native::Status sendNativeKeyEvent(const QNativeKeyEvent &event, int pid = 0); + static Qt::Native::Status sendNativeModifierEvent(const QNativeModifierEvent &event); + // sendNativeEvent will NOT differ from OS to OS. + static Qt::Native::Status sendNativeEvent(const QNativeEvent &event, int pid = 0); + + // The following methods will differ in implementation from OS to OS: + Qt::Native::Status subscribeForNativeEvents(); + Qt::Native::Status unsubscribeForNativeEvents(); +}; + +#endif // Q_NATIVE_INPUT diff --git a/tests/auto/macnativeevents/qnativeevents_mac.cpp b/tests/auto/macnativeevents/qnativeevents_mac.cpp new file mode 100644 index 0000000..6c04bf3 --- /dev/null +++ b/tests/auto/macnativeevents/qnativeevents_mac.cpp @@ -0,0 +1,382 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qnativeevents.h" +#include +#include + +// ************************************************************ +// Quartz +// ************************************************************ + +static Qt::KeyboardModifiers getModifiersFromQuartzEvent(CGEventRef inEvent) +{ + Qt::KeyboardModifiers m; + CGEventFlags flags = CGEventGetFlags(inEvent); + if (flags & kCGEventFlagMaskShift || flags & kCGEventFlagMaskAlphaShift) + m |= Qt::ShiftModifier; + if (flags & kCGEventFlagMaskControl) + m |= Qt::MetaModifier; + if (flags & kCGEventFlagMaskAlternate) + m |= Qt::AltModifier; + if (flags & kCGEventFlagMaskCommand) + m |= Qt::ControlModifier; + return m; +} + +static void setModifiersFromQNativeEvent(CGEventRef inEvent, const QNativeEvent &event) +{ + CGEventFlags flags = 0; + if (event.modifiers.testFlag(Qt::ShiftModifier)) + flags |= kCGEventFlagMaskShift; + if (event.modifiers.testFlag(Qt::MetaModifier)) + flags |= kCGEventFlagMaskControl; + if (event.modifiers.testFlag(Qt::AltModifier)) + flags |= kCGEventFlagMaskAlternate; + if (event.modifiers.testFlag(Qt::ControlModifier)) + flags |= kCGEventFlagMaskCommand; + CGEventSetFlags(inEvent, flags); +} + +static QPoint getMouseLocationFromQuartzEvent(CGEventRef inEvent) +{ + CGPoint pos = CGEventGetLocation(inEvent); + QPoint tmp; + tmp.setX(pos.x); + tmp.setY(pos.y); + return tmp; +} + +static QChar getCharFromQuartzEvent(CGEventRef inEvent) +{ + UniCharCount count = 0; + UniChar c; + CGEventKeyboardGetUnicodeString(inEvent, 1, &count, &c); + return QChar(c); +} + +static CGEventRef EventHandler_Quartz(CGEventTapProxy proxy, CGEventType type, CGEventRef inEvent, void *refCon) +{ + Q_UNUSED(proxy); + QNativeInput *nativeInput = static_cast(refCon); + switch (type){ + case kCGEventKeyDown:{ + QNativeKeyEvent e; + e.modifiers = getModifiersFromQuartzEvent(inEvent); + e.nativeKeyCode = CGEventGetIntegerValueField(inEvent, kCGKeyboardEventKeycode); + e.character = getCharFromQuartzEvent(inEvent); + e.press = true; + nativeInput->notify(&e); + break; + } + case kCGEventKeyUp:{ + QNativeKeyEvent e; + e.modifiers = getModifiersFromQuartzEvent(inEvent); + e.nativeKeyCode = CGEventGetIntegerValueField(inEvent, kCGKeyboardEventKeycode); + e.character = getCharFromQuartzEvent(inEvent); + e.press = false; + nativeInput->notify(&e); + break; + } + case kCGEventLeftMouseDown:{ + QNativeMouseButtonEvent e; + e.modifiers = getModifiersFromQuartzEvent(inEvent); + e.globalPos = getMouseLocationFromQuartzEvent(inEvent); + e.clickCount = CGEventGetIntegerValueField(inEvent, kCGMouseEventClickState); + e.button = Qt::LeftButton; + nativeInput->notify(&e); + break; + } + case kCGEventLeftMouseUp:{ + QNativeMouseButtonEvent e; + e.modifiers = getModifiersFromQuartzEvent(inEvent); + e.globalPos = getMouseLocationFromQuartzEvent(inEvent); + e.clickCount = 0; + e.button = Qt::LeftButton; + nativeInput->notify(&e); + break; + } + case kCGEventRightMouseDown:{ + QNativeMouseButtonEvent e; + e.modifiers = getModifiersFromQuartzEvent(inEvent); + e.globalPos = getMouseLocationFromQuartzEvent(inEvent); + e.clickCount = CGEventGetIntegerValueField(inEvent, kCGMouseEventClickState); + e.button = Qt::RightButton; + nativeInput->notify(&e); + break; + } + case kCGEventRightMouseUp:{ + QNativeMouseButtonEvent e; + e.modifiers = getModifiersFromQuartzEvent(inEvent); + e.globalPos = getMouseLocationFromQuartzEvent(inEvent); + e.clickCount = 0; + e.button = Qt::RightButton; + nativeInput->notify(&e); + break; + } + case kCGEventMouseMoved:{ + QNativeMouseMoveEvent e; + e.modifiers = getModifiersFromQuartzEvent(inEvent); + e.globalPos = getMouseLocationFromQuartzEvent(inEvent); + nativeInput->notify(&e); + break; + } + case kCGEventLeftMouseDragged:{ + QNativeMouseDragEvent e; + e.modifiers = getModifiersFromQuartzEvent(inEvent); + e.globalPos = getMouseLocationFromQuartzEvent(inEvent); + e.clickCount = CGEventGetIntegerValueField(inEvent, kCGMouseEventClickState); + e.button = Qt::LeftButton; + nativeInput->notify(&e); + break; + } + case kCGEventScrollWheel:{ + QNativeMouseWheelEvent e; + e.modifiers = getModifiersFromQuartzEvent(inEvent); + e.delta = CGEventGetIntegerValueField(inEvent, kCGScrollWheelEventDeltaAxis1); + e.globalPos = getMouseLocationFromQuartzEvent(inEvent); + nativeInput->notify(&e); + break; + } + case kCGEventFlagsChanged:{ + QNativeModifierEvent e; + e.modifiers = getModifiersFromQuartzEvent(inEvent); + e.nativeKeyCode = CGEventGetIntegerValueField(inEvent, kCGKeyboardEventKeycode); + nativeInput->notify(&e); + break; + } + + } + + return inEvent; +} + +Qt::Native::Status insertEventHandler_Quartz(QNativeInput *nativeInput, int pid = 0) +{ + uid_t uid = geteuid(); + if (uid != 0) + qWarning("MacNativeEvents: You must be root to listen for key events!"); + + CFMachPortRef port; + if (!pid){ + port = CGEventTapCreate(kCGHIDEventTap, + kCGHeadInsertEventTap, kCGEventTapOptionListenOnly, + kCGEventMaskForAllEvents, EventHandler_Quartz, nativeInput); + } else { + ProcessSerialNumber psn; + GetProcessForPID(pid, &psn); + port = CGEventTapCreateForPSN(&psn, + kCGHeadInsertEventTap, kCGEventTapOptionListenOnly, + kCGEventMaskForAllEvents, EventHandler_Quartz, nativeInput); + } + + CFRunLoopSourceRef eventSrc = CFMachPortCreateRunLoopSource(NULL, port, 0); + CFRunLoopAddSource((CFRunLoopRef) GetCFRunLoopFromEventLoop(GetMainEventLoop()), + eventSrc, kCFRunLoopCommonModes); + + return Qt::Native::Success; +} + +Qt::Native::Status removeEventHandler_Quartz() +{ + return Qt::Native::Success; // ToDo: +} + +Qt::Native::Status sendNativeKeyEventToProcess_Quartz(const QNativeKeyEvent &event, int pid) +{ + ProcessSerialNumber psn; + GetProcessForPID(pid, &psn); + + CGEventRef e = CGEventCreateKeyboardEvent(0, (uint)event.nativeKeyCode, event.press); + setModifiersFromQNativeEvent(e, event); + SetFrontProcess(&psn); + CGEventPostToPSN(&psn, e); + CFRelease(e); + return Qt::Native::Success; +} + +Qt::Native::Status sendNativeKeyEvent_Quartz(const QNativeKeyEvent &event) +{ + CGEventRef e = CGEventCreateKeyboardEvent(0, (uint)event.nativeKeyCode, event.press); + setModifiersFromQNativeEvent(e, event); + CGEventPost(kCGHIDEventTap, e); + CFRelease(e); + return Qt::Native::Success; +} + +Qt::Native::Status sendNativeMouseMoveEvent_Quartz(const QNativeMouseMoveEvent &event) +{ + CGPoint pos; + pos.x = event.globalPos.x(); + pos.y = event.globalPos.y(); + + CGEventRef e = CGEventCreateMouseEvent(0, kCGEventMouseMoved, pos, 0); + setModifiersFromQNativeEvent(e, event); + CGEventPost(kCGHIDEventTap, e); + CFRelease(e); + return Qt::Native::Success; +} + +Qt::Native::Status sendNativeMouseButtonEvent_Quartz(const QNativeMouseButtonEvent &event) +{ + CGPoint pos; + pos.x = event.globalPos.x(); + pos.y = event.globalPos.y(); + + CGEventType type = 0; + if (event.button == Qt::LeftButton) + type = (event.clickCount > 0) ? kCGEventLeftMouseDown : kCGEventLeftMouseUp; + else if (event.button == Qt::RightButton) + type = (event.clickCount > 0) ? kCGEventRightMouseDown : kCGEventRightMouseUp; + else + type = (event.clickCount > 0) ? kCGEventOtherMouseDown : kCGEventOtherMouseUp; + + CGEventRef e = CGEventCreateMouseEvent(0, type, pos, event.button); + setModifiersFromQNativeEvent(e, event); + CGEventSetIntegerValueField(e, kCGMouseEventClickState, event.clickCount); + CGEventPost(kCGHIDEventTap, e); + CFRelease(e); + return Qt::Native::Success; +} + +Qt::Native::Status sendNativeMouseDragEvent_Quartz(const QNativeMouseDragEvent &event) +{ + CGPoint pos; + pos.x = event.globalPos.x(); + pos.y = event.globalPos.y(); + + CGEventType type = 0; + if (event.button == Qt::LeftButton) + type = kCGEventLeftMouseDragged; + else if (event.button == Qt::RightButton) + type = kCGEventRightMouseDragged; + else + type = kCGEventOtherMouseDragged; + + CGEventRef e = CGEventCreateMouseEvent(0, type, pos, event.button); + setModifiersFromQNativeEvent(e, event); + CGEventPost(kCGHIDEventTap, e); + CFRelease(e); + return Qt::Native::Success; +} + +Qt::Native::Status sendNativeMouseWheelEvent_Quartz(const QNativeMouseWheelEvent &event) +{ + CGPoint pos; + pos.x = event.globalPos.x(); + pos.y = event.globalPos.y(); + + CGEventRef e = CGEventCreateScrollWheelEvent(0, kCGScrollEventUnitPixel, 1, 0); + CGEventSetIntegerValueField(e, kCGScrollWheelEventDeltaAxis1, event.delta); + CGEventSetLocation(e, pos); + setModifiersFromQNativeEvent(e, event); + CGEventPost(kCGHIDEventTap, e); + CFRelease(e); + + return Qt::Native::Success; +} + +Qt::Native::Status sendNativeModifierEvent_Quartz(const QNativeModifierEvent &event) +{ + CGEventRef e = CGEventCreateKeyboardEvent(0, (uint)event.nativeKeyCode, 0); + CGEventSetType(e, kCGEventFlagsChanged); + setModifiersFromQNativeEvent(e, event); + CGEventPost(kCGHIDEventTap, e); + CFRelease(e); + return Qt::Native::Success; +} + +// ************************************************************ +// QNativeInput methods: +// ************************************************************ + +Qt::Native::Status QNativeInput::sendNativeMouseButtonEvent(const QNativeMouseButtonEvent &event) +{ + return sendNativeMouseButtonEvent_Quartz(event); +} + +Qt::Native::Status QNativeInput::sendNativeMouseMoveEvent(const QNativeMouseMoveEvent &event) +{ + return sendNativeMouseMoveEvent_Quartz(event); +} + +Qt::Native::Status QNativeInput::sendNativeMouseDragEvent(const QNativeMouseDragEvent &event) +{ + return sendNativeMouseDragEvent_Quartz(event); +} + +Qt::Native::Status QNativeInput::sendNativeMouseWheelEvent(const QNativeMouseWheelEvent &event) +{ + return sendNativeMouseWheelEvent_Quartz(event); +} + +Qt::Native::Status QNativeInput::sendNativeKeyEvent(const QNativeKeyEvent &event, int pid) +{ + if (!pid) + return sendNativeKeyEvent_Quartz(event); + else + return sendNativeKeyEventToProcess_Quartz(event, pid); +} + +Qt::Native::Status QNativeInput::sendNativeModifierEvent(const QNativeModifierEvent &event) +{ + return sendNativeModifierEvent_Quartz(event); +} + +Qt::Native::Status QNativeInput::subscribeForNativeEvents() +{ + return insertEventHandler_Quartz(this); +} + +Qt::Native::Status QNativeInput::unsubscribeForNativeEvents() +{ + return removeEventHandler_Quartz(); +} + +// Some Qt to Mac mappings: +int QNativeKeyEvent::Key_A = 0; +int QNativeKeyEvent::Key_B = 11; +int QNativeKeyEvent::Key_C = 8; +int QNativeKeyEvent::Key_1 = 18; +int QNativeKeyEvent::Key_Backspace = 51; +int QNativeKeyEvent::Key_Enter = 36; +int QNativeKeyEvent::Key_Del = 117; + diff --git a/tests/auto/macnativeevents/qnativeinput.cpp b/tests/auto/macnativeevents/qnativeinput.cpp deleted file mode 100644 index c9462a6..0000000 --- a/tests/auto/macnativeevents/qnativeinput.cpp +++ /dev/null @@ -1,378 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qnativeinput.h" - -QNativeInput::QNativeInput(bool subscribe) -{ - if (subscribe) - subscribeForNativeEvents(); -} - -QNativeInput::~QNativeInput() -{ - unsubscribeForNativeEvents(); -} - -void QNativeInput::notify(QNativeEvent *event) -{ - nativeEvent(event); -} - -void QNativeInput::nativeEvent(QNativeEvent *event) -{ - switch (event->id()){ - case QNativeMouseButtonEvent::eventId:{ - QNativeMouseButtonEvent *e = static_cast(event); - (e->clickCount > 0) ? nativeMousePressEvent(e) : nativeMouseReleaseEvent(e); - break; } - case QNativeMouseMoveEvent::eventId: - nativeMouseMoveEvent(static_cast(event)); - break; - case QNativeMouseDragEvent::eventId: - nativeMouseDragEvent(static_cast(event)); - break; - case QNativeMouseWheelEvent::eventId: - nativeMouseWheelEvent(static_cast(event)); - break; - case QNativeKeyEvent::eventId:{ - QNativeKeyEvent *e = static_cast(event); - e->press ? nativeKeyPressEvent(e) : nativeKeyReleaseEvent(e); - break; } - case QNativeModifierEvent::eventId: - nativeModifierEvent(static_cast(event)); - break; - default: - break; - } -} - -Qt::Native::Status QNativeInput::sendNativeEvent(const QNativeEvent &event, int pid) -{ - switch (event.id()){ - case QNativeMouseMoveEvent::eventId: - return sendNativeMouseMoveEvent(static_cast(event)); - case QNativeMouseButtonEvent::eventId: - return sendNativeMouseButtonEvent(static_cast(event)); - case QNativeMouseDragEvent::eventId: - return sendNativeMouseDragEvent(static_cast(event)); - case QNativeMouseWheelEvent::eventId: - return sendNativeMouseWheelEvent(static_cast(event)); - case QNativeKeyEvent::eventId: - return sendNativeKeyEvent(static_cast(event), pid); - case QNativeModifierEvent::eventId: - return sendNativeModifierEvent(static_cast(event)); - case QNativeEvent::eventId: - qWarning() << "Warning: Cannot send a pure native event. Use a sub class."; - default: - return Qt::Native::Failure; - } -} - -QNativeEvent::QNativeEvent(Qt::KeyboardModifiers modifiers) - : modifiers(modifiers){} - -QNativeMouseEvent::QNativeMouseEvent(QPoint pos, Qt::KeyboardModifiers modifiers) - : QNativeEvent(modifiers), globalPos(pos){} - -QNativeMouseMoveEvent::QNativeMouseMoveEvent(QPoint pos, Qt::KeyboardModifiers modifiers) - : QNativeMouseEvent(pos, modifiers){} - -QNativeMouseButtonEvent::QNativeMouseButtonEvent(QPoint globalPos, Qt::MouseButton button, int clickCount, Qt::KeyboardModifiers modifiers) - : QNativeMouseEvent(globalPos, modifiers), button(button), clickCount(clickCount){} - -QNativeMouseDragEvent::QNativeMouseDragEvent(QPoint globalPos, Qt::MouseButton button, Qt::KeyboardModifiers modifiers) - : QNativeMouseButtonEvent(globalPos, button, true, modifiers){} - -QNativeMouseWheelEvent::QNativeMouseWheelEvent(QPoint globalPos, int delta, Qt::KeyboardModifiers modifiers) - : QNativeMouseEvent(globalPos, modifiers), delta(delta){} - -QNativeKeyEvent::QNativeKeyEvent(int nativeKeyCode, bool press, Qt::KeyboardModifiers modifiers) - : QNativeEvent(modifiers), nativeKeyCode(nativeKeyCode), press(press), character(QChar()){} - -QNativeModifierEvent::QNativeModifierEvent(Qt::KeyboardModifiers modifiers, int nativeKeyCode) - : QNativeEvent(modifiers), nativeKeyCode(nativeKeyCode){} - -QNativeKeyEvent::QNativeKeyEvent(int nativeKeyCode, bool press, QChar character, Qt::KeyboardModifiers modifiers) - : QNativeEvent(modifiers), nativeKeyCode(nativeKeyCode), press(press), character(character){} - -static QString getButtonAsString(const QNativeMouseButtonEvent *e) -{ - switch (e->button){ - case Qt::LeftButton: - return "button = LeftButton"; - break; - case Qt::RightButton: - return "button = RightButton"; - break; - case Qt::MidButton: - return "button = MidButton"; - break; - default: - return "button = Other"; - break; - } -} - -static QString getModifiersAsString(const QNativeEvent *e) -{ - if (e->modifiers == 0) - return "modifiers = none"; - - QString tmp = "modifiers = "; - if (e->modifiers.testFlag(Qt::ShiftModifier)) - tmp += "Shift"; - if (e->modifiers.testFlag(Qt::ControlModifier)) - tmp += "Control"; - if (e->modifiers.testFlag(Qt::AltModifier)) - tmp += "Alt"; - if (e->modifiers.testFlag(Qt::MetaModifier)) - tmp += "Meta"; - return tmp; -} - -static QString getPosAsString(QPoint pos) -{ - return QString("QPoint(%1, %2)").arg(pos.x()).arg(pos.y()); -} - -static QString getBoolAsString(bool b) -{ - return b ? QString("true") : QString("false"); -} - -QString QNativeMouseMoveEvent::toString() const -{ - return QString("QNativeMouseMoveEvent(globalPos = %1 %2)").arg(getPosAsString(globalPos)) - .arg(getModifiersAsString(this)); -} - -QString QNativeMouseButtonEvent::toString() const -{ - return QString("QNativeMouseButtonEvent(globalPos = %1, %2, clickCount = %3, %4)").arg(getPosAsString(globalPos)) - .arg(getButtonAsString(this)).arg(clickCount).arg(getModifiersAsString(this)); -} - -QString QNativeMouseDragEvent::toString() const -{ - return QString("QNativeMouseDragEvent(globalPos = %1, %2, clickCount = %3, %4)").arg(getPosAsString(globalPos)) - .arg(getButtonAsString(this)).arg(clickCount).arg(getModifiersAsString(this)); -} - -QString QNativeMouseWheelEvent::toString() const -{ - return QString("QNativeMouseWheelEvent(globalPos = %1, delta = %2, %3)").arg(getPosAsString(globalPos)) - .arg(delta).arg(getModifiersAsString(this)); -} - -QString QNativeKeyEvent::toString() const -{ - return QString("QNativeKeyEvent(press = %1, native key code = %2, character = %3, %4)").arg(getBoolAsString(press)) - .arg(nativeKeyCode).arg(character.isPrint() ? character : QString("")) - .arg(getModifiersAsString(this)); -} - -QString QNativeModifierEvent::toString() const -{ - return QString("QNativeModifierEvent(%1, native key code = %2)").arg(getModifiersAsString(this)) - .arg(nativeKeyCode); -} - -QDebug operator<<(QDebug d, QNativeEvent *e) -{ - Q_UNUSED(e); - return d << e->toString(); -} - -QDebug operator<<(QDebug d, const QNativeEvent &e) -{ - Q_UNUSED(e); - return d << e.toString(); -} - -QTextStream &operator<<(QTextStream &s, QNativeEvent *e) -{ - return s << e->eventId << " " << e->modifiers << " QNativeEvent"; -} - -QTextStream &operator<<(QTextStream &s, QNativeMouseEvent *e) -{ - return s << e->eventId << " " << e->globalPos.x() << " " << e->globalPos.y() << " " << e->modifiers << " " << e->toString(); -} - -QTextStream &operator<<(QTextStream &s, QNativeMouseMoveEvent *e) -{ - return s << e->eventId << " " << e->globalPos.x() << " " << e->globalPos.y() << " " << e->modifiers << " " << e->toString(); -} - -QTextStream &operator<<(QTextStream &s, QNativeMouseButtonEvent *e) -{ - return s << e->eventId << " " << e->globalPos.x() << " " << e->globalPos.y() << " " << e->button - << " " << e->clickCount << " " << e->modifiers << " " << e->toString(); -} - -QTextStream &operator<<(QTextStream &s, QNativeMouseDragEvent *e) -{ - return s << e->eventId << " " << e->globalPos.x() << " " << e->globalPos.y() << " " << e->button << " " << e->clickCount - << " " << e->modifiers << " " << e->toString(); -} - -QTextStream &operator<<(QTextStream &s, QNativeMouseWheelEvent *e) -{ - return s << e->eventId << " " << e->globalPos.x() << " " << e->globalPos.y() << " " << e->delta - << " " << e->modifiers << " " << e->toString(); -} - -QTextStream &operator<<(QTextStream &s, QNativeKeyEvent *e) -{ - return s << e->eventId << " " << e->press << " " << e->nativeKeyCode << " " << e->character - << " " << e->modifiers << " " << e->toString(); -} - -QTextStream &operator<<(QTextStream &s, QNativeModifierEvent *e) -{ - return s << e->eventId << " " << e->modifiers << " " << e->nativeKeyCode << " " << e->toString(); -} - - - - -QTextStream &operator>>(QTextStream &s, QNativeMouseMoveEvent *e) -{ - // Skip reading eventId. - QString humanReadable; - int x, y, modifiers; - s >> x >> y >> modifiers >> humanReadable; - e->globalPos.setX(x); - e->globalPos.setY(y); - e->modifiers = Qt::KeyboardModifiers(modifiers); - return s; -} - -QTextStream &operator>>(QTextStream &s, QNativeMouseButtonEvent *e) -{ - // Skip reading eventId. - QString humanReadable; - int x, y, button, clickCount, modifiers; - s >> x >> y >> button >> clickCount >> modifiers >> humanReadable; - e->globalPos.setX(x); - e->globalPos.setY(y); - e->clickCount = clickCount; - e->modifiers = Qt::KeyboardModifiers(modifiers); - switch (button){ - case 1: - e->button = Qt::LeftButton; - break; - case 2: - e->button = Qt::RightButton; - break; - case 3: - e->button = Qt::MidButton; - break; - default: - e->button = Qt::NoButton; - break; - } - return s; -} - -QTextStream &operator>>(QTextStream &s, QNativeMouseDragEvent *e) -{ - // Skip reading eventId. - QString humanReadable; - int x, y, button, clickCount, modifiers; - s >> x >> y >> button >> clickCount >> modifiers >> humanReadable; - e->globalPos.setX(x); - e->globalPos.setY(y); - e->clickCount = clickCount; - e->modifiers = Qt::KeyboardModifiers(modifiers); - switch (button){ - case 1: - e->button = Qt::LeftButton; - break; - case 2: - e->button = Qt::RightButton; - break; - case 3: - e->button = Qt::MidButton; - break; - default: - e->button = Qt::NoButton; - break; - } - return s; -} - -QTextStream &operator>>(QTextStream &s, QNativeMouseWheelEvent *e) -{ - // Skip reading eventId. - QString humanReadable; - int x, y, modifiers; - s >> x >> y >> e->delta >> modifiers >> humanReadable; - e->globalPos.setX(x); - e->globalPos.setY(y); - e->modifiers = Qt::KeyboardModifiers(modifiers); - return s; -} - -QTextStream &operator>>(QTextStream &s, QNativeKeyEvent *e) -{ - // Skip reading eventId. - QString humanReadable; - int press, modifiers; - QString character; - s >> press >> e->nativeKeyCode >> character >> modifiers >> humanReadable; - e->press = bool(press); - e->character = character[0]; - e->modifiers = Qt::KeyboardModifiers(modifiers); - return s; -} - -QTextStream &operator>>(QTextStream &s, QNativeModifierEvent *e) -{ - // Skip reading eventId. - QString humanReadable; - int modifiers; - s >> modifiers >> e->nativeKeyCode >> humanReadable; - e->modifiers = Qt::KeyboardModifiers(modifiers); - return s; -} - diff --git a/tests/auto/macnativeevents/qnativeinput.h b/tests/auto/macnativeevents/qnativeinput.h deleted file mode 100644 index a98e4e4..0000000 --- a/tests/auto/macnativeevents/qnativeinput.h +++ /dev/null @@ -1,228 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef Q_NATIVE_INPUT -#define Q_NATIVE_INPUT - -#include - -namespace Qt { -namespace Native { - enum Status {Success, Failure}; -}} - -// ---------------------------------------------------------------------------- -// Declare a set of native events that can be used to communicate with -// client applications in an platform independent way -// ---------------------------------------------------------------------------- - -class QNativeEvent -{ -public: - static const int eventId = 1; - - QNativeEvent(Qt::KeyboardModifiers modifiers = Qt::NoModifier); - virtual ~QNativeEvent(){}; - virtual int id() const { return eventId; }; - virtual QString toString() const = 0; - Qt::KeyboardModifiers modifiers; // Yields for mouse events too. -}; - -class QNativeMouseEvent : public QNativeEvent { -public: - static const int eventId = 2; - - QNativeMouseEvent(){}; - QNativeMouseEvent(QPoint globalPos, Qt::KeyboardModifiers modifiers = Qt::NoModifier); - virtual ~QNativeMouseEvent(){}; - virtual int id() const { return eventId; }; - - QPoint globalPos; -}; - -class QNativeMouseMoveEvent : public QNativeMouseEvent { -public: - static const int eventId = 4; - - QNativeMouseMoveEvent(){}; - QNativeMouseMoveEvent(QPoint globalPos, Qt::KeyboardModifiers modifiers = Qt::NoModifier); - virtual ~QNativeMouseMoveEvent(){}; - virtual int id() const { return eventId; }; - virtual QString toString() const; -}; - -class QNativeMouseButtonEvent : public QNativeMouseEvent { -public: - static const int eventId = 8; - - QNativeMouseButtonEvent(){}; - QNativeMouseButtonEvent(QPoint globalPos, Qt::MouseButton button, int clickCount, Qt::KeyboardModifiers modifiers = Qt::NoModifier); - virtual ~QNativeMouseButtonEvent(){}; - virtual int id() const { return eventId; }; - virtual QString toString() const; - - Qt::MouseButton button; - int clickCount; -}; - -class QNativeMouseDragEvent : public QNativeMouseButtonEvent { -public: - static const int eventId = 16; - - QNativeMouseDragEvent(){}; - QNativeMouseDragEvent(QPoint globalPos, Qt::MouseButton button, Qt::KeyboardModifiers modifiers = Qt::NoModifier); - virtual ~QNativeMouseDragEvent(){}; - virtual int id() const { return eventId; }; - virtual QString toString() const; -}; - -class QNativeMouseWheelEvent : public QNativeMouseEvent { -public: - static const int eventId = 32; - - QNativeMouseWheelEvent(){}; - QNativeMouseWheelEvent(QPoint globalPos, int delta, Qt::KeyboardModifiers modifiers = Qt::NoModifier); - virtual ~QNativeMouseWheelEvent(){}; - virtual int id() const { return eventId; }; - virtual QString toString() const; - - int delta; -}; - -class QNativeKeyEvent : public QNativeEvent { - public: - static const int eventId = 64; - - QNativeKeyEvent(){}; - QNativeKeyEvent(int nativeKeyCode, bool press, Qt::KeyboardModifiers modifiers = Qt::NoModifier); - QNativeKeyEvent(int nativeKeyCode, bool press, QChar character, Qt::KeyboardModifiers modifiers); - virtual ~QNativeKeyEvent(){}; - virtual int id() const { return eventId; }; - virtual QString toString() const; - - int nativeKeyCode; - bool press; - QChar character; - - // Some Qt to Native mappings: - static int Key_A; - static int Key_B; - static int Key_C; - static int Key_1; - static int Key_Backspace; - static int Key_Enter; - static int Key_Del; -}; - -class QNativeModifierEvent : public QNativeEvent { -public: - static const int eventId = 128; - - QNativeModifierEvent(Qt::KeyboardModifiers modifiers = Qt::NoModifier, int nativeKeyCode = 0); - virtual ~QNativeModifierEvent(){}; - virtual int id() const { return eventId; }; - virtual QString toString() const; - - int nativeKeyCode; -}; - -// ---------------------------------------------------------------------------- -// Declare a set of related output / input functions for convenience: -// ---------------------------------------------------------------------------- - -QDebug operator<<(QDebug d, QNativeEvent *e); -QDebug operator<<(QDebug d, const QNativeEvent &e); - -QTextStream &operator<<(QTextStream &s, QNativeEvent *e); -QTextStream &operator<<(QTextStream &s, QNativeMouseEvent *e); -QTextStream &operator<<(QTextStream &s, QNativeMouseMoveEvent *e); -QTextStream &operator<<(QTextStream &s, QNativeMouseButtonEvent *e); -QTextStream &operator<<(QTextStream &s, QNativeMouseDragEvent *e); -QTextStream &operator<<(QTextStream &s, QNativeMouseWheelEvent *e); -QTextStream &operator<<(QTextStream &s, QNativeKeyEvent *e); -QTextStream &operator<<(QTextStream &s, QNativeModifierEvent *e); - -QTextStream &operator>>(QTextStream &s, QNativeMouseMoveEvent *e); -QTextStream &operator>>(QTextStream &s, QNativeMouseButtonEvent *e); -QTextStream &operator>>(QTextStream &s, QNativeMouseDragEvent *e); -QTextStream &operator>>(QTextStream &s, QNativeMouseWheelEvent *e); -QTextStream &operator>>(QTextStream &s, QNativeKeyEvent *e); -QTextStream &operator>>(QTextStream &s, QNativeModifierEvent *e); - -// ---------------------------------------------------------------------------- -// Declare the main class that is supposed to be sub-classed by components -// that are to receive native events -// ---------------------------------------------------------------------------- - -class QNativeInput -{ - public: - QNativeInput(bool subscribe = true); - virtual ~QNativeInput(); - - // Callback methods. Should be implemented by interested sub-classes: - void notify(QNativeEvent *event); - virtual void nativeEvent(QNativeEvent *event); - virtual void nativeMousePressEvent(QNativeMouseButtonEvent *){}; - virtual void nativeMouseReleaseEvent(QNativeMouseButtonEvent *){}; - virtual void nativeMouseMoveEvent(QNativeMouseMoveEvent *){}; - virtual void nativeMouseDragEvent(QNativeMouseDragEvent *){}; - virtual void nativeMouseWheelEvent(QNativeMouseWheelEvent *){}; - virtual void nativeKeyPressEvent(QNativeKeyEvent *){}; - virtual void nativeKeyReleaseEvent(QNativeKeyEvent *){}; - virtual void nativeModifierEvent(QNativeModifierEvent *){}; - - // The following methods will differ in implementation from OS to OS: - static Qt::Native::Status sendNativeMouseButtonEvent(const QNativeMouseButtonEvent &event); - static Qt::Native::Status sendNativeMouseMoveEvent(const QNativeMouseMoveEvent &event); - static Qt::Native::Status sendNativeMouseDragEvent(const QNativeMouseDragEvent &event); - static Qt::Native::Status sendNativeMouseWheelEvent(const QNativeMouseWheelEvent &event); - static Qt::Native::Status sendNativeKeyEvent(const QNativeKeyEvent &event, int pid = 0); - static Qt::Native::Status sendNativeModifierEvent(const QNativeModifierEvent &event); - // sendNativeEvent will NOT differ from OS to OS. - static Qt::Native::Status sendNativeEvent(const QNativeEvent &event, int pid = 0); - - // The following methods will differ in implementation from OS to OS: - Qt::Native::Status subscribeForNativeEvents(); - Qt::Native::Status unsubscribeForNativeEvents(); -}; - -#endif // Q_NATIVE_INPUT diff --git a/tests/auto/macnativeevents/qnativeinput_mac.cpp b/tests/auto/macnativeevents/qnativeinput_mac.cpp deleted file mode 100644 index 143a633..0000000 --- a/tests/auto/macnativeevents/qnativeinput_mac.cpp +++ /dev/null @@ -1,382 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qnativeinput.h" -#include -#include - -// ************************************************************ -// Quartz -// ************************************************************ - -static Qt::KeyboardModifiers getModifiersFromQuartzEvent(CGEventRef inEvent) -{ - Qt::KeyboardModifiers m; - CGEventFlags flags = CGEventGetFlags(inEvent); - if (flags & kCGEventFlagMaskShift || flags & kCGEventFlagMaskAlphaShift) - m |= Qt::ShiftModifier; - if (flags & kCGEventFlagMaskControl) - m |= Qt::MetaModifier; - if (flags & kCGEventFlagMaskAlternate) - m |= Qt::AltModifier; - if (flags & kCGEventFlagMaskCommand) - m |= Qt::ControlModifier; - return m; -} - -static void setModifiersFromQNativeEvent(CGEventRef inEvent, const QNativeEvent &event) -{ - CGEventFlags flags = 0; - if (event.modifiers.testFlag(Qt::ShiftModifier)) - flags |= kCGEventFlagMaskShift; - if (event.modifiers.testFlag(Qt::MetaModifier)) - flags |= kCGEventFlagMaskControl; - if (event.modifiers.testFlag(Qt::AltModifier)) - flags |= kCGEventFlagMaskAlternate; - if (event.modifiers.testFlag(Qt::ControlModifier)) - flags |= kCGEventFlagMaskCommand; - CGEventSetFlags(inEvent, flags); -} - -static QPoint getMouseLocationFromQuartzEvent(CGEventRef inEvent) -{ - CGPoint pos = CGEventGetLocation(inEvent); - QPoint tmp; - tmp.setX(pos.x); - tmp.setY(pos.y); - return tmp; -} - -static QChar getCharFromQuartzEvent(CGEventRef inEvent) -{ - UniCharCount count = 0; - UniChar c; - CGEventKeyboardGetUnicodeString(inEvent, 1, &count, &c); - return QChar(c); -} - -static CGEventRef EventHandler_Quartz(CGEventTapProxy proxy, CGEventType type, CGEventRef inEvent, void *refCon) -{ - Q_UNUSED(proxy); - QNativeInput *nativeInput = static_cast(refCon); - switch (type){ - case kCGEventKeyDown:{ - QNativeKeyEvent e; - e.modifiers = getModifiersFromQuartzEvent(inEvent); - e.nativeKeyCode = CGEventGetIntegerValueField(inEvent, kCGKeyboardEventKeycode); - e.character = getCharFromQuartzEvent(inEvent); - e.press = true; - nativeInput->notify(&e); - break; - } - case kCGEventKeyUp:{ - QNativeKeyEvent e; - e.modifiers = getModifiersFromQuartzEvent(inEvent); - e.nativeKeyCode = CGEventGetIntegerValueField(inEvent, kCGKeyboardEventKeycode); - e.character = getCharFromQuartzEvent(inEvent); - e.press = false; - nativeInput->notify(&e); - break; - } - case kCGEventLeftMouseDown:{ - QNativeMouseButtonEvent e; - e.modifiers = getModifiersFromQuartzEvent(inEvent); - e.globalPos = getMouseLocationFromQuartzEvent(inEvent); - e.clickCount = CGEventGetIntegerValueField(inEvent, kCGMouseEventClickState); - e.button = Qt::LeftButton; - nativeInput->notify(&e); - break; - } - case kCGEventLeftMouseUp:{ - QNativeMouseButtonEvent e; - e.modifiers = getModifiersFromQuartzEvent(inEvent); - e.globalPos = getMouseLocationFromQuartzEvent(inEvent); - e.clickCount = 0; - e.button = Qt::LeftButton; - nativeInput->notify(&e); - break; - } - case kCGEventRightMouseDown:{ - QNativeMouseButtonEvent e; - e.modifiers = getModifiersFromQuartzEvent(inEvent); - e.globalPos = getMouseLocationFromQuartzEvent(inEvent); - e.clickCount = CGEventGetIntegerValueField(inEvent, kCGMouseEventClickState); - e.button = Qt::RightButton; - nativeInput->notify(&e); - break; - } - case kCGEventRightMouseUp:{ - QNativeMouseButtonEvent e; - e.modifiers = getModifiersFromQuartzEvent(inEvent); - e.globalPos = getMouseLocationFromQuartzEvent(inEvent); - e.clickCount = 0; - e.button = Qt::RightButton; - nativeInput->notify(&e); - break; - } - case kCGEventMouseMoved:{ - QNativeMouseMoveEvent e; - e.modifiers = getModifiersFromQuartzEvent(inEvent); - e.globalPos = getMouseLocationFromQuartzEvent(inEvent); - nativeInput->notify(&e); - break; - } - case kCGEventLeftMouseDragged:{ - QNativeMouseDragEvent e; - e.modifiers = getModifiersFromQuartzEvent(inEvent); - e.globalPos = getMouseLocationFromQuartzEvent(inEvent); - e.clickCount = CGEventGetIntegerValueField(inEvent, kCGMouseEventClickState); - e.button = Qt::LeftButton; - nativeInput->notify(&e); - break; - } - case kCGEventScrollWheel:{ - QNativeMouseWheelEvent e; - e.modifiers = getModifiersFromQuartzEvent(inEvent); - e.delta = CGEventGetIntegerValueField(inEvent, kCGScrollWheelEventDeltaAxis1); - e.globalPos = getMouseLocationFromQuartzEvent(inEvent); - nativeInput->notify(&e); - break; - } - case kCGEventFlagsChanged:{ - QNativeModifierEvent e; - e.modifiers = getModifiersFromQuartzEvent(inEvent); - e.nativeKeyCode = CGEventGetIntegerValueField(inEvent, kCGKeyboardEventKeycode); - nativeInput->notify(&e); - break; - } - - } - - return inEvent; -} - -Qt::Native::Status insertEventHandler_Quartz(QNativeInput *nativeInput, int pid = 0) -{ - uid_t uid = geteuid(); - if (uid != 0) - qWarning("MacNativeEvents: You must be root to listen for key events!"); - - CFMachPortRef port; - if (!pid){ - port = CGEventTapCreate(kCGHIDEventTap, - kCGHeadInsertEventTap, kCGEventTapOptionListenOnly, - kCGEventMaskForAllEvents, EventHandler_Quartz, nativeInput); - } else { - ProcessSerialNumber psn; - GetProcessForPID(pid, &psn); - port = CGEventTapCreateForPSN(&psn, - kCGHeadInsertEventTap, kCGEventTapOptionListenOnly, - kCGEventMaskForAllEvents, EventHandler_Quartz, nativeInput); - } - - CFRunLoopSourceRef eventSrc = CFMachPortCreateRunLoopSource(NULL, port, 0); - CFRunLoopAddSource((CFRunLoopRef) GetCFRunLoopFromEventLoop(GetMainEventLoop()), - eventSrc, kCFRunLoopCommonModes); - - return Qt::Native::Success; -} - -Qt::Native::Status removeEventHandler_Quartz() -{ - return Qt::Native::Success; // ToDo: -} - -Qt::Native::Status sendNativeKeyEventToProcess_Quartz(const QNativeKeyEvent &event, int pid) -{ - ProcessSerialNumber psn; - GetProcessForPID(pid, &psn); - - CGEventRef e = CGEventCreateKeyboardEvent(0, (uint)event.nativeKeyCode, event.press); - setModifiersFromQNativeEvent(e, event); - SetFrontProcess(&psn); - CGEventPostToPSN(&psn, e); - CFRelease(e); - return Qt::Native::Success; -} - -Qt::Native::Status sendNativeKeyEvent_Quartz(const QNativeKeyEvent &event) -{ - CGEventRef e = CGEventCreateKeyboardEvent(0, (uint)event.nativeKeyCode, event.press); - setModifiersFromQNativeEvent(e, event); - CGEventPost(kCGHIDEventTap, e); - CFRelease(e); - return Qt::Native::Success; -} - -Qt::Native::Status sendNativeMouseMoveEvent_Quartz(const QNativeMouseMoveEvent &event) -{ - CGPoint pos; - pos.x = event.globalPos.x(); - pos.y = event.globalPos.y(); - - CGEventRef e = CGEventCreateMouseEvent(0, kCGEventMouseMoved, pos, 0); - setModifiersFromQNativeEvent(e, event); - CGEventPost(kCGHIDEventTap, e); - CFRelease(e); - return Qt::Native::Success; -} - -Qt::Native::Status sendNativeMouseButtonEvent_Quartz(const QNativeMouseButtonEvent &event) -{ - CGPoint pos; - pos.x = event.globalPos.x(); - pos.y = event.globalPos.y(); - - CGEventType type = 0; - if (event.button == Qt::LeftButton) - type = (event.clickCount > 0) ? kCGEventLeftMouseDown : kCGEventLeftMouseUp; - else if (event.button == Qt::RightButton) - type = (event.clickCount > 0) ? kCGEventRightMouseDown : kCGEventRightMouseUp; - else - type = (event.clickCount > 0) ? kCGEventOtherMouseDown : kCGEventOtherMouseUp; - - CGEventRef e = CGEventCreateMouseEvent(0, type, pos, event.button); - setModifiersFromQNativeEvent(e, event); - CGEventSetIntegerValueField(e, kCGMouseEventClickState, event.clickCount); - CGEventPost(kCGHIDEventTap, e); - CFRelease(e); - return Qt::Native::Success; -} - -Qt::Native::Status sendNativeMouseDragEvent_Quartz(const QNativeMouseDragEvent &event) -{ - CGPoint pos; - pos.x = event.globalPos.x(); - pos.y = event.globalPos.y(); - - CGEventType type = 0; - if (event.button == Qt::LeftButton) - type = kCGEventLeftMouseDragged; - else if (event.button == Qt::RightButton) - type = kCGEventRightMouseDragged; - else - type = kCGEventOtherMouseDragged; - - CGEventRef e = CGEventCreateMouseEvent(0, type, pos, event.button); - setModifiersFromQNativeEvent(e, event); - CGEventPost(kCGHIDEventTap, e); - CFRelease(e); - return Qt::Native::Success; -} - -Qt::Native::Status sendNativeMouseWheelEvent_Quartz(const QNativeMouseWheelEvent &event) -{ - CGPoint pos; - pos.x = event.globalPos.x(); - pos.y = event.globalPos.y(); - - CGEventRef e = CGEventCreateScrollWheelEvent(0, kCGScrollEventUnitPixel, 1, 0); - CGEventSetIntegerValueField(e, kCGScrollWheelEventDeltaAxis1, event.delta); - CGEventSetLocation(e, pos); - setModifiersFromQNativeEvent(e, event); - CGEventPost(kCGHIDEventTap, e); - CFRelease(e); - - return Qt::Native::Success; -} - -Qt::Native::Status sendNativeModifierEvent_Quartz(const QNativeModifierEvent &event) -{ - CGEventRef e = CGEventCreateKeyboardEvent(0, (uint)event.nativeKeyCode, 0); - CGEventSetType(e, kCGEventFlagsChanged); - setModifiersFromQNativeEvent(e, event); - CGEventPost(kCGHIDEventTap, e); - CFRelease(e); - return Qt::Native::Success; -} - -// ************************************************************ -// QNativeInput methods: -// ************************************************************ - -Qt::Native::Status QNativeInput::sendNativeMouseButtonEvent(const QNativeMouseButtonEvent &event) -{ - return sendNativeMouseButtonEvent_Quartz(event); -} - -Qt::Native::Status QNativeInput::sendNativeMouseMoveEvent(const QNativeMouseMoveEvent &event) -{ - return sendNativeMouseMoveEvent_Quartz(event); -} - -Qt::Native::Status QNativeInput::sendNativeMouseDragEvent(const QNativeMouseDragEvent &event) -{ - return sendNativeMouseDragEvent_Quartz(event); -} - -Qt::Native::Status QNativeInput::sendNativeMouseWheelEvent(const QNativeMouseWheelEvent &event) -{ - return sendNativeMouseWheelEvent_Quartz(event); -} - -Qt::Native::Status QNativeInput::sendNativeKeyEvent(const QNativeKeyEvent &event, int pid) -{ - if (!pid) - return sendNativeKeyEvent_Quartz(event); - else - return sendNativeKeyEventToProcess_Quartz(event, pid); -} - -Qt::Native::Status QNativeInput::sendNativeModifierEvent(const QNativeModifierEvent &event) -{ - return sendNativeModifierEvent_Quartz(event); -} - -Qt::Native::Status QNativeInput::subscribeForNativeEvents() -{ - return insertEventHandler_Quartz(this); -} - -Qt::Native::Status QNativeInput::unsubscribeForNativeEvents() -{ - return removeEventHandler_Quartz(); -} - -// Some Qt to Mac mappings: -int QNativeKeyEvent::Key_A = 0; -int QNativeKeyEvent::Key_B = 11; -int QNativeKeyEvent::Key_C = 8; -int QNativeKeyEvent::Key_1 = 18; -int QNativeKeyEvent::Key_Backspace = 51; -int QNativeKeyEvent::Key_Enter = 36; -int QNativeKeyEvent::Key_Del = 117; - diff --git a/tests/auto/macnativeevents/qnativeplayer.cpp b/tests/auto/macnativeevents/qnativeplayer.cpp deleted file mode 100644 index 92298ef..0000000 --- a/tests/auto/macnativeevents/qnativeplayer.cpp +++ /dev/null @@ -1,139 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qnativeplayer.h" - -QNativePlayer::QNativePlayer() -{ - currIndex = -1; - playbackMultiplier = 1.0; - wait = false; -} - -QNativePlayer::~QNativePlayer() -{ - for (int i=0; i= eventList.size()){ - emit done(); - stop(); - return; - } - - int interval = eventList.at(currIndex).first; - QTimer::singleShot(interval * playbackMultiplier, this, SLOT(sendNextEvent())); -} - -void QNativePlayer::append(int waitMs, QNativeEvent *event) -{ - eventList.append(QPair(waitMs, event)); -} - -void QNativePlayer::play(Playback playback) -{ - waitNextEvent(); - - wait = (playback == WaitUntilFinished); - while (wait) - QCoreApplication::processEvents(QEventLoop::WaitForMoreEvents); -} - -void QNativePlayer::stop() -{ - wait = false; - QAbstractEventDispatcher::instance()->interrupt(); -} - -// ************************************************************************ - -QEventOutputList::QEventOutputList() -{ - wait = true; -} - -QEventOutputList::~QEventOutputList() -{ - qDeleteAll(*this); -} - -bool QEventOutputList::waitUntilEmpty(int maxEventWaitTime) -{ - int currSize = size(); - QTime time; - time.restart(); - while (wait){ - QCoreApplication::processEvents(QEventLoop::AllEvents, 50); - - if (isEmpty()){ - return true; - } - else if (currSize == size()){ - if (time.elapsed() > maxEventWaitTime){ - return false; - } - } - else{ - currSize = size(); - time.restart(); - } - } - return false; -} - -void QEventOutputList::sleep(int sleepTime) -{ - QTime time; - time.restart(); - while (time.elapsed() < sleepTime) - QCoreApplication::processEvents(QEventLoop::AllEvents, 50); -} diff --git a/tests/auto/macnativeevents/qnativeplayer.h b/tests/auto/macnativeevents/qnativeplayer.h deleted file mode 100644 index 61ee162..0000000 --- a/tests/auto/macnativeevents/qnativeplayer.h +++ /dev/null @@ -1,92 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef Q_NATIVE_PLAYBACK -#define Q_NATIVE_PLAYBACK - -#include -#include "qnativeinput.h" - -class QNativePlayer : public QObject -{ - Q_OBJECT; - - public: - enum Playback {ReturnImmediately, WaitUntilFinished}; - - QNativePlayer(); - ~QNativePlayer(); - - void append(int waitMs, QNativeEvent *event = 0); - void play(Playback playback = WaitUntilFinished); - void stop(); - float playbackMultiplier; - -signals: - void done(); - -private slots: - void sendNextEvent(); - - private: - void waitNextEvent(); - - QList > eventList; - int currIndex; - bool wait; -}; - -// ****************************************************************** - -class QEventOutputList : public QList -{ -public: - QEventOutputList(); - ~QEventOutputList(); - bool waitUntilEmpty(int maxEventWaitTime = 1000); - bool wait; - - // Useful method. Just sleep and process events: - static void sleep(int sleepTime); -}; - - -#endif diff --git a/tests/auto/macnativeevents/tst_macnativeevents.cpp b/tests/auto/macnativeevents/tst_macnativeevents.cpp index ccadd54..c6da3ff 100644 --- a/tests/auto/macnativeevents/tst_macnativeevents.cpp +++ b/tests/auto/macnativeevents/tst_macnativeevents.cpp @@ -44,8 +44,9 @@ #include #include -#include "qnativeinput.h" -#include "qnativeplayer.h" +#include "qnativeevents.h" +#include "nativeeventlist.h" +#include "expectedeventlist.h" #ifdef Q_OS_MAC @@ -55,19 +56,126 @@ class tst_MacNativeEvents : public QObject { Q_OBJECT private slots: - void testLeftMousePressRelease(); + void testMouseMoveLocation(); + void testPushButtonPressRelease(); + void testMouseLeftDoubleClick(); + void stressTestMouseLeftDoubleClick(); + void testMouseDragInside(); }; -void tst_MacNativeEvents::testLeftMousePressRelease() +void tst_MacNativeEvents::testMouseMoveLocation() { + QWidget w; + w.setMouseTracking(true); + w.show(); + QPoint p = w.geometry().center(); + + NativeEventList native; + native.append(new QNativeMouseMoveEvent(p, Qt::NoModifier)); + + ExpectedEventList expected(&w); + expected.append(new QMouseEvent(QEvent::MouseMove, w.mapFromGlobal(p), p, Qt::NoButton, Qt::NoButton, Qt::NoModifier)); + + native.play(); + QVERIFY2(expected.waitForAllEvents(500), "the test did not receive all expected events!"); +} + +void tst_MacNativeEvents::testPushButtonPressRelease() +{ + // Check that a native mouse press and release generates the + // same qevents on a pushbutton: QPushButton w("click me"); w.show(); QPoint p = w.geometry().center(); - QNativePlayer player; - player.append(50, new QNativeMouseButtonEvent(p, Qt::LeftButton, 1, Qt::NoModifier)); - player.append(50, new QNativeMouseButtonEvent(p, Qt::LeftButton, 0, Qt::NoModifier)); - player.play(); + NativeEventList native; + native.append(new QNativeMouseButtonEvent(p, Qt::LeftButton, 1, Qt::NoModifier)); + native.append(new QNativeMouseButtonEvent(p, Qt::LeftButton, 0, Qt::NoModifier)); + + ExpectedEventList expected(&w); + expected.append(new QMouseEvent(QEvent::MouseButtonPress, w.mapFromGlobal(p), p, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)); + expected.append(new QMouseEvent(QEvent::MouseButtonRelease, w.mapFromGlobal(p), p, Qt::LeftButton, Qt::NoButton, Qt::NoModifier)); + + native.play(); + QVERIFY2(expected.waitForAllEvents(), "the test did not receive all expected events!"); +} + +void tst_MacNativeEvents::testMouseLeftDoubleClick() +{ + // Check that a native double click makes + // the test widget receive a press-release-click-release: + QWidget w; + w.show(); + QPoint p = w.geometry().center(); + + NativeEventList native; + native.append(new QNativeMouseButtonEvent(p, Qt::LeftButton, 1, Qt::NoModifier)); + native.append(new QNativeMouseButtonEvent(p, Qt::LeftButton, 0, Qt::NoModifier)); + native.append(new QNativeMouseButtonEvent(p, Qt::LeftButton, 2, Qt::NoModifier)); + native.append(new QNativeMouseButtonEvent(p, Qt::LeftButton, 0, Qt::NoModifier)); + + ExpectedEventList expected(&w); + expected.append(new QMouseEvent(QEvent::MouseButtonPress, w.mapFromGlobal(p), p, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)); + expected.append(new QMouseEvent(QEvent::MouseButtonRelease, w.mapFromGlobal(p), p, Qt::LeftButton, Qt::NoButton, Qt::NoModifier)); + expected.append(new QMouseEvent(QEvent::MouseButtonDblClick, w.mapFromGlobal(p), p, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)); + expected.append(new QMouseEvent(QEvent::MouseButtonRelease, w.mapFromGlobal(p), p, Qt::LeftButton, Qt::NoButton, Qt::NoModifier)); + + native.play(); + QVERIFY2(expected.waitForAllEvents(), "the test did not receive all expected events!"); +} + +void tst_MacNativeEvents::stressTestMouseLeftDoubleClick() +{ + // Check that multiple, fast, double clicks makes + // the test widget receive correct click events + QWidget w; + w.show(); + QPoint p = w.geometry().center(); + + NativeEventList native; + ExpectedEventList expected(&w); + + for (int i=0; i<10; ++i){ + native.append(new QNativeMouseButtonEvent(p, Qt::LeftButton, 1, Qt::NoModifier)); + native.append(new QNativeMouseButtonEvent(p, Qt::LeftButton, 0, Qt::NoModifier)); + native.append(new QNativeMouseButtonEvent(p, Qt::LeftButton, 2, Qt::NoModifier)); + native.append(new QNativeMouseButtonEvent(p, Qt::LeftButton, 0, Qt::NoModifier)); + + expected.append(new QMouseEvent(QEvent::MouseButtonPress, w.mapFromGlobal(p), p, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)); + expected.append(new QMouseEvent(QEvent::MouseButtonRelease, w.mapFromGlobal(p), p, Qt::LeftButton, Qt::NoButton, Qt::NoModifier)); + expected.append(new QMouseEvent(QEvent::MouseButtonDblClick, w.mapFromGlobal(p), p, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)); + expected.append(new QMouseEvent(QEvent::MouseButtonRelease, w.mapFromGlobal(p), p, Qt::LeftButton, Qt::NoButton, Qt::NoModifier)); + } + + native.play(); + QVERIFY2(expected.waitForAllEvents(), "the test did not receive all expected events!"); +} + +void tst_MacNativeEvents::testMouseDragInside() +{ + // Check that a mouse drag inside a widget + // will cause press-move-release events to be delivered + QWidget w; + w.show(); + QPoint p1 = w.geometry().center(); + QPoint p2 = p1 - QPoint(10, 0); + QPoint p3 = p1 - QPoint(20, 0); + QPoint p4 = p1 - QPoint(30, 0); + + NativeEventList native; + native.append(new QNativeMouseButtonEvent(p1, Qt::LeftButton, 1, Qt::NoModifier)); + native.append(new QNativeMouseDragEvent(p2, Qt::LeftButton, Qt::NoModifier)); + native.append(new QNativeMouseDragEvent(p3, Qt::LeftButton, Qt::NoModifier)); + native.append(new QNativeMouseButtonEvent(p4, Qt::LeftButton, 0, Qt::NoModifier)); + + ExpectedEventList expected(&w); + expected.append(new QMouseEvent(QEvent::MouseButtonPress, w.mapFromGlobal(p1), p1, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)); + expected.append(new QMouseEvent(QEvent::MouseMove, w.mapFromGlobal(p2), p2, Qt::NoButton, Qt::LeftButton, Qt::NoModifier)); + expected.append(new QMouseEvent(QEvent::MouseMove, w.mapFromGlobal(p3), p3, Qt::NoButton, Qt::LeftButton, Qt::NoModifier)); + expected.append(new QMouseEvent(QEvent::MouseButtonRelease, w.mapFromGlobal(p4), p4, Qt::LeftButton, Qt::NoButton, Qt::NoModifier)); + + native.play(); + QVERIFY2(expected.waitForAllEvents(), "the test did not receive all expected events!"); } #include "tst_macnativeevents.moc" -- cgit v0.12