From c147617c3f33872a412318d9cd660e5391229619 Mon Sep 17 00:00:00 2001 From: Tom Cooksey Date: Tue, 30 Mar 2010 16:17:10 +0200 Subject: Change the ifdef for resolving function ptrs to match declaration Reviewed-By: TrustMe --- src/gui/egl/qegl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/egl/qegl.cpp b/src/gui/egl/qegl.cpp index 498245c..6f215cc 100644 --- a/src/gui/egl/qegl.cpp +++ b/src/gui/egl/qegl.cpp @@ -556,7 +556,7 @@ EGLDisplay QEgl::display() } // Resolve the egl extension function pointers: -#if !defined(EGL_KHR_image) && !defined(EGL_KHR_image_base) +#if (defined(EGL_KHR_image) || defined(EGL_KHR_image_base)) && !defined(EGL_EGLEXT_PROTOTYPES) if (QEgl::hasExtension("EGL_KHR_image") || QEgl::hasExtension("EGL_KHR_image_base")) { eglCreateImageKHR = (_eglCreateImageKHR) eglGetProcAddress("eglCreateImageKHR"); eglDestroyImageKHR = (_eglDestroyImageKHR) eglGetProcAddress("eglDestroyImageKHR"); -- cgit v0.12 From ce0af99f47c1728a6d8145ea89f41b1c9207104a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Tue, 6 Apr 2010 16:08:20 +0200 Subject: Prevented unnecessary copy in QImage::setAlphaChannel(). If the formats don't match the detch is unnecessary as operator= will anyways destroy the detached QImageData and substitute it with the newly created QImageData from convertToFormat. Task-number: QTBUG-9640 Reviewed-by: Trond --- src/gui/image/qimage.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp index 233c58d..ce1d6d3 100644 --- a/src/gui/image/qimage.cpp +++ b/src/gui/image/qimage.cpp @@ -5704,9 +5704,10 @@ void QImage::setAlphaChannel(const QImage &alphaChannel) return; } - detach(); - - *this = convertToFormat(QImage::Format_ARGB32_Premultiplied); + if (d->format == QImage::Format_ARGB32_Premultiplied) + detach(); + else + *this = convertToFormat(QImage::Format_ARGB32_Premultiplied); // Slight optimization since alphachannels are returned as 8-bit grays. if (alphaChannel.d->depth == 8 && alphaChannel.isGrayscale()) { -- cgit v0.12 From 06e8d0cae3651beaf95de05e89696cbab4978740 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Tue, 6 Apr 2010 16:23:34 +0200 Subject: Fix painting artifacts on text The height of the row is not only decided by the maximum height of the set of glyphs currently being added to the glyph cache, but also the height of the glyphs previously added to the current line in the glyph cache. To minimize the space used, we now calculate the maximum height for glyphs per line, and use this as the vertical advancement when positioning the next line in the cache. The change also removes a redundant test ((c_x + c.w > c.h) is caught earlier on and will always be false at this point.) Task-number: QTBUG-9176 Reviewed-by: Trond --- src/gui/painting/qtextureglyphcache.cpp | 14 +++++--------- src/gui/painting/qtextureglyphcache_p.h | 3 ++- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/src/gui/painting/qtextureglyphcache.cpp b/src/gui/painting/qtextureglyphcache.cpp index cf545be..9eda0ef 100644 --- a/src/gui/painting/qtextureglyphcache.cpp +++ b/src/gui/painting/qtextureglyphcache.cpp @@ -133,10 +133,13 @@ void QTextureGlyphCache::populate(QFontEngine *fontEngine, int numGlyphs, const while (iter != listItemCoordinates.end()) { Coord c = iter.value(); + m_currentRowHeight = qMax(m_currentRowHeight, c.h + margin * 2); + if (m_cx + c.w > m_w) { // no room on the current line, start new glyph strip m_cx = 0; - m_cy += rowHeight; + m_cy += m_currentRowHeight; + m_currentRowHeight = 0; // New row } if (m_cy + c.h > m_h) { int new_height = m_h*2; @@ -153,14 +156,7 @@ void QTextureGlyphCache::populate(QFontEngine *fontEngine, int numGlyphs, const fillTexture(c, iter.key()); coords.insert(iter.key(), c); - if (m_cx + c.w > m_w) { - m_cx = 0; - m_cy += rowHeight; - } else { - // for the Mono case, glyph_width is 8-bit aligned, - // and therefore so will m_cx - m_cx += c.w; - } + m_cx += c.w; ++iter; } diff --git a/src/gui/painting/qtextureglyphcache_p.h b/src/gui/painting/qtextureglyphcache_p.h index 803e71b..8c2f5b4 100644 --- a/src/gui/painting/qtextureglyphcache_p.h +++ b/src/gui/painting/qtextureglyphcache_p.h @@ -77,7 +77,7 @@ class Q_GUI_EXPORT QTextureGlyphCache : public QFontEngineGlyphCache public: QTextureGlyphCache(QFontEngineGlyphCache::Type type, const QTransform &matrix) : QFontEngineGlyphCache(matrix, type), m_current_fontengine(0), - m_w(0), m_h(0), m_cx(0), m_cy(0) + m_w(0), m_h(0), m_cx(0), m_cy(0), m_currentRowHeight(0) { } virtual ~QTextureGlyphCache() { } @@ -120,6 +120,7 @@ protected: int m_h; // image height int m_cx; // current x int m_cy; // current y + int m_currentRowHeight; // Height of last row }; -- cgit v0.12 From 253b87180e0a6c5db0feaaed7e321139c4ff1643 Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Tue, 6 Apr 2010 17:04:20 +0200 Subject: Moved item wouldn't follow mouse cursor when ItemIgnoresTransformations is set Since the introduction of transform properties in QGraphicsItem, QGraphicsItem::transform() is no longer enough to get the correct transform of an item. No auto-test as it involves mouse dragging. Reviewed-by: Yoann Task-number: QTBUG-9295 --- src/gui/graphicsview/qgraphicsitem.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index f106b3d..d6daf4d 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -7112,7 +7112,8 @@ void QGraphicsItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) // Root items that ignore transformations need to // calculate their diff by mapping viewport coordinates // directly to parent coordinates. - QTransform viewToParentTransform = (item->transform().translate(item->d_ptr->pos.x(), item->d_ptr->pos.y())) + // COMBINE + QTransform viewToParentTransform = (item->d_func()->transformData->computedFullTransform().translate(item->d_ptr->pos.x(), item->d_ptr->pos.y())) * (item->sceneTransform() * view->viewportTransform()).inverted(); currentParentPos = viewToParentTransform.map(QPointF(view->mapFromGlobal(event->screenPos()))); buttonDownParentPos = viewToParentTransform.map(QPointF(view->mapFromGlobal(event->buttonDownScreenPos(Qt::LeftButton)))); -- cgit v0.12 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 From 61e26e2fcc086112e5e8897a6d1c20c4b9df5f49 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Fri, 26 Mar 2010 10:34:42 +0100 Subject: Cocoa: send mouse move event upon a mouse enter On all platforms, we always send a mouse move event when the mouse enters a widget (if mouse tracking is on, that is). Then macnativeevents auto test revealed that we did not do this for the cocoa port. This patch will fix this. Reviewed-by: cduclos Reviewed-by: prasanth --- src/gui/kernel/qcocoaview_mac.mm | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/src/gui/kernel/qcocoaview_mac.mm b/src/gui/kernel/qcocoaview_mac.mm index 06eb7ff..9c5380b 100644 --- a/src/gui/kernel/qcocoaview_mac.mm +++ b/src/gui/kernel/qcocoaview_mac.mm @@ -657,23 +657,33 @@ static int qCocoaViewCount = 0; { if (!qwidget) return; - if (qwidgetprivate->data.in_destructor) return; - QEvent enterEvent(QEvent::Enter); - NSPoint windowPoint = [event locationInWindow]; - NSPoint globalPoint = [[event window] convertBaseToScreen:windowPoint]; - NSPoint viewPoint = [self convertPoint:windowPoint fromView:nil]; + if (!qAppInstance()->activeModalWidget() || QApplicationPrivate::tryModalHelper(qwidget, 0)) { + QEvent enterEvent(QEvent::Enter); + NSPoint windowPoint = [event locationInWindow]; + NSPoint globalPoint = [[event window] convertBaseToScreen:windowPoint]; + NSPoint viewPoint = [self convertPoint:windowPoint fromView:nil]; QApplication::sendEvent(qwidget, &enterEvent); qt_mouseover = qwidget; - // Update cursor and dispatch hover events. + // Update cursor icon: qt_mac_update_cursor_at_global_pos(flipPoint(globalPoint).toPoint()); - if (qwidget->testAttribute(Qt::WA_Hover) && - (!qAppInstance()->activePopupWidget() || qAppInstance()->activePopupWidget() == qwidget->window())) { - QHoverEvent he(QEvent::HoverEnter, QPoint(viewPoint.x, viewPoint.y), QPoint(-1, -1)); - QApplicationPrivate::instance()->notify_helper(qwidget, &he); + + // Send mouse move and hover events as well: + if (!qAppInstance()->activePopupWidget() || qAppInstance()->activePopupWidget() == qwidget->window()) { + if (qwidget->testAttribute(Qt::WA_MouseTracking)) { + NSEvent *mouseEvent = [NSEvent mouseEventWithType:NSMouseMoved + location:windowPoint modifierFlags:[event modifierFlags] timestamp:[event timestamp] + windowNumber:[event windowNumber] context:[event context] eventNumber:[event eventNumber] + clickCount:0 pressure:0]; + qt_mac_handleMouseEvent(self, mouseEvent, QEvent::MouseMove, Qt::NoButton); + } + if (qwidget->testAttribute(Qt::WA_Hover)) { + QHoverEvent he(QEvent::HoverEnter, QPoint(viewPoint.x, viewPoint.y), QPoint(-1, -1)); + QApplicationPrivate::instance()->notify_helper(qwidget, &he); + } } } } -- cgit v0.12 From d3ae1a9386a85475ba685cfc9a3009f119cad895 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Fri, 26 Mar 2010 10:57:17 +0100 Subject: Autotest: added more tests to macnativeevents (2) --- tests/auto/macnativeevents/expectedeventlist.cpp | 31 +++--- tests/auto/macnativeevents/expectedeventlist.h | 1 + tests/auto/macnativeevents/nativeeventlist.cpp | 8 ++ tests/auto/macnativeevents/nativeeventlist.h | 3 +- tests/auto/macnativeevents/tst_macnativeevents.cpp | 107 ++++++++++++++++++++- 5 files changed, 136 insertions(+), 14 deletions(-) diff --git a/tests/auto/macnativeevents/expectedeventlist.cpp b/tests/auto/macnativeevents/expectedeventlist.cpp index 48cfe1f..b1fb9a6 100644 --- a/tests/auto/macnativeevents/expectedeventlist.cpp +++ b/tests/auto/macnativeevents/expectedeventlist.cpp @@ -49,6 +49,7 @@ ExpectedEventList::ExpectedEventList(QObject *target) : QObject(target), eventCount(0) { target->installEventFilter(this); + debug = !qgetenv("NATIVEDEBUG").isEmpty(); } ExpectedEventList::~ExpectedEventList() @@ -92,10 +93,10 @@ bool ExpectedEventList::waitForAllEvents(int maxEventWaitTime) return false; } -void ExpectedEventList::compareMouseEvents(QEvent *expected, QEvent *received) +void ExpectedEventList::compareMouseEvents(QEvent *received, QEvent *expected) { - QMouseEvent *e1 = static_cast(expected); - QMouseEvent *e2 = static_cast(received); + QMouseEvent *e1 = static_cast(received); + QMouseEvent *e2 = static_cast(expected); if (e1->pos() == e2->pos() && (e1->globalPos() == e2->globalPos()) && (e1->button() == e2->button()) @@ -104,14 +105,18 @@ void ExpectedEventList::compareMouseEvents(QEvent *expected, QEvent *received) 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()); + if (!debug) { + qWarning() << "Expected event" << eventListNr << "differs from received event:"; + 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()); + } else { + qWarning() << "*** FAIL *** : Expected event" << eventListNr << "differs from received event:"; + qWarning() << "Received:" << e1 << e1->globalPos(); + qWarning() << "Expected:" << e2 << e2->globalPos(); + } } void ExpectedEventList::compareKeyEvents(QEvent *event1, QEvent *event2) @@ -124,6 +129,8 @@ void ExpectedEventList::compareKeyEvents(QEvent *event1, QEvent *event2) bool ExpectedEventList::eventFilter(QObject *, QEvent *received) { + if (debug) + qDebug() << received; if (eventList.isEmpty()) return false; @@ -139,7 +146,7 @@ bool ExpectedEventList::eventFilter(QObject *, QEvent *received) case QEvent::NonClientAreaMouseButtonRelease: case QEvent::NonClientAreaMouseButtonDblClick: case QEvent::NonClientAreaMouseMove: { - compareMouseEvents(expected, received); + compareMouseEvents(received, expected); break; } case QEvent::KeyPress: { diff --git a/tests/auto/macnativeevents/expectedeventlist.h b/tests/auto/macnativeevents/expectedeventlist.h index 3bdbb67..bd9f358 100644 --- a/tests/auto/macnativeevents/expectedeventlist.h +++ b/tests/auto/macnativeevents/expectedeventlist.h @@ -51,6 +51,7 @@ class ExpectedEventList : public QObject { QList eventList; QBasicTimer timer; + bool debug; int eventCount; void timerEvent(QTimerEvent *); diff --git a/tests/auto/macnativeevents/nativeeventlist.cpp b/tests/auto/macnativeevents/nativeeventlist.cpp index 614e9d0..d5d7b95 100644 --- a/tests/auto/macnativeevents/nativeeventlist.cpp +++ b/tests/auto/macnativeevents/nativeeventlist.cpp @@ -47,6 +47,9 @@ NativeEventList::NativeEventList(int defaultWaitMs) , wait(false) , defaultWaitMs(defaultWaitMs) { + QString multiplier = qgetenv("NATIVEDEBUG"); + if (!multiplier.isEmpty()) + setTimeMultiplier(multiplier.toFloat()); } NativeEventList::~NativeEventList() @@ -105,3 +108,8 @@ void NativeEventList::stop() QAbstractEventDispatcher::instance()->interrupt(); } +void NativeEventList::setTimeMultiplier(float multiplier) +{ + playbackMultiplier = multiplier; +} + diff --git a/tests/auto/macnativeevents/nativeeventlist.h b/tests/auto/macnativeevents/nativeeventlist.h index 886ab78..688665d 100644 --- a/tests/auto/macnativeevents/nativeeventlist.h +++ b/tests/auto/macnativeevents/nativeeventlist.h @@ -61,7 +61,7 @@ class NativeEventList : public QObject void play(Playback playback = WaitUntilFinished); void stop(); - float playbackMultiplier; + void setTimeMultiplier(float multiplier); signals: void done(); @@ -73,6 +73,7 @@ private: void waitNextEvent(); QList > eventList; + float playbackMultiplier; int currIndex; bool wait; int defaultWaitMs; diff --git a/tests/auto/macnativeevents/tst_macnativeevents.cpp b/tests/auto/macnativeevents/tst_macnativeevents.cpp index c6da3ff..08ab9e6 100644 --- a/tests/auto/macnativeevents/tst_macnativeevents.cpp +++ b/tests/auto/macnativeevents/tst_macnativeevents.cpp @@ -61,6 +61,10 @@ private slots: void testMouseLeftDoubleClick(); void stressTestMouseLeftDoubleClick(); void testMouseDragInside(); + void testMouseDragOutside(); + void testMouseDragToNonClientArea(); + void testDragWindow(); + void testMouseEnter(); }; void tst_MacNativeEvents::testMouseMoveLocation() @@ -77,7 +81,7 @@ void tst_MacNativeEvents::testMouseMoveLocation() 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!"); + QVERIFY2(expected.waitForAllEvents(), "the test did not receive all expected events!"); } void tst_MacNativeEvents::testPushButtonPressRelease() @@ -178,6 +182,107 @@ void tst_MacNativeEvents::testMouseDragInside() QVERIFY2(expected.waitForAllEvents(), "the test did not receive all expected events!"); } +void tst_MacNativeEvents::testMouseDragOutside() +{ + // Check that if we drag the mouse from inside the + // widget, and release it outside, we still get mouse move + // and release events when the mouse is outside the widget. + QWidget w; + w.show(); + QPoint inside1 = w.geometry().center(); + QPoint inside2 = inside1 - QPoint(10, 0); + QPoint outside1 = w.geometry().topLeft() - QPoint(50, 0); + QPoint outside2 = outside1 - QPoint(10, 0); + + NativeEventList native; + native.append(new QNativeMouseButtonEvent(inside1, Qt::LeftButton, 1, Qt::NoModifier)); + native.append(new QNativeMouseDragEvent(inside2, Qt::LeftButton, Qt::NoModifier)); + native.append(new QNativeMouseDragEvent(outside1, Qt::LeftButton, Qt::NoModifier)); + native.append(new QNativeMouseButtonEvent(outside2, Qt::LeftButton, 0, Qt::NoModifier)); + + ExpectedEventList expected(&w); + expected.append(new QMouseEvent(QEvent::MouseButtonPress, w.mapFromGlobal(inside1), inside1, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)); + expected.append(new QMouseEvent(QEvent::MouseMove, w.mapFromGlobal(inside2), inside2, Qt::NoButton, Qt::LeftButton, Qt::NoModifier)); + expected.append(new QMouseEvent(QEvent::MouseMove, w.mapFromGlobal(outside1), outside1, Qt::NoButton, Qt::LeftButton, Qt::NoModifier)); + expected.append(new QMouseEvent(QEvent::MouseButtonRelease, w.mapFromGlobal(outside2), outside2, Qt::LeftButton, Qt::NoButton, Qt::NoModifier)); + + native.play(); + QVERIFY2(expected.waitForAllEvents(), "the test did not receive all expected events!"); +} + +void tst_MacNativeEvents::testMouseDragToNonClientArea() +{ + // Check that if we drag the mouse from inside the + // widget, and release it on the title bar, we still get mouse move + // and release events when the mouse is on the title bar + QWidget w; + w.show(); + QPoint inside1 = w.geometry().center(); + QPoint inside2 = inside1 - QPoint(10, 0); + QPoint titlebar1 = w.geometry().topLeft() - QPoint(-100, 10); + QPoint titlebar2 = titlebar1 - QPoint(10, 0); + + NativeEventList native; + native.append(new QNativeMouseButtonEvent(inside1, Qt::LeftButton, 1, Qt::NoModifier)); + native.append(new QNativeMouseDragEvent(inside2, Qt::LeftButton, Qt::NoModifier)); + native.append(new QNativeMouseDragEvent(titlebar1, Qt::LeftButton, Qt::NoModifier)); + native.append(new QNativeMouseButtonEvent(titlebar2, Qt::LeftButton, 0, Qt::NoModifier)); + + ExpectedEventList expected(&w); + expected.append(new QMouseEvent(QEvent::MouseButtonPress, w.mapFromGlobal(inside1), inside1, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)); + expected.append(new QMouseEvent(QEvent::MouseMove, w.mapFromGlobal(inside2), inside2, Qt::NoButton, Qt::LeftButton, Qt::NoModifier)); + expected.append(new QMouseEvent(QEvent::MouseMove, w.mapFromGlobal(titlebar1), titlebar1, Qt::NoButton, Qt::LeftButton, Qt::NoModifier)); + expected.append(new QMouseEvent(QEvent::MouseButtonRelease, w.mapFromGlobal(titlebar2), titlebar2, Qt::LeftButton, Qt::NoButton, Qt::NoModifier)); + + native.play(); + QVERIFY2(expected.waitForAllEvents(), "the test did not receive all expected events!"); +} + +void tst_MacNativeEvents::testDragWindow() +{ + // Check that if we drag the mouse from inside the + // widgets title bar, we get a move event on the window + QWidget w; + w.show(); + QPoint titlebar = w.geometry().topLeft() - QPoint(-100, 10); + QPoint moveTo = titlebar + QPoint(100, 0); + + NativeEventList native; + native.append(new QNativeMouseButtonEvent(titlebar, Qt::LeftButton, 1, Qt::NoModifier)); + native.append(new QNativeMouseDragEvent(moveTo, Qt::LeftButton, Qt::NoModifier)); + native.append(500, new QNativeMouseButtonEvent(moveTo, Qt::LeftButton, 0, Qt::NoModifier)); + + ExpectedEventList expected(&w); + expected.append(new QMouseEvent(QEvent::NonClientAreaMouseButtonPress, w.mapFromGlobal(titlebar), titlebar, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)); + expected.append(new QMouseEvent(QEvent::NonClientAreaMouseButtonRelease, w.mapFromGlobal(titlebar), moveTo, Qt::LeftButton, Qt::NoButton, Qt::NoModifier)); + + native.play(); + QVERIFY2(expected.waitForAllEvents(), "the test did not receive all expected events!"); +} + +void tst_MacNativeEvents::testMouseEnter() +{ + // When a mouse enters a widget, both a mouse enter events and a + // mouse move event should be sendt. Lets test this: + QWidget w; + w.setMouseTracking(true); + w.show(); + QPoint outside = w.geometry().topLeft() - QPoint(50, 0); + QPoint inside = w.geometry().center(); + + NativeEventList native; + native.append(new QNativeMouseMoveEvent(outside, Qt::NoModifier)); + native.append(new QNativeMouseMoveEvent(inside, Qt::NoModifier)); + + ExpectedEventList expected(&w); + expected.append(new QEvent(QEvent::Enter)); + expected.append(new QMouseEvent(QEvent::MouseMove, w.mapFromGlobal(inside), inside, Qt::NoButton, Qt::NoButton, Qt::NoModifier)); + + native.play(); + QVERIFY2(expected.waitForAllEvents(), "the test did not receive all expected events!"); +} + + #include "tst_macnativeevents.moc" QTEST_MAIN(tst_MacNativeEvents) -- cgit v0.12 From bb718c6a6e626b5b353884525223de5d7a178c2d Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Wed, 7 Apr 2010 09:43:36 +0200 Subject: Cocoa: mouse release event reports wrong button state If you release the mouse over a non-client area, the following mouse up event contains the mouse button that was released in the 'buttons' state. This is wrong, according to the documentation (and the native events auto test!) Reviewed-by: msorvig --- src/gui/kernel/qt_cocoa_helpers_mac.mm | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/gui/kernel/qt_cocoa_helpers_mac.mm b/src/gui/kernel/qt_cocoa_helpers_mac.mm index b1e4c94..a05c7d5 100644 --- a/src/gui/kernel/qt_cocoa_helpers_mac.mm +++ b/src/gui/kernel/qt_cocoa_helpers_mac.mm @@ -882,7 +882,15 @@ void qt_mac_dispatchNCMouseMessage(void * /* NSWindow* */eventWindow, void * /* } } - QMouseEvent qme(eventType, qlocalPoint, qglobalPoint, button, button, keyMods); + Qt::MouseButtons buttons = 0; + { + UInt32 mac_buttons; + if (GetEventParameter((EventRef)[event eventRef], kEventParamMouseChord, typeUInt32, 0, + sizeof(mac_buttons), 0, &mac_buttons) == noErr) + buttons = qt_mac_get_buttons(mac_buttons); + } + + QMouseEvent qme(eventType, qlocalPoint, qglobalPoint, button, buttons, keyMods); qt_sendSpontaneousEvent(widgetToGetEvent, &qme); // We don't need to set the implicit grab widget here because we won't -- cgit v0.12 From 723fc322438fedc07f774d833195e030e8789d9d Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Wed, 7 Apr 2010 12:31:43 +0200 Subject: Cocoa: remove hackish code that is no longer needed After Carlos' patch (0c442405a9f85), the code in the event dispatcher that tried to restore correct window level (or actually block cocoa from setting the wrong level) can now be removed. Tested on 10.5 and 10.6. Reviewed-by: cduclos --- src/gui/kernel/qcocoasharedwindowmethods_mac_p.h | 25 ----------------- src/gui/kernel/qeventdispatcher_mac.mm | 34 +++--------------------- src/gui/kernel/qeventdispatcher_mac_p.h | 1 - 3 files changed, 3 insertions(+), 57 deletions(-) diff --git a/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h b/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h index 129e0a5..ec00915 100644 --- a/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h +++ b/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h @@ -58,7 +58,6 @@ QT_BEGIN_NAMESPACE extern Qt::MouseButton cocoaButton2QtButton(NSInteger buttonNum); // qcocoaview.mm extern QPointer qt_button_down; //qapplication_mac.cpp extern const QStringList& qEnabledDraggedTypes(); // qmime_mac.cpp -extern bool qt_blockCocoaSettingModalWindowLevel; // qeventdispatcher_mac_p.h Q_GLOBAL_STATIC(QPointer, currentDragTarget); @@ -102,30 +101,6 @@ QT_END_NAMESPACE return !(isPopup || isToolTip || isTool); } -- (void)orderWindow:(NSWindowOrderingMode)orderingMode relativeTo:(NSInteger)otherWindowNumber -{ - if (qt_blockCocoaSettingModalWindowLevel) { - // To avoid windows popping in front while restoring modal sessions - // in the event dispatcher, we block cocoa from ordering this window - // to front. The result of not doing this can be seen if executing - // a native color dialog on top of another executing dialog. - return; - } - [super orderWindow:orderingMode relativeTo:otherWindowNumber]; -} - -- (void)setLevel:(NSInteger)windowLevel -{ - if (qt_blockCocoaSettingModalWindowLevel) { - // To avoid windows popping in front while restoring modal sessions - // in the event dispatcher, we block cocoa from ordering this window - // to front. The result of not doing this can be seen if executing - // a native color dialog on top of another executing dialog. - return; - } - [super setLevel:windowLevel]; -} - - (void)toggleToolbarShown:(id)sender { macSendToolbarChangeEvent([self QT_MANGLE_NAMESPACE(qt_qwidget)]); diff --git a/src/gui/kernel/qeventdispatcher_mac.mm b/src/gui/kernel/qeventdispatcher_mac.mm index a7f1224..0d93b9f 100644 --- a/src/gui/kernel/qeventdispatcher_mac.mm +++ b/src/gui/kernel/qeventdispatcher_mac.mm @@ -97,11 +97,6 @@ QT_BEGIN_NAMESPACE QT_USE_NAMESPACE /***************************************************************************** - Internal variables and functions - *****************************************************************************/ -bool qt_blockCocoaSettingModalWindowLevel = false; - -/***************************************************************************** Externals *****************************************************************************/ extern void qt_event_request_timer(MacTimerInfo *); //qapplication_mac.cpp @@ -752,7 +747,6 @@ bool QEventDispatcherMacPrivate::interrupt = false; #ifdef QT_MAC_USE_COCOA QStack QEventDispatcherMacPrivate::cocoaModalSessionStack; bool QEventDispatcherMacPrivate::currentExecIsNSAppRun = false; -bool QEventDispatcherMacPrivate::modalSessionsTemporarilyStopped = false; bool QEventDispatcherMacPrivate::nsAppRunCalledByQt = false; bool QEventDispatcherMacPrivate::cleanupModalSessionsNeeded = false; NSModalSession QEventDispatcherMacPrivate::currentModalSessionCached = 0; @@ -788,19 +782,14 @@ void QEventDispatcherMacPrivate::temporarilyStopAllModalSessions() // we need to stop all the modal session first. To avoid changing // the stacking order of the windows while doing so, we put // up a block that is used in QCocoaWindow and QCocoaPanel: - QBoolBlocker block1(blockSendPostedEvents, true); - QBoolBlocker block2(qt_blockCocoaSettingModalWindowLevel, true); - int stackSize = cocoaModalSessionStack.size(); for (int i=stackSize-1; i>=0; --i) { QCocoaModalSessionInfo &info = cocoaModalSessionStack[i]; if (info.session) { - [NSApp runModalSession:info.session]; [NSApp endModalSession:info.session]; info.session = 0; } } - modalSessionsTemporarilyStopped = true; currentModalSessionCached = 0; } @@ -834,29 +823,12 @@ NSModalSession QEventDispatcherMacPrivate::currentModalSession() // When creating a modal session cocoa will rearrange the windows. // In order to avoid windows to be put behind another we need to // keep the window level. - { - int level = [window level]; - info.session = [NSApp beginModalSessionForWindow:window]; - [window setLevel:level]; - } + int level = [window level]; + info.session = [NSApp beginModalSessionForWindow:window]; + [window setLevel:level]; } currentModalSessionCached = info.session; } - - if (modalSessionsTemporarilyStopped && currentModalSessionCached) { - // After a call to temporarilyStopAllModalSessions, cocoa have - // now posted events to restore ended modal session windows to - // the correct window level. Those events will be processed - // _after_ our new calls to beginModalSessionForWindow have - // taken effect, which will end up stacking the windows wrong on - // screen. To work around this, we block cocoa from changing the - // stacking order of the windows, and flush out the pending events - // (the block is used in QCocoaWindow and QCocoaPanel): - QBoolBlocker block1(blockSendPostedEvents, true); - QBoolBlocker block2(qt_blockCocoaSettingModalWindowLevel, true); - [NSApp runModalSession:currentModalSessionCached]; - } - modalSessionsTemporarilyStopped = false; return currentModalSessionCached; } diff --git a/src/gui/kernel/qeventdispatcher_mac_p.h b/src/gui/kernel/qeventdispatcher_mac_p.h index 8ac7c65..a0afb84 100644 --- a/src/gui/kernel/qeventdispatcher_mac_p.h +++ b/src/gui/kernel/qeventdispatcher_mac_p.h @@ -176,7 +176,6 @@ public: static bool currentExecIsNSAppRun; static bool nsAppRunCalledByQt; static bool cleanupModalSessionsNeeded; - static bool modalSessionsTemporarilyStopped; static NSModalSession currentModalSessionCached; static NSModalSession currentModalSession(); static void updateChildrenWorksWhenModal(); -- cgit v0.12 From 00b648107e97e4f6bb23342b44e087db46cd742b Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 7 Apr 2010 11:43:07 +0200 Subject: comment out variable which is used only by commented out debug code --- qmake/option.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qmake/option.cpp b/qmake/option.cpp index d7c5397..49030c3 100644 --- a/qmake/option.cpp +++ b/qmake/option.cpp @@ -613,7 +613,7 @@ bool Option::postProcessProject(QMakeProject *project) QString Option::fixString(QString string, uchar flags) { - const QString orig_string = string; + //const QString orig_string = string; static QHash *cache = 0; if(!cache) { cache = new QHash; -- cgit v0.12 From b73f1b11bdf953cd1452989b57b24ccc442de111 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 7 Apr 2010 10:58:51 +0200 Subject: fix non-bootstrapped qmake build --- qmake/qmake.pri | 2 ++ 1 file changed, 2 insertions(+) diff --git a/qmake/qmake.pri b/qmake/qmake.pri index 0821f00..281417c 100644 --- a/qmake/qmake.pri +++ b/qmake/qmake.pri @@ -14,6 +14,7 @@ SOURCES += project.cpp property.cpp main.cpp generators/makefile.cpp \ generators/win32/msvc_nmake.cpp generators/projectgenerator.cpp \ generators/win32/msvc_vcproj.cpp \ generators/win32/msvc_objectmodel.cpp \ + generators/symbian/symbiancommon.cpp \ generators/symbian/symmake.cpp \ generators/symbian/symmake_abld.cpp \ generators/symbian/symmake_sbsv2.cpp \ @@ -28,6 +29,7 @@ HEADERS += project.h property.h generators/makefile.h \ generators/xmloutput.h generators/win32/borland_bmake.h generators/win32/msvc_nmake.h \ generators/win32/msvc_vcproj.h \ generators/win32/mingw_make.h generators/win32/msvc_objectmodel.h \ + generators/symbian/symbiancommon.h \ generators/symbian/symmake.h \ generators/symbian/symmake_abld.h \ generators/symbian/symmake_sbsv2.h \ -- cgit v0.12 From bb838213a33c2f493ae9bd9a16cc4968d64dc2da Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Wed, 7 Apr 2010 13:12:41 +0200 Subject: compile fix for WinCE Armv4i missing include Reviewed-by: Joerg Bornemann --- src/corelib/tools/qsimd.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/corelib/tools/qsimd.cpp b/src/corelib/tools/qsimd.cpp index 52d2cea..1ef513c 100644 --- a/src/corelib/tools/qsimd.cpp +++ b/src/corelib/tools/qsimd.cpp @@ -42,6 +42,10 @@ #include "qsimd_p.h" #include +#if defined(Q_OS_WINCE) +#include +#endif + QT_BEGIN_NAMESPACE uint qDetectCPUFeatures() -- cgit v0.12