diff options
Diffstat (limited to 'src/plugins/platforms/xcb')
-rw-r--r-- | src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp | 4 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbconnection.cpp | 11 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbconnection.h | 1 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbconnection_xi2.cpp | 21 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbkeyboard.cpp | 6 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbscreen.cpp | 20 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbscreen.h | 2 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbwindow.cpp | 117 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbwindow.h | 3 |
9 files changed, 107 insertions, 78 deletions
diff --git a/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp b/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp index bea25e8826..37f01d4eed 100644 --- a/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp +++ b/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp @@ -542,6 +542,9 @@ void QGLXContext::swapBuffers(QPlatformSurface *surface) void (*QGLXContext::getProcAddress(const QByteArray &procName)) () { +#ifdef QT_STATIC + return glXGetProcAddressARB(reinterpret_cast<const GLubyte *>(procName.constData())); +#else typedef void *(*qt_glXGetProcAddressARB)(const GLubyte *); static qt_glXGetProcAddressARB glXGetProcAddressARB = 0; static bool resolved = false; @@ -573,6 +576,7 @@ void (*QGLXContext::getProcAddress(const QByteArray &procName)) () if (!glXGetProcAddressARB) return 0; return (void (*)())glXGetProcAddressARB(reinterpret_cast<const GLubyte *>(procName.constData())); +#endif } QSurfaceFormat QGLXContext::format() const diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp index 78282d1415..f324942c8b 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection.cpp @@ -532,9 +532,14 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGra QStringList glIntegrationNames; glIntegrationNames << QStringLiteral("xcb_glx") << QStringLiteral("xcb_egl"); QString glIntegrationName = QString::fromLocal8Bit(qgetenv("QT_XCB_GL_INTEGRATION")); - if (glIntegrationName.size()) { - glIntegrationNames.removeAll(glIntegrationName); - glIntegrationNames.prepend(glIntegrationName); + if (!glIntegrationName.isEmpty()) { + qCDebug(QT_XCB_GLINTEGRATION) << "QT_XCB_GL_INTEGRATION is set to" << glIntegrationName; + if (glIntegrationName != QStringLiteral("none")) { + glIntegrationNames.removeAll(glIntegrationName); + glIntegrationNames.prepend(glIntegrationName); + } else { + glIntegrationNames.clear(); + } } qCDebug(QT_XCB_GLINTEGRATION) << "Choosing xcb gl-integration based on following priority\n" << glIntegrationNames; diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h index 0191b0e1ef..90603ac9bc 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.h +++ b/src/plugins/platforms/xcb/qxcbconnection.h @@ -609,7 +609,6 @@ private: #endif QXcbEventReader *m_reader; #if defined(XCB_USE_XINPUT2) - QHash<int, QWindowSystemInterface::TouchPoint> m_touchPoints; QHash<int, XInput2TouchDeviceData*> m_touchDevices; #endif #ifdef Q_XCB_DEBUG diff --git a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp index c7784ddb48..2f46436ce2 100644 --- a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp @@ -52,6 +52,7 @@ struct XInput2TouchDeviceData { } XIDeviceInfo *xiDeviceInfo; QTouchDevice *qtTouchDevice; + QHash<int, QWindowSystemInterface::TouchPoint> touchPoints; // Stuff that is relevant only for touchpads QHash<int, QPointF> pointPressedPosition; // in screen coordinates where each point was pressed @@ -525,7 +526,7 @@ void QXcbConnection::xi2HandleEvent(xcb_ge_event_t *event) case XI_ButtonPress: case XI_ButtonRelease: case XI_Motion: - if (xi2MouseEvents() && eventListener) + if (xi2MouseEvents() && eventListener && !(xiDeviceEvent->flags & XIPointerEmulated)) eventListener->handleXIMouseEvent(event); break; @@ -552,19 +553,21 @@ void QXcbConnection::xi2ProcessTouch(void *xiDevEvent, QXcbWindow *platformWindo xXIDeviceEvent *xiDeviceEvent = static_cast<xXIDeviceEvent *>(xiDevEvent); XInput2TouchDeviceData *dev = touchDeviceForId(xiDeviceEvent->sourceid); Q_ASSERT(dev); - const bool firstTouch = m_touchPoints.isEmpty(); + const bool firstTouch = dev->touchPoints.isEmpty(); if (xiDeviceEvent->evtype == XI_TouchBegin) { QWindowSystemInterface::TouchPoint tp; tp.id = xiDeviceEvent->detail % INT_MAX; tp.state = Qt::TouchPointPressed; tp.pressure = -1.0; - m_touchPoints[tp.id] = tp; + dev->touchPoints[tp.id] = tp; } - QWindowSystemInterface::TouchPoint &touchPoint = m_touchPoints[xiDeviceEvent->detail]; - qreal x = fixed1616ToReal(xiDeviceEvent->root_x); - qreal y = fixed1616ToReal(xiDeviceEvent->root_y); + QWindowSystemInterface::TouchPoint &touchPoint = dev->touchPoints[xiDeviceEvent->detail]; + QXcbScreen* screen = platformWindow->xcbScreen(); + QPointF pos = screen->mapFromNative(QPointF(fixed1616ToReal(xiDeviceEvent->root_x), + fixed1616ToReal(xiDeviceEvent->root_y))); + qreal x = pos.x(); + qreal y = pos.y(); qreal nx = -1.0, ny = -1.0, d = 0.0; - QXcbScreen* screen = m_screens.at(0); for (int i = 0; i < dev->xiDeviceInfo->num_classes; ++i) { XIAnyClassInfo *classinfo = dev->xiDeviceInfo->classes[i]; if (classinfo->type == XIValuatorClass) { @@ -677,10 +680,10 @@ void QXcbConnection::xi2ProcessTouch(void *xiDevEvent, QXcbWindow *platformWindo if (Q_UNLIKELY(lcQpaXInput().isDebugEnabled())) qCDebug(lcQpaXInput) << " touchpoint " << touchPoint.id << " state " << touchPoint.state << " pos norm " << touchPoint.normalPosition << " area " << touchPoint.area << " pressure " << touchPoint.pressure; - QWindowSystemInterface::handleTouchEvent(platformWindow->window(), xiDeviceEvent->time, dev->qtTouchDevice, m_touchPoints.values()); + QWindowSystemInterface::handleTouchEvent(platformWindow->window(), xiDeviceEvent->time, dev->qtTouchDevice, dev->touchPoints.values()); if (touchPoint.state == Qt::TouchPointReleased) // If a touchpoint was released, we can forget it, because the ID won't be reused. - m_touchPoints.remove(touchPoint.id); + dev->touchPoints.remove(touchPoint.id); else // Make sure that we don't send TouchPointPressed/Moved in more than one QTouchEvent // with this touch point if the next XI2 event is about a different touch point. diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.cpp b/src/plugins/platforms/xcb/qxcbkeyboard.cpp index f3bffd2998..2e088d3ca5 100644 --- a/src/plugins/platforms/xcb/qxcbkeyboard.cpp +++ b/src/plugins/platforms/xcb/qxcbkeyboard.cpp @@ -1473,8 +1473,6 @@ void QXcbKeyboard::handleKeyEvent(xcb_window_t sourceWindow, QEvent::Type type, } QString string = lookupString(xkb_state, code); - int count = string.size(); - string.truncate(count); // Ιf control modifier is set we should prefer latin character, this is // used for standard shortcuts in checks like "key == QKeySequence::Copy", @@ -1506,7 +1504,7 @@ void QXcbKeyboard::handleKeyEvent(xcb_window_t sourceWindow, QEvent::Type type, bool filtered = false; if (inputContext) { - QKeyEvent event(type, qtcode, modifiers, code, sym, state, string, isAutoRepeat, count); + QKeyEvent event(type, qtcode, modifiers, code, sym, state, string, isAutoRepeat, string.length()); event.setTimestamp(time); filtered = inputContext->filterEvent(&event); } @@ -1535,7 +1533,7 @@ void QXcbKeyboard::handleKeyEvent(xcb_window_t sourceWindow, QEvent::Type type, } if (!filtered && inputContext) { - QKeyEvent event(QEvent::KeyPress, qtcode, modifiers, code, sym, state, string, isAutoRepeat, count); + QKeyEvent event(QEvent::KeyPress, qtcode, modifiers, code, sym, state, string, isAutoRepeat, string.length()); event.setTimestamp(time); filtered = inputContext->filterEvent(&event); } diff --git a/src/plugins/platforms/xcb/qxcbscreen.cpp b/src/plugins/platforms/xcb/qxcbscreen.cpp index c14ec0bb3f..040cea1cb2 100644 --- a/src/plugins/platforms/xcb/qxcbscreen.cpp +++ b/src/plugins/platforms/xcb/qxcbscreen.cpp @@ -282,6 +282,18 @@ QPoint QXcbScreen::mapFromNative(const QPoint &pos) const return (pos - m_nativeGeometry.topLeft()) / dpr + m_geometry.topLeft(); } +QPointF QXcbScreen::mapToNative(const QPointF &pos) const +{ + const int dpr = int(devicePixelRatio()); + return (pos - m_geometry.topLeft()) * dpr + m_nativeGeometry.topLeft(); +} + +QPointF QXcbScreen::mapFromNative(const QPointF &pos) const +{ + const int dpr = int(devicePixelRatio()); + return (pos - m_nativeGeometry.topLeft()) / dpr + m_geometry.topLeft(); +} + QRect QXcbScreen::mapToNative(const QRect &rect) const { const int dpr = int(devicePixelRatio()); @@ -361,11 +373,11 @@ QDpi QXcbScreen::logicalDpi() const if (overrideDpi) return QDpi(overrideDpi, overrideDpi); - if (m_forcedDpi > 0) { - int primaryDpr = int(connection()->screens().at(0)->devicePixelRatio()); + int primaryDpr = int(connection()->screens().at(0)->devicePixelRatio()); + if (m_forcedDpi > 0) return QDpi(m_forcedDpi/primaryDpr, m_forcedDpi/primaryDpr); - } - return virtualDpi(); + QDpi vDpi = virtualDpi(); + return QDpi(vDpi.first/primaryDpr, vDpi.second/primaryDpr); } diff --git a/src/plugins/platforms/xcb/qxcbscreen.h b/src/plugins/platforms/xcb/qxcbscreen.h index ec05e3bb25..44519470e9 100644 --- a/src/plugins/platforms/xcb/qxcbscreen.h +++ b/src/plugins/platforms/xcb/qxcbscreen.h @@ -143,6 +143,8 @@ public: QPoint mapToNative(const QPoint &pos) const; QPoint mapFromNative(const QPoint &pos) const; + QPointF mapToNative(const QPointF &pos) const; + QPointF mapFromNative(const QPointF &pos) const; QRect mapToNative(const QRect &rect) const; QRect mapFromNative(const QRect &rect) const; diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index daee44fa96..05d7292430 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -874,11 +874,6 @@ void QXcbWindow::show() updateNetWmStateBeforeMap(); } - if (window()->metaObject()->indexOfProperty(wm_window_type_property_id) >= 0) { - QXcbWindowFunctions::WmWindowTypes wmWindowTypes(window()->property(wm_window_type_property_id).value<int>()); - setWmWindowType(wmWindowTypes); - } - if (connection()->time() != XCB_TIME_CURRENT_TIME) updateNetWmUserTime(connection()->time()); @@ -1141,7 +1136,13 @@ void QXcbWindow::setWindowFlags(Qt::WindowFlags flags) xcb_change_window_attributes(xcb_connection(), xcb_window(), mask, values); - setNetWmWindowFlags(flags); + QXcbWindowFunctions::WmWindowTypes wmWindowTypes = 0; + if (window()->dynamicPropertyNames().contains(wm_window_type_property_id)) { + wmWindowTypes = static_cast<QXcbWindowFunctions::WmWindowTypes>( + window()->property(wm_window_type_property_id).value<int>()); + } + + setWmWindowType(wmWindowTypes, flags); setMotifWindowFlags(flags); setTransparentForMouseEvents(flags & Qt::WindowTransparentForInput); @@ -1292,42 +1293,6 @@ void QXcbWindow::setWindowState(Qt::WindowState state) m_windowState = state; } -void QXcbWindow::setNetWmWindowFlags(Qt::WindowFlags flags) -{ - // in order of decreasing priority - QVector<uint> windowTypes; - - Qt::WindowType type = static_cast<Qt::WindowType>(int(flags & Qt::WindowType_Mask)); - - switch (type) { - case Qt::Dialog: - case Qt::Sheet: - windowTypes.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_DIALOG)); - break; - case Qt::Tool: - case Qt::Drawer: - windowTypes.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_UTILITY)); - break; - case Qt::ToolTip: - windowTypes.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_TOOLTIP)); - break; - case Qt::SplashScreen: - windowTypes.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_SPLASH)); - break; - default: - break; - } - - if (flags & Qt::FramelessWindowHint) - windowTypes.append(atom(QXcbAtom::_KDE_NET_WM_WINDOW_TYPE_OVERRIDE)); - - windowTypes.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_NORMAL)); - - Q_XCB_CALL(xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, m_window, - atom(QXcbAtom::_NET_WM_WINDOW_TYPE), XCB_ATOM_ATOM, 32, - windowTypes.count(), windowTypes.constData())); -} - void QXcbWindow::updateMotifWmHintsBeforeMap() { QtMotifWmHints mwmhints = getMotifWmHints(connection(), m_window); @@ -1716,10 +1681,10 @@ QSurfaceFormat QXcbWindow::format() const void QXcbWindow::setWmWindowTypeStatic(QWindow *window, QXcbWindowFunctions::WmWindowTypes windowTypes) { + window->setProperty(wm_window_type_property_id, QVariant::fromValue(static_cast<int>(windowTypes))); + if (window->handle()) - static_cast<QXcbWindow *>(window->handle())->setWmWindowType(windowTypes); - else - window->setProperty(wm_window_type_property_id, QVariant::fromValue(static_cast<int>(windowTypes))); + static_cast<QXcbWindow *>(window->handle())->setWmWindowType(windowTypes, window->flags()); } void QXcbWindow::setWindowIconTextStatic(QWindow *window, const QString &text) @@ -1806,40 +1771,82 @@ QXcbWindowFunctions::WmWindowTypes QXcbWindow::wmWindowTypes() const return result; } -void QXcbWindow::setWmWindowType(QXcbWindowFunctions::WmWindowTypes types) +void QXcbWindow::setWmWindowType(QXcbWindowFunctions::WmWindowTypes types, Qt::WindowFlags flags) { QVector<xcb_atom_t> atoms; + // manual selection 1 (these are never set by Qt and take precedence) if (types & QXcbWindowFunctions::Normal) atoms.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_NORMAL)); if (types & QXcbWindowFunctions::Desktop) atoms.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_DESKTOP)); if (types & QXcbWindowFunctions::Dock) atoms.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_DOCK)); - if (types & QXcbWindowFunctions::Toolbar) - atoms.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_TOOLBAR)); - if (types & QXcbWindowFunctions::Menu) - atoms.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_MENU)); + if (types & QXcbWindowFunctions::Notification) + atoms.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_NOTIFICATION)); + + // manual selection 2 (Qt uses these during auto selection); if (types & QXcbWindowFunctions::Utility) atoms.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_UTILITY)); if (types & QXcbWindowFunctions::Splash) atoms.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_SPLASH)); if (types & QXcbWindowFunctions::Dialog) atoms.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_DIALOG)); + if (types & QXcbWindowFunctions::Tooltip) + atoms.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_TOOLTIP)); + if (types & QXcbWindowFunctions::KdeOverride) + atoms.append(atom(QXcbAtom::_KDE_NET_WM_WINDOW_TYPE_OVERRIDE)); + + // manual selection 3 (these can be set by Qt, but don't have a + // corresponding Qt::WindowType). note that order of the *MENU + // atoms is important + if (types & QXcbWindowFunctions::Menu) + atoms.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_MENU)); if (types & QXcbWindowFunctions::DropDownMenu) atoms.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_DROPDOWN_MENU)); if (types & QXcbWindowFunctions::PopupMenu) atoms.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_POPUP_MENU)); - if (types & QXcbWindowFunctions::Tooltip) - atoms.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_TOOLTIP)); - if (types & QXcbWindowFunctions::Notification) - atoms.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_NOTIFICATION)); + if (types & QXcbWindowFunctions::Toolbar) + atoms.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_TOOLBAR)); if (types & QXcbWindowFunctions::Combo) atoms.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_COMBO)); if (types & QXcbWindowFunctions::Dnd) atoms.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_DND)); - if (types & QXcbWindowFunctions::KdeOverride) + + // automatic selection + Qt::WindowType type = static_cast<Qt::WindowType>(int(flags & Qt::WindowType_Mask)); + switch (type) { + case Qt::Dialog: + case Qt::Sheet: + if (!(types & QXcbWindowFunctions::Dialog)) + atoms.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_DIALOG)); + break; + case Qt::Tool: + case Qt::Drawer: + if (!(types & QXcbWindowFunctions::Utility)) + atoms.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_UTILITY)); + break; + case Qt::ToolTip: + if (!(types & QXcbWindowFunctions::Tooltip)) + atoms.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_TOOLTIP)); + break; + case Qt::SplashScreen: + if (!(types & QXcbWindowFunctions::Splash)) + atoms.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_SPLASH)); + break; + default: + break; + } + + if ((flags & Qt::FramelessWindowHint) && !(type & QXcbWindowFunctions::KdeOverride)) { + // override netwm type - quick and easy for KDE noborder atoms.append(atom(QXcbAtom::_KDE_NET_WM_WINDOW_TYPE_OVERRIDE)); + } + + if (atoms.size() == 1 && atoms.first() == atom(QXcbAtom::_NET_WM_WINDOW_TYPE_NORMAL)) + atoms.clear(); + else + atoms.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_NORMAL)); if (atoms.isEmpty()) { Q_XCB_CALL(xcb_delete_property(xcb_connection(), m_window, atom(QXcbAtom::_NET_WM_WINDOW_TYPE))); diff --git a/src/plugins/platforms/xcb/qxcbwindow.h b/src/plugins/platforms/xcb/qxcbwindow.h index 07019223c8..43c73180f5 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.h +++ b/src/plugins/platforms/xcb/qxcbwindow.h @@ -144,7 +144,7 @@ public: static uint visualIdStatic(QWindow *window); QXcbWindowFunctions::WmWindowTypes wmWindowTypes() const; - void setWmWindowType(QXcbWindowFunctions::WmWindowTypes types); + void setWmWindowType(QXcbWindowFunctions::WmWindowTypes types, Qt::WindowFlags flags); static void setWindowIconTextStatic(QWindow *window, const QString &text); @@ -190,7 +190,6 @@ protected: NetWmStates netWmStates(); void setNetWmStates(NetWmStates); - void setNetWmWindowFlags(Qt::WindowFlags flags); void setMotifWindowFlags(Qt::WindowFlags flags); void updateMotifWmHintsBeforeMap(); |