summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJørgen Lind <jorgen.lind@digia.com>2013-04-26 08:39:20 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-04-26 14:18:16 +0200
commitfca94fa5ed8321e84e7b0ff515620fbb901db545 (patch)
tree0172dcecbc859ced094a7ce4665f70902b7dbf7d
parent7288625c52749f566570a7e7ef047faa8171b18c (diff)
Add QXcbWindowEventListener
This makes it possible to listen for events on xcb_window_t which are not platformwindows inside the xcb plugin Change-Id: Ic9ec17ed757a7f9a5302ef2759c119a72bac573c Reviewed-by: Samuel Rødal <samuel.rodal@digia.com>
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.cpp28
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.h33
-rw-r--r--src/plugins/platforms/xcb/qxcbkeyboard.cpp10
-rw-r--r--src/plugins/platforms/xcb/qxcbkeyboard.h4
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.cpp17
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.h34
6 files changed, 90 insertions, 36 deletions
diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp
index 0597b18679..10a8f26614 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection.cpp
@@ -391,28 +391,36 @@ QXcbConnection::~QXcbConnection()
delete m_keyboard;
}
-void QXcbConnection::addWindow(xcb_window_t id, QXcbWindow *window)
+void QXcbConnection::addWindowEventListener(xcb_window_t id, QXcbWindowEventListener *eventListener)
{
- m_mapper.insert(id, window);
+ m_mapper.insert(id, eventListener);
}
-void QXcbConnection::removeWindow(xcb_window_t id)
+void QXcbConnection::removeWindowEventListener(xcb_window_t id)
{
m_mapper.remove(id);
}
-QXcbWindow *QXcbConnection::platformWindowFromId(xcb_window_t id)
+QXcbWindowEventListener *QXcbConnection::windowEventListenerFromId(xcb_window_t id)
{
return m_mapper.value(id, 0);
}
+QXcbWindow *QXcbConnection::platformWindowFromId(xcb_window_t id)
+{
+ QXcbWindowEventListener *listener = m_mapper.value(id, 0);
+ if (listener)
+ return listener->toWindow();
+ return 0;
+}
+
#define HANDLE_PLATFORM_WINDOW_EVENT(event_t, windowMember, handler) \
{ \
event_t *e = (event_t *)event; \
- if (QXcbWindow *platformWindow = platformWindowFromId(e->windowMember)) { \
- handled = QWindowSystemInterface::handleNativeEvent(platformWindow->window(), m_nativeInterface->genericEventFilterType(), event, &result); \
+ if (QXcbWindowEventListener *eventListener = windowEventListenerFromId(e->windowMember)) { \
+ handled = eventListener->handleGenericEvent(event, &result); \
if (!handled) \
- platformWindow->handler(e); \
+ eventListener->handler(e); \
} \
} \
break;
@@ -420,10 +428,10 @@ break;
#define HANDLE_KEYBOARD_EVENT(event_t, handler) \
{ \
event_t *e = (event_t *)event; \
- if (QXcbWindow *platformWindow = platformWindowFromId(e->event)) { \
- handled = QWindowSystemInterface::handleNativeEvent(platformWindow->window(), m_nativeInterface->genericEventFilterType(), event, &result); \
+ if (QXcbWindowEventListener *eventListener = windowEventListenerFromId(e->event)) { \
+ handled = eventListener->handleGenericEvent(event, &result); \
if (!handled) \
- m_keyboard->handler(m_focusWindow ? m_focusWindow : platformWindow, e); \
+ m_keyboard->handler(m_focusWindow ? m_focusWindow : eventListener, e); \
} \
} \
break;
diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h
index 27de5a4e83..44c0e28dd5 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.h
+++ b/src/plugins/platforms/xcb/qxcbconnection.h
@@ -80,8 +80,6 @@ class QXcbClipboard;
class QXcbWMSupport;
class QXcbNativeInterface;
-typedef QHash<xcb_window_t, QXcbWindow *> WindowMapper;
-
namespace QXcbAtom {
enum Atom {
// window-manager <-> client protocols
@@ -301,6 +299,30 @@ private:
XcbPollForQueuedEventFunctionPointer m_xcb_poll_for_queued_event;
};
+class QXcbWindowEventListener
+{
+public:
+ virtual bool handleGenericEvent(xcb_generic_event_t *, long *) { return false; }
+
+ virtual void handleExposeEvent(const xcb_expose_event_t *) {}
+ virtual void handleClientMessageEvent(const xcb_client_message_event_t *) {}
+ virtual void handleConfigureNotifyEvent(const xcb_configure_notify_event_t *) {}
+ virtual void handleMapNotifyEvent(const xcb_map_notify_event_t *) {}
+ virtual void handleUnmapNotifyEvent(const xcb_unmap_notify_event_t *) {}
+ virtual void handleButtonPressEvent(const xcb_button_press_event_t *) {}
+ virtual void handleButtonReleaseEvent(const xcb_button_release_event_t *) {}
+ virtual void handleMotionNotifyEvent(const xcb_motion_notify_event_t *) {}
+ virtual void handleEnterNotifyEvent(const xcb_enter_notify_event_t *) {}
+ virtual void handleLeaveNotifyEvent(const xcb_leave_notify_event_t *) {}
+ virtual void handleFocusInEvent(const xcb_focus_in_event_t *) {}
+ virtual void handleFocusOutEvent(const xcb_focus_out_event_t *) {}
+ virtual void handlePropertyNotifyEvent(const xcb_property_notify_event_t *) {}
+
+ virtual QXcbWindow *toWindow() { return 0; }
+};
+
+typedef QHash<xcb_window_t, QXcbWindowEventListener *> WindowMapper;
+
class QAbstractEventDispatcher;
class QXcbConnection : public QObject
{
@@ -356,8 +378,9 @@ public:
void handleXcbError(xcb_generic_error_t *error);
void handleXcbEvent(xcb_generic_event_t *event);
- void addWindow(xcb_window_t id, QXcbWindow *window);
- void removeWindow(xcb_window_t id);
+ void addWindowEventListener(xcb_window_t id, QXcbWindowEventListener *eventListener);
+ void removeWindowEventListener(xcb_window_t id);
+ QXcbWindowEventListener *windowEventListenerFromId(xcb_window_t id);
QXcbWindow *platformWindowFromId(xcb_window_t id);
xcb_generic_event_t *checkEvent(int type);
@@ -393,6 +416,8 @@ public:
void grabServer();
void ungrabServer();
+
+ QXcbNativeInterface *nativeInterface() const { return m_nativeInterface; }
private slots:
void processXcbEvents();
diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.cpp b/src/plugins/platforms/xcb/qxcbkeyboard.cpp
index 4ac60f6077..51c400ed9c 100644
--- a/src/plugins/platforms/xcb/qxcbkeyboard.cpp
+++ b/src/plugins/platforms/xcb/qxcbkeyboard.cpp
@@ -1172,14 +1172,20 @@ xcb_keysym_t QXcbKeyboard::lookupString(QWindow *window, uint state, xcb_keycode
#endif
}
-void QXcbKeyboard::handleKeyPressEvent(QXcbWindow *window, const xcb_key_press_event_t *event)
+void QXcbKeyboard::handleKeyPressEvent(QXcbWindowEventListener *eventListener, const xcb_key_press_event_t *event)
{
+ QXcbWindow *window = eventListener->toWindow();
+ if (!window)
+ return;
window->updateNetWmUserTime(event->time);
handleKeyEvent(window->window(), QEvent::KeyPress, event->detail, event->state, event->time);
}
-void QXcbKeyboard::handleKeyReleaseEvent(QXcbWindow *window, const xcb_key_release_event_t *event)
+void QXcbKeyboard::handleKeyReleaseEvent(QXcbWindowEventListener *eventListener, const xcb_key_release_event_t *event)
{
+ QXcbWindow *window = eventListener->toWindow();
+ if (!window)
+ return;
handleKeyEvent(window->window(), QEvent::KeyRelease, event->detail, event->state, event->time);
}
diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.h b/src/plugins/platforms/xcb/qxcbkeyboard.h
index da25c51107..3c71daa57f 100644
--- a/src/plugins/platforms/xcb/qxcbkeyboard.h
+++ b/src/plugins/platforms/xcb/qxcbkeyboard.h
@@ -58,8 +58,8 @@ public:
QXcbKeyboard(QXcbConnection *connection);
~QXcbKeyboard();
- void handleKeyPressEvent(QXcbWindow *window, const xcb_key_press_event_t *event);
- void handleKeyReleaseEvent(QXcbWindow *window, const xcb_key_release_event_t *event);
+ void handleKeyPressEvent(QXcbWindowEventListener *eventListener, const xcb_key_press_event_t *event);
+ void handleKeyReleaseEvent(QXcbWindowEventListener *eventListener, const xcb_key_release_event_t *event);
void handleMappingNotifyEvent(const xcb_mapping_notify_event_t *event);
diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp
index 7d6d6a94b3..c845b875bf 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.cpp
+++ b/src/plugins/platforms/xcb/qxcbwindow.cpp
@@ -53,6 +53,7 @@
#include "qxcbkeyboard.h"
#include "qxcbwmsupport.h"
#include "qxcbimage.h"
+#include "qxcbnativeinterface.h"
#include <qpa/qplatformintegration.h>
@@ -224,7 +225,7 @@ void QXcbWindow::create()
m_window = m_screen->root();
m_depth = m_screen->screen()->root_depth;
m_imageFormat = imageFormatForDepth(m_depth);
- connection()->addWindow(m_window, this);
+ connection()->addWindowEventListener(m_window, this);
return;
}
@@ -347,7 +348,7 @@ void QXcbWindow::create()
0)); // value list
}
- connection()->addWindow(m_window, this);
+ connection()->addWindowEventListener(m_window, this);
Q_XCB_CALL(xcb_change_window_attributes(xcb_connection(), m_window, mask, values));
@@ -481,7 +482,7 @@ void QXcbWindow::destroy()
xcb_destroy_window(xcb_connection(), m_netWmUserTimeWindow);
m_netWmUserTimeWindow = XCB_NONE;
}
- connection()->removeWindow(m_window);
+ connection()->removeWindowEventListener(m_window);
Q_XCB_CALL(xcb_destroy_window(xcb_connection(), m_window));
m_window = 0;
}
@@ -1447,6 +1448,14 @@ private:
bool m_pending;
};
+bool QXcbWindow::handleGenericEvent(xcb_generic_event_t *event, long *result)
+{
+ return QWindowSystemInterface::handleNativeEvent(window(),
+ connection()->nativeInterface()->genericEventFilterType(),
+ event,
+ result);
+}
+
void QXcbWindow::handleExposeEvent(const xcb_expose_event_t *event)
{
QRect rect(event->x, event->y, event->width, event->height);
@@ -1682,6 +1691,8 @@ void QXcbWindow::handleMotionNotifyEvent(const xcb_motion_notify_event_t *event)
handleMouseEvent(event->time, local, global, modifiers);
}
+QXcbWindow *QXcbWindow::toWindow() { return this; }
+
void QXcbWindow::handleMouseEvent(xcb_timestamp_t time, const QPoint &local, const QPoint &global, Qt::KeyboardModifiers modifiers)
{
connection()->setTime(time);
diff --git a/src/plugins/platforms/xcb/qxcbwindow.h b/src/plugins/platforms/xcb/qxcbwindow.h
index 300596845e..5601a115e9 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.h
+++ b/src/plugins/platforms/xcb/qxcbwindow.h
@@ -56,7 +56,7 @@ QT_BEGIN_NAMESPACE
class QXcbScreen;
class QXcbEGLSurface;
class QIcon;
-class QXcbWindow : public QXcbObject, public QPlatformWindow
+class QXcbWindow : public QXcbObject, public QXcbWindowEventListener, public QPlatformWindow
{
public:
enum NetWmState {
@@ -126,20 +126,24 @@ public:
uint depth() const { return m_depth; }
QImage::Format imageFormat() const { return m_imageFormat; }
- void handleExposeEvent(const xcb_expose_event_t *event);
- void handleClientMessageEvent(const xcb_client_message_event_t *event);
- void handleConfigureNotifyEvent(const xcb_configure_notify_event_t *event);
- void handleMapNotifyEvent(const xcb_map_notify_event_t *event);
- void handleUnmapNotifyEvent(const xcb_unmap_notify_event_t *event);
- void handleButtonPressEvent(const xcb_button_press_event_t *event);
- void handleButtonReleaseEvent(const xcb_button_release_event_t *event);
- void handleMotionNotifyEvent(const xcb_motion_notify_event_t *event);
-
- void handleEnterNotifyEvent(const xcb_enter_notify_event_t *event);
- void handleLeaveNotifyEvent(const xcb_leave_notify_event_t *event);
- void handleFocusInEvent(const xcb_focus_in_event_t *event);
- void handleFocusOutEvent(const xcb_focus_out_event_t *event);
- void handlePropertyNotifyEvent(const xcb_property_notify_event_t *event);
+ bool handleGenericEvent(xcb_generic_event_t *event, long *result) Q_DECL_OVERRIDE;
+
+ void handleExposeEvent(const xcb_expose_event_t *event) Q_DECL_OVERRIDE;
+ void handleClientMessageEvent(const xcb_client_message_event_t *event) Q_DECL_OVERRIDE;
+ void handleConfigureNotifyEvent(const xcb_configure_notify_event_t *event) Q_DECL_OVERRIDE;
+ void handleMapNotifyEvent(const xcb_map_notify_event_t *event) Q_DECL_OVERRIDE;
+ void handleUnmapNotifyEvent(const xcb_unmap_notify_event_t *event) Q_DECL_OVERRIDE;
+ void handleButtonPressEvent(const xcb_button_press_event_t *event) Q_DECL_OVERRIDE;
+ void handleButtonReleaseEvent(const xcb_button_release_event_t *event) Q_DECL_OVERRIDE;
+ void handleMotionNotifyEvent(const xcb_motion_notify_event_t *event) Q_DECL_OVERRIDE;
+
+ void handleEnterNotifyEvent(const xcb_enter_notify_event_t *event) Q_DECL_OVERRIDE;
+ void handleLeaveNotifyEvent(const xcb_leave_notify_event_t *event) Q_DECL_OVERRIDE;
+ void handleFocusInEvent(const xcb_focus_in_event_t *event) Q_DECL_OVERRIDE;
+ void handleFocusOutEvent(const xcb_focus_out_event_t *event) Q_DECL_OVERRIDE;
+ void handlePropertyNotifyEvent(const xcb_property_notify_event_t *event) Q_DECL_OVERRIDE;
+
+ QXcbWindow *toWindow() Q_DECL_OVERRIDE;
void handleMouseEvent(xcb_timestamp_t time, const QPoint &local, const QPoint &global, Qt::KeyboardModifiers modifiers);