summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--dist/changes-5.0.08
-rw-r--r--src/corelib/doc/snippets/code/src_corelib_kernel_qabstractnativeeventfilter.cpp (renamed from src/corelib/doc/snippets/code/src_corelib_kernel_qabstracteventdispatcher.cpp)13
-rw-r--r--src/corelib/doc/snippets/code/src_corelib_kernel_qcoreapplication.cpp2
-rw-r--r--src/corelib/kernel/kernel.pri2
-rw-r--r--src/corelib/kernel/qabstracteventdispatcher.cpp126
-rw-r--r--src/corelib/kernel/qabstracteventdispatcher.h11
-rw-r--r--src/corelib/kernel/qabstracteventdispatcher_p.h4
-rw-r--r--src/corelib/kernel/qabstractnativeeventfilter.cpp105
-rw-r--r--src/corelib/kernel/qabstractnativeeventfilter.h70
-rw-r--r--src/corelib/kernel/qcoreapplication.cpp125
-rw-r--r--src/corelib/kernel/qcoreapplication.h7
-rw-r--r--src/corelib/kernel/qcoreapplication_p.h2
-rw-r--r--src/corelib/kernel/qcoreapplication_win.cpp6
-rw-r--r--src/corelib/kernel/qeventdispatcher_win.cpp2
-rw-r--r--src/gui/kernel/qplatformnativeinterface.cpp47
-rw-r--r--src/gui/kernel/qplatformnativeinterface.h3
-rw-r--r--src/gui/kernel/qwindowsysteminterface.cpp6
-rw-r--r--src/plugins/bearer/blackberry/qbbengine.cpp33
-rw-r--r--src/plugins/bearer/blackberry/qbbengine.h11
-rw-r--r--src/plugins/platforms/qnx/qqnxbpseventfilter.cpp22
-rw-r--r--src/plugins/platforms/qnx/qqnxbpseventfilter.h6
-rw-r--r--src/plugins/platforms/windows/qwindowscontext.cpp39
-rw-r--r--src/plugins/platforms/windows/qwindowscontext.h3
-rw-r--r--src/plugins/platforms/windows/qwindowsintegration.cpp2
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.cpp7
-rw-r--r--src/plugins/platforms/xcb/qxcbnativeinterface.cpp16
-rw-r--r--src/plugins/platforms/xcb/qxcbnativeinterface.h8
-rw-r--r--src/testlib/qbenchmarkevent.cpp25
-rw-r--r--src/testlib/qbenchmarkevent_p.h8
-rw-r--r--tests/auto/testlib/selftests/benchlibeventcounter/tst_benchlibeventcounter.cpp2
-rw-r--r--tests/auto/testlib/selftests/benchliboptions/tst_benchliboptions.cpp6
-rw-r--r--tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp30
32 files changed, 422 insertions, 335 deletions
diff --git a/dist/changes-5.0.0 b/dist/changes-5.0.0
index 438885888f..df110ee3d0 100644
--- a/dist/changes-5.0.0
+++ b/dist/changes-5.0.0
@@ -389,6 +389,14 @@ QtCore
* QEvent::AccessibilityPrepare, AccessibilityHelp and AccessibilityDescription removed:
* The enum values simply didn't make sense in the first place and should simply be dropped.
+* Filtering of native events (QCoreApplication::setEventFilter, as well as
+ QApplication::x11EventFilter/macEventFilter/qwsEventFilter) have been replaced
+ with QCoreApplication::installNativeEventFilter and removeNativeEventFilter,
+ for an API much closer to QEvent filtering. Note that the native events that can be
+ filtered this way depend on which QPA backend is chosen, at runtime. On X11, XEvents are
+ not used anymore, and have been replaced with xcb_generic_event_t due to the switch to
+ XCB, which requires porting the application code to XCB as well.
+
* [QTBUG-23529] QHash is now more resilient to a family of denial of service
attacks exploiting algorithmic complexity, by supporting two-arguments overloads
of the qHash() hashing function.
diff --git a/src/corelib/doc/snippets/code/src_corelib_kernel_qabstracteventdispatcher.cpp b/src/corelib/doc/snippets/code/src_corelib_kernel_qabstractnativeeventfilter.cpp
index eba007e947..3f2aecbbad 100644
--- a/src/corelib/doc/snippets/code/src_corelib_kernel_qabstracteventdispatcher.cpp
+++ b/src/corelib/doc/snippets/code/src_corelib_kernel_qabstractnativeeventfilter.cpp
@@ -39,5 +39,16 @@
****************************************************************************/
//! [0]
-bool myEventFilter(void *message);
+class MyXcbEventFilter : public QAbstractNativeEventFilter
+{
+public:
+ virtual bool nativeEventFilter(const QByteArray &eventType, void *message, long *) Q_DECL_OVERRIDE
+ {
+ if (eventType == "xcb_generic_event_t") {
+ xcb_generic_event_t* ev = static_cast<xcb_generic_event_t *>(message);
+ // ...
+ }
+ return false;
+ }
+};
//! [0]
diff --git a/src/corelib/doc/snippets/code/src_corelib_kernel_qcoreapplication.cpp b/src/corelib/doc/snippets/code/src_corelib_kernel_qcoreapplication.cpp
index 8023e6a218..6f09d9a389 100644
--- a/src/corelib/doc/snippets/code/src_corelib_kernel_qcoreapplication.cpp
+++ b/src/corelib/doc/snippets/code/src_corelib_kernel_qcoreapplication.cpp
@@ -57,7 +57,7 @@ foreach (const QString &path, app.libraryPaths())
//! [3]
-bool myEventFilter(void *message, long *result);
+
//! [3]
diff --git a/src/corelib/kernel/kernel.pri b/src/corelib/kernel/kernel.pri
index 31dceba886..d2de873cef 100644
--- a/src/corelib/kernel/kernel.pri
+++ b/src/corelib/kernel/kernel.pri
@@ -2,6 +2,7 @@
HEADERS += \
kernel/qabstracteventdispatcher.h \
+ kernel/qabstractnativeeventfilter.h \
kernel/qbasictimer.h \
kernel/qeventloop.h\
kernel/qpointer.h \
@@ -42,6 +43,7 @@ HEADERS += \
SOURCES += \
kernel/qabstracteventdispatcher.cpp \
+ kernel/qabstractnativeeventfilter.cpp \
kernel/qbasictimer.cpp \
kernel/qeventloop.cpp \
kernel/qcoreapplication.cpp \
diff --git a/src/corelib/kernel/qabstracteventdispatcher.cpp b/src/corelib/kernel/qabstracteventdispatcher.cpp
index 2ef98dba0f..d17d1c6335 100644
--- a/src/corelib/kernel/qabstracteventdispatcher.cpp
+++ b/src/corelib/kernel/qabstracteventdispatcher.cpp
@@ -41,6 +41,7 @@
#include "qabstracteventdispatcher.h"
#include "qabstracteventdispatcher_p.h"
+#include "qabstractnativeeventfilter.h"
#include "qthread.h"
#include <private/qthread_p.h>
@@ -370,87 +371,96 @@ void QAbstractEventDispatcher::closingDown()
*/
/*!
- \typedef QAbstractEventDispatcher::EventFilter
-
- Typedef for a function with the signature
-
- \snippet code/src_corelib_kernel_qabstracteventdispatcher.cpp 0
-
- Note that the type of the \a message is platform dependent. The
- following table shows the \a {message}'s type on Windows, Mac, and
- X11. You can do a static cast to these types.
-
- \table
- \header
- \li Platform
- \li type
- \row
- \li Windows
- \li MSG
- \row
- \li X11
- \li XEvent
- \row
- \li Mac
- \li NSEvent
- \endtable
-
-
-
- \sa setEventFilter(), filterEvent()
+ Installs an event filter \a filterObj for all native event filters
+ received by the application.
+
+ The event filter \a filterObj receives events via its nativeEventFilter()
+ function, which is called for all events received by all threads.
+
+ The nativeEventFilter() function should return true if the event should
+ be filtered, (i.e. stopped). It should return false to allow
+ normal Qt processing to continue: the native event can then be translated
+ into a QEvent and handled by the standard Qt \l{QEvent} {event} filtering,
+ e.g. QObject::installEventFilter().
+
+ If multiple event filters are installed, the filter that was installed last
+ is activated first.
+
+ \note The filter function set here receives native messages,
+ i.e. MSG or XEvent structs.
+
+ For maximum portability, you should always try to use QEvents
+ and QObject::installEventFilter() whenever possible.
+
+ \sa QObject::installEventFilter()
+
+ \since 5.0
*/
+void QAbstractEventDispatcher::installNativeEventFilter(QAbstractNativeEventFilter *filterObj)
+{
+ Q_D(QAbstractEventDispatcher);
+
+ // clean up unused items in the list
+ d->eventFilters.removeAll(0);
+ d->eventFilters.removeAll(filterObj);
+ d->eventFilters.prepend(filterObj);
+}
/*!
- Replaces the event filter function for this
- QAbstractEventDispatcher with \a filter and returns the replaced
- event filter function. Only the current event filter function is
- called. If you want to use both filter functions, save the
- replaced EventFilter in a place where yours can call it.
-
- The event filter function set here is called for all messages
- taken from the system event loop before the event is dispatched to
- the respective target, including the messages not meant for Qt
- objects.
-
- The event filter function should return true if the message should
- be filtered, (i.e. stopped). It should return false to allow
- processing the message to continue.
+ Removes an event filter object \a obj from this object. The
+ request is ignored if such an event filter has not been installed.
+
+ All event filters for this object are automatically removed when
+ this object is destroyed.
- By default, no event filter function is set (i.e., this function
- returns a null EventFilter the first time it is called).
+ It is always safe to remove an event filter, even during event
+ filter activation (i.e. from the nativeEventFilter() function).
+
+ \sa installNativeEventFilter(), QAbstractNativeEventFilter
+ \since 5.0
*/
-QAbstractEventDispatcher::EventFilter QAbstractEventDispatcher::setEventFilter(EventFilter filter)
+void QAbstractEventDispatcher::removeNativeEventFilter(QAbstractNativeEventFilter *filterObj)
{
Q_D(QAbstractEventDispatcher);
- EventFilter oldFilter = d->event_filter;
- d->event_filter = filter;
- return oldFilter;
+ for (int i = 0; i < d->eventFilters.count(); ++i) {
+ if (d->eventFilters.at(i) == filterObj) {
+ d->eventFilters[i] = 0;
+ break;
+ }
+ }
}
/*!
- Sends \a message through the event filter that was set by
- setEventFilter(). If no event filter has been set, this function
- returns false; otherwise, this function returns the result of the
- event filter function.
+ Sends \a message through the event filters that were set by
+ installNativeEventFilter(). This function returns true as soon as an
+ event filter returns true, and false otherwise to indicate that
+ the processing of the event should continue.
Subclasses of QAbstractEventDispatcher \e must call this function
for \e all messages received from the system to ensure
compatibility with any extensions that may be used in the
application.
- Note that the type of \a message is platform dependent. See
- QAbstractEventDispatcher::EventFilter for details.
+ Note that the type of \a message is platform dependent. See
+ QAbstractNativeEventFilter for details.
- \sa setEventFilter()
+ \sa installNativeEventFilter()
+ \since 5.0
*/
-bool QAbstractEventDispatcher::filterEvent(void *message)
+bool QAbstractEventDispatcher::filterNativeEvent(const QByteArray &eventType, void *message, long *result)
{
Q_D(QAbstractEventDispatcher);
- if (d->event_filter) {
+ if (!d->eventFilters.isEmpty()) {
// Raise the loopLevel so that deleteLater() calls in or triggered
// by event_filter() will be processed from the main event loop.
QScopedLoopLevelCounter loopLevelCounter(d->threadData);
- return d->event_filter(message);
+ for (int i = 0; i < d->eventFilters.size(); ++i) {
+ QAbstractNativeEventFilter *filter = d->eventFilters.at(i);
+ if (!filter)
+ continue;
+ if (filter->nativeEventFilter(eventType, message, result))
+ return true;
+ }
}
return false;
}
diff --git a/src/corelib/kernel/qabstracteventdispatcher.h b/src/corelib/kernel/qabstracteventdispatcher.h
index e70530b283..73c1ad7afd 100644
--- a/src/corelib/kernel/qabstracteventdispatcher.h
+++ b/src/corelib/kernel/qabstracteventdispatcher.h
@@ -49,7 +49,7 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-
+class QAbstractNativeEventFilter;
class QAbstractEventDispatcherPrivate;
class QSocketNotifier;
@@ -111,9 +111,12 @@ public:
virtual void startingUp();
virtual void closingDown();
- typedef bool(*EventFilter)(void *message);
- EventFilter setEventFilter(EventFilter filter);
- bool filterEvent(void *message);
+ void installNativeEventFilter(QAbstractNativeEventFilter *filterObj);
+ void removeNativeEventFilter(QAbstractNativeEventFilter *filterObj);
+ bool filterNativeEvent(const QByteArray &eventType, void *message, long *result);
+#if QT_DEPRECATED_SINCE(5, 0)
+ QT_DEPRECATED bool filterEvent(void *message) { return filterNativeEvent("", message, 0); }
+#endif
Q_SIGNALS:
void aboutToBlock();
diff --git a/src/corelib/kernel/qabstracteventdispatcher_p.h b/src/corelib/kernel/qabstracteventdispatcher_p.h
index b6f0160342..e34e30e7d1 100644
--- a/src/corelib/kernel/qabstracteventdispatcher_p.h
+++ b/src/corelib/kernel/qabstracteventdispatcher_p.h
@@ -65,9 +65,9 @@ class Q_CORE_EXPORT QAbstractEventDispatcherPrivate : public QObjectPrivate
Q_DECLARE_PUBLIC(QAbstractEventDispatcher)
public:
inline QAbstractEventDispatcherPrivate()
- : event_filter(0)
{ }
- QAbstractEventDispatcher::EventFilter event_filter;
+
+ QList<QAbstractNativeEventFilter *> eventFilters;
static int allocateTimerId();
static void releaseTimerId(int id);
diff --git a/src/corelib/kernel/qabstractnativeeventfilter.cpp b/src/corelib/kernel/qabstractnativeeventfilter.cpp
new file mode 100644
index 0000000000..69ce560f5d
--- /dev/null
+++ b/src/corelib/kernel/qabstractnativeeventfilter.cpp
@@ -0,0 +1,105 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qabstractnativeeventfilter.h"
+#include "qabstracteventdispatcher.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QAbstractNativeEventFilter
+ \since 5.0
+
+ \brief The QAbstractNativeEventFilter class provides an interface for receiving native
+ events, such as MSG or XCB event structs.
+*/
+
+/*!
+ Creates a native event filter.
+
+ By default this doesn't do anything. Remember to install it on the application
+ object.
+*/
+QAbstractNativeEventFilter::QAbstractNativeEventFilter()
+{
+}
+
+/*!
+ Destroys the native event filter.
+
+ This automatically removes it from the application.
+*/
+QAbstractNativeEventFilter::~QAbstractNativeEventFilter()
+{
+ QAbstractEventDispatcher *eventDispatcher = QAbstractEventDispatcher::instance();
+ if (eventDispatcher)
+ eventDispatcher->removeNativeEventFilter(this);
+}
+
+/*!
+ \fn bool QAbstractNativeEventFilter::nativeEventFilter(const QByteArray &eventType, void *message, long *result)
+
+ This method is called for every native event.
+
+ \note The filter function here receives native messages,
+ for example, MSG or XCB event structs.
+
+ It is called by the QPA platform plugin. On Windows, it is called by
+ the event dispatcher.
+
+ The type of event \a eventType is specific to the platform plugin chosen at run-time,
+ and can be used to cast \a message to the right type.
+
+ On X11, \a eventType is set to "xcb_generic_event_t", and the \a message can be casted
+ to a xcb_generic_event_t pointer.
+
+ On Windows, \a eventType is set to "windows_generic_MSG" for messages sent to toplevel windows,
+ and "windows_dispatcher_MSG" for system-wide messages such as messages from a registered hot key.
+ In both cases, the \a message can be casted to a MSG pointer.
+ The \a result pointer is only used on Windows, and corresponds to the LRESULT pointer.
+
+ On Mac, \a eventType is set to "mac_generic_NSEvent", and the \a message can be casted to an EventRef.
+
+ Example:
+ \snippet code/src_corelib_kernel_qabstractnativeeventfilter.cpp 0
+*/
+
+QT_END_NAMESPACE
diff --git a/src/corelib/kernel/qabstractnativeeventfilter.h b/src/corelib/kernel/qabstractnativeeventfilter.h
new file mode 100644
index 0000000000..87ec88b9e4
--- /dev/null
+++ b/src/corelib/kernel/qabstractnativeeventfilter.h
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QABSTRACTNATIVEEVENTFILTER_H
+#define QABSTRACTNATIVEEVENTFILTER_H
+
+#include <QtCore/qnamespace.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QAbstractNativeEventFilterPrivate;
+
+class Q_CORE_EXPORT QAbstractNativeEventFilter
+{
+public:
+ QAbstractNativeEventFilter();
+ virtual ~QAbstractNativeEventFilter();
+
+ virtual bool nativeEventFilter(const QByteArray &eventType, void *message, long *result) = 0;
+
+private:
+ Q_DISABLE_COPY(QAbstractNativeEventFilter)
+ QAbstractNativeEventFilterPrivate *d;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif /* QABSTRACTNATIVEEVENTFILTER_H */
diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp
index d24cbc7d58..5ffd94b068 100644
--- a/src/corelib/kernel/qcoreapplication.cpp
+++ b/src/corelib/kernel/qcoreapplication.cpp
@@ -286,7 +286,6 @@ QCoreApplicationPrivate::QCoreApplicationPrivate(int &aargc, char **aargv, uint
, origArgv(new char *[aargc])
#endif
, application_type(0)
- , eventFilter(0)
, in_exec(false)
, aboutToQuitEmitted(false)
, threadData_clean(false)
@@ -765,7 +764,7 @@ bool QCoreApplication::notifyInternal(QObject *receiver, QEvent *event)
do not change the focus widget.
\endlist
- \sa QObject::event(), installEventFilter()
+ \sa QObject::event(), installNativeEventFilter()
*/
bool QCoreApplication::notify(QObject *receiver, QEvent *event)
@@ -2140,80 +2139,94 @@ void QCoreApplication::removeLibraryPath(const QString &path)
#endif //QT_NO_LIBRARY
/*!
- \typedef QCoreApplication::EventFilter
+ Sends \a message through the event filters that were set by
+ installNativeEventFilter(). This function returns true as soon as an
+ event filter returns true, and false otherwise to indicate that
+ the processing of the event should continue.
- A function with the following signature that can be used as an
- event filter:
+ Subclasses of QAbstractEventDispatcher \e must call this function
+ for \e all messages received from the system to ensure
+ compatibility with any extensions that may be used in the
+ application.
- \snippet code/src_corelib_kernel_qcoreapplication.cpp 3
+ Note that the type of \a message is platform dependent. See
+ QAbstractNativeEventFilter for details.
- \sa setEventFilter()
+ \sa installNativeEventFilter()
+ \since 5.0
+
+ \internal
+ This method only exists for the Windows event dispatcher to call the winEventFilter virtual.
+ Every other platform can just use QAbstractNativeEventFilter::filterNativeEvent directly.
*/
+bool QCoreApplication::filterNativeEvent(const QByteArray &eventType, void *message, long *result)
+{
+ if (result)
+ *result = 0;
+#ifdef Q_OS_WIN
+ if (winEventFilter(reinterpret_cast<MSG *>(message), result))
+ return true;
+#endif
+ QAbstractEventDispatcher* dispatcher = QAbstractEventDispatcher::instance();
+ if (dispatcher)
+ return dispatcher->filterNativeEvent(eventType, message, result);
+ return false;
+}
-/*!
- \fn EventFilter QCoreApplication::setEventFilter(EventFilter filter)
- Replaces the event filter function for the QCoreApplication with
- \a filter and returns the pointer to the replaced event filter
- function. Only the current event filter function is called. If you
- want to use both filter functions, save the replaced EventFilter
- in a place where yours can call it.
+/*!
+ Installs an event filter \a filterObj for all native events
+ received by the application in the main thread.
- The event filter function set here is called for all messages
- received by all threads meant for all Qt objects. It is \e not
- called for messages that are not meant for Qt objects.
+ The event filter \a filterObj receives events via its nativeEventFilter()
+ function, which is called for all native events received in the main thread.
- The event filter function should return true if the message should
+ The nativeEventFilter() function should return true if the event should
be filtered, (i.e. stopped). It should return false to allow
- processing the message to continue.
+ normal Qt processing to continue: the native event can then be translated
+ into a QEvent and handled by the standard Qt \l{QEvent} {event} filtering,
+ e.g. QObject::installEventFilter().
- By default, no event filter function is set (i.e., this function
- returns a null EventFilter the first time it is called).
+ If multiple event filters are installed, the filter that was
+ installed last is activated first.
\note The filter function set here receives native messages,
- i.e. MSG or XEvent structs, that are going to Qt objects. It is
- called by QCoreApplication::filterEvent(). If the filter function
- returns false to indicate the message should be processed further,
- the native message can then be translated into a QEvent and
- handled by the standard Qt \l{QEvent} {event} filering, e.g.
- QObject::installEventFilter().
-
- \note The filter function set here is different form the filter
- function set via QAbstractEventDispatcher::setEventFilter(), which
- gets all messages received by its thread, even messages meant for
- objects that are not handled by Qt.
-
- \sa QObject::installEventFilter(), QAbstractEventDispatcher::setEventFilter()
+ i.e. MSG or XCB event structs.
+
+ For maximum portability, you should always try to use QEvents
+ and QObject::installEventFilter() whenever possible.
+
+ \sa QObject::installEventFilter()
+
+ \since 5.0
*/
-QCoreApplication::EventFilter
-QCoreApplication::setEventFilter(QCoreApplication::EventFilter filter)
+void QCoreApplication::installNativeEventFilter(QAbstractNativeEventFilter *filterObj)
{
- Q_D(QCoreApplication);
- EventFilter old = d->eventFilter;
- d->eventFilter = filter;
- return old;
+ QAbstractEventDispatcher *eventDispatcher = QAbstractEventDispatcher::instance(QCoreApplicationPrivate::theMainThread);
+ if (!filterObj || !eventDispatcher)
+ return;
+ eventDispatcher->installNativeEventFilter(filterObj);
}
/*!
- Sends \a message through the event filter that was set by
- setEventFilter(). If no event filter has been set, this function
- returns false; otherwise, this function returns the result of the
- event filter function in the \a result parameter.
+ Removes an event filter object \a obj from this object. The
+ request is ignored if such an event filter has not been installed.
+
+ All event filters for this object are automatically removed when
+ this object is destroyed.
- \sa setEventFilter()
+ It is always safe to remove an event filter, even during event
+ filter activation (i.e. from the nativeEventFilter() function).
+
+ \sa installNativeEventFilter(), QAbstractNativeEventFilter
+ \since 5.0
*/
-bool QCoreApplication::filterEvent(void *message, long *result)
+void QCoreApplication::removeNativeEventFilter(QAbstractNativeEventFilter *filterObj)
{
- Q_D(QCoreApplication);
- if (result)
- *result = 0;
- if (d->eventFilter)
- return d->eventFilter(message, result);
-#ifdef Q_OS_WIN
- return winEventFilter(reinterpret_cast<MSG *>(message), result);
-#else
- return false;
-#endif
+ QAbstractEventDispatcher *eventDispatcher = QAbstractEventDispatcher::instance();
+ if (!filterObj || !eventDispatcher)
+ return;
+ eventDispatcher->removeNativeEventFilter(filterObj);
}
/*!
diff --git a/src/corelib/kernel/qcoreapplication.h b/src/corelib/kernel/qcoreapplication.h
index 555686f9ab..549b6f135d 100644
--- a/src/corelib/kernel/qcoreapplication.h
+++ b/src/corelib/kernel/qcoreapplication.h
@@ -61,6 +61,7 @@ class QTranslator;
class QPostEventList;
class QStringList;
class QAbstractEventDispatcher;
+class QAbstractNativeEventFilter;
#define qApp QCoreApplication::instance()
@@ -159,9 +160,9 @@ public:
static void watchUnixSignal(int signal, bool watch);
#endif
- typedef bool (*EventFilter)(void *message, long *result);
- EventFilter setEventFilter(EventFilter filter);
- bool filterEvent(void *message, long *result);
+ void installNativeEventFilter(QAbstractNativeEventFilter *filterObj);
+ void removeNativeEventFilter(QAbstractNativeEventFilter *filterObj);
+ bool filterNativeEvent(const QByteArray &eventType, void *message, long *result);
static bool isQuitLockEnabled();
static void setQuitLockEnabled(bool enabled);
diff --git a/src/corelib/kernel/qcoreapplication_p.h b/src/corelib/kernel/qcoreapplication_p.h
index 1f1d58c009..0fe64621f3 100644
--- a/src/corelib/kernel/qcoreapplication_p.h
+++ b/src/corelib/kernel/qcoreapplication_p.h
@@ -121,8 +121,6 @@ public:
#endif
uint application_type;
- QCoreApplication::EventFilter eventFilter;
-
bool in_exec;
bool aboutToQuitEmitted;
bool threadData_clean;
diff --git a/src/corelib/kernel/qcoreapplication_win.cpp b/src/corelib/kernel/qcoreapplication_win.cpp
index 5649a8dd76..9d92f83b04 100644
--- a/src/corelib/kernel/qcoreapplication_win.cpp
+++ b/src/corelib/kernel/qcoreapplication_win.cpp
@@ -207,12 +207,6 @@ void qWinMain(HINSTANCE instance, HINSTANCE prevInstance, LPSTR cmdParam,
the event to be processed by Qt, then return true and set \a result
to the value that the window procedure should return. Otherwise
return false.
-
- It is only directly addressed messages that are filtered. To
- handle system wide messages, such as messages from a registered
- hot key, you need to install an event filter on the event
- dispatcher, which is returned from
- QAbstractEventDispatcher::instance().
*/
bool QCoreApplication::winEventFilter(MSG *msg, long *result) // Windows event filter
{
diff --git a/src/corelib/kernel/qeventdispatcher_win.cpp b/src/corelib/kernel/qeventdispatcher_win.cpp
index 8d357b5085..e5cc627edb 100644
--- a/src/corelib/kernel/qeventdispatcher_win.cpp
+++ b/src/corelib/kernel/qeventdispatcher_win.cpp
@@ -359,7 +359,7 @@ LRESULT QT_WIN_CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPA
if (message == WM_TIMER)
KillTimer(hwnd, wp);
return 0;
- } else if (app->filterEvent(&msg, &result)) {
+ } else if (app->filterNativeEvent(QByteArrayLiteral("windows_dispatcher_MSG"), &msg, &result)) {
return result;
}
diff --git a/src/gui/kernel/qplatformnativeinterface.cpp b/src/gui/kernel/qplatformnativeinterface.cpp
index f0bd3f0658..e35948fd0c 100644
--- a/src/gui/kernel/qplatformnativeinterface.cpp
+++ b/src/gui/kernel/qplatformnativeinterface.cpp
@@ -146,51 +146,4 @@ void QPlatformNativeInterface::setWindowProperty(QPlatformWindow *window, const
Q_UNUSED(value);
}
-/*!
- \typedef QPlatformNativeInterface::EventFilter
- \since 5.0
-
- A function with the following signature that can be used as an
- event filter:
-
- \code
- bool myEventFilter(void *message, long *result);
- \endcode
-
- \sa setEventFilter()
-*/
-
-/*!
- \fn EventFilter QPlatformNativeInterface::setEventFilter(const QByteArray &eventType, EventFilter filter)
- \since 5.0
-
- Replaces the event filter function for the native interface with
- \a filter and returns the pointer to the replaced event filter
- function. Only the current event filter function is called. If you
- want to use both filter functions, save the replaced EventFilter
- in a place where you can call it from.
-
- The event filter function set here is called for all messages
- received from the platform if they are given type \eventType.
- It is \e not called for messages that are not meant for Qt objects.
-
- The type of event is specific to the platform plugin chosen at run-time.
-
- The event filter function should return \c true if the message should
- be filtered, (i.e. stopped). It should return \c false to allow
- processing the message to continue.
-
- By default, no event filter function is set. For example, this function
- returns a null EventFilter the first time it is called.
-
- \note The filter function here receives native messages,
- for example, MSG or XEvent structs. It is called by the platform plugin.
-*/
-QPlatformNativeInterface::EventFilter QPlatformNativeInterface::setEventFilter(const QByteArray &eventType, QPlatformNativeInterface::EventFilter filter)
-{
- Q_UNUSED(eventType);
- Q_UNUSED(filter);
- return 0;
-}
-
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qplatformnativeinterface.h b/src/gui/kernel/qplatformnativeinterface.h
index 37339f4860..16a9db0f73 100644
--- a/src/gui/kernel/qplatformnativeinterface.h
+++ b/src/gui/kernel/qplatformnativeinterface.h
@@ -88,9 +88,6 @@ public:
virtual QVariant windowProperty(QPlatformWindow *window, const QString &name, const QVariant &defaultValue) const;
virtual void setWindowProperty(QPlatformWindow *window, const QString &name, const QVariant &value);
- typedef bool (*EventFilter)(void *message, long *result);
- virtual EventFilter setEventFilter(const QByteArray &eventType, EventFilter filter);
-
Q_SIGNALS:
void windowPropertyChanged(QPlatformWindow *window, const QString &propertyName);
};
diff --git a/src/gui/kernel/qwindowsysteminterface.cpp b/src/gui/kernel/qwindowsysteminterface.cpp
index f9eae3b765..207c858a76 100644
--- a/src/gui/kernel/qwindowsysteminterface.cpp
+++ b/src/gui/kernel/qwindowsysteminterface.cpp
@@ -518,11 +518,6 @@ bool QWindowSystemInterface::sendWindowSystemEvents(QAbstractEventDispatcher *ev
break;
}
- if (eventDispatcher->filterEvent(event)) {
- delete event;
- continue;
- }
-
nevents++;
QGuiApplicationPrivate::processWindowSystemEvent(event);
@@ -554,7 +549,6 @@ QPlatformDropQtResponse QWindowSystemInterface::handleDrop(QWindow *w, const QMi
\brief Passes a native event identified by \a eventType to the \a window.
\note This function can only be called from the GUI thread.
- \sa QPlatformNativeInterface::setEventFilter()
*/
bool QWindowSystemInterface::handleNativeEvent(QWindow *window, const QByteArray &eventType, void *message, long *result)
diff --git a/src/plugins/bearer/blackberry/qbbengine.cpp b/src/plugins/bearer/blackberry/qbbengine.cpp
index 7f8abd0e50..921d8f8040 100644
--- a/src/plugins/bearer/blackberry/qbbengine.cpp
+++ b/src/plugins/bearer/blackberry/qbbengine.cpp
@@ -122,7 +122,6 @@ QT_BEGIN_NAMESPACE
QBBEngine::QBBEngine(QObject *parent) :
QBearerEngineImpl(parent),
- previousEventFilter(0),
pollingRequired(false),
initialized(false)
{
@@ -130,7 +129,6 @@ QBBEngine::QBBEngine(QObject *parent) :
QBBEngine::~QBBEngine()
{
- QAbstractEventDispatcher::instance()->setEventFilter(previousEventFilter);
}
@@ -173,8 +171,7 @@ void QBBEngine::initialize()
const QMutexLocker locker(&pollingMutex);
pollingRequired = true;
} else {
- previousEventFilter =
- QAbstractEventDispatcher::instance()->setEventFilter(filterEvent);
+ QAbstractEventDispatcher::instance()->installEventFilter(this);
}
doRequestUpdate();
@@ -288,34 +285,23 @@ bool QBBEngine::requiresPolling() const
return pollingRequired;
}
-bool QBBEngine::filterEvent(void *message)
+bool QBBEngine::nativeEventFilter(const QByteArray &eventType, void *message, long *result)
{
+ Q_UNUSED(eventType);
+ Q_UNUSED(result);
+
bps_event_t * const event = static_cast<bps_event_t *>(message);
Q_ASSERT(event);
- QBBEngine *self = instanceStorage()->localData()->instance;
-
- Q_ASSERT(self);
-
- if (bps_event_get_domain(event) == netstatus_get_domain())
- self->filterEvent(event);
-
- if (self->previousEventFilter)
- return self->previousEventFilter(message);
+ if (bps_event_get_domain(event) == netstatus_get_domain()) {
+ qBearerDebug() << Q_FUNC_INFO << "got update request.";
+ doRequestUpdate();
+ }
return false;
}
-void QBBEngine::filterEvent(bps_event_t *event)
-{
- Q_UNUSED(event);
-
- qBearerDebug() << Q_FUNC_INFO << "got update request.";
-
- doRequestUpdate();
-}
-
void QBBEngine::updateConfiguration(const char *interface)
{
netstatus_interface_details_t *details = 0;
@@ -421,4 +407,3 @@ void QBBEngine::removeConfiguration(const QString &id)
QT_END_NAMESPACE
#endif // QT_NO_BEARERMANAGEMENT
-
diff --git a/src/plugins/bearer/blackberry/qbbengine.h b/src/plugins/bearer/blackberry/qbbengine.h
index 1c9a5d4aa5..2ad0f1fc65 100644
--- a/src/plugins/bearer/blackberry/qbbengine.h
+++ b/src/plugins/bearer/blackberry/qbbengine.h
@@ -45,6 +45,7 @@
#include "../qbearerengine_impl.h"
#include <QAbstractEventDispatcher>
+#include <QAbstractNativeEventFilter>
#ifndef QT_NO_BEARERMANAGEMENT
@@ -55,7 +56,7 @@ QT_BEGIN_NAMESPACE
class QNetworkConfigurationPrivate;
class QNetworkSessionPrivate;
-class QBBEngine : public QBearerEngineImpl
+class QBBEngine : public QBearerEngineImpl, public QAbstractNativeEventFilter
{
Q_OBJECT
@@ -82,6 +83,8 @@ public:
bool requiresPolling() const Q_DECL_OVERRIDE;
+ bool nativeEventFilter(const QByteArray &eventType, void *message, long *result) Q_DECL_OVERRIDE;
+
protected:
void updateConfiguration(const char *interface);
void removeConfiguration(const QString &id);
@@ -90,14 +93,8 @@ private Q_SLOTS:
void doRequestUpdate();
private:
- static bool filterEvent(void *message);
-
- void filterEvent(bps_event_t *event);
-
QHash<QString, QString> configurationInterface;
- QAbstractEventDispatcher::EventFilter previousEventFilter;
-
mutable QMutex pollingMutex;
bool pollingRequired;
diff --git a/src/plugins/platforms/qnx/qqnxbpseventfilter.cpp b/src/plugins/platforms/qnx/qqnxbpseventfilter.cpp
index 93bb2d3584..4ce38b9fdc 100644
--- a/src/plugins/platforms/qnx/qqnxbpseventfilter.cpp
+++ b/src/plugins/platforms/qnx/qqnxbpseventfilter.cpp
@@ -90,13 +90,7 @@ void QQnxBpsEventFilter::installOnEventDispatcher(QAbstractEventDispatcher *disp
if (navigator_request_events(0) != BPS_SUCCESS)
qWarning("QQNX: failed to register for navigator events");
- QAbstractEventDispatcher::EventFilter previousEventFilter = dispatcher->setEventFilter(dispatcherEventFilter);
-
- // the QPA plugin creates the event dispatcher so we are the first event
- // filter assert on that just in case somebody adds another event filter
- // in the QQnxIntegration constructor instead of adding a new section in here
- Q_ASSERT(previousEventFilter == 0);
- Q_UNUSED(previousEventFilter);
+ dispatcher->installNativeEventFilter(this);
}
void QQnxBpsEventFilter::registerForScreenEvents(QQnxScreen *screen)
@@ -137,19 +131,11 @@ void QQnxBpsEventFilter::unregisterForDialogEvents(QQnxFileDialogHelper *dialog)
qWarning("QQNX: attempting to unregister dialog that was not registered");
}
-bool QQnxBpsEventFilter::dispatcherEventFilter(void *message)
+bool QQnxBpsEventFilter::nativeEventFilter(const QByteArray &eventType, void *message, long *result)
{
- qBpsEventFilterDebug() << Q_FUNC_INFO;
-
- if (s_instance == 0)
- return false;
-
+ Q_UNUSED(eventType);
+ Q_UNUSED(result);
bps_event_t *event = static_cast<bps_event_t *>(message);
- return s_instance->bpsEventFilter(event);
-}
-
-bool QQnxBpsEventFilter::bpsEventFilter(bps_event_t *event)
-{
const int eventDomain = bps_event_get_domain(event);
qBpsEventFilterDebug() << Q_FUNC_INFO << "event=" << event << "domain=" << eventDomain;
diff --git a/src/plugins/platforms/qnx/qqnxbpseventfilter.h b/src/plugins/platforms/qnx/qqnxbpseventfilter.h
index aafca0f989..164cb0291b 100644
--- a/src/plugins/platforms/qnx/qqnxbpseventfilter.h
+++ b/src/plugins/platforms/qnx/qqnxbpseventfilter.h
@@ -44,6 +44,7 @@
#include <QObject>
#include <QHash>
+#include <QAbstractNativeEventFilter>
#include <bps/dialog.h>
@@ -58,7 +59,7 @@ class QQnxScreen;
class QQnxScreenEventHandler;
class QQnxVirtualKeyboardBps;
-class QQnxBpsEventFilter : public QObject
+class QQnxBpsEventFilter : public QObject, public QAbstractNativeEventFilter
{
Q_OBJECT
public:
@@ -76,8 +77,7 @@ public:
void unregisterForDialogEvents(QQnxFileDialogHelper *dialog);
private:
- static bool dispatcherEventFilter(void *message);
- bool bpsEventFilter(bps_event_t *event);
+ bool nativeEventFilter(const QByteArray &eventType, void *message, long *result) Q_DECL_OVERRIDE;
bool handleNavigatorEvent(bps_event_t *event);
diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp
index 37493fe3db..b12975174f 100644
--- a/src/plugins/platforms/windows/qwindowscontext.cpp
+++ b/src/plugins/platforms/windows/qwindowscontext.cpp
@@ -240,13 +240,6 @@ QWindowsContext *QWindowsContext::m_instance = 0;
typedef QHash<HWND, QWindowsWindow *> HandleBaseWindowHash;
struct QWindowsContextPrivate {
- typedef QPlatformNativeInterface::EventFilter EventFilter;
-
- enum EventFilterType
- {
- GenericWindowsEventFilter,
- EventFilterTypeCount
- };
QWindowsContextPrivate();
@@ -262,7 +255,6 @@ struct QWindowsContextPrivate {
QSharedPointer<QWindowCreationContext> m_creationContext;
const HRESULT m_oleInitializeResult;
const QByteArray m_eventType;
- EventFilter m_eventFilters[EventFilterTypeCount];
QWindow *m_lastActiveWindow;
};
@@ -289,7 +281,6 @@ QWindowsContextPrivate::QWindowsContextPrivate() :
m_systemInfo |= QWindowsContext::SI_RTL_Extensions;
m_keyMapper.setUseRTLExtensions(true);
}
- qFill(m_eventFilters, m_eventFilters + EventFilterTypeCount, EventFilter(0));
}
QWindowsContext::QWindowsContext() :
@@ -695,27 +686,6 @@ QByteArray QWindowsContext::comErrorString(HRESULT hr)
}
/*!
- \brief Set event filter.
-
- \sa QWindowsNativeInterface
-*/
-
-QWindowsContext::EventFilter QWindowsContext::setEventFilter(const QByteArray &eventType, EventFilter filter)
-{
- int eventFilterType = -1;
- if (eventType == d->m_eventType)
- eventFilterType = QWindowsContextPrivate::GenericWindowsEventFilter;
- if (eventFilterType < 0) {
- qWarning("%s: Attempt to set unsupported event filter '%s'.",
- __FUNCTION__, eventType.constData());
- return 0;
- }
- const EventFilter previous = d->m_eventFilters[eventFilterType];
- d->m_eventFilters[eventFilterType] = filter;
- return previous;
-}
-
-/*!
\brief Main windows procedure registered for windows.
\sa QWindowsGuiEventDispatcher
@@ -736,11 +706,10 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message,
msg.pt.y = GET_Y_LPARAM(lParam);
long filterResult = 0;
- if (d->m_eventFilters[QWindowsContextPrivate::GenericWindowsEventFilter]) {
- if (d->m_eventFilters[QWindowsContextPrivate::GenericWindowsEventFilter](&msg, &filterResult)) {
- *result = LRESULT(filterResult);
- return true;
- }
+ QCoreApplication* coreApp = QCoreApplication::instance();
+ if (coreApp && coreApp->filterNativeEvent(d->m_eventType, &msg, &filterResult)) {
+ *result = LRESULT(filterResult);
+ return true;
}
// Events without an associated QWindow or events we are not interested in.
switch (et) {
diff --git a/src/plugins/platforms/windows/qwindowscontext.h b/src/plugins/platforms/windows/qwindowscontext.h
index 0b18196abe..e4fde55464 100644
--- a/src/plugins/platforms/windows/qwindowscontext.h
+++ b/src/plugins/platforms/windows/qwindowscontext.h
@@ -107,7 +107,6 @@ class QWindowsContext
{
Q_DISABLE_COPY(QWindowsContext)
public:
- typedef bool (*EventFilter)(void *message, long *result);
enum SystemInfoFlags
{
@@ -143,8 +142,6 @@ public:
HDC displayContext() const;
int screenDepth() const;
- EventFilter setEventFilter(const QByteArray &eventType, EventFilter filter);
-
static QWindowsContext *instance();
static QString windowsErrorMessage(unsigned long errorCode);
diff --git a/src/plugins/platforms/windows/qwindowsintegration.cpp b/src/plugins/platforms/windows/qwindowsintegration.cpp
index 1ff142bc98..f32f8cd689 100644
--- a/src/plugins/platforms/windows/qwindowsintegration.cpp
+++ b/src/plugins/platforms/windows/qwindowsintegration.cpp
@@ -102,8 +102,6 @@ public:
#endif
virtual void *nativeResourceForWindow(const QByteArray &resource, QWindow *window);
virtual void *nativeResourceForBackingStore(const QByteArray &resource, QBackingStore *bs);
- virtual EventFilter setEventFilter(const QByteArray &eventType, EventFilter filter)
- { return QWindowsContext::instance()->setEventFilter(eventType, filter); }
Q_INVOKABLE void *createMessageWindow(const QString &classNameTemplate,
const QString &windowName,
diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp
index b808a74a83..7f197c8ad5 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection.cpp
@@ -270,7 +270,6 @@ QXcbWindow *QXcbConnection::platformWindowFromId(xcb_window_t id)
{ \
event_t *e = (event_t *)event; \
if (QXcbWindow *platformWindow = platformWindowFromId(e->windowMember)) { \
- long result = 0; \
handled = QWindowSystemInterface::handleNativeEvent(platformWindow->window(), m_nativeInterface->genericEventFilterType(), event, &result); \
if (!handled) \
platformWindow->handler(e); \
@@ -282,7 +281,6 @@ break;
{ \
event_t *e = (event_t *)event; \
if (QXcbWindow *platformWindow = platformWindowFromId(e->event)) { \
- long result = 0; \
handled = QWindowSystemInterface::handleNativeEvent(platformWindow->window(), m_nativeInterface->genericEventFilterType(), event, &result); \
if (!handled) \
m_keyboard->handler(platformWindow, e); \
@@ -543,10 +541,9 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event)
m_callLog.remove(0, i);
}
#endif
- bool handled = false;
- if (QPlatformNativeInterface::EventFilter filter = m_nativeInterface->eventFilter(QXcbNativeInterface::GenericEventFilter))
- handled = filter(event, 0);
+ long result = 0;
+ bool handled = QCoreApplication::instance()->filterNativeEvent(m_nativeInterface->genericEventFilterType(), event, &result);
uint response_type = event->response_type & ~0x80;
diff --git a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp
index a6647da8be..2948ee6aae 100644
--- a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp
+++ b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp
@@ -80,7 +80,6 @@ QXcbNativeInterface::QXcbNativeInterface() :
m_genericEventFilterType(QByteArrayLiteral("xcb_generic_event_t"))
{
- qFill(m_eventFilters, m_eventFilters + EventFilterCount, EventFilter(0));
}
void *QXcbNativeInterface::nativeResourceForContext(const QByteArray &resourceString, QOpenGLContext *context)
@@ -142,21 +141,6 @@ QPlatformNativeInterface::NativeResourceForContextFunction QXcbNativeInterface::
return 0;
}
-QPlatformNativeInterface::EventFilter QXcbNativeInterface::setEventFilter(const QByteArray &eventType, QPlatformNativeInterface::EventFilter filter)
-{
- int type = -1;
- if (eventType == m_genericEventFilterType)
- type = GenericEventFilter;
- if (type == -1) {
- qWarning("QXcbNativeInterface: %s: Attempt to set invalid event filter type '%s'.",
- Q_FUNC_INFO, eventType.constData());
- return 0;
- }
- const EventFilter oldFilter = m_eventFilters[type];
- m_eventFilters[type] = filter;
- return oldFilter;
-}
-
QXcbScreen *QXcbNativeInterface::qPlatformScreenForWindow(QWindow *window)
{
QXcbScreen *screen;
diff --git a/src/plugins/platforms/xcb/qxcbnativeinterface.h b/src/plugins/platforms/xcb/qxcbnativeinterface.h
index 8221d9a36b..c91b4d7e88 100644
--- a/src/plugins/platforms/xcb/qxcbnativeinterface.h
+++ b/src/plugins/platforms/xcb/qxcbnativeinterface.h
@@ -61,11 +61,6 @@ public:
EglContext
};
- enum EventFilterType {
- GenericEventFilter,
- EventFilterCount
- };
-
QXcbNativeInterface();
void *nativeResourceForContext(const QByteArray &resourceString, QOpenGLContext *context);
@@ -74,8 +69,6 @@ public:
NativeResourceForContextFunction nativeResourceFunctionForContext(const QByteArray &resource);
inline const QByteArray &genericEventFilterType() const { return m_genericEventFilterType; }
- EventFilter setEventFilter(const QByteArray &eventType, EventFilter filter);
- EventFilter eventFilter(EventFilterType type) const { return m_eventFilters[type]; }
void *displayForWindow(QWindow *window);
void *eglDisplayForWindow(QWindow *window);
@@ -86,7 +79,6 @@ public:
private:
const QByteArray m_genericEventFilterType;
- EventFilter m_eventFilters[EventFilterCount];
static QXcbScreen *qPlatformScreenForWindow(QWindow *window);
};
diff --git a/src/testlib/qbenchmarkevent.cpp b/src/testlib/qbenchmarkevent.cpp
index bbba0ba5d9..f37162ae9d 100644
--- a/src/testlib/qbenchmarkevent.cpp
+++ b/src/testlib/qbenchmarkevent.cpp
@@ -46,8 +46,10 @@
QT_BEGIN_NAMESPACE
-QAbstractEventDispatcher::EventFilter oldEventFilter = 0;
-qint64 QBenchmarkEvent::eventCounter = 0;
+QBenchmarkEvent::QBenchmarkEvent()
+ : eventCounter(0)
+{
+}
QBenchmarkEvent::~QBenchmarkEvent()
{
@@ -55,21 +57,19 @@ QBenchmarkEvent::~QBenchmarkEvent()
void QBenchmarkEvent::start()
{
- QBenchmarkEvent::eventCounter = 0;
- QAbstractEventDispatcher *parent = QAbstractEventDispatcher::instance();
- oldEventFilter = parent->setEventFilter(QBenchmarkEvent::eventCountingMechanism);
+ eventCounter = 0;
+ QAbstractEventDispatcher::instance()->installNativeEventFilter(this);
}
qint64 QBenchmarkEvent::checkpoint()
{
- return QBenchmarkEvent::eventCounter;
+ return eventCounter;
}
qint64 QBenchmarkEvent::stop()
{
- QAbstractEventDispatcher *parent = QAbstractEventDispatcher::instance();
- parent->setEventFilter(oldEventFilter);
- return QBenchmarkEvent::eventCounter;
+ QAbstractEventDispatcher::instance()->removeNativeEventFilter(this);
+ return eventCounter;
}
// It's very tempting to simply reject a measurement if 0 events
@@ -98,10 +98,13 @@ QTest::QBenchmarkMetric QBenchmarkEvent::metricType()
}
// This could be done in a much better way, this is just the beginning.
-bool QBenchmarkEvent::eventCountingMechanism(void *message)
+bool QBenchmarkEvent::nativeEventFilter(const QByteArray &eventType, void *message, long *result)
{
+ Q_UNUSED(eventType);
Q_UNUSED(message);
- QBenchmarkEvent::eventCounter++;
+ Q_UNUSED(result);
+
+ eventCounter++;
return false;
}
diff --git a/src/testlib/qbenchmarkevent_p.h b/src/testlib/qbenchmarkevent_p.h
index c4d98bf8a1..938ce13f3c 100644
--- a/src/testlib/qbenchmarkevent_p.h
+++ b/src/testlib/qbenchmarkevent_p.h
@@ -56,12 +56,14 @@
#include <QtTest/private/qbenchmarkmeasurement_p.h>
#include <QAbstractEventDispatcher>
#include <QObject>
+#include <QAbstractNativeEventFilter>
QT_BEGIN_NAMESPACE
-class QBenchmarkEvent : public QBenchmarkMeasurerBase
+class QBenchmarkEvent : public QBenchmarkMeasurerBase, public QAbstractNativeEventFilter
{
public:
+ QBenchmarkEvent();
~QBenchmarkEvent();
void start();
qint64 checkpoint();
@@ -71,8 +73,8 @@ public:
int adjustMedianCount(int suggestion);
bool repeatCount() { return 1; }
QTest::QBenchmarkMetric metricType();
- static bool eventCountingMechanism(void *message);
- static qint64 eventCounter;
+ virtual bool nativeEventFilter(const QByteArray &eventType, void *message, long *result);
+ qint64 eventCounter;
};
QT_END_NAMESPACE
diff --git a/tests/auto/testlib/selftests/benchlibeventcounter/tst_benchlibeventcounter.cpp b/tests/auto/testlib/selftests/benchlibeventcounter/tst_benchlibeventcounter.cpp
index b077291cc6..966c81ec30 100644
--- a/tests/auto/testlib/selftests/benchlibeventcounter/tst_benchlibeventcounter.cpp
+++ b/tests/auto/testlib/selftests/benchlibeventcounter/tst_benchlibeventcounter.cpp
@@ -87,7 +87,7 @@ void tst_BenchlibEventCounter::events()
QAbstractEventDispatcher* ed = QAbstractEventDispatcher::instance();
QBENCHMARK {
for (int i = 0; i < eventCount; ++i) {
- ed->filterEvent(0);
+ ed->filterNativeEvent("", 0, 0);
}
}
}
diff --git a/tests/auto/testlib/selftests/benchliboptions/tst_benchliboptions.cpp b/tests/auto/testlib/selftests/benchliboptions/tst_benchliboptions.cpp
index 7673aa396e..c60addf972 100644
--- a/tests/auto/testlib/selftests/benchliboptions/tst_benchliboptions.cpp
+++ b/tests/auto/testlib/selftests/benchliboptions/tst_benchliboptions.cpp
@@ -88,9 +88,9 @@ void tst_BenchlibOptions::threeEvents()
{
QAbstractEventDispatcher* ed = QAbstractEventDispatcher::instance();
QBENCHMARK {
- ed->filterEvent(0);
- ed->filterEvent(0);
- ed->filterEvent(0);
+ ed->filterNativeEvent("", 0, 0);
+ ed->filterNativeEvent("", 0, 0);
+ ed->filterNativeEvent("", 0, 0);
}
}
diff --git a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp
index 37e945ddb1..c670c5bf72 100644
--- a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp
+++ b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp
@@ -71,6 +71,7 @@
#include <qcompleter.h>
#include <qtableview.h>
#include <qtreewidget.h>
+#include <qabstractnativeeventfilter.h>
#include <QtWidgets/QGraphicsView>
#include <QtWidgets/QGraphicsProxyWidget>
@@ -5505,16 +5506,17 @@ void tst_QWidget::minAndMaxSizeWithX11BypassWindowManagerHint()
}
}
-class ShowHideShowWidget : public QWidget
+class ShowHideShowWidget : public QWidget, public QAbstractNativeEventFilter
{
Q_OBJECT
int state;
public:
bool gotExpectedMapNotify;
+ bool gotExpectedGlobalEvent;
ShowHideShowWidget()
- : state(0), gotExpectedMapNotify(false)
+ : state(0), gotExpectedMapNotify(false), gotExpectedGlobalEvent(false)
{
startTimer(1000);
}
@@ -5531,19 +5533,32 @@ public:
}
}
- bool nativeEvent(const QByteArray &eventType, void *message, long *)
+ bool isMapNotify(const QByteArray &eventType, void *message)
{
enum { XCB_MAP_NOTIFY = 19 };
-
if (state == 1 && eventType == QByteArrayLiteral("xcb_generic_event_t")) {
// XCB events have a uint8 response_type member at the beginning.
const unsigned char responseType = *(const unsigned char *)(message);
- if ((responseType & ~0x80) == XCB_MAP_NOTIFY)
- gotExpectedMapNotify = true;
+ return ((responseType & ~0x80) == XCB_MAP_NOTIFY);
}
return false;
}
+ bool nativeEvent(const QByteArray &eventType, void *message, long *)
+ {
+ if (isMapNotify(eventType, message))
+ gotExpectedMapNotify = true;
+ return false;
+ }
+
+ // QAbstractNativeEventFilter interface
+ virtual bool nativeEventFilter(const QByteArray &eventType, void *message, long *) Q_DECL_OVERRIDE
+ {
+ if (isMapNotify(eventType, message))
+ gotExpectedGlobalEvent = true;
+ return false;
+ }
+
signals:
void done();
};
@@ -5554,6 +5569,8 @@ void tst_QWidget::showHideShowX11()
QSKIP("This test is for X11 only.");
ShowHideShowWidget w;
+ qApp->installNativeEventFilter(&w);
+
w.show();
w.hide();
@@ -5561,6 +5578,7 @@ void tst_QWidget::showHideShowX11()
connect(&w, SIGNAL(done()), &eventLoop, SLOT(quit()));
eventLoop.exec();
+ QVERIFY(w.gotExpectedGlobalEvent);
QVERIFY(w.gotExpectedMapNotify);
}