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>
This commit is contained in:
parent
7288625c52
commit
fca94fa5ed
@ -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;
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
bool handleGenericEvent(xcb_generic_event_t *event, long *result) Q_DECL_OVERRIDE;
|
||||
|
||||
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);
|
||||
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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user