diff options
Diffstat (limited to 'src/plugins')
45 files changed, 546 insertions, 295 deletions
diff --git a/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp b/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp index 843387e679..e662d5f2d3 100644 --- a/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp +++ b/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp @@ -79,10 +79,14 @@ QNetworkManagerEngine::QNetworkManagerEngine(QObject *parent) connect(ofonoWatcher, SIGNAL(serviceUnregistered(QString)), this, SLOT(ofonoUnRegistered(QString))); - if (QDBusConnection::systemBus().interface()->isServiceRegistered("org.ofono")) + QDBusConnectionInterface *interface = QDBusConnection::systemBus().interface(); + + if (!interface) return; + + if (interface->isServiceRegistered("org.ofono")) QMetaObject::invokeMethod(this, "ofonoRegistered", Qt::QueuedConnection); - if (QDBusConnection::systemBus().interface()->isServiceRegistered(NM_DBUS_SERVICE)) + if (interface->isServiceRegistered(NM_DBUS_SERVICE)) QMetaObject::invokeMethod(this, "nmRegistered", Qt::QueuedConnection); } diff --git a/src/plugins/generic/evdevtouch/main.cpp b/src/plugins/generic/evdevtouch/main.cpp index d9aebfbe4c..ef6774b0a0 100644 --- a/src/plugins/generic/evdevtouch/main.cpp +++ b/src/plugins/generic/evdevtouch/main.cpp @@ -32,7 +32,7 @@ ****************************************************************************/ #include <QtGui/qgenericplugin.h> -#include <QtPlatformSupport/private/qevdevtouch_p.h> +#include <QtPlatformSupport/private/qevdevtouchmanager_p.h> QT_BEGIN_NAMESPACE @@ -55,7 +55,7 @@ QObject* QEvdevTouchScreenPlugin::create(const QString &key, const QString &spec) { if (!key.compare(QLatin1String("EvdevTouch"), Qt::CaseInsensitive)) - return new QEvdevTouchScreenHandlerThread(spec); + return new QEvdevTouchManager(key, spec); return 0; } diff --git a/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp b/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp index dca5fe871e..ad9877eb25 100644 --- a/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp +++ b/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp @@ -554,6 +554,10 @@ void TableGenerator::parseKeySequence(char *line) if (!composeValueEnd) return; + // if composed value is a quotation mark adjust the end pointer + if (composeValueEnd[1] == '"') + ++composeValueEnd; + if (*composeValue == '\\' && composeValue[1] >= '0' && composeValue[1] <= '9') { // handle octal and hex code values char detectBase = composeValue[2]; @@ -568,7 +572,7 @@ void TableGenerator::parseKeySequence(char *line) // handle direct text encoded in the locale if (*composeValue == '\\') ++composeValue; - elem.value = QString::fromLocal8Bit(composeValue).at(0).unicode(); + elem.value = QString::fromLocal8Bit(composeValue, composeValueEnd - composeValue).at(0).unicode(); ++composeValue; } diff --git a/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontext.cpp b/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontext.cpp index 49fa32004e..d1bea9af23 100644 --- a/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontext.cpp +++ b/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontext.cpp @@ -80,37 +80,32 @@ static const int composingKeys[] = { }; QComposeInputContext::QComposeInputContext() + : m_tableState(TableGenerator::EmptyTable) + , m_compositionTableInitialized(false) { - TableGenerator reader; - m_tableState = reader.tableState(); - - if ((m_tableState & TableGenerator::NoErrors) == TableGenerator::NoErrors) { - m_composeTable = reader.composeTable(); - clearComposeBuffer(); - } + clearComposeBuffer(); } bool QComposeInputContext::filterEvent(const QEvent *event) { - // if there were errors when generating the compose table input - // context should not try to filter anything, simply return false - if ((m_tableState & TableGenerator::NoErrors) != TableGenerator::NoErrors) - return false; - const QKeyEvent *keyEvent = (const QKeyEvent *)event; // should pass only the key presses if (keyEvent->type() != QEvent::KeyPress) { return false; } + // if there were errors when generating the compose table input + // context should not try to filter anything, simply return false + if (m_compositionTableInitialized && (m_tableState & TableGenerator::NoErrors) != TableGenerator::NoErrors) + return false; + int keyval = keyEvent->key(); int keysym = 0; if (ignoreKey(keyval)) return false; - QString text = keyEvent->text(); - if (!composeKey(keyval) && text.isEmpty()) + if (!composeKey(keyval) && keyEvent->text().isEmpty()) return false; keysym = keyEvent->nativeVirtualKey(); @@ -163,6 +158,15 @@ static bool isDuplicate(const QComposeTableElement &lhs, const QComposeTableElem bool QComposeInputContext::checkComposeTable() { + if (!m_compositionTableInitialized) { + TableGenerator reader; + m_tableState = reader.tableState(); + + if ((m_tableState & TableGenerator::NoErrors) == TableGenerator::NoErrors) + m_composeTable = reader.composeTable(); + + m_compositionTableInitialized = true; + } QVector<QComposeTableElement>::const_iterator it = std::lower_bound(m_composeTable.constBegin(), m_composeTable.constEnd(), m_composeBuffer, Compare()); diff --git a/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontext.h b/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontext.h index 643b93c32d..bdf5a91335 100644 --- a/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontext.h +++ b/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontext.h @@ -70,6 +70,7 @@ private: QVector<QComposeTableElement> m_composeTable; uint m_composeBuffer[QT_KEYSEQUENCE_MAX_LEN + 1]; TableGenerator::TableState m_tableState; + bool m_compositionTableInitialized; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/android/androidjniinput.cpp b/src/plugins/platforms/android/androidjniinput.cpp index 14b0c96cb5..8ee3ff88d1 100644 --- a/src/plugins/platforms/android/androidjniinput.cpp +++ b/src/plugins/platforms/android/androidjniinput.cpp @@ -663,24 +663,24 @@ namespace QtAndroidInput return unicode ? QString(QChar(unicode)) : QString(); } - static void keyDown(JNIEnv */*env*/, jobject /*thiz*/, jint key, jint unicode, jint modifier) + static void keyDown(JNIEnv */*env*/, jobject /*thiz*/, jint key, jint unicode, jint modifier, jboolean autoRepeat) { QWindowSystemInterface::handleKeyEvent(0, QEvent::KeyPress, mapAndroidKey(key), mapAndroidModifiers(modifier), toString(unicode), - false); + autoRepeat); } - static void keyUp(JNIEnv */*env*/, jobject /*thiz*/, jint key, jint unicode, jint modifier) + static void keyUp(JNIEnv */*env*/, jobject /*thiz*/, jint key, jint unicode, jint modifier, jboolean autoRepeat) { QWindowSystemInterface::handleKeyEvent(0, QEvent::KeyRelease, mapAndroidKey(key), mapAndroidModifiers(modifier), toString(unicode), - false); + autoRepeat); } static void keyboardVisibilityChanged(JNIEnv */*env*/, jobject /*thiz*/, jboolean visibility) @@ -702,8 +702,8 @@ namespace QtAndroidInput {"mouseUp", "(III)V", (void *)mouseUp}, {"mouseMove", "(III)V", (void *)mouseMove}, {"longPress", "(III)V", (void *)longPress}, - {"keyDown", "(III)V", (void *)keyDown}, - {"keyUp", "(III)V", (void *)keyUp}, + {"keyDown", "(IIIZ)V", (void *)keyDown}, + {"keyUp", "(IIIZ)V", (void *)keyUp}, {"keyboardVisibilityChanged", "(Z)V", (void *)keyboardVisibilityChanged} }; diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.h b/src/plugins/platforms/cocoa/qcocoaintegration.h index dc9140d990..ee42a83446 100644 --- a/src/plugins/platforms/cocoa/qcocoaintegration.h +++ b/src/plugins/platforms/cocoa/qcocoaintegration.h @@ -138,6 +138,8 @@ public: QCocoaWindow *popPopupWindow(); QCocoaWindow *activePopupWindow() const; QList<QCocoaWindow *> *popupWindowStack(); + + void setApplicationIcon(const QIcon &icon) const; private: static QCocoaIntegration *mInstance; diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm index aa33cfd8bc..c8f6dd05db 100644 --- a/src/plugins/platforms/cocoa/qcocoaintegration.mm +++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm @@ -420,6 +420,7 @@ bool QCocoaIntegration::hasCapability(QPlatformIntegration::Capability cap) cons case ForeignWindows: case RasterGLSurface: case ApplicationState: + case ApplicationIcon: return true; default: return QPlatformIntegration::hasCapability(cap); @@ -569,4 +570,16 @@ QList<QCocoaWindow *> *QCocoaIntegration::popupWindowStack() return &m_popupWindowStack; } +void QCocoaIntegration::setApplicationIcon(const QIcon &icon) const +{ + NSImage *image = nil; + if (!icon.isNull()) { + NSSize size = [[[NSApplication sharedApplication] dockTile] size]; + QPixmap pixmap = icon.pixmap(size.width, size.height); + image = static_cast<NSImage *>(qt_mac_create_nsimage(pixmap)); + } + [[NSApplication sharedApplication] setApplicationIconImage:image]; + [image release]; +} + QT_END_NAMESPACE diff --git a/src/plugins/platforms/cocoa/qcocoamenuitem.mm b/src/plugins/platforms/cocoa/qcocoamenuitem.mm index bf12c0f2ce..f288ab85c0 100644 --- a/src/plugins/platforms/cocoa/qcocoamenuitem.mm +++ b/src/plugins/platforms/cocoa/qcocoamenuitem.mm @@ -308,7 +308,6 @@ NSMenuItem *QCocoaMenuItem::sync() } [m_native setHidden: !m_isVisible]; - [m_native setEnabled: m_enabled]; [m_native setView:m_itemView]; QString text = mergeText(); @@ -410,7 +409,7 @@ void QCocoaMenuItem::syncModalState(bool modal) if (modal) [m_native setEnabled:NO]; else - [m_native setEnabled:m_enabled]; + [m_native setEnabled:YES]; } QPlatformMenuItem::MenuRole QCocoaMenuItem::effectiveRole() const diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index c0c0080f9a..f6389a2096 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -1515,10 +1515,11 @@ void QCocoaWindow::syncWindowState(Qt::WindowState newState) } } + const bool effMax = m_effectivelyMaximized; if ((m_synchedWindowState & Qt::WindowMaximized) != (newState & Qt::WindowMaximized) || (m_effectivelyMaximized && newState == Qt::WindowNoState)) { if ((m_synchedWindowState & Qt::WindowFullScreen) == (newState & Qt::WindowFullScreen)) { [m_nsWindow zoom : m_nsWindow]; // toggles - m_effectivelyMaximized = !m_effectivelyMaximized; + m_effectivelyMaximized = !effMax; } else if (!(newState & Qt::WindowMaximized)) { // it would be nice to change the target geometry that toggleFullScreen will animate toward // but there is no known way, so the maximized state is not possible at this time diff --git a/src/plugins/platforms/cocoa/qnsview.h b/src/plugins/platforms/cocoa/qnsview.h index c3815ee60a..32bc15d092 100644 --- a/src/plugins/platforms/cocoa/qnsview.h +++ b/src/plugins/platforms/cocoa/qnsview.h @@ -59,6 +59,7 @@ Q_FORWARD_DECLARE_OBJC_CLASS(QT_MANGLE_NAMESPACE(QNSViewMouseMoveHelper)); bool m_shouldInvalidateWindowShadow; QWindow *m_window; QCocoaWindow *m_platformWindow; + NSTrackingArea *m_trackingArea; Qt::MouseButtons m_buttons; Qt::MouseButtons m_frameStrutButtons; QString m_composingText; diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index a27c93e23f..25a92d2868 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -167,6 +167,7 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil; - (void)dealloc { CGImageRelease(m_maskImage); + [m_trackingArea release]; m_maskImage = 0; m_window = 0; m_subscribesForGlobalFrameNotifications = false; @@ -188,6 +189,7 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil; m_window = window; m_platformWindow = platformWindow; m_sendKeyEvent = false; + m_trackingArea = nil; #ifdef QT_COCOA_ENABLE_ACCESSIBILITY_INSPECTOR // prevent rift in space-time continuum, disable @@ -847,19 +849,11 @@ QT_WARNING_POP { [super updateTrackingAreas]; - // [NSView addTrackingArea] is slow, so bail out early if we can: - if (NSIsEmptyRect([self visibleRect])) - return; - - // Remove current trakcing areas: QCocoaAutoReleasePool pool; - if (NSArray *trackingArray = [self trackingAreas]) { - NSUInteger size = [trackingArray count]; - for (NSUInteger i = 0; i < size; ++i) { - NSTrackingArea *t = [trackingArray objectAtIndex:i]; - [self removeTrackingArea:t]; - } - } + + // NSTrackingInVisibleRect keeps care of updating once the tracking is set up, so bail out early + if (m_trackingArea && [[self trackingAreas] containsObject:m_trackingArea]) + return; // Ideally, we shouldn't have NSTrackingMouseMoved events included below, it should // only be turned on if mouseTracking, hover is on or a tool tip is set. @@ -869,12 +863,12 @@ QT_WARNING_POP // is a performance hit). So it goes. NSUInteger trackingOptions = NSTrackingMouseEnteredAndExited | NSTrackingActiveInActiveApp | NSTrackingInVisibleRect | NSTrackingMouseMoved | NSTrackingCursorUpdate; - NSTrackingArea *ta = [[[NSTrackingArea alloc] initWithRect:[self frame] - options:trackingOptions - owner:m_mouseMoveHelper - userInfo:nil] - autorelease]; - [self addTrackingArea:ta]; + [m_trackingArea release]; + m_trackingArea = [[NSTrackingArea alloc] initWithRect:[self frame] + options:trackingOptions + owner:m_mouseMoveHelper + userInfo:nil]; + [self addTrackingArea:m_trackingArea]; } -(void)cursorUpdateImpl:(NSEvent *)theEvent @@ -1889,6 +1883,48 @@ static QPoint mapWindowCoordinates(QWindow *source, QWindow *target, QPoint poin response = QWindowSystemInterface::handleDrag(target, &mimeData, mapWindowCoordinates(m_window, target, qt_windowPoint), qtAllowed); } + QCocoaDrag* nativeDrag = QCocoaIntegration::instance()->drag(); + const QPixmap pixmapCursor = nativeDrag->currentDrag()->dragCursor(response.acceptedAction()); + NSCursor *nativeCursor = nil; + + if (pixmapCursor.isNull()) { + switch (response.acceptedAction()) { + case Qt::CopyAction: + nativeCursor = [NSCursor dragCopyCursor]; + break; + case Qt::LinkAction: + nativeCursor = [NSCursor dragLinkCursor]; + break; + case Qt::IgnoreAction: + // Uncomment the next lines if forbiden cursor wanted on non droppable targets. + /*nativeCursor = [NSCursor operationNotAllowedCursor]; + break;*/ + case Qt::MoveAction: + default: + nativeCursor = [NSCursor arrowCursor]; + break; + } + } + else { + NSImage *nsimage = qt_mac_create_nsimage(pixmapCursor); + nativeCursor = [[NSCursor alloc] initWithImage:nsimage hotSpot:NSZeroPoint]; + [nsimage release]; + } + + // change the cursor + [nativeCursor set]; + + // Make sure the cursor is updated correctly if the mouse does not move and window is under cursor + // by creating a fake move event + const QPoint mousePos(QCursor::pos()); + CGEventRef moveEvent(CGEventCreateMouseEvent( + NULL, kCGEventMouseMoved, + CGPointMake(mousePos.x(), mousePos.y()), + kCGMouseButtonLeft // ignored + )); + CGEventPost(kCGHIDEventTap, moveEvent); + CFRelease(moveEvent); + return qt_mac_mapDropAction(response.acceptedAction()); } diff --git a/src/plugins/platforms/ios/qiostextresponder.mm b/src/plugins/platforms/ios/qiostextresponder.mm index 4f85fb7b55..3d0bac82c8 100644 --- a/src/plugins/platforms/ios/qiostextresponder.mm +++ b/src/plugins/platforms/ios/qiostextresponder.mm @@ -218,7 +218,9 @@ else if (hints & Qt::ImhFormattedNumbersOnly) self.keyboardType = UIKeyboardTypeDecimalPad; else if (hints & Qt::ImhDialableCharactersOnly) - self.keyboardType = UIKeyboardTypeNumberPad; + self.keyboardType = UIKeyboardTypePhonePad; + else if (hints & Qt::ImhLatinOnly) + self.keyboardType = UIKeyboardTypeASCIICapable; else self.keyboardType = UIKeyboardTypeDefault; diff --git a/src/plugins/platforms/linuxfb/qlinuxfbintegration.cpp b/src/plugins/platforms/linuxfb/qlinuxfbintegration.cpp index 2c61f68e83..ccf86dafb2 100644 --- a/src/plugins/platforms/linuxfb/qlinuxfbintegration.cpp +++ b/src/plugins/platforms/linuxfb/qlinuxfbintegration.cpp @@ -49,7 +49,7 @@ #if !defined(QT_NO_EVDEV) && (!defined(Q_OS_ANDROID) || defined(Q_OS_ANDROID_NO_SDK)) #include <QtPlatformSupport/private/qevdevmousemanager_p.h> #include <QtPlatformSupport/private/qevdevkeyboardmanager_p.h> -#include <QtPlatformSupport/private/qevdevtouch_p.h> +#include <QtPlatformSupport/private/qevdevtouchmanager_p.h> #endif #if !defined(QT_NO_TSLIB) && (!defined(Q_OS_ANDROID) || defined(Q_OS_ANDROID_NO_SDK)) @@ -139,7 +139,7 @@ void QLinuxFbIntegration::createInputHandlers() new QTsLibMouseHandler(QLatin1String("TsLib"), QString()); else #endif // QT_NO_TSLIB - new QEvdevTouchScreenHandlerThread(QString(), this); + new QEvdevTouchManager(QLatin1String("EvdevTouch"), QString() /* spec */, this); #endif } diff --git a/src/plugins/platforms/qnx/qqnxfilepicker.cpp b/src/plugins/platforms/qnx/qqnxfilepicker.cpp index 96ca531899..ca8d731e66 100644 --- a/src/plugins/platforms/qnx/qqnxfilepicker.cpp +++ b/src/plugins/platforms/qnx/qqnxfilepicker.cpp @@ -55,6 +55,8 @@ #define qFilePickerDebug QT_NO_QDEBUG_MACRO #endif +QT_BEGIN_NAMESPACE + static const char s_filePickerTarget[] = "sys.filepicker.target"; QQnxFilePicker::QQnxFilePicker(QObject *parent) @@ -316,3 +318,5 @@ QString QQnxFilePicker::modeToString(QQnxFilePicker::Mode mode) const return QStringLiteral("Picker"); } + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/qnx/qqnxfilepicker.h b/src/plugins/platforms/qnx/qqnxfilepicker.h index aef8f43abc..7e4f9010cc 100644 --- a/src/plugins/platforms/qnx/qqnxfilepicker.h +++ b/src/plugins/platforms/qnx/qqnxfilepicker.h @@ -38,6 +38,8 @@ #include <QObject> #include <QStringList> +QT_BEGIN_NAMESPACE + struct navigator_invoke_invocation_t; class QQnxFilePicker : public QObject, public QAbstractNativeEventFilter @@ -100,4 +102,6 @@ private: QString m_title; }; +QT_END_NAMESPACE + #endif // QQNXFILEPICKER_H diff --git a/src/plugins/platforms/qnx/qqnxsystemsettings.h b/src/plugins/platforms/qnx/qqnxsystemsettings.h index 5535e02dd8..6a99d5a70c 100644 --- a/src/plugins/platforms/qnx/qqnxsystemsettings.h +++ b/src/plugins/platforms/qnx/qqnxsystemsettings.h @@ -37,10 +37,10 @@ #include <QtCore/qhash.h> #include <qpa/qplatformtheme.h> -class QPlatformFontDatabase; - QT_BEGIN_NAMESPACE +class QPlatformFontDatabase; + QHash<QPlatformTheme::Font, QFont *> qt_qnx_createRoleFonts(QPlatformFontDatabase *fontDatabase); QT_END_NAMESPACE diff --git a/src/plugins/platforms/qnx/qqnxvirtualkeyboardpps.h b/src/plugins/platforms/qnx/qqnxvirtualkeyboardpps.h index c32a519d97..6bde4c7354 100644 --- a/src/plugins/platforms/qnx/qqnxvirtualkeyboardpps.h +++ b/src/plugins/platforms/qnx/qqnxvirtualkeyboardpps.h @@ -86,4 +86,6 @@ private: static const size_t ms_bufferSize; }; +QT_END_NAMESPACE + #endif // VIRTUALKEYBOARDPPS_H diff --git a/src/plugins/platforms/windows/accessible/iaccessible2.cpp b/src/plugins/platforms/windows/accessible/iaccessible2.cpp index eaf44f0f72..99c44c69ef 100644 --- a/src/plugins/platforms/windows/accessible/iaccessible2.cpp +++ b/src/plugins/platforms/windows/accessible/iaccessible2.cpp @@ -38,7 +38,7 @@ #include <QtPlatformSupport/private/qaccessiblebridgeutils_p.h> #include <QtGui/qaccessible.h> #include <QtGui/qclipboard.h> -#include <QtWidgets/qapplication.h> +#include <QtGui/qguiapplication.h> #include <QtCore/qdebug.h> QT_BEGIN_NAMESPACE diff --git a/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp b/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp index 013f1a5b77..8b67f235bb 100644 --- a/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp +++ b/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp @@ -49,10 +49,6 @@ #include <QtGui/qguiapplication.h> #include <qpa/qplatformnativeinterface.h> #include <QtGui/qwindow.h> -#include <QtWidgets/qapplication.h> -#include <QtWidgets/qgraphicsitem.h> -#include <QtWidgets/qgraphicsview.h> -#include <QtWidgets/qmessagebox.h> //#include <uiautomationcoreapi.h> #ifndef UiaRootObjectId diff --git a/src/plugins/platforms/windows/openglblacklists/default.json b/src/plugins/platforms/windows/openglblacklists/default.json index 0217b79ecf..23607523bd 100644 --- a/src/plugins/platforms/windows/openglblacklists/default.json +++ b/src/plugins/platforms/windows/openglblacklists/default.json @@ -4,12 +4,16 @@ "entries": [ { "id": 1, - "description": "Desktop OpenGL is unreliable on Intel HD3000/GMA (QTBUG-43263, QTBUG-42240)", + "description": "Desktop OpenGL is unreliable on some Intel HD laptops (QTBUG-43263, QTBUG-42240)", "vendor_id": "0x8086", "device_id": [ "0x0A16" ], "os": { "type": "win" }, + "driver_version": { + "op": "<=", + "value": "10.18.10.3277" + }, "features": [ "disable_desktopgl" ] diff --git a/src/plugins/platforms/windows/qwindowseglcontext.cpp b/src/plugins/platforms/windows/qwindowseglcontext.cpp index 7db6abd8ef..0184877fdd 100644 --- a/src/plugins/platforms/windows/qwindowseglcontext.cpp +++ b/src/plugins/platforms/windows/qwindowseglcontext.cpp @@ -366,7 +366,8 @@ QWindowsEGLStaticContext *QWindowsEGLStaticContext::create(QWindowsOpenGLTester: const EGLint anglePlatformAttributes[][5] = { { EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, EGL_NONE }, { EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE, EGL_NONE }, - { EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, EGL_PLATFORM_ANGLE_USE_WARP_ANGLE, EGL_TRUE, EGL_NONE } + { EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, + EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE, EGL_NONE } }; const EGLint *attributes = 0; if (preferredType & QWindowsOpenGLTester::AngleRendererD3d11) diff --git a/src/plugins/platforms/windows/qwindowsglcontext.cpp b/src/plugins/platforms/windows/qwindowsglcontext.cpp index 7a17942b27..d9eec9f603 100644 --- a/src/plugins/platforms/windows/qwindowsglcontext.cpp +++ b/src/plugins/platforms/windows/qwindowsglcontext.cpp @@ -601,6 +601,14 @@ static int choosePixelFormat(HDC hdc, break; if (iAttributes[samplesValuePosition] > 1) { iAttributes[samplesValuePosition] /= 2; + } else if (iAttributes[samplesValuePosition] == 1) { + // Fallback in case it is unable to initialize with any + // samples to avoid falling back to the GDI path + // NB: The sample attributes needs to be at the end for this + // to work correctly + iAttributes[samplesValuePosition - 1] = FALSE; + iAttributes[samplesValuePosition] = 0; + iAttributes[samplesValuePosition + 1] = 0; } else { break; } diff --git a/src/plugins/platforms/windows/qwindowsopengltester.cpp b/src/plugins/platforms/windows/qwindowsopengltester.cpp index f5065a22b8..2e6a43f596 100644 --- a/src/plugins/platforms/windows/qwindowsopengltester.cpp +++ b/src/plugins/platforms/windows/qwindowsopengltester.cpp @@ -224,10 +224,7 @@ QWindowsOpenGLTester::Renderers QWindowsOpenGLTester::detectSupportedRenderers(c #elif defined(Q_OS_WINCE) return QWindowsOpenGLTester::Gles; #else - QOpenGLConfig::Gpu qgpu; - qgpu.deviceId = gpu.deviceId; - qgpu.vendorId = gpu.vendorId; - qgpu.driverVersion = gpu.driverVersion; + QOpenGLConfig::Gpu qgpu = QOpenGLConfig::Gpu::fromDevice(gpu.deviceId, gpu.vendorId, gpu.driverVersion); SupportedRenderersCache *srCache = supportedRenderersCache(); SupportedRenderersCache::const_iterator it = srCache->find(qgpu); if (it != srCache->cend()) diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index 6afa4e6591..b19510073a 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -540,13 +540,9 @@ void WindowCreationData::fromWindow(const QWindow *w, const Qt::WindowFlags flag } if (flags & Qt::WindowSystemMenuHint) style |= WS_SYSMENU; - else if (dialog) { - // QTBUG-2027, dialogs without system menu. - style |= WS_SYSMENU; - if (!(flags & Qt::FramelessWindowHint)) { - style |= WS_BORDER; - exStyle |= WS_EX_DLGMODALFRAME; - } + else if (dialog && (flags & Qt::WindowCloseButtonHint) && !(flags & Qt::FramelessWindowHint)) { + style |= WS_SYSMENU | WS_BORDER; // QTBUG-2027, dialogs without system menu. + exStyle |= WS_EX_DLGMODALFRAME; } if (flags & Qt::WindowMinimizeButtonHint) style |= WS_MINIMIZEBOX; diff --git a/src/plugins/platforms/winrt/qwinrtinputcontext.cpp b/src/plugins/platforms/winrt/qwinrtinputcontext.cpp index 299a80b1d7..f0de578db6 100644 --- a/src/plugins/platforms/winrt/qwinrtinputcontext.cpp +++ b/src/plugins/platforms/winrt/qwinrtinputcontext.cpp @@ -32,6 +32,7 @@ ****************************************************************************/ #include "qwinrtinputcontext.h" +#include "qwinrtscreen.h" #include <QtGui/QWindow> #include <wrl.h> @@ -44,11 +45,6 @@ using namespace ABI::Windows::Foundation; using namespace ABI::Windows::UI::ViewManagement; using namespace ABI::Windows::UI::Core; -#if defined(Q_OS_WINPHONE) && _MSC_VER==1700 -#include <windows.phone.ui.core.h> -using namespace ABI::Windows::Phone::UI::Core; -#endif - typedef ITypedEventHandler<InputPane*, InputPaneVisibilityEventArgs*> InputPaneVisibilityHandler; QT_BEGIN_NAMESPACE @@ -66,8 +62,8 @@ QT_BEGIN_NAMESPACE Windows Phone, however, supports direct hiding/showing of the keyboard. */ -QWinRTInputContext::QWinRTInputContext(ICoreWindow *window) - : m_window(window) +QWinRTInputContext::QWinRTInputContext(QWinRTScreen *screen) + : m_screen(screen) { IInputPaneStatics *statics; if (FAILED(GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_UI_ViewManagement_InputPane).Get(), @@ -86,9 +82,7 @@ QWinRTInputContext::QWinRTInputContext(ICoreWindow *window) inputPane->add_Hiding(Callback<InputPaneVisibilityHandler>( this, &QWinRTInputContext::onHiding).Get(), &hideToken); - Rect rect; - inputPane->get_OccludedRect(&rect); - m_keyboardRect = QRectF(rect.X, rect.Y, rect.Width, rect.Height); + handleVisibilityChange(inputPane); m_isInputPanelVisible = !m_keyboardRect.isEmpty(); } else { qWarning(Q_FUNC_INFO ": failed to retrieve InputPane."); @@ -109,38 +103,31 @@ HRESULT QWinRTInputContext::onShowing(IInputPane *pane, IInputPaneVisibilityEven { m_isInputPanelVisible = true; emitInputPanelVisibleChanged(); - - Rect rect; - pane->get_OccludedRect(&rect); - setKeyboardRect(QRectF(rect.X, rect.Y, rect.Width, rect.Height)); - - return S_OK; + return handleVisibilityChange(pane); } HRESULT QWinRTInputContext::onHiding(IInputPane *pane, IInputPaneVisibilityEventArgs *) { m_isInputPanelVisible = false; emitInputPanelVisibleChanged(); + return handleVisibilityChange(pane); +} +HRESULT QWinRTInputContext::handleVisibilityChange(IInputPane *pane) +{ Rect rect; pane->get_OccludedRect(&rect); - setKeyboardRect(QRectF(rect.X, rect.Y, rect.Width, rect.Height)); - + const QRectF keyboardRect = QRectF(qRound(rect.X * m_screen->scaleFactor()), qRound(rect.Y * m_screen->scaleFactor()), + qRound(rect.Width * m_screen->scaleFactor()), qRound(rect.Height * m_screen->scaleFactor())); + if (m_keyboardRect != keyboardRect) { + m_keyboardRect = keyboardRect; + emitKeyboardRectChanged(); + } return S_OK; } -void QWinRTInputContext::setKeyboardRect(const QRectF rect) -{ - if (m_keyboardRect == rect) - return; - - m_keyboardRect = rect; - emitKeyboardRectChanged(); -} - #ifdef Q_OS_WINPHONE -#if _MSC_VER>1700 // Windows Phone 8.1+ static HRESULT getInputPane(ComPtr<IInputPane2> *inputPane2) { ComPtr<IInputPaneStatics> factory; @@ -165,17 +152,9 @@ static HRESULT getInputPane(ComPtr<IInputPane2> *inputPane2) } return hr; } -#endif // _MSC_VER>1700 void QWinRTInputContext::showInputPanel() { -#if _MSC_VER<=1700 // Windows Phone 8.0 - ICoreWindowKeyboardInput *input; - if (SUCCEEDED(m_window->QueryInterface(IID_PPV_ARGS(&input)))) { - input->put_IsKeyboardInputEnabled(true); - input->Release(); - } -#else // _MSC_VER<=1700 ComPtr<IInputPane2> inputPane; HRESULT hr = getInputPane(&inputPane); if (FAILED(hr)) @@ -185,18 +164,10 @@ void QWinRTInputContext::showInputPanel() hr = inputPane->TryShow(&success); if (FAILED(hr)) qErrnoWarning(hr, "Failed to show input panel."); -#endif // _MSC_VER>1700 } void QWinRTInputContext::hideInputPanel() { -#if _MSC_VER<=1700 // Windows Phone 8.0 - ICoreWindowKeyboardInput *input; - if (SUCCEEDED(m_window->QueryInterface(IID_PPV_ARGS(&input)))) { - input->put_IsKeyboardInputEnabled(false); - input->Release(); - } -#else // _MSC_VER<=1700 ComPtr<IInputPane2> inputPane; HRESULT hr = getInputPane(&inputPane); if (FAILED(hr)) @@ -206,7 +177,6 @@ void QWinRTInputContext::hideInputPanel() hr = inputPane->TryHide(&success); if (FAILED(hr)) qErrnoWarning(hr, "Failed to hide input panel."); -#endif // _MSC_VER>1700 } #else // Q_OS_WINPHONE @@ -257,7 +227,7 @@ HRESULT QWinRTInputContext::GetPropertyValue(PROPERTYID idProp, VARIANT *retVal) break; case 30020: //UIA_NativeWindowHandlePropertyId retVal->vt = VT_PTR; - retVal->punkVal = m_window; + retVal->punkVal = m_screen->coreWindow(); break; } return S_OK; @@ -267,7 +237,7 @@ HRESULT QWinRTInputContext::get_HostRawElementProvider(IRawElementProviderSimple { // Return the window's element provider IInspectable *hostProvider; - HRESULT hr = m_window->get_AutomationHostProvider(&hostProvider); + HRESULT hr = m_screen->coreWindow()->get_AutomationHostProvider(&hostProvider); if (SUCCEEDED(hr)) { hr = hostProvider->QueryInterface(IID_PPV_ARGS(retVal)); hostProvider->Release(); diff --git a/src/plugins/platforms/winrt/qwinrtinputcontext.h b/src/plugins/platforms/winrt/qwinrtinputcontext.h index 6b1b66c0a3..761908a9cb 100644 --- a/src/plugins/platforms/winrt/qwinrtinputcontext.h +++ b/src/plugins/platforms/winrt/qwinrtinputcontext.h @@ -58,6 +58,7 @@ namespace ABI { QT_BEGIN_NAMESPACE +class QWinRTScreen; class QWinRTInputContext : public QPlatformInputContext #ifndef Q_OS_WINPHONE , public Microsoft::WRL::RuntimeClass< @@ -66,7 +67,7 @@ class QWinRTInputContext : public QPlatformInputContext #endif // !Q_OS_WINPHONE { public: - explicit QWinRTInputContext(ABI::Windows::UI::Core::ICoreWindow *window); + explicit QWinRTInputContext(QWinRTScreen *); QRectF keyboardRect() const; @@ -101,9 +102,10 @@ private: ABI::Windows::UI::ViewManagement::IInputPaneVisibilityEventArgs *); HRESULT onHiding(ABI::Windows::UI::ViewManagement::IInputPane *, ABI::Windows::UI::ViewManagement::IInputPaneVisibilityEventArgs *); - void setKeyboardRect(const QRectF rect); - ABI::Windows::UI::Core::ICoreWindow *m_window; + HRESULT handleVisibilityChange(ABI::Windows::UI::ViewManagement::IInputPane *); + + QWinRTScreen *m_screen; QRectF m_keyboardRect; bool m_isInputPanelVisible; }; diff --git a/src/plugins/platforms/winrt/qwinrtscreen.cpp b/src/plugins/platforms/winrt/qwinrtscreen.cpp index d7888194c2..c4512b4d2d 100644 --- a/src/plugins/platforms/winrt/qwinrtscreen.cpp +++ b/src/plugins/platforms/winrt/qwinrtscreen.cpp @@ -497,9 +497,9 @@ QWinRTScreen::QWinRTScreen() Q_ASSERT_SUCCEEDED(hr); #ifdef Q_OS_WINPHONE - d->inputContext.reset(new QWinRTInputContext(d->coreWindow.Get())); + d->inputContext.reset(new QWinRTInputContext(this)); #else - d->inputContext = Make<QWinRTInputContext>(d->coreWindow.Get()); + d->inputContext = Make<QWinRTInputContext>(this); #endif Rect rect; @@ -580,7 +580,7 @@ QWinRTScreen::QWinRTScreen() d->orientation = d->nativeOrientation; onOrientationChanged(Q_NULLPTR, Q_NULLPTR); - d->eglDisplay = eglGetDisplay(d->displayInformation.Get()); + d->eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); if (d->eglDisplay == EGL_NO_DISPLAY) qCritical("Failed to initialize EGL display: 0x%x", eglGetError()); @@ -616,14 +616,7 @@ QWinRTScreen::QWinRTScreen() d->eglConfig = q_configFromGLFormat(d->eglDisplay, d->surfaceFormat); d->surfaceFormat = q_glFormatFromConfig(d->eglDisplay, d->eglConfig, d->surfaceFormat); - const QRect bounds = geometry(); - EGLint windowAttributes[] = { - EGL_FIXED_SIZE_ANGLE, EGL_TRUE, - EGL_WIDTH, bounds.width(), - EGL_HEIGHT, bounds.height(), - EGL_NONE - }; - d->eglSurface = eglCreateWindowSurface(d->eglDisplay, d->eglConfig, d->coreWindow.Get(), windowAttributes); + d->eglSurface = eglCreateWindowSurface(d->eglDisplay, d->eglConfig, d->coreWindow.Get(), NULL); if (d->eglSurface == EGL_NO_SURFACE) qCritical("Failed to create EGL window surface: 0x%x", eglGetError()); } @@ -680,6 +673,12 @@ QDpi QWinRTScreen::logicalDpi() const return QDpi(d->logicalDpi, d->logicalDpi); } +qreal QWinRTScreen::scaleFactor() const +{ + Q_D(const QWinRTScreen); + return d->scaleFactor; +} + QWinRTInputContext *QWinRTScreen::inputContext() const { Q_D(const QWinRTScreen); @@ -1081,14 +1080,6 @@ HRESULT QWinRTScreen::onSizeChanged(ICoreWindow *, IWindowSizeChangedEventArgs * d->logicalSize = logicalSize; if (d->eglDisplay) { const QRect newGeometry = geometry(); - int width = newGeometry.width(); - int height = newGeometry.height(); -#ifdef Q_OS_WINPHONE // Windows Phone can pass in a negative size to provide orientation information - width *= (d->orientation == Qt::InvertedPortraitOrientation || d->orientation == Qt::LandscapeOrientation) ? -1 : 1; - height *= (d->orientation == Qt::InvertedPortraitOrientation || d->orientation == Qt::InvertedLandscapeOrientation) ? -1 : 1; -#endif - eglSurfaceAttrib(d->eglDisplay, d->eglSurface, EGL_WIDTH, width); - eglSurfaceAttrib(d->eglDisplay, d->eglSurface, EGL_HEIGHT, height); QWindowSystemInterface::handleScreenGeometryChange(screen(), newGeometry, newGeometry); QPlatformScreen::resizeMaximizedWindows(); handleExpose(); diff --git a/src/plugins/platforms/winrt/qwinrtscreen.h b/src/plugins/platforms/winrt/qwinrtscreen.h index 404c8ca04e..cbef9543a9 100644 --- a/src/plugins/platforms/winrt/qwinrtscreen.h +++ b/src/plugins/platforms/winrt/qwinrtscreen.h @@ -93,6 +93,7 @@ public: QSurfaceFormat surfaceFormat() const; QSizeF physicalSize() const Q_DECL_OVERRIDE; QDpi logicalDpi() const Q_DECL_OVERRIDE; + qreal scaleFactor() const; QWinRTInputContext *inputContext() const; QPlatformCursor *cursor() const; Qt::KeyboardModifiers keyboardModifiers() const; diff --git a/src/plugins/platforms/xcb/gl_integrations/gl_integrations_plugin_base.pri b/src/plugins/platforms/xcb/gl_integrations/gl_integrations_plugin_base.pri index 8c60268e0d..e859865687 100644 --- a/src/plugins/platforms/xcb/gl_integrations/gl_integrations_plugin_base.pri +++ b/src/plugins/platforms/xcb/gl_integrations/gl_integrations_plugin_base.pri @@ -29,8 +29,8 @@ CONFIG += qpa/genericunixfontdatabase contains(QT_CONFIG, xcb-qt) { DEFINES += XCB_USE_RENDER - XCB_DIR = ../../../3rdparty/xcb - INCLUDEPATH += $$XCB_DIR/include $$XCB_DIR/sysinclude + XCB_DIR = $$clean_path($$PWD/../../../../3rdparty/xcb) + INCLUDEPATH += $$XCB_DIR/include $$XCB_DIR/include/xcb $$XCB_DIR/sysinclude LIBS += -lxcb -L$$OUT_PWD/xcb-static -lxcb-static } else { LIBS += -lxcb -lxcb-image -lxcb-icccm -lxcb-sync -lxcb-xfixes -lxcb-shm -lxcb-randr -lxcb-shape -lxcb-keysyms diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp index 706b9c8e48..8500aa1ffa 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection.cpp @@ -66,6 +66,7 @@ #include <X11/Xlib.h> #include <X11/Xlib-xcb.h> #include <X11/Xlibint.h> +#include <X11/Xutil.h> #endif #if defined(XCB_USE_XINPUT2) @@ -83,6 +84,12 @@ Q_LOGGING_CATEGORY(lcQpaXInput, "qt.qpa.input") Q_LOGGING_CATEGORY(lcQpaXInputDevices, "qt.qpa.input.devices") Q_LOGGING_CATEGORY(lcQpaScreen, "qt.qpa.screen") +// this event type was added in libxcb 1.10, +// but we support also older version +#ifndef XCB_GE_GENERIC +#define XCB_GE_GENERIC 35 +#endif + #ifdef XCB_USE_XLIB static const char * const xcbConnectionErrors[] = { "No error", /* Error 0 */ @@ -137,7 +144,7 @@ QXcbScreen* QXcbConnection::findScreenForOutput(xcb_window_t rootWindow, xcb_ran return 0; } -QXcbScreen* QXcbConnection::createScreen(int screenNumber, xcb_screen_t* xcbScreen, +QXcbScreen* QXcbConnection::createScreen(QXcbVirtualDesktop* virtualDesktop, xcb_randr_output_t outputId, xcb_randr_get_output_info_reply_t *output) { @@ -150,10 +157,10 @@ QXcbScreen* QXcbConnection::createScreen(int screenNumber, xcb_screen_t* xcbScre int dotPos = displayName.lastIndexOf('.'); if (dotPos != -1) displayName.truncate(dotPos); - name = QString::fromLocal8Bit(displayName) + QLatin1Char('.') + QString::number(screenNumber); + name = QString::fromLocal8Bit(displayName) + QLatin1Char('.') + QString::number(virtualDesktop->number()); } - return new QXcbScreen(this, xcbScreen, outputId, output, name, screenNumber); + return new QXcbScreen(this, virtualDesktop, outputId, output, name); } bool QXcbConnection::checkOutputIsPrimary(xcb_window_t rootWindow, xcb_randr_output_t output) @@ -173,15 +180,11 @@ bool QXcbConnection::checkOutputIsPrimary(xcb_window_t rootWindow, xcb_randr_out return isPrimary; } -xcb_screen_t* QXcbConnection::xcbScreenForRootWindow(xcb_window_t rootWindow, int *xcbScreenNumber) +QXcbVirtualDesktop* QXcbConnection::virtualDesktopForRootWindow(xcb_window_t rootWindow) { - xcb_screen_iterator_t xcbScreenIter = xcb_setup_roots_iterator(m_setup); - for (; xcbScreenIter.rem; xcb_screen_next(&xcbScreenIter)) { - if (xcbScreenIter.data->root == rootWindow) { - if (xcbScreenNumber) - *xcbScreenNumber = xcb_setup_roots_length(m_setup) - xcbScreenIter.rem; - return xcbScreenIter.data; - } + foreach (QXcbVirtualDesktop *virtualDesktop, m_virtualDesktops) { + if (virtualDesktop->screen()->root == rootWindow) + return virtualDesktop; } return 0; @@ -194,8 +197,8 @@ void QXcbConnection::updateScreens(const xcb_randr_notify_event_t *event) { if (event->subCode == XCB_RANDR_NOTIFY_CRTC_CHANGE) { xcb_randr_crtc_change_t crtc = event->u.cc; - xcb_screen_t *xcbScreen = xcbScreenForRootWindow(crtc.window); - if (!xcbScreen) + QXcbVirtualDesktop *virtualDesktop = virtualDesktopForRootWindow(crtc.window); + if (!virtualDesktop) // Not for us return; @@ -212,9 +215,8 @@ void QXcbConnection::updateScreens(const xcb_randr_notify_event_t *event) } else if (event->subCode == XCB_RANDR_NOTIFY_OUTPUT_CHANGE) { xcb_randr_output_change_t output = event->u.oc; - int xcbScreenNumber = 0; - xcb_screen_t *xcbScreen = xcbScreenForRootWindow(output.window, &xcbScreenNumber); - if (!xcbScreen) + QXcbVirtualDesktop *virtualDesktop = virtualDesktopForRootWindow(output.window); + if (!virtualDesktop) // Not for us return; @@ -242,7 +244,7 @@ void QXcbConnection::updateScreens(const xcb_randr_notify_event_t *event) QScopedPointer<xcb_randr_get_output_info_reply_t, QScopedPointerPodDeleter> outputInfo( xcb_randr_get_output_info_reply(xcb_connection(), outputInfoCookie, NULL)); - screen = createScreen(xcbScreenNumber, xcbScreen, output.output, outputInfo.data()); + screen = createScreen(virtualDesktop, output.output, outputInfo.data()); qCDebug(lcQpaScreen) << "output" << screen->name() << "is connected and enabled"; screen->setPrimary(checkOutputIsPrimary(output.window, output.output)); @@ -293,14 +295,15 @@ void QXcbConnection::initializeScreens() xcb_screen_iterator_t it = xcb_setup_roots_iterator(m_setup); int xcbScreenNumber = 0; // screen number in the xcb sense QXcbScreen* primaryScreen = Q_NULLPTR; - xcb_screen_t *xcbScreen = Q_NULLPTR; bool hasOutputs = false; while (it.rem) { // Each "screen" in xcb terminology is a virtual desktop, // potentially a collection of separate juxtaposed monitors. // But we want a separate QScreen for each output (e.g. DVI-I-1, VGA-1, etc.) // which will become virtual siblings. - xcbScreen = it.data; + xcb_screen_t *xcbScreen = it.data; + QXcbVirtualDesktop *virtualDesktop = new QXcbVirtualDesktop(this, xcbScreen, xcbScreenNumber); + m_virtualDesktops.append(virtualDesktop); QList<QPlatformScreen *> siblings; int outputCount = 0; int connectedOutputCount = 0; @@ -370,7 +373,7 @@ void QXcbConnection::initializeScreens() continue; } - QXcbScreen *screen = createScreen(xcbScreenNumber, xcbScreen, outputs[i], output.data()); + QXcbScreen *screen = createScreen(virtualDesktop, outputs[i], output.data()); siblings << screen; ++connectedOutputCount; hasOutputs = true; @@ -405,8 +408,9 @@ void QXcbConnection::initializeScreens() // but the dimensions are known anyway, and we don't already have any lingering // (possibly disconnected) screens, then showing windows should be possible, // so create one screen. (QTBUG-31389) - if (xcbScreen && !hasOutputs && xcbScreen->width_in_pixels > 0 && xcbScreen->height_in_pixels > 0 && m_screens.isEmpty()) { - QXcbScreen *screen = createScreen(0, xcbScreen, 0, Q_NULLPTR); + QXcbVirtualDesktop *virtualDesktop = m_virtualDesktops.value(0); + if (virtualDesktop && !hasOutputs && !virtualDesktop->size().isEmpty() && m_screens.isEmpty()) { + QXcbScreen *screen = createScreen(virtualDesktop, 0, Q_NULLPTR); screen->setVirtualSiblings(QList<QPlatformScreen *>() << screen); m_screens << screen; primaryScreen = screen; @@ -434,9 +438,10 @@ void QXcbConnection::initializeScreens() qCDebug(lcQpaScreen) << "primary output is" << m_screens.first()->name(); } -QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGrabServer, const char *displayName) +QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGrabServer, xcb_visualid_t defaultVisualId, const char *displayName) : m_connection(0) , m_canGrabServer(canGrabServer) + , m_defaultVisualId(defaultVisualId) , m_primaryScreenNumber(0) , m_displayName(displayName ? QByteArray(displayName) : qgetenv("DISPLAY")) , m_nativeInterface(nativeInterface) @@ -577,6 +582,9 @@ QXcbConnection::~QXcbConnection() while (!m_screens.isEmpty()) integration->destroyScreen(m_screens.takeLast()); + while (!m_virtualDesktops.isEmpty()) + delete m_virtualDesktops.takeLast(); + delete m_glIntegration; #ifdef XCB_USE_XLIB @@ -666,6 +674,7 @@ void printXcbEvent(const char *message, xcb_generic_event_t *event) PRINT_XCB_EVENT(XCB_KEYMAP_NOTIFY); PRINT_XCB_EVENT(XCB_EXPOSE); PRINT_XCB_EVENT(XCB_GRAPHICS_EXPOSURE); + PRINT_XCB_EVENT(XCB_NO_EXPOSURE); PRINT_XCB_EVENT(XCB_VISIBILITY_NOTIFY); PRINT_XCB_EVENT(XCB_CREATE_NOTIFY); PRINT_XCB_EVENT(XCB_DESTROY_NOTIFY); @@ -685,6 +694,8 @@ void printXcbEvent(const char *message, xcb_generic_event_t *event) PRINT_XCB_EVENT(XCB_SELECTION_NOTIFY); PRINT_XCB_EVENT(XCB_COLORMAP_NOTIFY); PRINT_XCB_EVENT(XCB_CLIENT_MESSAGE); + PRINT_XCB_EVENT(XCB_MAPPING_NOTIFY); + PRINT_XCB_EVENT(XCB_GE_GENERIC); default: qDebug("QXcbConnection: %s: unknown event - response_type: %d - sequence: %d", message, int(event->response_type & ~0x80), int(event->sequence)); } @@ -1080,7 +1091,7 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event) HANDLE_PLATFORM_WINDOW_EVENT(xcb_property_notify_event_t, window, handlePropertyNotifyEvent); break; #if defined(XCB_USE_XINPUT2) - case GenericEvent: + case XCB_GE_GENERIC: if (m_xi2Enabled) xi2HandleEvent(reinterpret_cast<xcb_ge_event_t *>(event)); break; @@ -1342,6 +1353,21 @@ void *QXcbConnection::xlib_display() const { return m_xlib_display; } + +void *QXcbConnection::createVisualInfoForDefaultVisualId() const +{ + if (m_defaultVisualId == UINT_MAX) + return 0; + XVisualInfo info; + memset(&info, 0, sizeof info); + info.visualid = m_defaultVisualId; + + int count = 0; + XVisualInfo *retVisual = XGetVisualInfo(DISPLAY_FROM_XCB(this), VisualIDMask, &info, &count); + Q_ASSERT(count < 2); + return retVisual; +} + #endif void QXcbConnection::processXcbEvents() diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h index 1190e7c2b0..466492ce42 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.h +++ b/src/plugins/platforms/xcb/qxcbconnection.h @@ -80,6 +80,7 @@ Q_DECLARE_LOGGING_CATEGORY(lcQpaXInput) Q_DECLARE_LOGGING_CATEGORY(lcQpaXInputDevices) Q_DECLARE_LOGGING_CATEGORY(lcQpaScreen) +class QXcbVirtualDesktop; class QXcbScreen; class QXcbWindow; class QXcbDrag; @@ -369,7 +370,7 @@ class Q_XCB_EXPORT QXcbConnection : public QObject { Q_OBJECT public: - QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGrabServer, const char *displayName = 0); + QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGrabServer, xcb_visualid_t defaultVisualId, const char *displayName = 0); ~QXcbConnection(); QXcbConnection *connection() const { return const_cast<QXcbConnection *>(this); } @@ -399,8 +400,13 @@ public: QXcbWMSupport *wmSupport() const { return m_wmSupport.data(); } xcb_window_t rootWindow(); + + bool hasDefaultVisualId() const { return m_defaultVisualId != UINT_MAX; } + xcb_visualid_t defaultVisualId() const { return m_defaultVisualId; } + #ifdef XCB_USE_XLIB void *xlib_display() const; + void *createVisualInfoForDefaultVisualId() const; #endif #if defined(XCB_USE_XINPUT2) @@ -497,12 +503,12 @@ private: void initializeXShape(); void initializeXKB(); void handleClientMessageEvent(const xcb_client_message_event_t *event); - QXcbScreen* createScreen(int screenNumber, xcb_screen_t* xcbScreen, + QXcbScreen* createScreen(QXcbVirtualDesktop *virtualDesktop, xcb_randr_output_t outputId = XCB_NONE, xcb_randr_get_output_info_reply_t *output = 0); QXcbScreen* findScreenForCrtc(xcb_window_t rootWindow, xcb_randr_crtc_t crtc); QXcbScreen* findScreenForOutput(xcb_window_t rootWindow, xcb_randr_output_t output); - xcb_screen_t* xcbScreenForRootWindow(xcb_window_t rootWindow, int *xcbScreenNumber = 0); + QXcbVirtualDesktop* virtualDesktopForRootWindow(xcb_window_t rootWindow); bool checkOutputIsPrimary(xcb_window_t rootWindow, xcb_randr_output_t output); void initializeScreens(); void updateScreens(const xcb_randr_notify_event_t *event); @@ -566,7 +572,9 @@ private: xcb_connection_t *m_connection; const xcb_setup_t *m_setup; bool m_canGrabServer; + xcb_visualid_t m_defaultVisualId; + QList<QXcbVirtualDesktop *> m_virtualDesktops; QList<QXcbScreen *> m_screens; int m_primaryScreenNumber; @@ -633,6 +641,7 @@ private: }; #define DISPLAY_FROM_XCB(object) ((Display *)(object->connection()->xlib_display())) +#define CREATE_VISUALINFO_FROM_DEFAULT_VISUALID(object) ((XVisualInfo *)(object->connection()->createVisualInfoForDefaultVisualId())) template<typename T> xcb_generic_event_t *QXcbConnection::checkEvent(T &checker) diff --git a/src/plugins/platforms/xcb/qxcbcursor.cpp b/src/plugins/platforms/xcb/qxcbcursor.cpp index 8dd27ec9c5..e51ab85e30 100644 --- a/src/plugins/platforms/xcb/qxcbcursor.cpp +++ b/src/plugins/platforms/xcb/qxcbcursor.cpp @@ -502,7 +502,7 @@ bool updateCursorTheme(void *dpy, const QByteArray &theme) { return setTheme; } - void QXcbCursor::cursorThemePropertyChanged(QXcbScreen *screen, const QByteArray &name, const QVariant &property, void *handle) + void QXcbCursor::cursorThemePropertyChanged(QXcbVirtualDesktop *screen, const QByteArray &name, const QVariant &property, void *handle) { Q_UNUSED(screen); Q_UNUSED(name); @@ -633,18 +633,17 @@ void QXcbCursor::queryPointer(QXcbConnection *c, xcb_window_t *rootWin, QPoint * QPoint QXcbCursor::pos() const { - const int dpr = int(m_screen->devicePixelRatio()); QPoint p; queryPointer(connection(), 0, &p); - return p / dpr; + return m_screen->mapFromNative(p); } void QXcbCursor::setPos(const QPoint &pos) { - const int dpr = int(m_screen->devicePixelRatio()); + const QPoint xPos = m_screen->mapToNative(pos); xcb_window_t root = 0; queryPointer(connection(), &root, 0); - xcb_warp_pointer(xcb_connection(), XCB_NONE, root, 0, 0, 0, 0, pos.x()*dpr, pos.y()*dpr); + xcb_warp_pointer(xcb_connection(), XCB_NONE, root, 0, 0, 0, 0, xPos.x(), xPos.y()); xcb_flush(xcb_connection()); } diff --git a/src/plugins/platforms/xcb/qxcbcursor.h b/src/plugins/platforms/xcb/qxcbcursor.h index 1280c7e042..7e5cdc6870 100644 --- a/src/plugins/platforms/xcb/qxcbcursor.h +++ b/src/plugins/platforms/xcb/qxcbcursor.h @@ -91,7 +91,7 @@ private: CursorHash m_cursorHash; #endif #ifdef XCB_USE_XLIB - static void cursorThemePropertyChanged(QXcbScreen *screen, + static void cursorThemePropertyChanged(QXcbVirtualDesktop *screen, const QByteArray &name, const QVariant &property, void *handle); diff --git a/src/plugins/platforms/xcb/qxcbintegration.cpp b/src/plugins/platforms/xcb/qxcbintegration.cpp index 2547e537a7..fc06f1a7b0 100644 --- a/src/plugins/platforms/xcb/qxcbintegration.cpp +++ b/src/plugins/platforms/xcb/qxcbintegration.cpp @@ -116,6 +116,7 @@ QXcbIntegration::QXcbIntegration(const QStringList ¶meters, int &argc, char : m_services(new QGenericUnixServices) , m_instanceName(0) , m_canGrab(true) + , m_defaultVisualId(UINT_MAX) { m_instance = this; @@ -143,6 +144,12 @@ QXcbIntegration::QXcbIntegration(const QStringList ¶meters, int &argc, char noGrabArg = true; else if (arg == "-dograb") doGrabArg = true; + else if (arg == "-visual" && i < argc - 1) { + bool ok = false; + m_defaultVisualId = QByteArray(argv[++i]).toUInt(&ok, 0); + if (!ok) + m_defaultVisualId = UINT_MAX; + } else argv[j++] = argv[i]; } @@ -167,12 +174,12 @@ QXcbIntegration::QXcbIntegration(const QStringList ¶meters, int &argc, char if (canNotGrabEnv) m_canGrab = false; - m_connections << new QXcbConnection(m_nativeInterface.data(), m_canGrab, displayName); + m_connections << new QXcbConnection(m_nativeInterface.data(), m_canGrab, m_defaultVisualId, displayName); for (int i = 0; i < parameters.size() - 1; i += 2) { qCDebug(lcQpaScreen) << "connecting to additional display: " << parameters.at(i) << parameters.at(i+1); QString display = parameters.at(i) + QLatin1Char(':') + parameters.at(i+1); - m_connections << new QXcbConnection(m_nativeInterface.data(), m_canGrab, display.toLatin1().constData()); + m_connections << new QXcbConnection(m_nativeInterface.data(), m_canGrab, m_defaultVisualId, display.toLatin1().constData()); } m_fontDatabase.reset(new QGenericUnixFontDatabase()); diff --git a/src/plugins/platforms/xcb/qxcbintegration.h b/src/plugins/platforms/xcb/qxcbintegration.h index 4212d53810..4e2a3c2bbd 100644 --- a/src/plugins/platforms/xcb/qxcbintegration.h +++ b/src/plugins/platforms/xcb/qxcbintegration.h @@ -39,6 +39,8 @@ #include "qxcbexport.h" +#include <xcb/xcb.h> + QT_BEGIN_NAMESPACE class QXcbConnection; @@ -123,6 +125,7 @@ private: mutable QByteArray m_wmClass; const char *m_instanceName; bool m_canGrab; + xcb_visualid_t m_defaultVisualId; static QXcbIntegration *m_instance; }; diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.cpp b/src/plugins/platforms/xcb/qxcbkeyboard.cpp index 6c80c1b30e..5a7c2cef83 100644 --- a/src/plugins/platforms/xcb/qxcbkeyboard.cpp +++ b/src/plugins/platforms/xcb/qxcbkeyboard.cpp @@ -437,6 +437,7 @@ static const unsigned int KeyTbl[] = { XF86XK_AudioPrev, Qt::Key_MediaPrevious, XF86XK_AudioNext, Qt::Key_MediaNext, XF86XK_AudioRecord, Qt::Key_MediaRecord, + XF86XK_AudioPause, Qt::Key_MediaPause, XF86XK_Mail, Qt::Key_LaunchMail, XF86XK_MyComputer, Qt::Key_Launch0, // ### Qt 6: remap properly XF86XK_Calculator, Qt::Key_Launch1, diff --git a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp index 75ffaa37bb..1629f3013c 100644 --- a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp +++ b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp @@ -361,6 +361,9 @@ QFunctionPointer QXcbNativeInterface::platformFunction(const QByteArray &functio if (function == QXcbIntegrationFunctions::xEmbedSystemTrayVisualHasAlphaChannelIdentifier()) return QFunctionPointer(QXcbIntegrationFunctions::XEmbedSystemTrayVisualHasAlphaChannel(QXcbConnection::xEmbedSystemTrayVisualHasAlphaChannel)); + if (function == QXcbWindowFunctions::visualIdIdentifier()) { + return QFunctionPointer(QXcbWindowFunctions::VisualId(QXcbWindow::visualIdStatic)); + } return Q_NULLPTR; } diff --git a/src/plugins/platforms/xcb/qxcbscreen.cpp b/src/plugins/platforms/xcb/qxcbscreen.cpp index 383adf9734..a0d6d88d11 100644 --- a/src/plugins/platforms/xcb/qxcbscreen.cpp +++ b/src/plugins/platforms/xcb/qxcbscreen.cpp @@ -47,11 +47,33 @@ QT_BEGIN_NAMESPACE -QXcbScreen::QXcbScreen(QXcbConnection *connection, xcb_screen_t *scr, +QXcbVirtualDesktop::QXcbVirtualDesktop(QXcbConnection *connection, xcb_screen_t *screen, int number) + : QXcbObject(connection) + , m_screen(screen) + , m_number(number) + , m_xSettings(Q_NULLPTR) +{ +} + +QXcbVirtualDesktop::~QXcbVirtualDesktop() +{ + delete m_xSettings; +} + +QXcbXSettings *QXcbVirtualDesktop::xSettings() const +{ + if (!m_xSettings) { + QXcbVirtualDesktop *self = const_cast<QXcbVirtualDesktop *>(this); + self->m_xSettings = new QXcbXSettings(self); + } + return m_xSettings; +} + +QXcbScreen::QXcbScreen(QXcbConnection *connection, QXcbVirtualDesktop *virtualDesktop, xcb_randr_output_t outputId, xcb_randr_get_output_info_reply_t *output, - QString outputName, int number) + QString outputName) : QXcbObject(connection) - , m_screen(scr) + , m_virtualDesktop(virtualDesktop) , m_output(outputId) , m_crtc(output ? output->crtc : 0) , m_mode(XCB_NONE) @@ -59,10 +81,9 @@ QXcbScreen::QXcbScreen(QXcbConnection *connection, xcb_screen_t *scr, , m_rotation(XCB_RANDR_ROTATION_ROTATE_0) , m_outputName(outputName) , m_outputSizeMillimeters(output ? QSize(output->mm_width, output->mm_height) : QSize()) - , m_virtualSize(scr->width_in_pixels, scr->height_in_pixels) - , m_virtualSizeMillimeters(scr->width_in_millimeters, scr->height_in_millimeters) + , m_virtualSize(virtualDesktop->size()) + , m_virtualSizeMillimeters(virtualDesktop->physicalSize()) , m_orientation(Qt::PrimaryOrientation) - , m_number(number) , m_refreshRate(60) , m_forcedDpi(-1) , m_devicePixelRatio(1) @@ -70,7 +91,6 @@ QXcbScreen::QXcbScreen(QXcbConnection *connection, xcb_screen_t *scr, , m_noFontHinting(false) , m_subpixelType(QFontEngine::SubpixelAntialiasingType(-1)) , m_antialiasingEnabled(-1) - , m_xSettings(0) { if (connection->hasXRandr()) { xcb_randr_select_input(xcb_connection(), screen()->root, true); @@ -215,7 +235,7 @@ QXcbScreen::~QXcbScreen() QWindow *QXcbScreen::topLevelAt(const QPoint &p) const { - xcb_window_t root = m_screen->root; + xcb_window_t root = screen()->root; int dpr = int(devicePixelRatio()); int x = p.x() / dpr; @@ -253,6 +273,31 @@ QWindow *QXcbScreen::topLevelAt(const QPoint &p) const return 0; } + +QPoint QXcbScreen::mapToNative(const QPoint &pos) const +{ + const int dpr = int(devicePixelRatio()); + return (pos - m_geometry.topLeft()) * dpr + m_nativeGeometry.topLeft(); +} + +QPoint QXcbScreen::mapFromNative(const QPoint &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()); + return QRect(mapToNative(rect.topLeft()), rect.size() * dpr); +} + +QRect QXcbScreen::mapFromNative(const QRect &rect) const +{ + const int dpr = int(devicePixelRatio()); + return QRect(mapFromNative(rect.topLeft()), rect.size() / dpr); +} + void QXcbScreen::windowShown(QXcbWindow *window) { // Freedesktop.org Startup Notification @@ -310,19 +355,16 @@ QImage::Format QXcbScreen::format() const QDpi QXcbScreen::logicalDpi() const { - int dpr = int(devicePixelRatio()); - - if (m_forcedDpi > 0) - return QDpi(m_forcedDpi/dpr, m_forcedDpi/dpr); + static const int overrideDpi = qEnvironmentVariableIntValue("QT_FONT_DPI"); + if (overrideDpi) + return QDpi(overrideDpi, overrideDpi); - static const bool auto_dpr = qgetenv("QT_DEVICE_PIXEL_RATIO").toLower() == "auto"; - if (auto_dpr) { - return QDpi(Q_MM_PER_INCH * m_geometry.width() / m_sizeMillimeters.width(), - Q_MM_PER_INCH * m_geometry.height() / m_sizeMillimeters.height()); - } else { - return QDpi(Q_MM_PER_INCH * m_virtualSize.width() / m_virtualSizeMillimeters.width() / dpr, - Q_MM_PER_INCH * m_virtualSize.height() / m_virtualSizeMillimeters.height() / dpr); + if (m_forcedDpi > 0) { + int primaryDpr = int(connection()->screens().at(0)->devicePixelRatio()); + return QDpi(m_forcedDpi/primaryDpr, m_forcedDpi/primaryDpr); } + return QDpi(Q_MM_PER_INCH * m_virtualSize.width() / m_virtualSizeMillimeters.width(), + Q_MM_PER_INCH * m_virtualSize.height() / m_virtualSizeMillimeters.height()); } @@ -426,6 +468,9 @@ void QXcbScreen::handleScreenChange(xcb_randr_screen_change_notify_event_t *chan void QXcbScreen::updateGeometry(xcb_timestamp_t timestamp) { + if (!connection()->hasXRandr()) + return; + xcb_randr_get_crtc_info_cookie_t crtcCookie = xcb_randr_get_crtc_info_unchecked(xcb_connection(), m_crtc, timestamp); xcb_randr_get_crtc_info_reply_t *crtc = @@ -482,9 +527,9 @@ void QXcbScreen::updateGeometry(const QRect &geom, uint8_t rotation) qreal dpi = xGeometry.width() / physicalSize().width() * qreal(25.4); m_devicePixelRatio = qRound(dpi/96); const int dpr = int(devicePixelRatio()); // we may override m_devicePixelRatio - m_geometry = QRect(xGeometry.topLeft()/dpr, xGeometry.size()/dpr); + m_geometry = QRect(xGeometry.topLeft(), xGeometry.size()/dpr); m_nativeGeometry = QRect(xGeometry.topLeft(), xGeometry.size()); - m_availableGeometry = QRect(xAvailableGeometry.topLeft()/dpr, xAvailableGeometry.size()/dpr); + m_availableGeometry = QRect(mapFromNative(xAvailableGeometry.topLeft()), xAvailableGeometry.size()/dpr); QWindowSystemInterface::handleScreenGeometryChange(QPlatformScreen::screen(), m_geometry, m_availableGeometry); } @@ -499,7 +544,7 @@ void QXcbScreen::updateRefreshRate(xcb_randr_mode_t mode) // we can safely use get_screen_resources_current here, because in order to // get here, we must have called get_screen_resources before xcb_randr_get_screen_resources_current_cookie_t resourcesCookie = - xcb_randr_get_screen_resources_current_unchecked(xcb_connection(), m_screen->root); + xcb_randr_get_screen_resources_current_unchecked(xcb_connection(), screen()->root); xcb_randr_get_screen_resources_current_reply_t *resources = xcb_randr_get_screen_resources_current_reply(xcb_connection(), resourcesCookie, NULL); if (resources) { @@ -710,11 +755,7 @@ void QXcbScreen::readXResources() QXcbXSettings *QXcbScreen::xSettings() const { - if (!m_xSettings) { - QXcbScreen *self = const_cast<QXcbScreen *>(this); - self->m_xSettings = new QXcbXSettings(self); - } - return m_xSettings; + return m_virtualDesktop->xSettings(); } static inline void formatRect(QDebug &debug, const QRect r) diff --git a/src/plugins/platforms/xcb/qxcbscreen.h b/src/plugins/platforms/xcb/qxcbscreen.h index 3f228465f2..a29efc1e79 100644 --- a/src/plugins/platforms/xcb/qxcbscreen.h +++ b/src/plugins/platforms/xcb/qxcbscreen.h @@ -54,12 +54,32 @@ class QXcbXSettings; class QDebug; #endif +class QXcbVirtualDesktop : public QXcbObject +{ +public: + QXcbVirtualDesktop(QXcbConnection *connection, xcb_screen_t *screen, int number); + ~QXcbVirtualDesktop(); + + xcb_screen_t *screen() const { return m_screen; } + int number() const { return m_number; } + QSize size() const { return QSize(m_screen->width_in_pixels, m_screen->height_in_pixels); } + QSize physicalSize() const { return QSize(m_screen->width_in_millimeters, m_screen->height_in_millimeters); } + + QXcbXSettings *xSettings() const; + +private: + xcb_screen_t *m_screen; + int m_number; + + QXcbXSettings *m_xSettings; +}; + class Q_XCB_EXPORT QXcbScreen : public QXcbObject, public QPlatformScreen { public: - QXcbScreen(QXcbConnection *connection, xcb_screen_t *screen, + QXcbScreen(QXcbConnection *connection, QXcbVirtualDesktop *virtualDesktop, xcb_randr_output_t outputId, xcb_randr_get_output_info_reply_t *output, - QString outputName, int number); + QString outputName); ~QXcbScreen(); QPixmap grabWindow(WId window, int x, int y, int width, int height) const Q_DECL_OVERRIDE; @@ -69,7 +89,7 @@ public: QRect geometry() const Q_DECL_OVERRIDE { return m_geometry; } QRect nativeGeometry() const { return m_nativeGeometry; } QRect availableGeometry() const Q_DECL_OVERRIDE {return m_availableGeometry;} - int depth() const Q_DECL_OVERRIDE { return m_screen->root_depth; } + int depth() const Q_DECL_OVERRIDE { return screen()->root_depth; } QImage::Format format() const Q_DECL_OVERRIDE; QSizeF physicalSize() const Q_DECL_OVERRIDE { return m_sizeMillimeters; } QSize virtualSize() const { return m_virtualSize; } @@ -87,10 +107,10 @@ public: void setPrimary(bool primary) { m_primary = primary; } bool isPrimary() const { return m_primary; } - int screenNumber() const { return m_number; } + int screenNumber() const { return m_virtualDesktop->number(); } - xcb_screen_t *screen() const { return m_screen; } - xcb_window_t root() const { return m_screen->root; } + xcb_screen_t *screen() const { return m_virtualDesktop->screen(); } + xcb_window_t root() const { return screen()->root; } xcb_randr_output_t output() const { return m_output; } xcb_randr_crtc_t crtc() const { return m_crtc; } xcb_randr_mode_t mode() const { return m_mode; } @@ -120,13 +140,18 @@ public: QXcbXSettings *xSettings() const; + QPoint mapToNative(const QPoint &pos) const; + QPoint mapFromNative(const QPoint &pos) const; + QRect mapToNative(const QRect &rect) const; + QRect mapFromNative(const QRect &rect) const; + private: static bool xResource(const QByteArray &identifier, const QByteArray &expectedIdentifier, QByteArray &stringValue); void sendStartupMessage(const QByteArray &message) const; - xcb_screen_t *m_screen; + QXcbVirtualDesktop *m_virtualDesktop; xcb_randr_output_t m_output; xcb_randr_crtc_t m_crtc; xcb_randr_mode_t m_mode; @@ -143,7 +168,6 @@ private: QSizeF m_virtualSizeMillimeters; QList<QPlatformScreen *> m_siblings; Qt::ScreenOrientation m_orientation; - int m_number; QString m_windowManagerName; bool m_syncRequestSupported; xcb_window_t m_clientLeader; @@ -157,7 +181,6 @@ private: bool m_noFontHinting; QFontEngine::SubpixelAntialiasingType m_subpixelType; int m_antialiasingEnabled; - QXcbXSettings *m_xSettings; }; #ifndef QT_NO_DEBUG_STREAM diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index ceb95a1515..076cc1aa80 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -139,7 +139,7 @@ enum QX11EmbedMessageType { const quint32 XEMBED_VERSION = 0; -static inline QRect mapToNative(const QRect &qtRect, int dpr) +static inline QRect mapLocalGeometryToNative(const QRect &qtRect, int dpr) { return QRect(qtRect.x() * dpr, qtRect.y() * dpr, qtRect.width() * dpr, qtRect.height() * dpr); } @@ -167,11 +167,45 @@ static inline QRect mapExposeFromNative(const QRect &xRect, int dpr) return QRect(dpr_floor(xRect.topLeft(), dpr), dpr_ceil(xRect.bottomRight(), dpr)); } -static inline QRect mapGeometryFromNative(const QRect &xRect, int dpr) +static inline QRect mapLocalGeometryFromNative(const QRect &xRect, int dpr) { return QRect(xRect.topLeft() / dpr, dpr_ceil(xRect.size(), dpr)); } +QXcbScreen *QXcbWindow::parentScreen() +{ + return parent() ? static_cast<QXcbWindow*>(parent())->parentScreen() : m_xcbScreen; +} + +QPoint QXcbWindow::mapToNative(const QPoint &pos, const QXcbScreen *screen) const +{ + if (parent()) + return pos * int(screen->devicePixelRatio()); + else + return screen->mapToNative(pos); +} +QPoint QXcbWindow::mapFromNative(const QPoint &pos, const QXcbScreen *screen) const +{ + if (parent()) + return pos / int(screen->devicePixelRatio()); + else + return screen->mapFromNative(pos); +} +QRect QXcbWindow::mapToNative(const QRect &rect, const QXcbScreen *screen) const +{ + if (parent()) + return mapLocalGeometryToNative(rect, int(screen->devicePixelRatio())); + else + return screen->mapToNative(rect); +} +QRect QXcbWindow::mapFromNative(const QRect &rect, const QXcbScreen *screen) const +{ + if (parent()) + return mapLocalGeometryFromNative(rect, int(screen->devicePixelRatio())); + else + return screen->mapFromNative(rect); +} + // Returns \c true if we should set WM_TRANSIENT_FOR on \a w static inline bool isTransient(const QWindow *w) { @@ -292,6 +326,7 @@ static const char *wm_window_type_property_id = "_q_xcb_wm_window_type"; QXcbWindow::QXcbWindow(QWindow *window) : QPlatformWindow(window) , m_window(0) + , m_xcbScreen(0) , m_syncCounter(0) , m_gravity(XCB_GRAVITY_STATIC) , m_mapped(false) @@ -345,13 +380,25 @@ void QXcbWindow::create() Qt::WindowType type = window()->type(); - QXcbScreen *platformScreen = xcbScreen(); + QXcbScreen *currentScreen = xcbScreen(); + QRect rect = window()->geometry(); + QXcbScreen *platformScreen = parent() ? parentScreen() : static_cast<QXcbScreen*>(screenForGeometry(rect)); + m_xcbScreen = platformScreen; if (type == Qt::Desktop) { m_window = platformScreen->root(); m_depth = platformScreen->screen()->root_depth; m_visualId = platformScreen->screen()->root_visual; - const xcb_visualtype_t *visual = platformScreen->visualForId(m_visualId); + const xcb_visualtype_t *visual = 0; + if (connection()->hasDefaultVisualId()) { + visual = platformScreen->visualForId(connection()->defaultVisualId()); + if (visual) + m_visualId = connection()->defaultVisualId(); + if (!visual) + qWarning() << "Could not use default visual id. Falling back to root_visual for screen."; + } + if (!visual) + visual = platformScreen->visualForId(m_visualId); m_imageFormat = imageFormatForVisual(m_depth, visual->red_mask, visual->blue_mask, &m_imageRgbSwap); connection()->addWindowEventListener(m_window, this); return; @@ -372,13 +419,10 @@ void QXcbWindow::create() // Parameters to XCreateWindow() are frame corner + inner size. // This fits in case position policy is frame inclusive. There is // currently no way to implement it for frame-exclusive geometries. - QRect rect = window()->geometry(); QPlatformWindow::setGeometry(rect); - QXcbScreen *currentScreen = xcbScreen(); - QPlatformScreen *newScreen = screenForGeometry(rect); - if (newScreen != currentScreen) - QWindowSystemInterface::handleWindowScreenChanged(window(), newScreen->screen()); + if (platformScreen != currentScreen) + QWindowSystemInterface::handleWindowScreenChanged(window(), platformScreen->QPlatformScreen::screen()); const int dpr = int(devicePixelRatio()); @@ -408,7 +452,12 @@ void QXcbWindow::create() #ifdef XCB_USE_XLIB if (QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::OpenGL)) { - XVisualInfo *visualInfo = static_cast<XVisualInfo *>(createVisual()); + XVisualInfo *visualInfo = Q_NULLPTR; + if (connection()->hasDefaultVisualId()) + visualInfo = CREATE_VISUALINFO_FROM_DEFAULT_VISUALID(this); + if (!visualInfo) + visualInfo = static_cast<XVisualInfo *>(createVisual()); + if (!visualInfo && window()->surfaceType() == QSurface::OpenGLSurface) qFatal("Could not initialize OpenGL"); @@ -429,7 +478,7 @@ void QXcbWindow::create() m_visualId = visualInfo->visualid; - const QRect xRect = mapToNative(rect, dpr); + const QRect xRect = mapToNative(rect, platformScreen); m_window = XCreateWindow(DISPLAY_FROM_XCB(this), xcb_parent_id, xRect.x(), xRect.y(), xRect.width(), xRect.height(), 0, visualInfo->depth, InputOutput, visualInfo->visual, @@ -443,45 +492,60 @@ void QXcbWindow::create() if (!m_window) { m_window = xcb_generate_id(xcb_connection()); - m_visualId = platformScreen->screen()->root_visual; + m_visualId = UINT_MAX; + const xcb_visualtype_t *visual = Q_NULLPTR; m_depth = platformScreen->screen()->root_depth; uint32_t mask = 0; uint32_t values[3]; - if (m_format.alphaBufferSize() == 8) { - xcb_depth_iterator_t depthIter = xcb_screen_allowed_depths_iterator(platformScreen->screen()); - while (depthIter.rem) { - if (depthIter.data->depth == 32) { - xcb_visualtype_iterator_t visualIter = xcb_depth_visuals_iterator(depthIter.data); - if (visualIter.rem) { - m_visualId = visualIter.data->visual_id; - m_depth = 32; - uint32_t colormap = xcb_generate_id(xcb_connection()); - xcb_create_colormap(xcb_connection(), XCB_COLORMAP_ALLOC_NONE, colormap, - xcb_parent_id, m_visualId); - mask |= XCB_CW_BACK_PIXEL | XCB_CW_BORDER_PIXEL | XCB_CW_COLORMAP; - values[0] = platformScreen->screen()->white_pixel; - values[1] = platformScreen->screen()->black_pixel; - values[2] = colormap; - break; + if (connection()->hasDefaultVisualId()) { + m_visualId = connection()->defaultVisualId(); + visual = platformScreen->visualForId(m_visualId); + } + + if (!visual) { + if (connection()->hasDefaultVisualId()) + qWarning("Failed to use default visual id. Falling back to using screens root_visual"); + + m_visualId = platformScreen->screen()->root_visual; + + if (m_format.alphaBufferSize() == 8) { + xcb_depth_iterator_t depthIter = xcb_screen_allowed_depths_iterator(platformScreen->screen()); + while (depthIter.rem) { + if (depthIter.data->depth == 32) { + xcb_visualtype_iterator_t visualIter = xcb_depth_visuals_iterator(depthIter.data); + if (visualIter.rem) { + m_visualId = visualIter.data->visual_id; + m_depth = 32; + uint32_t colormap = xcb_generate_id(xcb_connection()); + xcb_create_colormap(xcb_connection(), XCB_COLORMAP_ALLOC_NONE, colormap, + xcb_parent_id, m_visualId); + mask |= XCB_CW_BACK_PIXEL | XCB_CW_BORDER_PIXEL | XCB_CW_COLORMAP; + values[0] = platformScreen->screen()->white_pixel; + values[1] = platformScreen->screen()->black_pixel; + values[2] = colormap; + break; + } } + xcb_depth_next(&depthIter); } - xcb_depth_next(&depthIter); } + + visual = platformScreen->visualForId(m_visualId); } - const xcb_visualtype_t *visual = platformScreen->visualForId(m_visualId); m_imageFormat = imageFormatForVisual(m_depth, visual->red_mask, visual->blue_mask, &m_imageRgbSwap); + const QRect xRect = mapToNative(rect, platformScreen); Q_XCB_CALL(xcb_create_window(xcb_connection(), m_depth, m_window, // window id xcb_parent_id, // parent window id - rect.x(), - rect.y(), - rect.width(), - rect.height(), + xRect.x(), + xRect.y(), + xRect.width(), + xRect.height(), 0, // border width XCB_WINDOW_CLASS_INPUT_OUTPUT, // window class m_visualId, // visual @@ -632,7 +696,7 @@ void QXcbWindow::destroy() void QXcbWindow::maybeSetScreen(QXcbScreen *screen) { - if (!window()->screen() && screen->geometry().contains(geometry().topLeft() * int(devicePixelRatio()))) { + if (!window()->screen() && screen->geometry().contains(geometry().topLeft())) { QWindowSystemInterface::handleWindowScreenChanged(window(), static_cast<QPlatformScreen *>(screen)->screen()); QWindowSystemInterface::handleExposeEvent(window(), QRegion(QRect(QPoint(0, 0), window()->size()))); } @@ -645,16 +709,17 @@ void QXcbWindow::setGeometry(const QRect &rect) propagateSizeHints(); QXcbScreen *currentScreen = xcbScreen(); - QPlatformScreen *newScreen = screenForGeometry(rect); + QXcbScreen *newScreen = parent() ? parentScreen() : static_cast<QXcbScreen*>(screenForGeometry(rect)); + if (!newScreen) newScreen = currentScreen; - const QRect xRect = mapToNative(rect, int(newScreen->devicePixelRatio())); + m_xcbScreen = newScreen; + const QRect xRect = mapToNative(rect, newScreen); const QRect wmGeometry = windowToWmGeometry(xRect); - if (newScreen != currentScreen) - QWindowSystemInterface::handleWindowScreenChanged(window(), newScreen->screen()); + QWindowSystemInterface::handleWindowScreenChanged(window(), newScreen->QPlatformScreen::screen()); if (qt_window_private(window())->positionAutomatic) { const quint32 mask = XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT; @@ -1161,6 +1226,8 @@ void QXcbWindow::changeNetWmState(bool set, xcb_atom_t one, xcb_atom_t two) event.data.data32[3] = 0; event.data.data32[4] = 0; + if (!xcbScreen()) + return; Q_XCB_CALL(xcb_send_event(xcb_connection(), 0, xcbScreen()->root(), XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, (const char *)&event)); } @@ -1567,7 +1634,7 @@ void QXcbWindow::propagateSizeHints() memset(&hints, 0, sizeof(hints)); const int dpr = int(devicePixelRatio()); - const QRect xRect = mapToNative(windowToWmGeometry(geometry()), dpr); + const QRect xRect = windowToWmGeometry(mapToNative(geometry(), xcbScreen())); QWindow *win = window(); @@ -1660,6 +1727,13 @@ void QXcbWindow::setWindowIconTextStatic(QWindow *window, const QString &text) static_cast<QXcbWindow *>(window->handle())->setWindowIconText(text); } +uint QXcbWindow::visualIdStatic(QWindow *window) +{ + if (window && window->handle()) + return static_cast<QXcbWindow *>(window->handle())->visualId(); + return UINT_MAX; +} + QXcbWindowFunctions::WmWindowTypes QXcbWindow::wmWindowTypes() const { QXcbWindowFunctions::WmWindowTypes result(0); @@ -1953,20 +2027,21 @@ void QXcbWindow::handleClientMessageEvent(const xcb_client_message_event_t *even } } -// Temporary workaround for bug in QPlatformScreen::screenForNativeGeometry +// Temporary workaround for bug in QPlatformScreen::screenForGeometry // we need the native geometries to detect our screen, but that's not // available in cross-platform code. Will be fixed properly when highDPI // support is refactored to expose the native coordinate system. -QPlatformScreen *QXcbWindow::screenForNativeGeometry(const QRect &newGeometry) const +QXcbScreen *QXcbWindow::screenForNativeGeometry(const QRect &newGeometry) const { - QXcbScreen *currentScreen = static_cast<QXcbScreen*>(screen()); + QXcbScreen *currentScreen = xcbScreen(); if (!currentScreen && QGuiApplication::primaryScreen()) currentScreen = static_cast<QXcbScreen*>(QGuiApplication::primaryScreen()->handle()); if (currentScreen && !parent() && !currentScreen->nativeGeometry().intersects(newGeometry)) { Q_FOREACH (QPlatformScreen* screen, currentScreen->virtualSiblings()) { - if (static_cast<QXcbScreen*>(screen)->nativeGeometry().intersects(newGeometry)) - return screen; + QXcbScreen *xcbScreen = static_cast<QXcbScreen*>(screen); + if (xcbScreen->nativeGeometry().intersects(newGeometry)) + return xcbScreen; } } return currentScreen; @@ -1988,23 +2063,19 @@ void QXcbWindow::handleConfigureNotifyEvent(const xcb_configure_notify_event_t * } } - const int dpr = devicePixelRatio(); const QRect nativeRect = QRect(pos, QSize(event->width, event->height)); - const QRect rect = mapGeometryFromNative(nativeRect, dpr); + QXcbScreen *newScreen = parent() ? parentScreen() : screenForNativeGeometry(nativeRect); + + QXcbScreen *currentScreen = m_xcbScreen; + m_xcbScreen = newScreen; + if (!newScreen) + return; + const QRect rect = mapFromNative(nativeRect, newScreen); QPlatformWindow::setGeometry(rect); QWindowSystemInterface::handleGeometryChange(window(), rect); - QPlatformScreen *newScreen = screenForNativeGeometry(nativeRect); - if (newScreen != screen()) { - if (newScreen) - QWindowSystemInterface::handleWindowScreenChanged(window(), newScreen->screen()); - int newDpr = newScreen->devicePixelRatio(); - if (newDpr != dpr) { - QRect newRect = mapGeometryFromNative(nativeRect, newDpr); - QPlatformWindow::setGeometry(newRect); - QWindowSystemInterface::handleGeometryChange(window(), newRect); - } - } + if (newScreen != currentScreen) + QWindowSystemInterface::handleWindowScreenChanged(window(), newScreen->QPlatformScreen::screen()); m_configureNotifyPending = false; @@ -2045,12 +2116,12 @@ QPoint QXcbWindow::mapToGlobal(const QPoint &pos) const xcb_translate_coordinates_reply_t *reply = xcb_translate_coordinates_reply(xcb_connection(), cookie, NULL); if (reply) { - ret.setX(reply->dst_x / dpr); - ret.setY(reply->dst_y / dpr); + ret.setX(reply->dst_x); + ret.setY(reply->dst_y); free(reply); } - return ret; + return mapFromNative(ret, xcbScreen()); } QPoint QXcbWindow::mapFromGlobal(const QPoint &pos) const @@ -2060,9 +2131,10 @@ QPoint QXcbWindow::mapFromGlobal(const QPoint &pos) const const int dpr = int(devicePixelRatio()); QPoint ret; + QPoint xPos = mapToNative(pos, xcbScreen()); xcb_translate_coordinates_cookie_t cookie = xcb_translate_coordinates(xcb_connection(), xcbScreen()->root(), xcb_window(), - pos.x() *dpr, pos.y() * dpr); + xPos.x(), xPos.y()); xcb_translate_coordinates_reply_t *reply = xcb_translate_coordinates_reply(xcb_connection(), cookie, NULL); if (reply) { @@ -2116,7 +2188,7 @@ void QXcbWindow::handleButtonPressEvent(const xcb_button_press_event_t *event) } const int dpr = int(devicePixelRatio()); QPoint local(event->event_x/dpr, event->event_y/dpr); - QPoint global(event->root_x/dpr, event->root_y/dpr); + QPoint global = xcbScreen()->mapFromNative(QPoint(event->root_x, event->root_y)); Qt::KeyboardModifiers modifiers = connection()->keyboard()->translateModifiers(event->state); @@ -2141,7 +2213,7 @@ void QXcbWindow::handleButtonReleaseEvent(const xcb_button_release_event_t *even { const int dpr = int(devicePixelRatio()); QPoint local(event->event_x/dpr, event->event_y/dpr); - QPoint global(event->root_x/dpr, event->root_y/dpr); + QPoint global = xcbScreen()->mapFromNative(QPoint(event->root_x, event->root_y)); Qt::KeyboardModifiers modifiers = connection()->keyboard()->translateModifiers(event->state); if (event->detail >= 4 && event->detail <= 7) { @@ -2156,7 +2228,9 @@ void QXcbWindow::handleMotionNotifyEvent(const xcb_motion_notify_event_t *event) { const int dpr = int(devicePixelRatio()); QPoint local(event->event_x/dpr, event->event_y/dpr); - QPoint global(event->root_x/dpr, event->root_y/dpr); + if (!xcbScreen()) + return; + QPoint global = xcbScreen()->mapFromNative(QPoint(event->root_x, event->root_y)); Qt::KeyboardModifiers modifiers = connection()->keyboard()->translateModifiers(event->state); handleMouseEvent(event->time, local, global, modifiers); @@ -2213,7 +2287,9 @@ void QXcbWindow::handleEnterNotifyEvent(const xcb_enter_notify_event_t *event) const int dpr = int(devicePixelRatio()); const QPoint local(event->event_x/dpr, event->event_y/dpr); - const QPoint global(event->root_x/dpr, event->root_y/dpr); + if (!xcbScreen()) + return; + QPoint global = xcbScreen()->mapFromNative(QPoint(event->root_x, event->root_y)); QWindowSystemInterface::handleEnterEvent(window(), local, global); } @@ -2231,7 +2307,9 @@ void QXcbWindow::handleLeaveNotifyEvent(const xcb_leave_notify_event_t *event) if (enterWindow) { const int dpr = int(devicePixelRatio()); QPoint local(enter->event_x/dpr, enter->event_y/dpr); - QPoint global(enter->root_x/dpr, enter->root_y/dpr); + if (!xcbScreen()) + return; + QPoint global = xcbScreen()->mapFromNative(QPoint(event->root_x, event->root_y)); QWindowSystemInterface::handleEnterLeaveEvent(enterWindow->window(), window(), local, global); } else { @@ -2246,6 +2324,8 @@ void QXcbWindow::handlePropertyNotifyEvent(const xcb_property_notify_event_t *ev connection()->setTime(event->time); const bool propertyDeleted = event->state == XCB_PROPERTY_DELETE; + if (!xcbScreen()) + return; if (event->atom == atom(QXcbAtom::_NET_WM_STATE) || event->atom == atom(QXcbAtom::WM_STATE)) { if (propertyDeleted) @@ -2394,7 +2474,6 @@ void QXcbWindow::windowEvent(QEvent *event) bool QXcbWindow::startSystemResize(const QPoint &pos, Qt::Corner corner) { - const int dpr = int(devicePixelRatio()); const xcb_atom_t moveResize = connection()->atom(QXcbAtom::_NET_WM_MOVERESIZE); if (!connection()->wmSupport()->isSupportedByWM(moveResize)) return false; @@ -2403,7 +2482,7 @@ bool QXcbWindow::startSystemResize(const QPoint &pos, Qt::Corner corner) xev.type = moveResize; xev.window = xcb_window(); xev.format = 32; - const QPoint globalPos = window()->mapToGlobal(pos) * dpr; + const QPoint globalPos = mapToNative(window()->mapToGlobal(pos), xcbScreen()); xev.data.data32[0] = globalPos.x(); xev.data.data32[1] = globalPos.y(); const bool bottom = corner == Qt::BottomRightCorner || corner == Qt::BottomLeftCorner; @@ -2532,7 +2611,7 @@ void QXcbWindow::setMask(const QRegion ®ion) const int dpr = devicePixelRatio(); QVector<xcb_rectangle_t> rects; foreach (const QRect &r, region.rects()) - rects.push_back(qRectToXCBRectangle(mapToNative(r, dpr))); + rects.push_back(qRectToXCBRectangle(mapLocalGeometryToNative(r, dpr))); xcb_shape_rectangles(connection()->xcb_connection(), XCB_SHAPE_SO_SET, XCB_SHAPE_SK_BOUNDING, XCB_CLIP_ORDERING_UNSORTED, xcb_window(), 0, 0, rects.size(), &rects[0]); @@ -2549,6 +2628,11 @@ void QXcbWindow::setAlertState(bool enabled) changeNetWmState(enabled, atom(QXcbAtom::_NET_WM_STATE_DEMANDS_ATTENTION)); } +uint QXcbWindow::visualId() const +{ + return m_visualId; +} + bool QXcbWindow::needsSync() const { return m_syncState == SyncAndConfigureReceived; @@ -2556,6 +2640,8 @@ bool QXcbWindow::needsSync() const void QXcbWindow::postSyncWindowRequest() { + if (!xcbScreen()) + return; if (!m_pendingSyncRequest) { QXcbSyncWindowRequest *e = new QXcbSyncWindowRequest(this); m_pendingSyncRequest = e; diff --git a/src/plugins/platforms/xcb/qxcbwindow.h b/src/plugins/platforms/xcb/qxcbwindow.h index 2442e6c4e3..52e8ac1459 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.h +++ b/src/plugins/platforms/xcb/qxcbwindow.h @@ -140,6 +140,7 @@ public: void updateNetWmUserTime(xcb_timestamp_t timestamp); static void setWmWindowTypeStatic(QWindow *window, QXcbWindowFunctions::WmWindowTypes windowTypes); + static uint visualIdStatic(QWindow *window); QXcbWindowFunctions::WmWindowTypes wmWindowTypes() const; void setWmWindowType(QXcbWindowFunctions::WmWindowTypes types); @@ -154,6 +155,7 @@ public: static QRect systemTrayWindowGlobalGeometryStatic(const QWindow *window); QRect systemTrayWindowGlobalGeometry() const; + uint visualId() const; bool needsSync() const; @@ -167,7 +169,7 @@ public: virtual void create(); virtual void destroy(); void maybeSetScreen(QXcbScreen *screen); - QPlatformScreen *screenForNativeGeometry(const QRect &newGeometry) const; + QXcbScreen *screenForNativeGeometry(const QRect &newGeometry) const; public Q_SLOTS: void updateSyncRequestCounter(); @@ -177,6 +179,12 @@ protected: virtual void *createVisual() { return Q_NULLPTR; } virtual bool supportsSyncProtocol() { return !window()->supportsOpenGL(); } + QPoint mapToNative(const QPoint &pos, const QXcbScreen *screen) const; + QPoint mapFromNative(const QPoint &pos, const QXcbScreen *screen) const; + QRect mapToNative(const QRect &rect, const QXcbScreen *screen) const; + QRect mapFromNative(const QRect &rect, const QXcbScreen *screen) const; + QXcbScreen *parentScreen(); + void changeNetWmState(bool set, xcb_atom_t one, xcb_atom_t two = 0); NetWmStates netWmStates(); void setNetWmStates(NetWmStates); @@ -204,6 +212,8 @@ protected: xcb_window_t m_window; + QXcbScreen *m_xcbScreen; + uint m_depth; QImage::Format m_imageFormat; bool m_imageRgbSwap; diff --git a/src/plugins/platforms/xcb/qxcbwmsupport.cpp b/src/plugins/platforms/xcb/qxcbwmsupport.cpp index bcdfde2ef9..7d31ac7118 100644 --- a/src/plugins/platforms/xcb/qxcbwmsupport.cpp +++ b/src/plugins/platforms/xcb/qxcbwmsupport.cpp @@ -68,7 +68,7 @@ void QXcbWMSupport::updateNetWMAtoms() remaining = 0; if (reply->type == XCB_ATOM_ATOM && reply->format == 32) { - int len = xcb_get_property_value_length(reply)/4; + int len = xcb_get_property_value_length(reply)/sizeof(xcb_atom_t); xcb_atom_t *atoms = (xcb_atom_t *)xcb_get_property_value(reply); int s = net_wm_atoms.size(); net_wm_atoms.resize(s + len); @@ -102,11 +102,11 @@ void QXcbWMSupport::updateVirtualRoots() remaining = 0; if (reply->type == XCB_ATOM_ATOM && reply->format == 32) { - int len = xcb_get_property_value_length(reply)/4; - xcb_atom_t *atoms = (xcb_atom_t *)xcb_get_property_value(reply); - int s = net_wm_atoms.size(); - net_wm_atoms.resize(s + len); - memcpy(net_wm_atoms.data() + s, atoms, len*sizeof(xcb_atom_t)); + int len = xcb_get_property_value_length(reply)/sizeof(xcb_window_t); + xcb_window_t *roots = (xcb_window_t *)xcb_get_property_value(reply); + int s = net_virtual_roots.size(); + net_virtual_roots.resize(s + len); + memcpy(net_virtual_roots.data() + s, roots, len*sizeof(xcb_window_t)); remaining = reply->bytes_after; offset += len; diff --git a/src/plugins/platforms/xcb/qxcbxsettings.cpp b/src/plugins/platforms/xcb/qxcbxsettings.cpp index c83edd506d..46cee5d6d0 100644 --- a/src/plugins/platforms/xcb/qxcbxsettings.cpp +++ b/src/plugins/platforms/xcb/qxcbxsettings.cpp @@ -63,7 +63,7 @@ public: : last_change_serial(-1) {} - void updateValue(QXcbScreen *screen, const QByteArray &name, const QVariant &value, int last_change_serial) + void updateValue(QXcbVirtualDesktop *screen, const QByteArray &name, const QVariant &value, int last_change_serial) { if (last_change_serial <= this->last_change_serial) return; @@ -92,7 +92,7 @@ public: class QXcbXSettingsPrivate { public: - QXcbXSettingsPrivate(QXcbScreen *screen) + QXcbXSettingsPrivate(QXcbVirtualDesktop *screen) : screen(screen) , initialized(false) { @@ -217,18 +217,18 @@ public: } #endif //XCB_USE_XLIB - QXcbScreen *screen; + QXcbVirtualDesktop *screen; xcb_window_t x_settings_window; QMap<QByteArray, QXcbXSettingsPropertyValue> settings; bool initialized; }; -QXcbXSettings::QXcbXSettings(QXcbScreen *screen) +QXcbXSettings::QXcbXSettings(QXcbVirtualDesktop *screen) : d_ptr(new QXcbXSettingsPrivate(screen)) { QByteArray settings_atom_for_screen("_XSETTINGS_S"); - settings_atom_for_screen.append(QByteArray::number(screen->screenNumber())); + settings_atom_for_screen.append(QByteArray::number(screen->number())); xcb_intern_atom_cookie_t atom_cookie = xcb_intern_atom(screen->xcb_connection(), true, settings_atom_for_screen.length(), diff --git a/src/plugins/platforms/xcb/qxcbxsettings.h b/src/plugins/platforms/xcb/qxcbxsettings.h index 4022f0a2c4..3f1d175336 100644 --- a/src/plugins/platforms/xcb/qxcbxsettings.h +++ b/src/plugins/platforms/xcb/qxcbxsettings.h @@ -44,13 +44,13 @@ class QXcbXSettings : public QXcbWindowEventListener { Q_DECLARE_PRIVATE(QXcbXSettings) public: - QXcbXSettings(QXcbScreen *screen); + QXcbXSettings(QXcbVirtualDesktop *screen); ~QXcbXSettings(); bool initialized() const; QVariant setting(const QByteArray &property) const; - typedef void (*PropertyChangeFunc)(QXcbScreen *screen, const QByteArray &name, const QVariant &property, void *handle); + typedef void (*PropertyChangeFunc)(QXcbVirtualDesktop *screen, const QByteArray &name, const QVariant &property, void *handle); void registerCallbackForProperty(const QByteArray &property, PropertyChangeFunc func, void *handle); void removeCallbackForHandle(const QByteArray &property, void *handle); void removeCallbackForHandle(void *handle); |