summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/xcb
diff options
context:
space:
mode:
authorOswald Buddenhagen <oswald.buddenhagen@qt.io>2018-08-21 02:32:49 +0200
committerOswald Buddenhagen <oswald.buddenhagen@qt.io>2018-08-21 02:32:50 +0200
commit5a03b75c50b2e34552c7ec3e1e15e7b2a0128bf7 (patch)
tree88e05cd6150e0b3cda4e8716668082c655007fb8 /src/plugins/platforms/xcb
parent0e7724079f1eae283714ae12769d1372b8f85659 (diff)
parent6553921dd537e416da2f4d1441ab6d63059cda60 (diff)
Merge dev into 5.12
Diffstat (limited to 'src/plugins/platforms/xcb')
-rw-r--r--src/plugins/platforms/xcb/gl_integrations/xcb_glx/qxcbglxintegration.cpp4
-rw-r--r--src/plugins/platforms/xcb/qxcbbackingstore.cpp143
-rw-r--r--src/plugins/platforms/xcb/qxcbclipboard.cpp91
-rw-r--r--src/plugins/platforms/xcb/qxcbclipboard.h2
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.cpp414
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.h24
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection_xi2.cpp3
-rw-r--r--src/plugins/platforms/xcb/qxcbdrag.cpp14
-rw-r--r--src/plugins/platforms/xcb/qxcbimage.cpp4
-rw-r--r--src/plugins/platforms/xcb/qxcbkeyboard.cpp119
-rw-r--r--src/plugins/platforms/xcb/qxcbkeyboard.h3
-rw-r--r--src/plugins/platforms/xcb/qxcbnativeinterface.cpp5
-rw-r--r--src/plugins/platforms/xcb/qxcbnativeinterface.h4
-rw-r--r--src/plugins/platforms/xcb/qxcbscreen.cpp16
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.cpp124
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.h4
16 files changed, 410 insertions, 564 deletions
diff --git a/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qxcbglxintegration.cpp b/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qxcbglxintegration.cpp
index a7641baea1..b751aaf8a3 100644
--- a/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qxcbglxintegration.cpp
+++ b/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qxcbglxintegration.cpp
@@ -163,9 +163,9 @@ bool QXcbGlxIntegration::handleXcbEvent(xcb_generic_event_t *event, uint respons
// Unlock the display before calling the native event filter
XUnlockDisplay(xdisplay);
locked = false;
- QByteArray genericEventFilterType = m_connection->nativeInterface()->genericEventFilterType();
+ auto eventType = m_connection->nativeInterface()->nativeEventType();
long result = 0;
- handled = dispatcher->filterNativeEvent(genericEventFilterType, &ev, &result);
+ handled = dispatcher->filterNativeEvent(eventType, &ev, &result);
}
#endif
}
diff --git a/src/plugins/platforms/xcb/qxcbbackingstore.cpp b/src/plugins/platforms/xcb/qxcbbackingstore.cpp
index e73e6f3e61..c29eb29b7e 100644
--- a/src/plugins/platforms/xcb/qxcbbackingstore.cpp
+++ b/src/plugins/platforms/xcb/qxcbbackingstore.cpp
@@ -85,7 +85,8 @@ class QXcbBackingStore;
class QXcbBackingStoreImage : public QXcbObject
{
public:
- QXcbBackingStoreImage(QXcbScreen *screen, const QSize &size, uint depth, QImage::Format format);
+ QXcbBackingStoreImage(QXcbBackingStore *backingStore, const QSize &size);
+ QXcbBackingStoreImage(QXcbBackingStore *backingStore, const QSize &size, uint depth, QImage::Format format);
~QXcbBackingStoreImage() { destroy(true); }
void resize(const QSize &size);
@@ -109,10 +110,10 @@ public:
xcb_shm_segment_info_t *shm_info = nullptr);
private:
- void createShmSegment(size_t segmentSize);
- void destroyShmSegment(size_t segmentSize);
+ void init(const QSize &size, uint depth, QImage::Format format);
- void create(const QSize &size, const xcb_format_t *fmt, QImage::Format format);
+ void createShmSegment(size_t segmentSize);
+ void destroyShmSegment();
void destroy(bool destroyShm);
void ensureGC(xcb_drawable_t dst);
@@ -120,10 +121,9 @@ private:
void flushPixmap(const QRegion &region, bool fullRegion = false);
void setClip(const QRegion &region);
- xcb_window_t m_screen_root;
-
xcb_shm_segment_info_t m_shm_info;
size_t m_segmentSize = 0;
+ QXcbBackingStore *m_backingStore = nullptr;
xcb_image_t *m_xcb_image = nullptr;
@@ -153,6 +153,9 @@ private:
bool m_hasAlpha = false;
bool m_clientSideScroll = false;
+
+ const xcb_format_t *m_xcb_format = nullptr;
+ QImage::Format m_qimage_format = QImage::Format_Invalid;
};
class QXcbGraphicsBuffer : public QPlatformGraphicsBuffer
@@ -190,83 +193,108 @@ static inline size_t imageDataSize(const xcb_image_t *image)
return static_cast<size_t>(image->stride) * image->height;
}
-QXcbBackingStoreImage::QXcbBackingStoreImage(QXcbScreen *screen, const QSize &size, uint depth, QImage::Format format)
- : QXcbObject(screen->connection())
- , m_screen_root(screen->screen()->root)
+QXcbBackingStoreImage::QXcbBackingStoreImage(QXcbBackingStore *backingStore, const QSize &size)
+ : QXcbObject(backingStore->connection())
+ , m_backingStore(backingStore)
{
- const xcb_format_t *fmt = connection()->formatForDepth(depth);
- Q_ASSERT(fmt);
+ auto window = static_cast<QXcbWindow *>(m_backingStore->window()->handle());
+ init(size, window->depth(), window->imageFormat());
+}
- memset(&m_shm_info, 0, sizeof m_shm_info);
+QXcbBackingStoreImage::QXcbBackingStoreImage(QXcbBackingStore *backingStore, const QSize &size,
+ uint depth, QImage::Format format)
+ : QXcbObject(backingStore->connection())
+ , m_backingStore(backingStore)
+{
+ init(size, depth, format);
+}
- m_hasAlpha = QImage::toPixelFormat(format).alphaUsage() == QPixelFormat::UsesAlpha;
+void QXcbBackingStoreImage::init(const QSize &size, uint depth, QImage::Format format)
+{
+ m_xcb_format = connection()->formatForDepth(depth);
+ Q_ASSERT(m_xcb_format);
+
+ m_qimage_format = format;
+ m_hasAlpha = QImage::toPixelFormat(m_qimage_format).alphaUsage() == QPixelFormat::UsesAlpha;
if (!m_hasAlpha)
- create(size, fmt, qt_maybeAlphaVersionWithSameDepth(format));
- else
- create(size, fmt, format);
+ m_qimage_format = qt_maybeAlphaVersionWithSameDepth(m_qimage_format);
+
+ memset(&m_shm_info, 0, sizeof m_shm_info);
+
+ resize(size);
}
void QXcbBackingStoreImage::resize(const QSize &size)
{
- xcb_format_t fmt;
- fmt.depth = m_xcb_image->depth;
- fmt.bits_per_pixel = m_xcb_image->bpp;
- fmt.scanline_pad = m_xcb_image->scanline_pad;
- memset(fmt.pad0, 0, sizeof(fmt.pad0));
destroy(false);
- create(size, &fmt, m_qimage.format());
-}
-void QXcbBackingStoreImage::create(const QSize &size, const xcb_format_t *fmt, QImage::Format format)
-{
+ auto byteOrder = QSysInfo::ByteOrder == QSysInfo::BigEndian ? XCB_IMAGE_ORDER_MSB_FIRST
+ : XCB_IMAGE_ORDER_LSB_FIRST;
m_xcb_image = xcb_image_create(size.width(), size.height(),
XCB_IMAGE_FORMAT_Z_PIXMAP,
- fmt->scanline_pad,
- fmt->depth, fmt->bits_per_pixel, 0,
- QSysInfo::ByteOrder == QSysInfo::BigEndian ? XCB_IMAGE_ORDER_MSB_FIRST : XCB_IMAGE_ORDER_LSB_FIRST,
+ m_xcb_format->scanline_pad,
+ m_xcb_format->depth,
+ m_xcb_format->bits_per_pixel,
+ 0, byteOrder,
XCB_IMAGE_ORDER_MSB_FIRST,
0, ~0, 0);
const size_t segmentSize = imageDataSize(m_xcb_image);
- if (!segmentSize)
- return;
if (connection()->hasShm()) {
- if (m_shm_info.shmaddr && (m_segmentSize < segmentSize || m_segmentSize / 2 >= segmentSize))
- destroyShmSegment(m_segmentSize);
- if (!m_shm_info.shmaddr) {
- qCDebug(lcQpaXcb) << "creating shared memory" << segmentSize << "for"
- << size << "depth" << fmt->depth << "bits" << fmt->bits_per_pixel;
- createShmSegment(segmentSize);
+ if (segmentSize == 0) {
+ if (m_segmentSize > 0) {
+ destroyShmSegment();
+ qCDebug(lcQpaXcb) << "[" << m_backingStore->window()
+ << "] destroyed SHM segment due to resize to" << size;
+ }
+ } else {
+ // Destroy shared memory segment if it is double (or more) of what we actually
+ // need with new window size. Or if the new size is bigger than what we currently
+ // have allocated.
+ if (m_shm_info.shmaddr && (m_segmentSize < segmentSize || m_segmentSize / 2 >= segmentSize))
+ destroyShmSegment();
+ if (!m_shm_info.shmaddr) {
+ qCDebug(lcQpaXcb) << "[" << m_backingStore->window()
+ << "] creating shared memory" << segmentSize << "bytes for"
+ << size << "depth" << m_xcb_format->depth << "bits"
+ << m_xcb_format->bits_per_pixel;
+ createShmSegment(segmentSize);
+ }
}
}
- m_xcb_image->data = m_shm_info.shmaddr ? m_shm_info.shmaddr : (uint8_t *)malloc(segmentSize);
+ if (segmentSize == 0)
+ return;
- m_qimage = QImage( (uchar*) m_xcb_image->data, m_xcb_image->width, m_xcb_image->height, m_xcb_image->stride, format);
+ m_xcb_image->data = m_shm_info.shmaddr ? m_shm_info.shmaddr : (uint8_t *)malloc(segmentSize);
+ m_qimage = QImage(static_cast<uchar *>(m_xcb_image->data), m_xcb_image->width,
+ m_xcb_image->height, m_xcb_image->stride, m_qimage_format);
m_graphics_buffer = new QXcbGraphicsBuffer(&m_qimage);
m_xcb_pixmap = xcb_generate_id(xcb_connection());
+ auto xcbScreen = static_cast<QXcbScreen *>(m_backingStore->window()->screen()->handle());
xcb_create_pixmap(xcb_connection(),
m_xcb_image->depth,
m_xcb_pixmap,
- m_screen_root,
+ xcbScreen->root(),
m_xcb_image->width, m_xcb_image->height);
}
void QXcbBackingStoreImage::destroy(bool destroyShm)
{
- if (m_xcb_image->data) {
- if (m_shm_info.shmaddr) {
- if (destroyShm)
- destroyShmSegment(m_segmentSize);
- } else {
- free(m_xcb_image->data);
+ if (m_xcb_image) {
+ if (m_xcb_image->data) {
+ if (m_shm_info.shmaddr) {
+ if (destroyShm)
+ destroyShmSegment();
+ } else {
+ free(m_xcb_image->data);
+ }
}
+ xcb_image_destroy(m_xcb_image);
}
- xcb_image_destroy(m_xcb_image);
-
if (m_gc) {
xcb_free_gc(xcb_connection(), m_gc);
m_gc = 0;
@@ -276,8 +304,12 @@ void QXcbBackingStoreImage::destroy(bool destroyShm)
delete m_graphics_buffer;
m_graphics_buffer = nullptr;
- xcb_free_pixmap(xcb_connection(), m_xcb_pixmap);
- m_xcb_pixmap = 0;
+ if (m_xcb_pixmap) {
+ xcb_free_pixmap(xcb_connection(), m_xcb_pixmap);
+ m_xcb_pixmap = 0;
+ }
+
+ m_qimage = QImage();
}
void QXcbBackingStoreImage::flushScrolledRegion(bool clientSideScroll)
@@ -420,11 +452,8 @@ bool QXcbBackingStoreImage::createSystemVShmSegment(QXcbConnection *c, size_t se
return true;
}
-void QXcbBackingStoreImage::destroyShmSegment(size_t segmentSize)
+void QXcbBackingStoreImage::destroyShmSegment()
{
-#ifndef XCB_USE_SHM_FD
- Q_UNUSED(segmentSize)
-#endif
auto cookie = xcb_shm_detach_checked(xcb_connection(), m_shm_info.shmseg);
xcb_generic_error_t *error = xcb_request_check(xcb_connection(), cookie);
if (error)
@@ -433,9 +462,9 @@ void QXcbBackingStoreImage::destroyShmSegment(size_t segmentSize)
#ifdef XCB_USE_SHM_FD
if (connection()->hasShmFd()) {
- if (munmap(m_shm_info.shmaddr, segmentSize) == -1) {
+ if (munmap(m_shm_info.shmaddr, m_segmentSize) == -1) {
qCWarning(lcQpaXcb, "munmap() failed (%d: %s) for %p with size %zu",
- errno, strerror(errno), m_shm_info.shmaddr, segmentSize);
+ errno, strerror(errno), m_shm_info.shmaddr, m_segmentSize);
}
} else
#endif
@@ -894,7 +923,7 @@ void QXcbBackingStore::recreateImage(QXcbWindow *win, const QSize &size)
if (m_image)
m_image->resize(size);
else
- m_image = new QXcbBackingStoreImage(win->xcbScreen(), size, win->depth(), win->imageFormat());
+ m_image = new QXcbBackingStoreImage(this, size);
// Slow path for bgr888 VNC: Create an additional image, paint into that and
// swap R and B while copying to m_image after each paint.
@@ -1024,7 +1053,7 @@ void QXcbSystemTrayBackingStore::recreateImage(QXcbWindow *win, const QSize &siz
if (m_image)
m_image->resize(size);
else
- m_image = new QXcbBackingStoreImage(screen, size, 32, QImage::Format_ARGB32_Premultiplied);
+ m_image = new QXcbBackingStoreImage(this, size, 32, QImage::Format_ARGB32_Premultiplied);
#endif // QT_CONFIG(xcb_render)
}
diff --git a/src/plugins/platforms/xcb/qxcbclipboard.cpp b/src/plugins/platforms/xcb/qxcbclipboard.cpp
index 24eb13326c..84831cdbe5 100644
--- a/src/plugins/platforms/xcb/qxcbclipboard.cpp
+++ b/src/plugins/platforms/xcb/qxcbclipboard.cpp
@@ -49,10 +49,6 @@
#include <QtCore/QDebug>
-#define class class_name // Workaround XCB-ICCCM 3.8 breakage
-#include <xcb/xcb_icccm.h>
-#undef class
-
QT_BEGIN_NAMESPACE
#ifndef QT_NO_CLIPBOARD
@@ -305,7 +301,7 @@ QXcbClipboard::~QXcbClipboard()
connection()->sync();
// waiting until the clipboard manager fetches the content.
- if (!waitForClipboardEvent(m_owner, XCB_SELECTION_NOTIFY, clipboard_timeout, true)) {
+ if (!waitForClipboardEvent(m_owner, XCB_SELECTION_NOTIFY, true)) {
qWarning("QXcbClipboard: Unable to receive an event from the "
"clipboard manager in a reasonable time");
}
@@ -807,73 +803,44 @@ bool QXcbClipboard::clipboardReadProperty(xcb_window_t win, xcb_atom_t property,
return ok;
}
-
-namespace
+xcb_generic_event_t *QXcbClipboard::waitForClipboardEvent(xcb_window_t window, int type, bool checkManager)
{
- class Notify {
- public:
- Notify(xcb_window_t win, int t)
- : window(win), type(t) {}
- xcb_window_t window;
- int type;
- bool checkEvent(xcb_generic_event_t *event) const {
- if (!event)
- return false;
- int t = event->response_type & 0x7f;
- if (t != type)
+ QElapsedTimer timer;
+ timer.start();
+ do {
+ auto e = connection()->checkEvent([window, type](xcb_generic_event_t *event, int eventType) {
+ if (eventType != type)
return false;
- if (t == XCB_PROPERTY_NOTIFY) {
- xcb_property_notify_event_t *pn = (xcb_property_notify_event_t *)event;
- if (pn->window == window)
+ if (eventType == XCB_PROPERTY_NOTIFY) {
+ auto propertyNotify = reinterpret_cast<xcb_property_notify_event_t *>(event);
+ if (propertyNotify->window == window)
return true;
- } else if (t == XCB_SELECTION_NOTIFY) {
- xcb_selection_notify_event_t *sn = (xcb_selection_notify_event_t *)event;
- if (sn->requestor == window)
+ } else if (eventType == XCB_SELECTION_NOTIFY) {
+ auto selectionNotify = reinterpret_cast<xcb_selection_notify_event_t *>(event);
+ if (selectionNotify->requestor == window)
return true;
}
return false;
- }
- };
- class ClipboardEvent {
- public:
- ClipboardEvent(QXcbConnection *c)
- { clipboard = c->internAtom("CLIPBOARD"); }
- xcb_atom_t clipboard;
- bool checkEvent(xcb_generic_event_t *e) const {
- if (!e)
- return false;
- int type = e->response_type & 0x7f;
- if (type == XCB_SELECTION_REQUEST) {
- xcb_selection_request_event_t *sr = (xcb_selection_request_event_t *)e;
- return sr->selection == XCB_ATOM_PRIMARY || sr->selection == clipboard;
- } else if (type == XCB_SELECTION_CLEAR) {
- xcb_selection_clear_event_t *sc = (xcb_selection_clear_event_t *)e;
- return sc->selection == XCB_ATOM_PRIMARY || sc->selection == clipboard;
- }
- return false;
- }
- };
-}
-
-xcb_generic_event_t *QXcbClipboard::waitForClipboardEvent(xcb_window_t win, int type, int timeout, bool checkManager)
-{
- QElapsedTimer timer;
- timer.start();
- do {
- Notify notify(win, type);
- xcb_generic_event_t *e = connection()->checkEvent(notify);
- if (e)
+ });
+ if (e) // found the waited for event
return e;
if (checkManager) {
auto reply = Q_XCB_REPLY(xcb_get_selection_owner, xcb_connection(), atom(QXcbAtom::CLIPBOARD_MANAGER));
if (!reply || reply->owner == XCB_NONE)
- return 0;
+ return nullptr;
}
// process other clipboard events, since someone is probably requesting data from us
- ClipboardEvent clipboard(connection());
- e = connection()->checkEvent(clipboard);
+ auto clipboardAtom = atom(QXcbAtom::CLIPBOARD);
+ e = connection()->checkEvent([clipboardAtom](xcb_generic_event_t *event, int type) {
+ xcb_atom_t selection = XCB_ATOM_NONE;
+ if (type == XCB_SELECTION_REQUEST)
+ selection = reinterpret_cast<xcb_selection_request_event_t *>(event)->selection;
+ else if (type == XCB_SELECTION_CLEAR)
+ selection = reinterpret_cast<xcb_selection_clear_event_t *>(event)->selection;
+ return selection == XCB_ATOM_PRIMARY || selection == clipboardAtom;
+ });
if (e) {
connection()->handleXcbEvent(e);
free(e);
@@ -883,9 +850,9 @@ xcb_generic_event_t *QXcbClipboard::waitForClipboardEvent(xcb_window_t win, int
// sleep 50 ms, so we don't use up CPU cycles all the time.
QThread::msleep(50);
- } while (timer.elapsed() < timeout);
+ } while (timer.elapsed() < clipboard_timeout);
- return 0;
+ return nullptr;
}
QByteArray QXcbClipboard::clipboardReadIncrementalProperty(xcb_window_t win, xcb_atom_t property, int nbytes, bool nullterm)
@@ -907,7 +874,7 @@ QByteArray QXcbClipboard::clipboardReadIncrementalProperty(xcb_window_t win, xcb
for (;;) {
connection()->flush();
- xcb_generic_event_t *ge = waitForClipboardEvent(win, XCB_PROPERTY_NOTIFY, clipboard_timeout);
+ xcb_generic_event_t *ge = waitForClipboardEvent(win, XCB_PROPERTY_NOTIFY);
if (!ge)
break;
xcb_property_notify_event_t *event = (xcb_property_notify_event_t *)ge;
@@ -970,7 +937,7 @@ QByteArray QXcbClipboard::getSelection(xcb_atom_t selection, xcb_atom_t target,
connection()->sync();
- xcb_generic_event_t *ge = waitForClipboardEvent(win, XCB_SELECTION_NOTIFY, clipboard_timeout);
+ xcb_generic_event_t *ge = waitForClipboardEvent(win, XCB_SELECTION_NOTIFY);
bool no_selection = !ge || ((xcb_selection_notify_event_t *)ge)->property == XCB_NONE;
free(ge);
diff --git a/src/plugins/platforms/xcb/qxcbclipboard.h b/src/plugins/platforms/xcb/qxcbclipboard.h
index bfeae13e10..abab42a613 100644
--- a/src/plugins/platforms/xcb/qxcbclipboard.h
+++ b/src/plugins/platforms/xcb/qxcbclipboard.h
@@ -89,7 +89,7 @@ public:
QByteArray getSelection(xcb_atom_t selection, xcb_atom_t target, xcb_atom_t property, xcb_timestamp_t t = 0);
private:
- xcb_generic_event_t *waitForClipboardEvent(xcb_window_t win, int type, int timeout, bool checkManager = false);
+ xcb_generic_event_t *waitForClipboardEvent(xcb_window_t window, int type, bool checkManager = false);
xcb_atom_t sendTargetsSelection(QMimeData *d, xcb_window_t window, xcb_atom_t property);
xcb_atom_t sendSelection(QMimeData *d, xcb_atom_t target, xcb_window_t window, xcb_atom_t property);
diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp
index 6fe1a121d8..48715e0812 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection.cpp
@@ -761,22 +761,22 @@ QXcbWindow *QXcbConnection::platformWindowFromId(xcb_window_t id)
#define HANDLE_PLATFORM_WINDOW_EVENT(event_t, windowMember, handler) \
{ \
- event_t *e = reinterpret_cast<event_t *>(event); \
+ auto e = reinterpret_cast<event_t *>(event); \
if (QXcbWindowEventListener *eventListener = windowEventListenerFromId(e->windowMember)) { \
- handled = eventListener->handleGenericEvent(event, &result); \
- if (!handled) \
- eventListener->handler(e); \
+ if (eventListener->handleNativeEvent(event)) \
+ return; \
+ eventListener->handler(e); \
} \
} \
break;
#define HANDLE_KEYBOARD_EVENT(event_t, handler) \
{ \
- event_t *e = reinterpret_cast<event_t *>(event); \
+ auto e = reinterpret_cast<event_t *>(event); \
if (QXcbWindowEventListener *eventListener = windowEventListenerFromId(e->event)) { \
- handled = eventListener->handleGenericEvent(event, &result); \
- if (!handled) \
- m_keyboard->handler(e); \
+ if (eventListener->handleNativeEvent(event)) \
+ return; \
+ m_keyboard->handler(e); \
} \
} \
break;
@@ -1002,7 +1002,7 @@ void QXcbConnection::handleXcbError(xcb_generic_error_t *error)
{
long result = 0;
QAbstractEventDispatcher* dispatcher = QAbstractEventDispatcher::instance();
- if (dispatcher && dispatcher->filterNativeEvent(m_nativeInterface->genericEventFilterType(), error, &result))
+ if (dispatcher && dispatcher->filterNativeEvent(m_nativeInterface->nativeEventType(), error, &result))
return;
printXcbError("QXcbConnection: XCB error", error);
@@ -1094,197 +1094,206 @@ namespace {
void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event)
{
- long result = 0;
+ if (Q_UNLIKELY(lcQpaEvents().isDebugEnabled()))
+ printXcbEvent(lcQpaEvents(), "Event", event);
+
+ long result = 0; // Used only by MS Windows
QAbstractEventDispatcher* dispatcher = QAbstractEventDispatcher::instance();
- bool handled = dispatcher && dispatcher->filterNativeEvent(m_nativeInterface->genericEventFilterType(), event, &result);
+ bool handledByNativeEventFilter = dispatcher && dispatcher->filterNativeEvent(
+ m_nativeInterface->nativeEventType(), event, &result);
+ if (handledByNativeEventFilter)
+ return;
uint response_type = event->response_type & ~0x80;
- if (!handled) {
- switch (response_type) {
- case XCB_EXPOSE:
- HANDLE_PLATFORM_WINDOW_EVENT(xcb_expose_event_t, window, handleExposeEvent);
-
- case XCB_BUTTON_PRESS: {
- xcb_button_press_event_t *ev = (xcb_button_press_event_t *)event;
- m_keyboard->updateXKBStateFromCore(ev->state);
- // the event explicitly contains the state of the three first buttons,
- // the rest we need to manage ourselves
- m_buttonState = (m_buttonState & ~0x7) | translateMouseButtons(ev->state);
- setButtonState(translateMouseButton(ev->detail), true);
- if (Q_UNLIKELY(lcQpaXInputEvents().isDebugEnabled()))
- qCDebug(lcQpaXInputEvents, "legacy mouse press, button %d state %X", ev->detail, static_cast<unsigned int>(m_buttonState));
- HANDLE_PLATFORM_WINDOW_EVENT(xcb_button_press_event_t, event, handleButtonPressEvent);
- }
- case XCB_BUTTON_RELEASE: {
- xcb_button_release_event_t *ev = (xcb_button_release_event_t *)event;
- m_keyboard->updateXKBStateFromCore(ev->state);
- m_buttonState = (m_buttonState & ~0x7) | translateMouseButtons(ev->state);
- setButtonState(translateMouseButton(ev->detail), false);
- if (Q_UNLIKELY(lcQpaXInputEvents().isDebugEnabled()))
- qCDebug(lcQpaXInputEvents, "legacy mouse release, button %d state %X", ev->detail, static_cast<unsigned int>(m_buttonState));
- HANDLE_PLATFORM_WINDOW_EVENT(xcb_button_release_event_t, event, handleButtonReleaseEvent);
- }
- case XCB_MOTION_NOTIFY: {
- xcb_motion_notify_event_t *ev = (xcb_motion_notify_event_t *)event;
- m_keyboard->updateXKBStateFromCore(ev->state);
- m_buttonState = (m_buttonState & ~0x7) | translateMouseButtons(ev->state);
- if (Q_UNLIKELY(lcQpaXInputEvents().isDebugEnabled()))
- qCDebug(lcQpaXInputEvents, "legacy mouse move %d,%d button %d state %X", ev->event_x, ev->event_y,
- ev->detail, static_cast<unsigned int>(m_buttonState));
- HANDLE_PLATFORM_WINDOW_EVENT(xcb_motion_notify_event_t, event, handleMotionNotifyEvent);
- }
-
- case XCB_CONFIGURE_NOTIFY:
- HANDLE_PLATFORM_WINDOW_EVENT(xcb_configure_notify_event_t, event, handleConfigureNotifyEvent);
- case XCB_MAP_NOTIFY:
- HANDLE_PLATFORM_WINDOW_EVENT(xcb_map_notify_event_t, event, handleMapNotifyEvent);
- case XCB_UNMAP_NOTIFY:
- HANDLE_PLATFORM_WINDOW_EVENT(xcb_unmap_notify_event_t, event, handleUnmapNotifyEvent);
- case XCB_DESTROY_NOTIFY:
- HANDLE_PLATFORM_WINDOW_EVENT(xcb_destroy_notify_event_t, event, handleDestroyNotifyEvent);
- case XCB_CLIENT_MESSAGE:
- handleClientMessageEvent((xcb_client_message_event_t *)event);
- break;
- case XCB_ENTER_NOTIFY:
-#if QT_CONFIG(xcb_xinput)
- if (hasXInput2() && !xi2MouseEventsDisabled())
- break;
+ bool handled = true;
+ switch (response_type) {
+ case XCB_EXPOSE:
+ HANDLE_PLATFORM_WINDOW_EVENT(xcb_expose_event_t, window, handleExposeEvent);
+ case XCB_BUTTON_PRESS: {
+ auto ev = reinterpret_cast<xcb_button_press_event_t *>(event);
+ m_keyboard->updateXKBStateFromCore(ev->state);
+ // the event explicitly contains the state of the three first buttons,
+ // the rest we need to manage ourselves
+ m_buttonState = (m_buttonState & ~0x7) | translateMouseButtons(ev->state);
+ setButtonState(translateMouseButton(ev->detail), true);
+ if (Q_UNLIKELY(lcQpaXInputEvents().isDebugEnabled()))
+ qCDebug(lcQpaXInputEvents, "legacy mouse press, button %d state %X",
+ ev->detail, static_cast<unsigned int>(m_buttonState));
+ HANDLE_PLATFORM_WINDOW_EVENT(xcb_button_press_event_t, event, handleButtonPressEvent);
+ }
+ case XCB_BUTTON_RELEASE: {
+ auto ev = reinterpret_cast<xcb_button_release_event_t *>(event);
+ m_keyboard->updateXKBStateFromCore(ev->state);
+ m_buttonState = (m_buttonState & ~0x7) | translateMouseButtons(ev->state);
+ setButtonState(translateMouseButton(ev->detail), false);
+ if (Q_UNLIKELY(lcQpaXInputEvents().isDebugEnabled()))
+ qCDebug(lcQpaXInputEvents, "legacy mouse release, button %d state %X",
+ ev->detail, static_cast<unsigned int>(m_buttonState));
+ HANDLE_PLATFORM_WINDOW_EVENT(xcb_button_release_event_t, event, handleButtonReleaseEvent);
+ }
+ case XCB_MOTION_NOTIFY: {
+ auto ev = reinterpret_cast<xcb_motion_notify_event_t *>(event);
+ m_keyboard->updateXKBStateFromCore(ev->state);
+ m_buttonState = (m_buttonState & ~0x7) | translateMouseButtons(ev->state);
+ if (Q_UNLIKELY(lcQpaXInputEvents().isDebugEnabled()))
+ qCDebug(lcQpaXInputEvents, "legacy mouse move %d,%d button %d state %X",
+ ev->event_x, ev->event_y, ev->detail, static_cast<unsigned int>(m_buttonState));
+ HANDLE_PLATFORM_WINDOW_EVENT(xcb_motion_notify_event_t, event, handleMotionNotifyEvent);
+ }
+ case XCB_CONFIGURE_NOTIFY:
+ HANDLE_PLATFORM_WINDOW_EVENT(xcb_configure_notify_event_t, event, handleConfigureNotifyEvent);
+ case XCB_MAP_NOTIFY:
+ HANDLE_PLATFORM_WINDOW_EVENT(xcb_map_notify_event_t, event, handleMapNotifyEvent);
+ case XCB_UNMAP_NOTIFY:
+ HANDLE_PLATFORM_WINDOW_EVENT(xcb_unmap_notify_event_t, event, handleUnmapNotifyEvent);
+ case XCB_DESTROY_NOTIFY:
+ HANDLE_PLATFORM_WINDOW_EVENT(xcb_destroy_notify_event_t, event, handleDestroyNotifyEvent);
+ case XCB_CLIENT_MESSAGE: {
+ auto clientMessage = reinterpret_cast<xcb_client_message_event_t *>(event);
+ if (clientMessage->format != 32)
+ return;
+#if QT_CONFIG(draganddrop)
+ if (clientMessage->type == atom(QXcbAtom::XdndStatus))
+ drag()->handleStatus(clientMessage);
+ else if (clientMessage->type == atom(QXcbAtom::XdndFinished))
+ drag()->handleFinished(clientMessage);
#endif
- HANDLE_PLATFORM_WINDOW_EVENT(xcb_enter_notify_event_t, event, handleEnterNotifyEvent);
- case XCB_LEAVE_NOTIFY:
+ if (m_systemTrayTracker && clientMessage->type == atom(QXcbAtom::MANAGER))
+ m_systemTrayTracker->notifyManagerClientMessageEvent(clientMessage);
+ HANDLE_PLATFORM_WINDOW_EVENT(xcb_client_message_event_t, window, handleClientMessageEvent);
+ }
+ case XCB_ENTER_NOTIFY:
#if QT_CONFIG(xcb_xinput)
- if (hasXInput2() && !xi2MouseEventsDisabled())
- break;
+ if (hasXInput2() && !xi2MouseEventsDisabled())
+ break;
#endif
- m_keyboard->updateXKBStateFromCore(((xcb_leave_notify_event_t *)event)->state);
- HANDLE_PLATFORM_WINDOW_EVENT(xcb_leave_notify_event_t, event, handleLeaveNotifyEvent);
- case XCB_FOCUS_IN:
- HANDLE_PLATFORM_WINDOW_EVENT(xcb_focus_in_event_t, event, handleFocusInEvent);
- case XCB_FOCUS_OUT:
- HANDLE_PLATFORM_WINDOW_EVENT(xcb_focus_out_event_t, event, handleFocusOutEvent);
- case XCB_KEY_PRESS:
- {
- xcb_key_press_event_t *kp = (xcb_key_press_event_t *)event;
- m_keyboard->updateXKBStateFromCore(kp->state);
- setTime(kp->time);
- HANDLE_KEYBOARD_EVENT(xcb_key_press_event_t, handleKeyPressEvent);
- }
- case XCB_KEY_RELEASE:
- m_keyboard->updateXKBStateFromCore(((xcb_key_release_event_t *)event)->state);
- HANDLE_KEYBOARD_EVENT(xcb_key_release_event_t, handleKeyReleaseEvent);
- case XCB_MAPPING_NOTIFY:
- m_keyboard->updateKeymap(reinterpret_cast<xcb_mapping_notify_event_t *>(event));
+ HANDLE_PLATFORM_WINDOW_EVENT(xcb_enter_notify_event_t, event, handleEnterNotifyEvent);
+ case XCB_LEAVE_NOTIFY:
+#if QT_CONFIG(xcb_xinput)
+ if (hasXInput2() && !xi2MouseEventsDisabled())
break;
- case XCB_SELECTION_REQUEST:
- {
+#endif
+ m_keyboard->updateXKBStateFromCore(reinterpret_cast<xcb_leave_notify_event_t *>(event)->state);
+ HANDLE_PLATFORM_WINDOW_EVENT(xcb_leave_notify_event_t, event, handleLeaveNotifyEvent);
+ case XCB_FOCUS_IN:
+ HANDLE_PLATFORM_WINDOW_EVENT(xcb_focus_in_event_t, event, handleFocusInEvent);
+ case XCB_FOCUS_OUT:
+ HANDLE_PLATFORM_WINDOW_EVENT(xcb_focus_out_event_t, event, handleFocusOutEvent);
+ case XCB_KEY_PRESS:
+ {
+ auto keyPress = reinterpret_cast<xcb_key_press_event_t *>(event);
+ m_keyboard->updateXKBStateFromCore(keyPress->state);
+ setTime(keyPress->time);
+ HANDLE_KEYBOARD_EVENT(xcb_key_press_event_t, handleKeyPressEvent);
+ }
+ case XCB_KEY_RELEASE:
+ m_keyboard->updateXKBStateFromCore(reinterpret_cast<xcb_key_release_event_t *>(event)->state);
+ HANDLE_KEYBOARD_EVENT(xcb_key_release_event_t, handleKeyReleaseEvent);
+ case XCB_MAPPING_NOTIFY:
+ m_keyboard->updateKeymap(reinterpret_cast<xcb_mapping_notify_event_t *>(event));
+ break;
+ case XCB_SELECTION_REQUEST:
+ {
#if QT_CONFIG(draganddrop) || QT_CONFIG(clipboard)
- xcb_selection_request_event_t *sr = reinterpret_cast<xcb_selection_request_event_t *>(event);
+ auto selectionRequest = reinterpret_cast<xcb_selection_request_event_t *>(event);
#endif
#if QT_CONFIG(draganddrop)
- if (sr->selection == atom(QXcbAtom::XdndSelection))
- m_drag->handleSelectionRequest(sr);
- else
+ if (selectionRequest->selection == atom(QXcbAtom::XdndSelection))
+ m_drag->handleSelectionRequest(selectionRequest);
+ else
#endif
- {
+ {
#ifndef QT_NO_CLIPBOARD
- m_clipboard->handleSelectionRequest(sr);
+ m_clipboard->handleSelectionRequest(selectionRequest);
#endif
- }
- break;
}
- case XCB_SELECTION_CLEAR:
- setTime((reinterpret_cast<xcb_selection_clear_event_t *>(event))->time);
+ break;
+ }
+ case XCB_SELECTION_CLEAR:
+ setTime((reinterpret_cast<xcb_selection_clear_event_t *>(event))->time);
#ifndef QT_NO_CLIPBOARD
- m_clipboard->handleSelectionClearRequest(reinterpret_cast<xcb_selection_clear_event_t *>(event));
+ m_clipboard->handleSelectionClearRequest(reinterpret_cast<xcb_selection_clear_event_t *>(event));
#endif
- handled = true;
- break;
- case XCB_SELECTION_NOTIFY:
- setTime((reinterpret_cast<xcb_selection_notify_event_t *>(event))->time);
- handled = false;
- break;
- case XCB_PROPERTY_NOTIFY:
- {
- xcb_property_notify_event_t *pn = reinterpret_cast<xcb_property_notify_event_t *>(event);
- if (pn->atom == atom(QXcbAtom::_NET_WORKAREA)) {
- QXcbVirtualDesktop *virtualDesktop = virtualDesktopForRootWindow(pn->window);
- if (virtualDesktop)
- virtualDesktop->updateWorkArea();
- } else {
- HANDLE_PLATFORM_WINDOW_EVENT(xcb_property_notify_event_t, window, handlePropertyNotifyEvent);
- }
- break;
+ break;
+ case XCB_SELECTION_NOTIFY:
+ setTime((reinterpret_cast<xcb_selection_notify_event_t *>(event))->time);
+ break;
+ case XCB_PROPERTY_NOTIFY:
+ {
+ auto propertyNotify = reinterpret_cast<xcb_property_notify_event_t *>(event);
+ if (propertyNotify->atom == atom(QXcbAtom::_NET_WORKAREA)) {
+ QXcbVirtualDesktop *virtualDesktop = virtualDesktopForRootWindow(propertyNotify->window);
+ if (virtualDesktop)
+ virtualDesktop->updateWorkArea();
+ } else {
+ HANDLE_PLATFORM_WINDOW_EVENT(xcb_property_notify_event_t, window, handlePropertyNotifyEvent);
}
+ break;
+ }
#if QT_CONFIG(xcb_xinput)
- case XCB_GE_GENERIC:
- // Here the windowEventListener is invoked from xi2HandleEvent()
- if (hasXInput2() && isXIEvent(event, m_xiOpCode))
- xi2HandleEvent(reinterpret_cast<xcb_ge_event_t *>(event));
- break;
+ case XCB_GE_GENERIC:
+ // Here the windowEventListener is invoked from xi2HandleEvent()
+ if (hasXInput2() && isXIEvent(event, m_xiOpCode))
+ xi2HandleEvent(reinterpret_cast<xcb_ge_event_t *>(event));
+ break;
#endif
- default:
- handled = false;
- break;
- }
+ default:
+ handled = false; // event type not recognized
+ break;
}
- if (!handled) {
- if (has_xfixes && response_type == xfixes_first_event + XCB_XFIXES_SELECTION_NOTIFY) {
- xcb_xfixes_selection_notify_event_t *notify_event = reinterpret_cast<xcb_xfixes_selection_notify_event_t *>(event);
- setTime(notify_event->timestamp);
+ if (handled)
+ return;
+
+ handled = true;
+ if (has_xfixes && response_type == xfixes_first_event + XCB_XFIXES_SELECTION_NOTIFY) {
+ auto notify_event = reinterpret_cast<xcb_xfixes_selection_notify_event_t *>(event);
+ setTime(notify_event->timestamp);
#ifndef QT_NO_CLIPBOARD
- m_clipboard->handleXFixesSelectionRequest(notify_event);
+ m_clipboard->handleXFixesSelectionRequest(notify_event);
#endif
- for (QXcbVirtualDesktop *virtualDesktop : qAsConst(m_virtualDesktops))
- virtualDesktop->handleXFixesSelectionNotify(notify_event);
-
- handled = true;
- } else if (has_randr_extension && response_type == xrandr_first_event + XCB_RANDR_NOTIFY) {
- updateScreens(reinterpret_cast<xcb_randr_notify_event_t *>(event));
- handled = true;
- } else if (has_randr_extension && response_type == xrandr_first_event + XCB_RANDR_SCREEN_CHANGE_NOTIFY) {
- xcb_randr_screen_change_notify_event_t *change_event = reinterpret_cast<xcb_randr_screen_change_notify_event_t *>(event);
- if (auto *virtualDesktop = virtualDesktopForRootWindow(change_event->root))
- virtualDesktop->handleScreenChange(change_event);
-
- handled = true;
+ for (QXcbVirtualDesktop *virtualDesktop : qAsConst(m_virtualDesktops))
+ virtualDesktop->handleXFixesSelectionNotify(notify_event);
+ } else if (has_randr_extension && response_type == xrandr_first_event + XCB_RANDR_NOTIFY) {
+ updateScreens(reinterpret_cast<xcb_randr_notify_event_t *>(event));
+ } else if (has_randr_extension && response_type == xrandr_first_event + XCB_RANDR_SCREEN_CHANGE_NOTIFY) {
+ auto change_event = reinterpret_cast<xcb_randr_screen_change_notify_event_t *>(event);
+ if (auto virtualDesktop = virtualDesktopForRootWindow(change_event->root))
+ virtualDesktop->handleScreenChange(change_event);
#if QT_CONFIG(xkb)
- } else if (response_type == xkb_first_event) { // https://bugs.freedesktop.org/show_bug.cgi?id=51295
- _xkb_event *xkb_event = reinterpret_cast<_xkb_event *>(event);
- if (xkb_event->any.deviceID == m_keyboard->coreDeviceId()) {
- switch (xkb_event->any.xkbType) {
- // XkbNewKkdNotify and XkbMapNotify together capture all sorts of keymap
- // updates (e.g. xmodmap, xkbcomp, setxkbmap), with minimal redundent recompilations.
- case XCB_XKB_STATE_NOTIFY:
- m_keyboard->updateXKBState(&xkb_event->state_notify);
- handled = true;
- break;
- case XCB_XKB_MAP_NOTIFY:
+ } else if (response_type == xkb_first_event) { // https://bugs.freedesktop.org/show_bug.cgi?id=51295
+ auto xkb_event = reinterpret_cast<_xkb_event *>(event);
+ if (xkb_event->any.deviceID == m_keyboard->coreDeviceId()) {
+ switch (xkb_event->any.xkbType) {
+ // XkbNewKkdNotify and XkbMapNotify together capture all sorts of keymap
+ // updates (e.g. xmodmap, xkbcomp, setxkbmap), with minimal redundent recompilations.
+ case XCB_XKB_STATE_NOTIFY:
+ m_keyboard->updateXKBState(&xkb_event->state_notify);
+ break;
+ case XCB_XKB_MAP_NOTIFY:
+ m_keyboard->updateKeymap();
+ break;
+ case XCB_XKB_NEW_KEYBOARD_NOTIFY: {
+ xcb_xkb_new_keyboard_notify_event_t *ev = &xkb_event->new_keyboard_notify;
+ if (ev->changed & XCB_XKB_NKN_DETAIL_KEYCODES)
m_keyboard->updateKeymap();
- handled = true;
- break;
- case XCB_XKB_NEW_KEYBOARD_NOTIFY: {
- xcb_xkb_new_keyboard_notify_event_t *ev = &xkb_event->new_keyboard_notify;
- if (ev->changed & XCB_XKB_NKN_DETAIL_KEYCODES)
- m_keyboard->updateKeymap();
- break;
- }
- default:
- break;
+ break;
}
+ default:
+ break;
}
-#endif
}
+#endif
+ } else {
+ handled = false; // event type still not recognized
}
- if (!handled && m_glIntegration)
- handled = m_glIntegration->handleXcbEvent(event, response_type);
+ if (handled)
+ return;
-#if 0
- if (Q_UNLIKELY(lcQpaEvents().isDebugEnabled()))
- printXcbEvent(lcQpaEvents(), handled ? "Handled" : "Unhandled", event);
-#endif
+ if (m_glIntegration)
+ m_glIntegration->handleXcbEvent(event, response_type);
}
void QXcbConnection::addPeekFunc(PeekFunc f)
@@ -1512,54 +1521,35 @@ void QXcbConnection::sendConnectionEvent(QXcbAtom::Atom a, uint id)
xcb_flush(xcb_connection());
}
-namespace
-{
- class PropertyNotifyEvent {
- public:
- PropertyNotifyEvent(xcb_window_t win, xcb_atom_t property)
- : window(win), type(XCB_PROPERTY_NOTIFY), atom(property) {}
- xcb_window_t window;
- int type;
- xcb_atom_t atom;
- bool checkEvent(xcb_generic_event_t *event) const {
- if (!event)
- return false;
- if ((event->response_type & ~0x80) != type) {
- return false;
- } else {
- xcb_property_notify_event_t *pn = reinterpret_cast<xcb_property_notify_event_t *>(event);
- if ((pn->window == window) && (pn->atom == atom))
- return true;
- }
- return false;
- }
- };
-}
-
xcb_timestamp_t QXcbConnection::getTimestamp()
{
// send a dummy event to myself to get the timestamp from X server.
- xcb_window_t root_win = rootWindow();
- xcb_change_property(xcb_connection(), XCB_PROP_MODE_APPEND, root_win, atom(QXcbAtom::CLIP_TEMPORARY),
- XCB_ATOM_INTEGER, 32, 0, NULL);
+ xcb_window_t window = rootWindow();
+ xcb_atom_t dummyAtom = atom(QXcbAtom::CLIP_TEMPORARY);
+ xcb_change_property(xcb_connection(), XCB_PROP_MODE_APPEND, window, dummyAtom,
+ XCB_ATOM_INTEGER, 32, 0, nullptr);
connection()->flush();
- PropertyNotifyEvent checker(root_win, atom(QXcbAtom::CLIP_TEMPORARY));
- xcb_generic_event_t *event = 0;
+ xcb_generic_event_t *event = nullptr;
// lets keep this inside a loop to avoid a possible race condition, where
// reader thread has not yet had the time to acquire the mutex in order
// to add the new set of events to its event queue
while (!event) {
connection()->sync();
- event = checkEvent(checker);
+ event = checkEvent([window, dummyAtom](xcb_generic_event_t *event, int type) {
+ if (type != XCB_PROPERTY_NOTIFY)
+ return false;
+ auto propertyNotify = reinterpret_cast<xcb_property_notify_event_t *>(event);
+ return propertyNotify->window == window && propertyNotify->atom == dummyAtom;
+ });
}
xcb_property_notify_event_t *pn = reinterpret_cast<xcb_property_notify_event_t *>(event);
xcb_timestamp_t timestamp = pn->time;
free(event);
- xcb_delete_property(xcb_connection(), root_win, atom(QXcbAtom::CLIP_TEMPORARY));
+ xcb_delete_property(xcb_connection(), window, dummyAtom);
return timestamp;
}
@@ -1808,28 +1798,6 @@ void QXcbConnection::processXcbEvents()
xcb_flush(xcb_connection());
}
-void QXcbConnection::handleClientMessageEvent(const xcb_client_message_event_t *event)
-{
- if (event->format != 32)
- return;
-
-#if QT_CONFIG(draganddrop)
- if (event->type == atom(QXcbAtom::XdndStatus)) {
- drag()->handleStatus(event);
- } else if (event->type == atom(QXcbAtom::XdndFinished)) {
- drag()->handleFinished(event);
- }
-#endif
- if (m_systemTrayTracker && event->type == atom(QXcbAtom::MANAGER))
- m_systemTrayTracker->notifyManagerClientMessageEvent(event);
-
- QXcbWindow *window = platformWindowFromId(event->window);
- if (!window)
- return;
-
- window->handleClientMessageEvent(event);
-}
-
static const char * xcb_atomnames = {
// window-manager <-> client protocols
"WM_PROTOCOLS\0"
@@ -2024,6 +1992,10 @@ static const char * xcb_atomnames = {
"_COMPIZ_DECOR_DELETE_PIXMAP\0"
"_COMPIZ_TOOLKIT_ACTION\0"
"_GTK_LOAD_ICONTHEMES\0"
+ "AT_SPI_BUS\0"
+ "EDID\0"
+ "EDID_DATA\0"
+ "XFree86_DDC_EDID1_RAWDATA\0"
// \0\0 terminates loop.
};
diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h
index c88100e580..b0c36e61b0 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.h
+++ b/src/plugins/platforms/xcb/qxcbconnection.h
@@ -295,6 +295,12 @@ namespace QXcbAtom {
_COMPIZ_TOOLKIT_ACTION,
_GTK_LOAD_ICONTHEMES,
+ AT_SPI_BUS,
+
+ EDID,
+ EDID_DATA,
+ XFree86_DDC_EDID1_RAWDATA,
+
NAtoms
};
}
@@ -335,7 +341,7 @@ class QXcbWindowEventListener
{
public:
virtual ~QXcbWindowEventListener() {}
- virtual bool handleGenericEvent(xcb_generic_event_t *, long *) { return false; }
+ virtual bool handleNativeEvent(xcb_generic_event_t *) { return false; }
virtual void handleExposeEvent(const xcb_expose_event_t *) {}
virtual void handleClientMessageEvent(const xcb_client_message_event_t *) {}
@@ -447,8 +453,8 @@ public:
QXcbWindowEventListener *windowEventListenerFromId(xcb_window_t id);
QXcbWindow *platformWindowFromId(xcb_window_t id);
- template<typename T>
- inline xcb_generic_event_t *checkEvent(T &checker);
+ template<typename Functor>
+ inline xcb_generic_event_t *checkEvent(Functor &&filter, bool removeFromQueue = true);
typedef bool (*PeekFunc)(QXcbConnection *, xcb_generic_event_t *);
void addPeekFunc(PeekFunc f);
@@ -560,7 +566,6 @@ private:
void initializeXShape();
void initializeXKB();
void initializeXSync();
- void handleClientMessageEvent(const xcb_client_message_event_t *event);
QXcbScreen* findScreenForCrtc(xcb_window_t rootWindow, xcb_randr_crtc_t crtc) const;
QXcbScreen* findScreenForOutput(xcb_window_t rootWindow, xcb_randr_output_t output) const;
QXcbVirtualDesktop* virtualDesktopForRootWindow(xcb_window_t rootWindow) const;
@@ -741,21 +746,22 @@ Q_DECLARE_TYPEINFO(QXcbConnection::TabletData, Q_MOVABLE_TYPE);
#endif
#endif
-template<typename T>
-xcb_generic_event_t *QXcbConnection::checkEvent(T &checker)
+template<typename Functor>
+xcb_generic_event_t *QXcbConnection::checkEvent(Functor &&filter, bool removeFromQueue)
{
QXcbEventArray *eventqueue = m_reader->lock();
for (int i = 0; i < eventqueue->size(); ++i) {
xcb_generic_event_t *event = eventqueue->at(i);
- if (checker.checkEvent(event)) {
- (*eventqueue)[i] = 0;
+ if (event && filter(event, event->response_type & ~0x80)) {
+ if (removeFromQueue)
+ (*eventqueue)[i] = nullptr;
m_reader->unlock();
return event;
}
}
m_reader->unlock();
- return 0;
+ return nullptr;
}
class QXcbConnectionGrabber
diff --git a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
index a327d8dea7..a3befc7384 100644
--- a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
@@ -581,8 +581,7 @@ void QXcbConnection::xi2HandleEvent(xcb_ge_event_t *event)
}
if (eventListener) {
- long result = 0;
- if (eventListener->handleGenericEvent(reinterpret_cast<xcb_generic_event_t *>(event), &result))
+ if (eventListener->handleNativeEvent(reinterpret_cast<xcb_generic_event_t *>(event)))
return;
}
diff --git a/src/plugins/platforms/xcb/qxcbdrag.cpp b/src/plugins/platforms/xcb/qxcbdrag.cpp
index 0d72da0701..2b8e507f30 100644
--- a/src/plugins/platforms/xcb/qxcbdrag.cpp
+++ b/src/plugins/platforms/xcb/qxcbdrag.cpp
@@ -781,12 +781,11 @@ namespace
public:
ClientMessageScanner(xcb_atom_t a) : atom(a) {}
xcb_atom_t atom;
- bool checkEvent(xcb_generic_event_t *event) const {
- if (!event)
+ bool operator() (xcb_generic_event_t *event, int type) const {
+ if (type != XCB_CLIENT_MESSAGE)
return false;
- if ((event->response_type & 0x7f) != XCB_CLIENT_MESSAGE)
- return false;
- return ((xcb_client_message_event_t *)event)->type == atom;
+ auto clientMessage = reinterpret_cast<xcb_client_message_event_t *>(event);
+ return clientMessage->type == atom;
}
};
}
@@ -794,12 +793,11 @@ namespace
void QXcbDrag::handlePosition(QPlatformWindow * w, const xcb_client_message_event_t *event)
{
xcb_client_message_event_t *lastEvent = const_cast<xcb_client_message_event_t *>(event);
- xcb_generic_event_t *nextEvent;
ClientMessageScanner scanner(atom(QXcbAtom::XdndPosition));
- while ((nextEvent = connection()->checkEvent(scanner))) {
+ while (auto nextEvent = connection()->checkEvent(scanner)) {
if (lastEvent != event)
free(lastEvent);
- lastEvent = (xcb_client_message_event_t *)nextEvent;
+ lastEvent = reinterpret_cast<xcb_client_message_event_t *>(nextEvent);
}
handle_xdnd_position(w, lastEvent);
diff --git a/src/plugins/platforms/xcb/qxcbimage.cpp b/src/plugins/platforms/xcb/qxcbimage.cpp
index e18a08755b..44c7d22344 100644
--- a/src/plugins/platforms/xcb/qxcbimage.cpp
+++ b/src/plugins/platforms/xcb/qxcbimage.cpp
@@ -69,7 +69,7 @@ QImage::Format imageFormatForMasks(int depth, int bits_per_pixel, int red_mask,
if (red_mask == 0xff && blue_mask == 0xff0000)
return QImage::Format_RGBA8888_Premultiplied;
#else
- if (red_mask == 0xff000000 && blue_mask == 0xff00)
+ if (unsigned(red_mask) == unsigned(0xff000000) && blue_mask == 0xff00)
return QImage::Format_RGBA8888_Premultiplied;
#endif
if (red_mask == 0x3ff && blue_mask == 0x3ff00000)
@@ -90,7 +90,7 @@ QImage::Format imageFormatForMasks(int depth, int bits_per_pixel, int red_mask,
if (red_mask == 0xff && blue_mask == 0xff0000)
return QImage::Format_RGBX8888;
#else
- if (red_mask == 0xff000000 && blue_mask == 0xff00)
+ if (unsigned(red_mask) == unsigned(0xff000000) && blue_mask == 0xff00)
return QImage::Format_RGBX8888;
#endif
break;
diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.cpp b/src/plugins/platforms/xcb/qxcbkeyboard.cpp
index 5a2dac4a5a..20c169fc53 100644
--- a/src/plugins/platforms/xcb/qxcbkeyboard.cpp
+++ b/src/plugins/platforms/xcb/qxcbkeyboard.cpp
@@ -161,6 +161,13 @@ static constexpr const auto KeyTbl = qMakeArray(
Xkb2Qt<XKB_KEY_KP_Decimal, Qt::Key_Period>,
Xkb2Qt<XKB_KEY_KP_Divide, Qt::Key_Slash>,
+ // special non-XF86 function keys
+
+ Xkb2Qt<XKB_KEY_Undo, Qt::Key_Undo>,
+ Xkb2Qt<XKB_KEY_Redo, Qt::Key_Redo>,
+ Xkb2Qt<XKB_KEY_Find, Qt::Key_Find>,
+ Xkb2Qt<XKB_KEY_Cancel, Qt::Key_Cancel>,
+
// International input method support keys
// International & multi-key character composition
@@ -1472,64 +1479,6 @@ void QXcbKeyboard::resolveMaskConflicts()
}
}
-class KeyChecker
-{
-public:
- KeyChecker(xcb_window_t window, xcb_keycode_t code, xcb_timestamp_t time, quint16 state)
- : m_window(window)
- , m_code(code)
- , m_time(time)
- , m_state(state)
- , m_error(false)
- , m_release(true)
- {
- }
-
- bool checkEvent(xcb_generic_event_t *ev)
- {
- if (m_error || !ev)
- return false;
-
- int type = ev->response_type & ~0x80;
- if (type != XCB_KEY_PRESS && type != XCB_KEY_RELEASE)
- return false;
-
- xcb_key_press_event_t *event = (xcb_key_press_event_t *)ev;
-
- if (event->event != m_window || event->detail != m_code || event->state != m_state) {
- m_error = true;
- return false;
- }
-
- if (type == XCB_KEY_PRESS) {
- m_error = !m_release || event->time - m_time > 10;
- return !m_error;
- }
-
- if (m_release) {
- m_error = true;
- return false;
- }
-
- m_release = true;
- m_time = event->time;
-
- return false;
- }
-
- bool release() const { return m_release; }
- xcb_timestamp_t time() const { return m_time; }
-
-private:
- xcb_window_t m_window;
- xcb_keycode_t m_code;
- xcb_timestamp_t m_time;
- quint16 m_state;
-
- bool m_error;
- bool m_release;
-};
-
void QXcbKeyboard::handleKeyEvent(xcb_window_t sourceWindow, QEvent::Type type, xcb_keycode_t code,
quint16 state, xcb_timestamp_t time, bool fromSendEvent)
{
@@ -1543,7 +1492,6 @@ void QXcbKeyboard::handleKeyEvent(xcb_window_t sourceWindow, QEvent::Type type,
if (type == QEvent::KeyPress)
targetWindow->updateNetWmUserTime(time);
-
ScopedXKBState sendEventState;
if (fromSendEvent) {
// Have a temporary keyboard state filled in from state
@@ -1561,7 +1509,7 @@ void QXcbKeyboard::handleKeyEvent(xcb_window_t sourceWindow, QEvent::Type type,
struct xkb_state *xkbState = fromSendEvent ? sendEventState.get() : m_xkbState.get();
xcb_keysym_t sym = xkb_state_key_get_one_sym(xkbState, code);
- QString string = lookupString(xkbState, code);
+ QString text = lookupString(xkbState, code);
Qt::KeyboardModifiers modifiers = translateModifiers(state);
if (sym >= XKB_KEY_KP_Space && sym <= XKB_KEY_KP_9)
@@ -1586,55 +1534,42 @@ void QXcbKeyboard::handleKeyEvent(xcb_window_t sourceWindow, QEvent::Type type,
int qtcode = keysymToQtKey(latinKeysym != XKB_KEY_NoSymbol ? latinKeysym : sym,
modifiers, xkbState, code);
- bool isAutoRepeat = false;
if (type == QEvent::KeyPress) {
- if (m_autorepeat_code == code) {
- isAutoRepeat = true;
- m_autorepeat_code = 0;
- }
+ if (m_isAutoRepeat && m_autoRepeatCode != code)
+ // Some other key was pressed while we are auto-repeating on a different key.
+ m_isAutoRepeat = false;
} else {
- // look ahead for auto-repeat
- KeyChecker checker(source->xcb_window(), code, time, state);
- xcb_generic_event_t *event = connection()->checkEvent(checker);
- if (event) {
- isAutoRepeat = true;
- free(event);
- }
- m_autorepeat_code = isAutoRepeat ? code : 0;
+ m_isAutoRepeat = false;
+ // Look at the next event in the queue to see if we are auto-repeating.
+ connection()->checkEvent([this, time, code](xcb_generic_event_t *event, int type) {
+ if (type == XCB_KEY_PRESS) {
+ auto keyPress = reinterpret_cast<xcb_key_press_event_t *>(event);
+ m_isAutoRepeat = keyPress->time == time && keyPress->detail == code;
+ if (m_isAutoRepeat)
+ m_autoRepeatCode = code;
+ }
+ return true;
+ }, false /* removeFromQueue */);
}
bool filtered = false;
- QPlatformInputContext *inputContext = QGuiApplicationPrivate::platformIntegration()->inputContext();
- if (inputContext) {
- QKeyEvent event(type, qtcode, modifiers, code, sym, state, string, isAutoRepeat, string.length());
+ if (auto inputContext = QGuiApplicationPrivate::platformIntegration()->inputContext()) {
+ QKeyEvent event(type, qtcode, modifiers, code, sym, state, text, m_isAutoRepeat, text.size());
event.setTimestamp(time);
filtered = inputContext->filterEvent(&event);
}
- QWindow *window = targetWindow->window();
if (!filtered) {
+ QWindow *window = targetWindow->window();
#ifndef QT_NO_CONTEXTMENU
if (type == QEvent::KeyPress && qtcode == Qt::Key_Menu) {
const QPoint globalPos = window->screen()->handle()->cursor()->pos();
const QPoint pos = window->mapFromGlobal(globalPos);
QWindowSystemInterface::handleContextMenuEvent(window, false, pos, globalPos, modifiers);
}
-#endif // QT_NO_CONTEXTMENU
+#endif
QWindowSystemInterface::handleExtendedKeyEvent(window, time, type, qtcode, modifiers,
- code, sym, state, string, isAutoRepeat);
- }
-
- if (isAutoRepeat && type == QEvent::KeyRelease) {
- // since we removed it from the event queue using checkEvent we need to send the key press here
- filtered = false;
- if (inputContext) {
- QKeyEvent event(QEvent::KeyPress, qtcode, modifiers, code, sym, state, string, isAutoRepeat, string.length());
- event.setTimestamp(time);
- filtered = inputContext->filterEvent(&event);
- }
- if (!filtered)
- QWindowSystemInterface::handleExtendedKeyEvent(window, time, QEvent::KeyPress, qtcode, modifiers,
- code, sym, state, string, isAutoRepeat);
+ code, sym, state, text, m_isAutoRepeat);
}
}
diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.h b/src/plugins/platforms/xcb/qxcbkeyboard.h
index ab926eab84..95915fb2e6 100644
--- a/src/plugins/platforms/xcb/qxcbkeyboard.h
+++ b/src/plugins/platforms/xcb/qxcbkeyboard.h
@@ -109,7 +109,8 @@ protected:
private:
bool m_config = false;
- xcb_keycode_t m_autorepeat_code = 0;
+ bool m_isAutoRepeat = false;
+ xcb_keycode_t m_autoRepeatCode = 0;
struct _mod_masks {
uint alt;
diff --git a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp
index 26b9fcc15a..98bedea48a 100644
--- a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp
+++ b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp
@@ -92,8 +92,7 @@ static int resourceType(const QByteArray &key)
return int(result - names);
}
-QXcbNativeInterface::QXcbNativeInterface() :
- m_genericEventFilterType(QByteArrayLiteral("xcb_generic_event_t"))
+QXcbNativeInterface::QXcbNativeInterface()
{
}
@@ -409,7 +408,7 @@ void *QXcbNativeInterface::atspiBus()
QXcbIntegration *integration = static_cast<QXcbIntegration *>(QGuiApplicationPrivate::platformIntegration());
QXcbConnection *defaultConnection = integration->defaultConnection();
if (defaultConnection) {
- xcb_atom_t atspiBusAtom = defaultConnection->internAtom("AT_SPI_BUS");
+ auto atspiBusAtom = defaultConnection->atom(QXcbAtom::AT_SPI_BUS);
auto reply = Q_XCB_REPLY(xcb_get_property, defaultConnection->xcb_connection(),
false, defaultConnection->rootWindow(),
atspiBusAtom, XCB_ATOM_STRING, 0, 128);
diff --git a/src/plugins/platforms/xcb/qxcbnativeinterface.h b/src/plugins/platforms/xcb/qxcbnativeinterface.h
index 5ec3827afd..d1f2747bea 100644
--- a/src/plugins/platforms/xcb/qxcbnativeinterface.h
+++ b/src/plugins/platforms/xcb/qxcbnativeinterface.h
@@ -98,7 +98,7 @@ public:
QFunctionPointer platformFunction(const QByteArray &function) const override;
- inline const QByteArray &genericEventFilterType() const { return m_genericEventFilterType; }
+ inline const QByteArray &nativeEventType() const { return m_nativeEventType; }
void *displayForWindow(QWindow *window);
void *connectionForWindow(QWindow *window);
@@ -131,7 +131,7 @@ signals:
void systemTrayWindowChanged(QScreen *screen);
private:
- const QByteArray m_genericEventFilterType;
+ const QByteArray m_nativeEventType = QByteArrayLiteral("xcb_generic_event_t");
xcb_atom_t m_sysTraySelectionAtom = XCB_ATOM_NONE;
diff --git a/src/plugins/platforms/xcb/qxcbscreen.cpp b/src/plugins/platforms/xcb/qxcbscreen.cpp
index b398768bbc..8c0ce8dd7e 100644
--- a/src/plugins/platforms/xcb/qxcbscreen.cpp
+++ b/src/plugins/platforms/xcb/qxcbscreen.cpp
@@ -906,16 +906,12 @@ QByteArray QXcbScreen::getEdid() const
return result;
// Try a bunch of atoms
- xcb_atom_t atom = connection()->internAtom("EDID");
- result = getOutputProperty(atom);
- if (result.isEmpty()) {
- atom = connection()->internAtom("EDID_DATA");
- result = getOutputProperty(atom);
- }
- if (result.isEmpty()) {
- atom = connection()->internAtom("XFree86_DDC_EDID1_RAWDATA");
- result = getOutputProperty(atom);
- }
+ result = getOutputProperty(atom(QXcbAtom::EDID));
+ if (result.isEmpty())
+ result = getOutputProperty(atom(QXcbAtom::EDID_DATA));
+ if (result.isEmpty())
+ result = getOutputProperty(atom(QXcbAtom::XFree86_DDC_EDID1_RAWDATA));
+
return result;
}
diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp
index d42d95f890..52c87ee8a4 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.cpp
+++ b/src/plugins/platforms/xcb/qxcbwindow.cpp
@@ -275,11 +275,7 @@ QXcbWindow::QXcbWindow(QWindow *window)
setConnection(xcbScreen()->connection());
}
-#ifdef Q_COMPILER_CLASS_ENUM
enum : quint32 {
-#else
-enum {
-#endif
baseEventMask
= XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_STRUCTURE_NOTIFY
| XCB_EVENT_MASK_PROPERTY_CHANGE | XCB_EVENT_MASK_FOCUS_CHANGE,
@@ -441,8 +437,6 @@ void QXcbWindow::create()
connection()->addWindowEventListener(m_window, this);
- xcb_change_window_attributes(xcb_connection(), m_window, mask, values);
-
propagateSizeHints();
xcb_atom_t properties[5];
@@ -738,13 +732,6 @@ void QXcbWindow::setVisible(bool visible)
hide();
}
-static inline bool testShowWithoutActivating(const QWindow *window)
-{
- // QWidget-attribute Qt::WA_ShowWithoutActivating.
- const QVariant showWithoutActivating = window->property("_q_showWithoutActivating");
- return showWithoutActivating.isValid() && showWithoutActivating.toBool();
-}
-
void QXcbWindow::show()
{
if (window()->isTopLevel()) {
@@ -792,7 +779,9 @@ void QXcbWindow::show()
updateNetWmStateBeforeMap();
}
- if (testShowWithoutActivating(window()))
+ // QWidget-attribute Qt::WA_ShowWithoutActivating.
+ const auto showWithoutActivating = window()->property("_q_showWithoutActivating");
+ if (showWithoutActivating.isValid() && showWithoutActivating.toBool())
updateNetWmUserTime(0);
else if (connection()->time() != XCB_TIME_CURRENT_TIME)
updateNetWmUserTime(connection()->time());
@@ -1813,67 +1802,34 @@ bool QXcbWindow::requestSystemTrayWindowDock()
return true;
}
-class ExposeCompressor
-{
-public:
- ExposeCompressor(xcb_window_t window, QRegion *region)
- : m_window(window)
- , m_region(region)
- , m_pending(true)
- {
- }
-
- bool checkEvent(xcb_generic_event_t *event)
- {
- if (!event)
- return false;
- if ((event->response_type & ~0x80) != XCB_EXPOSE)
- return false;
- xcb_expose_event_t *expose = (xcb_expose_event_t *)event;
- if (expose->window != m_window)
- return false;
- if (expose->count == 0)
- m_pending = false;
- *m_region |= QRect(expose->x, expose->y, expose->width, expose->height);
- return true;
- }
-
- bool pending() const
- {
- return m_pending;
- }
-
-private:
- xcb_window_t m_window;
- QRegion *m_region;
- bool m_pending;
-};
-
-bool QXcbWindow::compressExposeEvent(QRegion &exposeRegion)
-{
- ExposeCompressor compressor(m_window, &exposeRegion);
- xcb_generic_event_t *filter = 0;
- do {
- filter = connection()->checkEvent(compressor);
- free(filter);
- } while (filter);
- return compressor.pending();
-}
-
-bool QXcbWindow::handleGenericEvent(xcb_generic_event_t *event, long *result)
+bool QXcbWindow::handleNativeEvent(xcb_generic_event_t *event)
{
- return QWindowSystemInterface::handleNativeEvent(window(),
- connection()->nativeInterface()->genericEventFilterType(),
- event,
- result);
+ auto eventType = connection()->nativeInterface()->nativeEventType();
+ long result = 0; // Used only by MS Windows
+ return QWindowSystemInterface::handleNativeEvent(window(), eventType, event, &result);
}
void QXcbWindow::handleExposeEvent(const xcb_expose_event_t *event)
{
QRect rect(event->x, event->y, event->width, event->height);
-
m_exposeRegion |= rect;
- bool pending = compressExposeEvent(m_exposeRegion);
+
+ bool pending = true;
+ xcb_generic_event_t *e = nullptr;
+ do { // compress expose events
+ e = connection()->checkEvent([this, &pending](xcb_generic_event_t *event, int type) {
+ if (type != XCB_EXPOSE)
+ return false;
+ auto expose = reinterpret_cast<xcb_expose_event_t *>(event);
+ if (expose->window != m_window)
+ return false;
+ if (expose->count == 0)
+ pending = false;
+ m_exposeRegion |= QRect(expose->x, expose->y, expose->width, expose->height);
+ return true;
+ });
+ free(e);
+ } while (e);
// if count is non-zero there are more expose events pending
if (event->count == 0 || !pending) {
@@ -2166,24 +2122,6 @@ static bool ignoreEnterEvent(quint8 mode, quint8 detail, QXcbConnection *conn =
|| detail == XCB_NOTIFY_DETAIL_NONLINEAR_VIRTUAL);
}
-class EnterEventChecker
-{
-public:
- bool checkEvent(xcb_generic_event_t *event)
- {
- if (!event)
- return false;
- if ((event->response_type & ~0x80) != XCB_ENTER_NOTIFY)
- return false;
-
- xcb_enter_notify_event_t *enter = (xcb_enter_notify_event_t *)event;
- if (ignoreEnterEvent(enter->mode, enter->detail))
- return false;
-
- return true;
- }
-};
-
void QXcbWindow::handleEnterNotifyEvent(int event_x, int event_y, int root_x, int root_y,
quint8 mode, quint8 detail, xcb_timestamp_t timestamp)
{
@@ -2210,9 +2148,17 @@ void QXcbWindow::handleLeaveNotifyEvent(int root_x, int root_y,
if (ignoreLeaveEvent(mode, detail, connection()) || connection()->mousePressWindow())
return;
- EnterEventChecker checker;
- xcb_enter_notify_event_t *enter = (xcb_enter_notify_event_t *)connection()->checkEvent(checker);
- QXcbWindow *enterWindow = enter ? connection()->platformWindowFromId(enter->event) : 0;
+ // check if enter event is buffered
+ auto event = connection()->checkEvent([](xcb_generic_event_t *event, int type) {
+ if (type != XCB_ENTER_NOTIFY)
+ return false;
+ auto enter = reinterpret_cast<xcb_enter_notify_event_t *>(event);
+ if (ignoreEnterEvent(enter->mode, enter->detail))
+ return false;
+ return true;
+ });
+ auto enter = reinterpret_cast<xcb_enter_notify_event_t *>(event);
+ QXcbWindow *enterWindow = enter ? connection()->platformWindowFromId(enter->event) : nullptr;
if (enterWindow) {
QPoint local(enter->event_x, enter->event_y);
diff --git a/src/plugins/platforms/xcb/qxcbwindow.h b/src/plugins/platforms/xcb/qxcbwindow.h
index 047ee2eae9..99e8e40725 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.h
+++ b/src/plugins/platforms/xcb/qxcbwindow.h
@@ -121,7 +121,7 @@ public:
QImage::Format imageFormat() const { return m_imageFormat; }
bool imageNeedsRgbSwap() const { return m_imageRgbSwap; }
- bool handleGenericEvent(xcb_generic_event_t *event, long *result) override;
+ bool handleNativeEvent(xcb_generic_event_t *event) override;
void handleExposeEvent(const xcb_expose_event_t *event) override;
void handleClientMessageEvent(const xcb_client_message_event_t *event) override;
@@ -217,8 +217,6 @@ protected:
void doFocusIn();
void doFocusOut();
- bool compressExposeEvent(QRegion &exposeRegion);
-
void handleButtonPressEvent(int event_x, int event_y, int root_x, int root_y,
int detail, Qt::KeyboardModifiers modifiers, xcb_timestamp_t timestamp,
QEvent::Type type, Qt::MouseEventSource source = Qt::MouseEventNotSynthesized);