Add support for platform plugin specific event filters.
The setEventFilter on the platform native interface allows subscribing to events on the backend by event name. Change-Id: Ib10077fbc69f0207edbae1177e7bbd18c8d0f9ae Reviewed-by: Jørgen Lind <jorgen.lind@nokia.com> Reviewed-by: Michalina Ziemba <michalina.ziemba@nokia.com>
This commit is contained in:
parent
8060dd3c42
commit
1ca05bb0c1
@ -106,4 +106,51 @@ void QPlatformNativeInterface::setWindowProperty(QPlatformWindow *window, const
|
|||||||
Q_UNUSED(value);
|
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 \i 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
|
QT_END_NAMESPACE
|
||||||
|
@ -70,6 +70,9 @@ public:
|
|||||||
virtual QVariant windowProperty(QPlatformWindow *window, const QString &name, const QVariant &defaultValue) const;
|
virtual QVariant windowProperty(QPlatformWindow *window, const QString &name, const QVariant &defaultValue) const;
|
||||||
virtual void setWindowProperty(QPlatformWindow *window, const QString &name, const QVariant &value);
|
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:
|
Q_SIGNALS:
|
||||||
void windowPropertyChanged(QPlatformWindow *window, const QString &propertyName);
|
void windowPropertyChanged(QPlatformWindow *window, const QString &propertyName);
|
||||||
};
|
};
|
||||||
|
@ -49,11 +49,13 @@
|
|||||||
#include "qxcbclipboard.h"
|
#include "qxcbclipboard.h"
|
||||||
#include "qxcbdrag.h"
|
#include "qxcbdrag.h"
|
||||||
#include "qxcbwmsupport.h"
|
#include "qxcbwmsupport.h"
|
||||||
|
#include "qxcbnativeinterface.h"
|
||||||
|
|
||||||
#include <QtAlgorithms>
|
#include <QtAlgorithms>
|
||||||
#include <QSocketNotifier>
|
#include <QSocketNotifier>
|
||||||
#include <QAbstractEventDispatcher>
|
#include <QAbstractEventDispatcher>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
|
#include <QByteArray>
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
@ -93,9 +95,10 @@ static int nullErrorHandler(Display *, XErrorEvent *)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
QXcbConnection::QXcbConnection(const char *displayName)
|
QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, const char *displayName)
|
||||||
: m_connection(0)
|
: m_connection(0)
|
||||||
, m_displayName(displayName ? QByteArray(displayName) : qgetenv("DISPLAY"))
|
, m_displayName(displayName ? QByteArray(displayName) : qgetenv("DISPLAY"))
|
||||||
|
, m_nativeInterface(nativeInterface)
|
||||||
#ifdef XCB_USE_XINPUT2_MAEMO
|
#ifdef XCB_USE_XINPUT2_MAEMO
|
||||||
, m_xinputData(0)
|
, m_xinputData(0)
|
||||||
#endif
|
#endif
|
||||||
@ -493,72 +496,77 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event)
|
|||||||
m_callLog.remove(0, i);
|
m_callLog.remove(0, i);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
bool handled = true;
|
bool handled = false;
|
||||||
|
|
||||||
|
if (QPlatformNativeInterface::EventFilter filter = m_nativeInterface->eventFilterForEventType(QByteArrayLiteral("xcb_generic_event_t")))
|
||||||
|
handled = filter(event, 0);
|
||||||
|
|
||||||
uint response_type = event->response_type & ~0x80;
|
uint response_type = event->response_type & ~0x80;
|
||||||
|
|
||||||
switch (response_type) {
|
if (!handled) {
|
||||||
case XCB_EXPOSE:
|
switch (response_type) {
|
||||||
HANDLE_PLATFORM_WINDOW_EVENT(xcb_expose_event_t, window, handleExposeEvent);
|
case XCB_EXPOSE:
|
||||||
case XCB_BUTTON_PRESS:
|
HANDLE_PLATFORM_WINDOW_EVENT(xcb_expose_event_t, window, handleExposeEvent);
|
||||||
HANDLE_PLATFORM_WINDOW_EVENT(xcb_button_press_event_t, event, handleButtonPressEvent);
|
case XCB_BUTTON_PRESS:
|
||||||
case XCB_BUTTON_RELEASE:
|
HANDLE_PLATFORM_WINDOW_EVENT(xcb_button_press_event_t, event, handleButtonPressEvent);
|
||||||
HANDLE_PLATFORM_WINDOW_EVENT(xcb_button_release_event_t, event, handleButtonReleaseEvent);
|
case XCB_BUTTON_RELEASE:
|
||||||
case XCB_MOTION_NOTIFY:
|
HANDLE_PLATFORM_WINDOW_EVENT(xcb_button_release_event_t, event, handleButtonReleaseEvent);
|
||||||
HANDLE_PLATFORM_WINDOW_EVENT(xcb_motion_notify_event_t, event, handleMotionNotifyEvent);
|
case XCB_MOTION_NOTIFY:
|
||||||
case XCB_CONFIGURE_NOTIFY:
|
HANDLE_PLATFORM_WINDOW_EVENT(xcb_motion_notify_event_t, event, handleMotionNotifyEvent);
|
||||||
HANDLE_PLATFORM_WINDOW_EVENT(xcb_configure_notify_event_t, event, handleConfigureNotifyEvent);
|
case XCB_CONFIGURE_NOTIFY:
|
||||||
case XCB_MAP_NOTIFY:
|
HANDLE_PLATFORM_WINDOW_EVENT(xcb_configure_notify_event_t, event, handleConfigureNotifyEvent);
|
||||||
HANDLE_PLATFORM_WINDOW_EVENT(xcb_map_notify_event_t, event, handleMapNotifyEvent);
|
case XCB_MAP_NOTIFY:
|
||||||
case XCB_UNMAP_NOTIFY:
|
HANDLE_PLATFORM_WINDOW_EVENT(xcb_map_notify_event_t, event, handleMapNotifyEvent);
|
||||||
HANDLE_PLATFORM_WINDOW_EVENT(xcb_unmap_notify_event_t, event, handleUnmapNotifyEvent);
|
case XCB_UNMAP_NOTIFY:
|
||||||
case XCB_CLIENT_MESSAGE:
|
HANDLE_PLATFORM_WINDOW_EVENT(xcb_unmap_notify_event_t, event, handleUnmapNotifyEvent);
|
||||||
handleClientMessageEvent((xcb_client_message_event_t *)event);
|
case XCB_CLIENT_MESSAGE:
|
||||||
case XCB_ENTER_NOTIFY:
|
handleClientMessageEvent((xcb_client_message_event_t *)event);
|
||||||
HANDLE_PLATFORM_WINDOW_EVENT(xcb_enter_notify_event_t, event, handleEnterNotifyEvent);
|
case XCB_ENTER_NOTIFY:
|
||||||
case XCB_LEAVE_NOTIFY:
|
HANDLE_PLATFORM_WINDOW_EVENT(xcb_enter_notify_event_t, event, handleEnterNotifyEvent);
|
||||||
HANDLE_PLATFORM_WINDOW_EVENT(xcb_leave_notify_event_t, event, handleLeaveNotifyEvent);
|
case XCB_LEAVE_NOTIFY:
|
||||||
case XCB_FOCUS_IN:
|
HANDLE_PLATFORM_WINDOW_EVENT(xcb_leave_notify_event_t, event, handleLeaveNotifyEvent);
|
||||||
HANDLE_PLATFORM_WINDOW_EVENT(xcb_focus_in_event_t, event, handleFocusInEvent);
|
case XCB_FOCUS_IN:
|
||||||
case XCB_FOCUS_OUT:
|
HANDLE_PLATFORM_WINDOW_EVENT(xcb_focus_in_event_t, event, handleFocusInEvent);
|
||||||
HANDLE_PLATFORM_WINDOW_EVENT(xcb_focus_out_event_t, event, handleFocusOutEvent);
|
case XCB_FOCUS_OUT:
|
||||||
case XCB_KEY_PRESS:
|
HANDLE_PLATFORM_WINDOW_EVENT(xcb_focus_out_event_t, event, handleFocusOutEvent);
|
||||||
HANDLE_KEYBOARD_EVENT(xcb_key_press_event_t, handleKeyPressEvent);
|
case XCB_KEY_PRESS:
|
||||||
case XCB_KEY_RELEASE:
|
HANDLE_KEYBOARD_EVENT(xcb_key_press_event_t, handleKeyPressEvent);
|
||||||
HANDLE_KEYBOARD_EVENT(xcb_key_release_event_t, handleKeyReleaseEvent);
|
case XCB_KEY_RELEASE:
|
||||||
case XCB_MAPPING_NOTIFY:
|
HANDLE_KEYBOARD_EVENT(xcb_key_release_event_t, handleKeyReleaseEvent);
|
||||||
m_keyboard->handleMappingNotifyEvent((xcb_mapping_notify_event_t *)event);
|
case XCB_MAPPING_NOTIFY:
|
||||||
break;
|
m_keyboard->handleMappingNotifyEvent((xcb_mapping_notify_event_t *)event);
|
||||||
case XCB_SELECTION_REQUEST:
|
break;
|
||||||
{
|
case XCB_SELECTION_REQUEST:
|
||||||
xcb_selection_request_event_t *sr = (xcb_selection_request_event_t *)event;
|
{
|
||||||
if (sr->selection == atom(QXcbAtom::XdndSelection))
|
xcb_selection_request_event_t *sr = (xcb_selection_request_event_t *)event;
|
||||||
m_drag->handleSelectionRequest(sr);
|
if (sr->selection == atom(QXcbAtom::XdndSelection))
|
||||||
else
|
m_drag->handleSelectionRequest(sr);
|
||||||
m_clipboard->handleSelectionRequest(sr);
|
else
|
||||||
break;
|
m_clipboard->handleSelectionRequest(sr);
|
||||||
}
|
break;
|
||||||
case XCB_SELECTION_CLEAR:
|
}
|
||||||
setTime(((xcb_selection_clear_event_t *)event)->time);
|
case XCB_SELECTION_CLEAR:
|
||||||
m_clipboard->handleSelectionClearRequest((xcb_selection_clear_event_t *)event);
|
setTime(((xcb_selection_clear_event_t *)event)->time);
|
||||||
handled = true;
|
m_clipboard->handleSelectionClearRequest((xcb_selection_clear_event_t *)event);
|
||||||
break;
|
handled = true;
|
||||||
case XCB_SELECTION_NOTIFY:
|
break;
|
||||||
setTime(((xcb_selection_notify_event_t *)event)->time);
|
case XCB_SELECTION_NOTIFY:
|
||||||
qDebug() << "XCB_SELECTION_NOTIFY";
|
setTime(((xcb_selection_notify_event_t *)event)->time);
|
||||||
handled = false;
|
qDebug() << "XCB_SELECTION_NOTIFY";
|
||||||
break;
|
handled = false;
|
||||||
case XCB_PROPERTY_NOTIFY:
|
break;
|
||||||
HANDLE_PLATFORM_WINDOW_EVENT(xcb_property_notify_event_t, window, handlePropertyNotifyEvent);
|
case XCB_PROPERTY_NOTIFY:
|
||||||
break;
|
HANDLE_PLATFORM_WINDOW_EVENT(xcb_property_notify_event_t, window, handlePropertyNotifyEvent);
|
||||||
#ifdef XCB_USE_XINPUT2_MAEMO
|
break;
|
||||||
case GenericEvent:
|
#ifdef XCB_USE_XINPUT2_MAEMO
|
||||||
handleGenericEvent((xcb_ge_event_t*)event);
|
case GenericEvent:
|
||||||
break;
|
handleGenericEvent((xcb_ge_event_t*)event);
|
||||||
#endif
|
break;
|
||||||
default:
|
#endif
|
||||||
handled = false;
|
default:
|
||||||
break;
|
handled = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!handled) {
|
if (!handled) {
|
||||||
|
@ -66,6 +66,7 @@ class QXcbDrag;
|
|||||||
class QXcbKeyboard;
|
class QXcbKeyboard;
|
||||||
class QXcbClipboard;
|
class QXcbClipboard;
|
||||||
class QXcbWMSupport;
|
class QXcbWMSupport;
|
||||||
|
class QXcbNativeInterface;
|
||||||
|
|
||||||
typedef QHash<xcb_window_t, QXcbWindow *> WindowMapper;
|
typedef QHash<xcb_window_t, QXcbWindow *> WindowMapper;
|
||||||
|
|
||||||
@ -289,7 +290,7 @@ class QXcbConnection : public QObject
|
|||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
QXcbConnection(const char *displayName = 0);
|
QXcbConnection(QXcbNativeInterface *nativeInterface, const char *displayName = 0);
|
||||||
~QXcbConnection();
|
~QXcbConnection();
|
||||||
|
|
||||||
QXcbConnection *connection() const { return const_cast<QXcbConnection *>(this); }
|
QXcbConnection *connection() const { return const_cast<QXcbConnection *>(this); }
|
||||||
@ -390,6 +391,7 @@ private:
|
|||||||
QXcbClipboard *m_clipboard;
|
QXcbClipboard *m_clipboard;
|
||||||
QXcbDrag *m_drag;
|
QXcbDrag *m_drag;
|
||||||
QScopedPointer<QXcbWMSupport> m_wmSupport;
|
QScopedPointer<QXcbWMSupport> m_wmSupport;
|
||||||
|
QXcbNativeInterface *m_nativeInterface;
|
||||||
|
|
||||||
#if defined(XCB_USE_XLIB)
|
#if defined(XCB_USE_XLIB)
|
||||||
void *m_xlib_display;
|
void *m_xlib_display;
|
||||||
|
@ -90,13 +90,14 @@ QXcbIntegration::QXcbIntegration(const QStringList ¶meters)
|
|||||||
#ifdef XCB_USE_XLIB
|
#ifdef XCB_USE_XLIB
|
||||||
XInitThreads();
|
XInitThreads();
|
||||||
#endif
|
#endif
|
||||||
|
m_nativeInterface.reset(new QXcbNativeInterface);
|
||||||
|
|
||||||
m_connections << new QXcbConnection;
|
m_connections << new QXcbConnection(m_nativeInterface.data());
|
||||||
|
|
||||||
for (int i = 0; i < parameters.size() - 1; i += 2) {
|
for (int i = 0; i < parameters.size() - 1; i += 2) {
|
||||||
qDebug() << parameters.at(i) << parameters.at(i+1);
|
qDebug() << parameters.at(i) << parameters.at(i+1);
|
||||||
QString display = parameters.at(i) + ':' + parameters.at(i+1);
|
QString display = parameters.at(i) + ':' + parameters.at(i+1);
|
||||||
m_connections << new QXcbConnection(display.toAscii().constData());
|
m_connections << new QXcbConnection(m_nativeInterface.data(), display.toAscii().constData());
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (QXcbConnection *connection, m_connections)
|
foreach (QXcbConnection *connection, m_connections)
|
||||||
@ -104,7 +105,6 @@ QXcbIntegration::QXcbIntegration(const QStringList ¶meters)
|
|||||||
screenAdded(screen);
|
screenAdded(screen);
|
||||||
|
|
||||||
m_fontDatabase.reset(new QGenericUnixFontDatabase());
|
m_fontDatabase.reset(new QGenericUnixFontDatabase());
|
||||||
m_nativeInterface.reset(new QXcbNativeInterface);
|
|
||||||
m_inputContext.reset(QPlatformInputContextFactory::create());
|
m_inputContext.reset(QPlatformInputContextFactory::create());
|
||||||
m_accessibility.reset(new QPlatformAccessibility());
|
m_accessibility.reset(new QPlatformAccessibility());
|
||||||
}
|
}
|
||||||
|
@ -49,6 +49,7 @@ QT_BEGIN_NAMESPACE
|
|||||||
|
|
||||||
class QXcbConnection;
|
class QXcbConnection;
|
||||||
class QAbstractEventDispatcher;
|
class QAbstractEventDispatcher;
|
||||||
|
class QXcbNativeInterface;
|
||||||
|
|
||||||
class QXcbIntegration : public QPlatformIntegration
|
class QXcbIntegration : public QPlatformIntegration
|
||||||
{
|
{
|
||||||
@ -80,7 +81,7 @@ private:
|
|||||||
QList<QXcbConnection *> m_connections;
|
QList<QXcbConnection *> m_connections;
|
||||||
|
|
||||||
QScopedPointer<QPlatformFontDatabase> m_fontDatabase;
|
QScopedPointer<QPlatformFontDatabase> m_fontDatabase;
|
||||||
QScopedPointer<QPlatformNativeInterface> m_nativeInterface;
|
QScopedPointer<QXcbNativeInterface> m_nativeInterface;
|
||||||
|
|
||||||
QScopedPointer<QPlatformInputContext> m_inputContext;
|
QScopedPointer<QPlatformInputContext> m_inputContext;
|
||||||
QAbstractEventDispatcher *m_eventDispatcher;
|
QAbstractEventDispatcher *m_eventDispatcher;
|
||||||
|
@ -118,6 +118,18 @@ void *QXcbNativeInterface::nativeResourceForWindow(const QByteArray &resourceStr
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QPlatformNativeInterface::EventFilter QXcbNativeInterface::setEventFilter(const QByteArray &eventType, QPlatformNativeInterface::EventFilter filter)
|
||||||
|
{
|
||||||
|
EventFilter oldFilter = m_eventFilters.value(eventType);
|
||||||
|
m_eventFilters.insert(eventType, filter);
|
||||||
|
return oldFilter;
|
||||||
|
}
|
||||||
|
|
||||||
|
QPlatformNativeInterface::EventFilter QXcbNativeInterface::eventFilterForEventType(const QByteArray& eventType) const
|
||||||
|
{
|
||||||
|
return m_eventFilters.value(eventType);
|
||||||
|
}
|
||||||
|
|
||||||
QXcbScreen *QXcbNativeInterface::qPlatformScreenForWindow(QWindow *window)
|
QXcbScreen *QXcbNativeInterface::qPlatformScreenForWindow(QWindow *window)
|
||||||
{
|
{
|
||||||
QXcbScreen *screen;
|
QXcbScreen *screen;
|
||||||
|
@ -64,6 +64,9 @@ public:
|
|||||||
void *nativeResourceForContext(const QByteArray &resourceString, QOpenGLContext *context);
|
void *nativeResourceForContext(const QByteArray &resourceString, QOpenGLContext *context);
|
||||||
void *nativeResourceForWindow(const QByteArray &resourceString, QWindow *window);
|
void *nativeResourceForWindow(const QByteArray &resourceString, QWindow *window);
|
||||||
|
|
||||||
|
EventFilter setEventFilter(const QByteArray &eventType, EventFilter filter);
|
||||||
|
EventFilter eventFilterForEventType(const QByteArray& eventType) const;
|
||||||
|
|
||||||
void *displayForWindow(QWindow *window);
|
void *displayForWindow(QWindow *window);
|
||||||
void *eglDisplayForWindow(QWindow *window);
|
void *eglDisplayForWindow(QWindow *window);
|
||||||
void *connectionForWindow(QWindow *window);
|
void *connectionForWindow(QWindow *window);
|
||||||
@ -73,6 +76,8 @@ public:
|
|||||||
void *eglContextForContext(QOpenGLContext *context);
|
void *eglContextForContext(QOpenGLContext *context);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
QHash<QByteArray, EventFilter> m_eventFilters;
|
||||||
|
|
||||||
static QXcbScreen *qPlatformScreenForWindow(QWindow *window);
|
static QXcbScreen *qPlatformScreenForWindow(QWindow *window);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user