summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/xcb/qxcbwindow.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/platforms/xcb/qxcbwindow.cpp')
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.cpp37
1 files changed, 20 insertions, 17 deletions
diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp
index 0275cf5630..2d52f5dd46 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.cpp
+++ b/src/plugins/platforms/xcb/qxcbwindow.cpp
@@ -315,6 +315,7 @@ static const char *wm_window_role_property_id = "_q_xcb_wm_window_role";
QXcbWindow::QXcbWindow(QWindow *window)
: QPlatformWindow(window)
, m_window(0)
+ , m_cmap(0)
, m_syncCounter(0)
, m_gravity(XCB_GRAVITY_STATIC)
, m_mapped(false)
@@ -443,7 +444,6 @@ void QXcbWindow::create()
m_visualId = visual->visual_id;
m_depth = platformScreen->depthOfVisual(m_visualId);
m_imageFormat = imageFormatForVisual(m_depth, visual->red_mask, visual->blue_mask, &m_imageRgbSwap);
- xcb_colormap_t colormap = 0;
quint32 mask = XCB_CW_BACK_PIXMAP
| XCB_CW_BORDER_PIXEL
@@ -455,10 +455,10 @@ void QXcbWindow::create()
static const bool haveOpenGL = QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::OpenGL);
if ((window()->supportsOpenGL() && haveOpenGL) || m_format.hasAlpha()) {
- colormap = xcb_generate_id(xcb_connection());
+ m_cmap = xcb_generate_id(xcb_connection());
Q_XCB_CALL(xcb_create_colormap(xcb_connection(),
XCB_COLORMAP_ALLOC_NONE,
- colormap,
+ m_cmap,
xcb_parent_id,
m_visualId));
@@ -472,7 +472,7 @@ void QXcbWindow::create()
type == Qt::Popup || type == Qt::ToolTip || (window()->flags() & Qt::BypassWindowManagerHint),
type == Qt::Popup || type == Qt::Tool || type == Qt::SplashScreen || type == Qt::ToolTip || type == Qt::Drawer,
defaultEventMask,
- colormap
+ m_cmap
};
m_window = xcb_generate_id(xcb_connection());
@@ -638,6 +638,9 @@ void QXcbWindow::destroy()
Q_XCB_CALL(xcb_destroy_window(xcb_connection(), m_window));
m_window = 0;
}
+ if (m_cmap) {
+ xcb_free_colormap(xcb_connection(), m_cmap);
+ }
m_mapped = false;
if (m_pendingSyncRequest)
@@ -2420,22 +2423,27 @@ static inline int fixed1616ToInt(FP1616 val)
return int((qreal(val >> 16)) + (val & 0xFFFF) / (qreal)0xFFFF);
}
-void QXcbWindow::handleXIMouseButtonState(const xcb_ge_event_t *event)
+// With XI 2.2+ press/release/motion comes here instead of the above handlers.
+void QXcbWindow::handleXIMouseEvent(xcb_ge_event_t *event, Qt::MouseEventSource source)
{
QXcbConnection *conn = connection();
- const xXIDeviceEvent *ev = reinterpret_cast<const xXIDeviceEvent *>(event);
+ xXIDeviceEvent *ev = reinterpret_cast<xXIDeviceEvent *>(event);
+
if (ev->buttons_len > 0) {
unsigned char *buttonMask = (unsigned char *) &ev[1];
+ // There is a bug in the evdev driver which leads to receiving mouse events without
+ // XIPointerEmulated being set: https://bugs.freedesktop.org/show_bug.cgi?id=98188
+ // Filter them out by other attributes: when their source device is a touch screen
+ // and the LMB is pressed.
+ if (XIMaskIsSet(buttonMask, 1) && conn->isTouchScreen(ev->sourceid)) {
+ if (Q_UNLIKELY(lcQpaXInputEvents().isDebugEnabled()))
+ qCDebug(lcQpaXInput, "XI2 mouse event from touch device %d was ignored", ev->sourceid);
+ return;
+ }
for (int i = 1; i <= 15; ++i)
conn->setButton(conn->translateMouseButton(i), XIMaskIsSet(buttonMask, i));
}
-}
-// With XI 2.2+ press/release/motion comes here instead of the above handlers.
-void QXcbWindow::handleXIMouseEvent(xcb_ge_event_t *event, Qt::MouseEventSource source)
-{
- QXcbConnection *conn = connection();
- xXIDeviceEvent *ev = reinterpret_cast<xXIDeviceEvent *>(event);
const Qt::KeyboardModifiers modifiers = conn->keyboard()->translateModifiers(ev->mods.effective_mods);
const int event_x = fixed1616ToInt(ev->event_x);
const int event_y = fixed1616ToInt(ev->event_y);
@@ -2455,23 +2463,18 @@ void QXcbWindow::handleXIMouseEvent(xcb_ge_event_t *event, Qt::MouseEventSource
switch (ev->evtype) {
case XI_ButtonPress:
- handleXIMouseButtonState(event);
if (Q_UNLIKELY(lcQpaXInputEvents().isDebugEnabled()))
qCDebug(lcQpaXInputEvents, "XI2 mouse press, button %d, time %d, source %s", button, ev->time, sourceName);
conn->setButton(button, true);
handleButtonPressEvent(event_x, event_y, root_x, root_y, ev->detail, modifiers, ev->time, source);
break;
case XI_ButtonRelease:
- handleXIMouseButtonState(event);
if (Q_UNLIKELY(lcQpaXInputEvents().isDebugEnabled()))
qCDebug(lcQpaXInputEvents, "XI2 mouse release, button %d, time %d, source %s", button, ev->time, sourceName);
conn->setButton(button, false);
handleButtonReleaseEvent(event_x, event_y, root_x, root_y, ev->detail, modifiers, ev->time, source);
break;
case XI_Motion:
- // Here we do NOT call handleXIMouseButtonState because we don't expect button state change to be bundled with motion.
- // When a touchscreen is pressed, an XI_Motion event occurs in which XIMaskIsSet says the left button is pressed,
- // but we don't want QGuiApplicationPrivate::processMouseEvent() to react by generating a mouse press event.
if (Q_UNLIKELY(lcQpaXInputEvents().isDebugEnabled()))
qCDebug(lcQpaXInputEvents, "XI2 mouse motion %d,%d, time %d, source %s", event_x, event_y, ev->time, sourceName);
handleMotionNotifyEvent(event_x, event_y, root_x, root_y, modifiers, ev->time, source);