diff options
Diffstat (limited to 'src/plugins/platforms')
56 files changed, 539 insertions, 483 deletions
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/android/qandroidplatformforeignwindow.cpp b/src/plugins/platforms/android/qandroidplatformforeignwindow.cpp index ec80bf0f8c..315a0faac0 100644 --- a/src/plugins/platforms/android/qandroidplatformforeignwindow.cpp +++ b/src/plugins/platforms/android/qandroidplatformforeignwindow.cpp @@ -73,19 +73,10 @@ void QAndroidPlatformForeignWindow::raise() void QAndroidPlatformForeignWindow::setGeometry(const QRect &rect) { - QWindow *parent = window()->parent(); - QRect newGeometry = rect; - - if (parent != 0) - newGeometry.moveTo(parent->mapToGlobal(rect.topLeft())); - - if (newGeometry == geometry()) - return; - - QAndroidPlatformWindow::setGeometry(newGeometry); + QAndroidPlatformWindow::setGeometry(rect); if (m_surfaceId != -1) - QtAndroid::setSurfaceGeometry(m_surfaceId, newGeometry); + QtAndroid::setSurfaceGeometry(m_surfaceId, rect); } void QAndroidPlatformForeignWindow::setVisible(bool visible) @@ -118,18 +109,7 @@ void QAndroidPlatformForeignWindow::applicationStateChanged(Qt::ApplicationState void QAndroidPlatformForeignWindow::setParent(const QPlatformWindow *window) { - QRect newGeometry = geometry(); - - if (window != 0) - newGeometry.moveTo(window->mapToGlobal(geometry().topLeft())); - - if (newGeometry != geometry()) - QAndroidPlatformWindow::setGeometry(newGeometry); - - if (m_surfaceId == -1) - return; - - QtAndroid::setSurfaceGeometry(m_surfaceId, newGeometry); + Q_UNUSED(window); } QT_END_NAMESPACE diff --git a/src/plugins/platforms/cocoa/qcocoaapplication.mm b/src/plugins/platforms/cocoa/qcocoaapplication.mm index 79399e4183..227ab05c25 100644 --- a/src/plugins/platforms/cocoa/qcocoaapplication.mm +++ b/src/plugins/platforms/cocoa/qcocoaapplication.mm @@ -133,7 +133,7 @@ static const QByteArray q_macLocalEventType = QByteArrayLiteral("mac_generic_NSE return true; if ([event type] == NSApplicationDefined) { - switch ([event subtype]) { + switch (static_cast<short>([event subtype])) { case QtCocoaEventSubTypePostMessage: [NSApp QT_MANGLE_NAMESPACE(qt_sendPostedMessage):event]; return true; diff --git a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h index 13a8c89dbb..4a2cb42f87 100644 --- a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h +++ b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h @@ -80,7 +80,6 @@ // #include <QtCore/qabstracteventdispatcher.h> -#include <QtCore/qhash.h> #include <QtCore/qstack.h> #include <QtGui/qwindowdefs.h> #include <QtCore/private/qabstracteventdispatcher_p.h> diff --git a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm index 52b2e23345..050fade284 100644 --- a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm +++ b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm @@ -72,7 +72,6 @@ #include "qcocoahelpers.h" #include "qguiapplication.h" #include "qevent.h" -#include "qhash.h" #include "qmutex.h" #include "qsocketnotifier.h" #include <qpa/qplatformwindow.h> diff --git a/src/plugins/platforms/cocoa/qcocoainputcontext.mm b/src/plugins/platforms/cocoa/qcocoainputcontext.mm index 0eafae1f2d..c22fe8774b 100644 --- a/src/plugins/platforms/cocoa/qcocoainputcontext.mm +++ b/src/plugins/platforms/cocoa/qcocoainputcontext.mm @@ -99,9 +99,8 @@ void QCocoaInputContext::reset() return; QCocoaAutoReleasePool pool; - NSInputManager *currentIManager = [NSInputManager currentInputManager]; - if (currentIManager) { - [currentIManager markedTextAbandoned:view]; + if (NSTextInputContext *ctxt = [NSTextInputContext currentInputContext]) { + [ctxt discardMarkedText]; [view unmarkText]; } } 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 82b032e7d0..0c1da59748 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -1516,10 +1516,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..3c12228ef6 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 @@ -702,8 +704,10 @@ QT_WARNING_POP } // Popups implicitly grap mouse events; forward to the active popup if there is one - if (QCocoaWindow *popup = QCocoaIntegration::instance()->activePopupWindow()) - targetView = popup->contentView(); + if (QCocoaWindow *popup = QCocoaIntegration::instance()->activePopupWindow()) { + if (QNSView *popupView = popup->qtView()) + targetView = popupView; + } [targetView convertFromScreen:[self screenMousePoint:theEvent] toWindowPoint:&qtWindowPoint andScreenPoint:&qtScreenPoint]; ulong timestamp = [theEvent timestamp] * 1000; @@ -755,12 +759,13 @@ QT_WARNING_POP NSPoint windowPoint = [theEvent locationInWindow]; int windowScreenY = [window frame].origin.y + [window frame].size.height; - int viewScreenY = [window convertBaseToScreen:[self convertPoint:[self frame].origin toView:nil]].y; + NSPoint windowCoord = [self convertPoint:[self frame].origin toView:nil]; + int viewScreenY = [window convertRectToScreen:NSMakeRect(windowCoord.x, windowCoord.y, 0, 0)].origin.y; int titleBarHeight = windowScreenY - viewScreenY; NSPoint nsViewPoint = [self convertPoint: windowPoint fromView: nil]; QPoint qtWindowPoint = QPoint(nsViewPoint.x, titleBarHeight + nsViewPoint.y); - NSPoint screenPoint = [window convertBaseToScreen:windowPoint]; + NSPoint screenPoint = [window convertRectToScreen:NSMakeRect(windowPoint.x, windowPoint.y, 0, 0)].origin; QPoint qtScreenPoint = QPoint(screenPoint.x, qt_mac_flipYCoordinate(screenPoint.y)); ulong timestamp = [theEvent timestamp] * 1000; @@ -806,10 +811,7 @@ QT_WARNING_POP } if ([self hasMarkedText]) { - NSInputManager* inputManager = [NSInputManager currentInputManager]; - if ([inputManager wantsToHandleMouseEvents]) { - [inputManager handleMouseEvent:theEvent]; - } + [[NSTextInputContext currentInputContext] handleEvent:theEvent]; } else { if ([QNSView convertKeyModifiers:[theEvent modifierFlags]] & Qt::MetaModifier) { m_buttons |= Qt::RightButton; @@ -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()); } @@ -1947,7 +1983,7 @@ static QPoint mapWindowCoordinates(QWindow *source, QWindow *target, QPoint poin QPoint qtWindowPoint(windowPoint.x, windowPoint.y); NSWindow *window = [self window]; - NSPoint screenPoint = [window convertBaseToScreen :point]; + NSPoint screenPoint = [window convertRectToScreen:NSMakeRect(point.x, point.y, 0, 0)].origin; QPoint qtScreenPoint = QPoint(screenPoint.x, qt_mac_flipYCoordinate(screenPoint.y)); QWindowSystemInterface::handleMouseEvent(target, mapWindowCoordinates(m_window, target, qtWindowPoint), qtScreenPoint, m_buttons); diff --git a/src/plugins/platforms/haiku/qhaikuwindow.cpp b/src/plugins/platforms/haiku/qhaikuwindow.cpp index 5768e1cb40..140b79af12 100644 --- a/src/plugins/platforms/haiku/qhaikuwindow.cpp +++ b/src/plugins/platforms/haiku/qhaikuwindow.cpp @@ -306,10 +306,8 @@ void QHaikuWindow::haikuWindowMoved(const QPoint &pos) const QRect newGeometry(pos, geometry().size()); QPlatformWindow::setGeometry(newGeometry); - QWindowSystemInterface::setSynchronousWindowsSystemEvents(true); QWindowSystemInterface::handleGeometryChange(window(), newGeometry); QWindowSystemInterface::handleExposeEvent(window(), newGeometry); - QWindowSystemInterface::setSynchronousWindowsSystemEvents(false); } void QHaikuWindow::haikuWindowResized(const QSize &size, bool zoomInProgress) @@ -317,10 +315,8 @@ void QHaikuWindow::haikuWindowResized(const QSize &size, bool zoomInProgress) const QRect newGeometry(geometry().topLeft(), size); QPlatformWindow::setGeometry(newGeometry); - QWindowSystemInterface::setSynchronousWindowsSystemEvents(true); QWindowSystemInterface::handleGeometryChange(window(), newGeometry); QWindowSystemInterface::handleExposeEvent(window(), newGeometry); - QWindowSystemInterface::setSynchronousWindowsSystemEvents(false); if ((m_windowState == Qt::WindowMaximized) && !zoomInProgress) { // the user has resized the window while maximized -> reset maximized flag 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/qqnxintegration.cpp b/src/plugins/platforms/qnx/qqnxintegration.cpp index 1bcf8036bb..693749da55 100644 --- a/src/plugins/platforms/qnx/qqnxintegration.cpp +++ b/src/plugins/platforms/qnx/qqnxintegration.cpp @@ -95,7 +95,6 @@ #include <private/qsimpledrag_p.h> #include <QtCore/QDebug> -#include <QtCore/QHash> #include <errno.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/qwindowsclipboard.cpp b/src/plugins/platforms/windows/qwindowsclipboard.cpp index bfcc9e9bce..4cea845c36 100644 --- a/src/plugins/platforms/windows/qwindowsclipboard.cpp +++ b/src/plugins/platforms/windows/qwindowsclipboard.cpp @@ -71,22 +71,23 @@ static const char formatTextHtmlC[] = "text/html"; QDebug operator<<(QDebug d, const QMimeData &m) { - QDebug nospace = d.nospace(); + QDebugStateSaver saver(d); + d.nospace(); const QStringList formats = m.formats(); - nospace << "QMimeData: " << formats.join(QStringLiteral(", ")) << '\n' + d << "QMimeData: " << formats.join(QStringLiteral(", ")) << '\n' << " Text=" << m.hasText() << " HTML=" << m.hasHtml() << " Color=" << m.hasColor() << " Image=" << m.hasImage() << " URLs=" << m.hasUrls() << '\n'; if (m.hasText()) - nospace << " Text: '" << m.text() << "'\n"; + d << " Text: '" << m.text() << "'\n"; if (m.hasHtml()) - nospace << " HTML: '" << m.html() << "'\n"; + d << " HTML: '" << m.html() << "'\n"; if (m.hasColor()) - nospace << " Color: " << qvariant_cast<QColor>(m.colorData()) << '\n'; + d << " Color: " << qvariant_cast<QColor>(m.colorData()) << '\n'; if (m.hasImage()) - nospace << " Image: " << qvariant_cast<QImage>(m.imageData()).size() << '\n'; + d << " Image: " << qvariant_cast<QImage>(m.imageData()).size() << '\n'; if (m.hasUrls()) - nospace << " URLs: " << m.urls() << '\n'; + d << " URLs: " << m.urls() << '\n'; return d; } diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp index 7d7ea031a5..a532e92397 100644 --- a/src/plugins/platforms/windows/qwindowscontext.cpp +++ b/src/plugins/platforms/windows/qwindowscontext.cpp @@ -566,8 +566,8 @@ QString QWindowsContext::registerWindowClass(QString cname, d->m_registeredWindowClassNames.insert(cname); qCDebug(lcQpaWindows).nospace() << __FUNCTION__ << ' ' << cname - << " style=0x" << QString::number(style, 16) - << " brush=" << brush << " icon=" << icon << " atom=" << atom; + << " style=0x" << hex << style << dec + << " brush=" << brush << " icon=" << icon << " atom=" << atom; return cname; } diff --git a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp index 3284795fc1..da0ba27e3a 100644 --- a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp +++ b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp @@ -379,7 +379,12 @@ static inline QString guidToString(const GUID &g) } inline QDebug operator<<(QDebug d, const GUID &g) -{ d.nospace() << guidToString(g); return d; } +{ + QDebugStateSaver saver(d); + d.nospace(); + d << guidToString(g); + return d; +} // Return an allocated wchar_t array from a QString, reserve more memory if desired. static wchar_t *qStringToWCharArray(const QString &s, size_t reserveSize = 0) 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/qwindowsfontdatabase.cpp b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp index b979dc6c4e..a544b9d81e 100644 --- a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp +++ b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp @@ -608,11 +608,13 @@ static inline bool initDirectWrite(QWindowsFontEngineData *d) QDebug operator<<(QDebug d, const QFontDef &def) { - d.nospace() << "Family=" << def.family << " Stylename=" << def.styleName - << " pointsize=" << def.pointSize << " pixelsize=" << def.pixelSize - << " styleHint=" << def.styleHint << " weight=" << def.weight - << " stretch=" << def.stretch << " hintingPreference=" - << def.hintingPreference << ' '; + QDebugStateSaver saver(d); + d.nospace(); + d << "Family=" << def.family << " Stylename=" << def.styleName + << " pointsize=" << def.pointSize << " pixelsize=" << def.pixelSize + << " styleHint=" << def.styleHint << " weight=" << def.weight + << " stretch=" << def.stretch << " hintingPreference=" + << def.hintingPreference; return d; } @@ -1631,6 +1633,8 @@ QStringList QWindowsFontDatabase::extraTryFontsForFamily(const QString &family) ++tf; } } + result.append(QStringLiteral("Segoe UI Emoji")); + result.append(QStringLiteral("Segoe UI Symbol")); return result; } diff --git a/src/plugins/platforms/windows/qwindowsglcontext.cpp b/src/plugins/platforms/windows/qwindowsglcontext.cpp index 7a17942b27..a7c14ed2ac 100644 --- a/src/plugins/platforms/windows/qwindowsglcontext.cpp +++ b/src/plugins/platforms/windows/qwindowsglcontext.cpp @@ -286,40 +286,41 @@ static inline void initPixelFormatDescriptor(PIXELFORMATDESCRIPTOR *d) QDebug operator<<(QDebug d, const PIXELFORMATDESCRIPTOR &pd) { - QDebug nsp = d.nospace(); - nsp << "PIXELFORMATDESCRIPTOR " + QDebugStateSaver saver(d); + d.nospace(); + d << "PIXELFORMATDESCRIPTOR " << "dwFlags=" << hex << showbase << pd.dwFlags << dec << noshowbase; - if (pd.dwFlags & PFD_DRAW_TO_WINDOW) nsp << " PFD_DRAW_TO_WINDOW"; - if (pd.dwFlags & PFD_DRAW_TO_BITMAP) nsp << " PFD_DRAW_TO_BITMAP"; - if (pd.dwFlags & PFD_SUPPORT_GDI) nsp << " PFD_SUPPORT_GDI"; - if (pd.dwFlags & PFD_SUPPORT_OPENGL) nsp << " PFD_SUPPORT_OPENGL"; - if (pd.dwFlags & PFD_GENERIC_ACCELERATED) nsp << " PFD_GENERIC_ACCELERATED"; - if (pd.dwFlags & PFD_SUPPORT_DIRECTDRAW) nsp << " PFD_SUPPORT_DIRECTDRAW"; - if (pd.dwFlags & PFD_DIRECT3D_ACCELERATED) nsp << " PFD_DIRECT3D_ACCELERATED"; - if (pd.dwFlags & PFD_SUPPORT_COMPOSITION) nsp << " PFD_SUPPORT_COMPOSITION"; - if (pd.dwFlags & PFD_GENERIC_FORMAT) nsp << " PFD_GENERIC_FORMAT"; - if (pd.dwFlags & PFD_NEED_PALETTE) nsp << " PFD_NEED_PALETTE"; - if (pd.dwFlags & PFD_NEED_SYSTEM_PALETTE) nsp << " PFD_NEED_SYSTEM_PALETTE"; - if (pd.dwFlags & PFD_DOUBLEBUFFER) nsp << " PFD_DOUBLEBUFFER"; - if (pd.dwFlags & PFD_STEREO) nsp << " PFD_STEREO"; - if (pd.dwFlags & PFD_SWAP_LAYER_BUFFERS) nsp << " PFD_SWAP_LAYER_BUFFERS"; - if (hasGLOverlay(pd)) nsp << " overlay"; - nsp << " iPixelType=" << pd.iPixelType << " cColorBits=" << pd.cColorBits + if (pd.dwFlags & PFD_DRAW_TO_WINDOW) d << " PFD_DRAW_TO_WINDOW"; + if (pd.dwFlags & PFD_DRAW_TO_BITMAP) d << " PFD_DRAW_TO_BITMAP"; + if (pd.dwFlags & PFD_SUPPORT_GDI) d << " PFD_SUPPORT_GDI"; + if (pd.dwFlags & PFD_SUPPORT_OPENGL) d << " PFD_SUPPORT_OPENGL"; + if (pd.dwFlags & PFD_GENERIC_ACCELERATED) d << " PFD_GENERIC_ACCELERATED"; + if (pd.dwFlags & PFD_SUPPORT_DIRECTDRAW) d << " PFD_SUPPORT_DIRECTDRAW"; + if (pd.dwFlags & PFD_DIRECT3D_ACCELERATED) d << " PFD_DIRECT3D_ACCELERATED"; + if (pd.dwFlags & PFD_SUPPORT_COMPOSITION) d << " PFD_SUPPORT_COMPOSITION"; + if (pd.dwFlags & PFD_GENERIC_FORMAT) d << " PFD_GENERIC_FORMAT"; + if (pd.dwFlags & PFD_NEED_PALETTE) d << " PFD_NEED_PALETTE"; + if (pd.dwFlags & PFD_NEED_SYSTEM_PALETTE) d << " PFD_NEED_SYSTEM_PALETTE"; + if (pd.dwFlags & PFD_DOUBLEBUFFER) d << " PFD_DOUBLEBUFFER"; + if (pd.dwFlags & PFD_STEREO) d << " PFD_STEREO"; + if (pd.dwFlags & PFD_SWAP_LAYER_BUFFERS) d << " PFD_SWAP_LAYER_BUFFERS"; + if (hasGLOverlay(pd)) d << " overlay"; + d << " iPixelType=" << pd.iPixelType << " cColorBits=" << pd.cColorBits << " cRedBits=" << pd.cRedBits << " cRedShift=" << pd.cRedShift << " cGreenBits=" << pd.cGreenBits << " cGreenShift=" << pd.cGreenShift << " cBlueBits=" << pd.cBlueBits << " cBlueShift=" << pd.cBlueShift; - nsp << " cDepthBits=" << pd.cDepthBits; + d << " cDepthBits=" << pd.cDepthBits; if (pd.cStencilBits) - nsp << " cStencilBits=" << pd.cStencilBits; + d << " cStencilBits=" << pd.cStencilBits; if (pd.cAuxBuffers) - nsp << " cAuxBuffers=" << pd.cAuxBuffers; - nsp << " iLayerType=" << pd.iLayerType; + d << " cAuxBuffers=" << pd.cAuxBuffers; + d << " iLayerType=" << pd.iLayerType; if (pd.dwVisibleMask) - nsp << " dwVisibleMask=" << pd.dwVisibleMask; + d << " dwVisibleMask=" << pd.dwVisibleMask; if (pd.cAlphaBits) - nsp << " cAlphaBits=" << pd.cAlphaBits << " cAlphaShift=" << pd.cAlphaShift; + d << " cAlphaBits=" << pd.cAlphaBits << " cAlphaShift=" << pd.cAlphaShift; if (pd.cAccumBits) - nsp << " cAccumBits=" << pd.cAccumBits << " cAccumRedBits=" << pd.cAccumRedBits + d << " cAccumBits=" << pd.cAccumBits << " cAccumRedBits=" << pd.cAccumRedBits << " cAccumGreenBits=" << pd.cAccumGreenBits << " cAccumBlueBits=" << pd.cAccumBlueBits << " cAccumAlphaBits=" << pd.cAccumAlphaBits; return d; @@ -601,6 +602,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; } @@ -898,9 +907,10 @@ void QWindowsOpenGLContextFormat::apply(QSurfaceFormat *format) const QDebug operator<<(QDebug d, const QWindowsOpenGLContextFormat &f) { - d.nospace() << "ContextFormat: v" << (f.version >> 8) << '.' - << (f.version & 0xFF) << " profile: " << f.profile - << " options: " << f.options; + QDebugStateSaver saver(d); + d.nospace(); + d << "ContextFormat: v" << (f.version >> 8) << '.' << (f.version & 0xFF) + << " profile: " << f.profile << " options: " << f.options; return d; } @@ -1010,16 +1020,17 @@ QOpenGLStaticContext *QOpenGLStaticContext::create(bool softwareRendering) QDebug operator<<(QDebug d, const QOpenGLStaticContext &s) { - QDebug nsp = d.nospace(); - nsp << "OpenGL: " << s.vendor << ',' << s.renderer << " default " + QDebugStateSaver saver(d); + d.nospace(); + d << "OpenGL: " << s.vendor << ',' << s.renderer << " default " << s.defaultFormat; if (s.extensions & QOpenGLStaticContext::SampleBuffers) - nsp << ",SampleBuffers"; + d << ",SampleBuffers"; if (s.hasExtensions()) - nsp << ", Extension-API present"; - nsp << "\nExtensions: " << (s.extensionNames.count(' ') + 1); + d << ", Extension-API present"; + d << "\nExtensions: " << (s.extensionNames.count(' ') + 1); if (QWindowsContext::verbose > 1) - nsp << s.extensionNames; + d << s.extensionNames; return d; } diff --git a/src/plugins/platforms/windows/qwindowsintegration.cpp b/src/plugins/platforms/windows/qwindowsintegration.cpp index 1041ecf44d..9b0f126241 100644 --- a/src/plugins/platforms/windows/qwindowsintegration.cpp +++ b/src/plugins/platforms/windows/qwindowsintegration.cpp @@ -315,13 +315,12 @@ QWindowsWindowData QWindowsIntegration::createWindowData(QWindow *window) const QWindowsWindowData obtained = QWindowsWindowData::create(window, requested, window->title()); qCDebug(lcQpaWindows).nospace() - << __FUNCTION__ << '<' << window - << "\n Requested: " << requested.geometry << "frame incl.: " + << __FUNCTION__ << ' ' << window + << "\n Requested: " << requested.geometry << " frame incl.=" << QWindowsGeometryHint::positionIncludesFrame(window) - << " Flags=" << requested.flags - << "\n Obtained : " << obtained.geometry << " Margins "<< obtained.frame - << " Flags=" << obtained.flags - << " Handle=" << obtained.hwnd << '\n'; + << ' ' << requested.flags + << "\n Obtained : " << obtained.geometry << " margins=" << obtained.frame + << " handle=" << obtained.hwnd << ' ' << obtained.flags << '\n'; if (obtained.hwnd) { if (requested.flags != obtained.flags) 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/qwindowsscreen.cpp b/src/plugins/platforms/windows/qwindowsscreen.cpp index 28e2aadf14..7756c77001 100644 --- a/src/plugins/platforms/windows/qwindowsscreen.cpp +++ b/src/plugins/platforms/windows/qwindowsscreen.cpp @@ -173,20 +173,22 @@ static inline WindowsScreenDataList monitorData() static QDebug operator<<(QDebug dbg, const QWindowsScreenData &d) { - QDebug nospace = dbg.nospace(); - nospace << "Screen " << d.name << ' ' - << d.geometry.width() << 'x' << d.geometry.height() << '+' << d.geometry.x() << '+' << d.geometry.y() - << " avail: " - << d.availableGeometry.width() << 'x' << d.availableGeometry.height() << '+' << d.availableGeometry.x() << '+' << d.availableGeometry.y() - << " physical: " << d.physicalSizeMM.width() << 'x' << d.physicalSizeMM.height() - << " DPI: " << d.dpi.first << 'x' << d.dpi.second << " Depth: " << d.depth - << " Format: " << d.format; + QDebugStateSaver saver(dbg); + dbg.nospace(); + dbg.noquote(); + dbg << "Screen \"" << d.name << "\" " + << d.geometry.width() << 'x' << d.geometry.height() << '+' << d.geometry.x() << '+' << d.geometry.y() + << " avail: " + << d.availableGeometry.width() << 'x' << d.availableGeometry.height() << '+' << d.availableGeometry.x() << '+' << d.availableGeometry.y() + << " physical: " << d.physicalSizeMM.width() << 'x' << d.physicalSizeMM.height() + << " DPI: " << d.dpi.first << 'x' << d.dpi.second << " Depth: " << d.depth + << " Format: " << d.format; if (d.flags & QWindowsScreenData::PrimaryScreen) - nospace << " primary"; + dbg << " primary"; if (d.flags & QWindowsScreenData::VirtualDesktop) - nospace << " virtual desktop"; + dbg << " virtual desktop"; if (d.flags & QWindowsScreenData::LockScreen) - nospace << " lock screen"; + dbg << " lock screen"; return dbg; } diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index 6afa4e6591..923040fd71 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -109,12 +109,13 @@ static QByteArray debugWinExStyle(DWORD exStyle) #ifndef Q_OS_WINCE // maybe available on some SDKs revisit WM_GETMINMAXINFO QDebug operator<<(QDebug d, const MINMAXINFO &i) { - d.nospace() << "MINMAXINFO maxSize=" << i.ptMaxSize.x << ',' - << i.ptMaxSize.y << " maxpos=" << i.ptMaxPosition.x - << ',' << i.ptMaxPosition.y << " mintrack=" - << i.ptMinTrackSize.x << ',' << i.ptMinTrackSize.y - << " maxtrack=" << i.ptMaxTrackSize.x << ',' - << i.ptMaxTrackSize.y; + QDebugStateSaver saver(d); + d.nospace(); + d << "MINMAXINFO maxSize=" << i.ptMaxSize.x << ',' + << i.ptMaxSize.y << " maxpos=" << i.ptMaxPosition.x + << ',' << i.ptMaxPosition.y << " mintrack=" + << i.ptMinTrackSize.x << ',' << i.ptMinTrackSize.y + << " maxtrack=" << i.ptMaxTrackSize.x << ',' << i.ptMaxTrackSize.y; return d; } #endif // !Q_OS_WINCE @@ -139,18 +140,20 @@ static inline RECT RECTfromQRect(const QRect &rect) QDebug operator<<(QDebug d, const RECT &r) { - d.nospace() << "RECT: left/top=" << r.left << ',' << r.top - << " right/bottom=" << r.right << ',' << r.bottom; + QDebugStateSaver saver(d); + d.nospace(); + d << "RECT: left/top=" << r.left << ',' << r.top + << " right/bottom=" << r.right << ',' << r.bottom; return d; } #ifndef Q_OS_WINCE // maybe available on some SDKs revisit WM_NCCALCSIZE QDebug operator<<(QDebug d, const NCCALCSIZE_PARAMS &p) { - qDebug().nospace() << "NCCALCSIZE_PARAMS " - << qrectFromRECT(p.rgrc[0]) - << ' ' << qrectFromRECT(p.rgrc[1]) << ' ' - << qrectFromRECT(p.rgrc[2]); + QDebugStateSaver saver(d); + d.nospace(); + d << "NCCALCSIZE_PARAMS " << qrectFromRECT(p.rgrc[0]) + << ' ' << qrectFromRECT(p.rgrc[1]) << ' ' << qrectFromRECT(p.rgrc[2]); return d; } #endif // !Q_OS_WINCE @@ -417,13 +420,18 @@ struct WindowCreationData QDebug operator<<(QDebug debug, const WindowCreationData &d) { - debug.nospace() << d.flags - << " topLevel=" << d.topLevel << " popup=" - << d.popup << " dialog=" << d.dialog << " desktop=" << d.desktop - << " embedded=" << d.embedded - << " tool=" << d.tool << " style=" << debugWinStyle(d.style) - << " exStyle=" << debugWinExStyle(d.exStyle) - << " parent=" << d.parentHandle; + QDebugStateSaver saver(debug); + debug.nospace(); + debug.noquote(); + debug << "WindowCreationData: " << d.flags + << "\n topLevel=" << d.topLevel; + if (d.parentHandle) + debug << " parent=" << d.parentHandle; + debug << " popup=" << d.popup << " dialog=" << d.dialog << " desktop=" << d.desktop + << " embedded=" << d.embedded << " tool=" << d.tool + << "\n style=" << debugWinStyle(d.style); + if (d.exStyle) + debug << "\n exStyle=" << debugWinExStyle(d.exStyle); return debug; } @@ -540,13 +548,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; @@ -618,8 +622,8 @@ QWindowsWindowData QWindowsContext::instance()->setWindowCreationContext(context); qCDebug(lcQpaWindows).nospace() - << "CreateWindowEx: " << w << *this << " class=" <<windowClassName << " title=" << title - << "\nrequested: " << rect << ": " + << "CreateWindowEx: " << w << " class=" << windowClassName << " title=" << title + << '\n' << *this << "\nrequested: " << rect << ": " << context->frameWidth << 'x' << context->frameHeight << '+' << context->frameX << '+' << context->frameY << " custom margins: " << context->customMargins; @@ -635,7 +639,7 @@ QWindowsWindowData #endif qCDebug(lcQpaWindows).nospace() << "CreateWindowEx: returns " << w << ' ' << result.hwnd << " obtained geometry: " - << context->obtainedGeometry << context->margins; + << context->obtainedGeometry << ' ' << context->margins; if (!result.hwnd) { qErrnoWarning("%s: CreateWindowEx failed", __FUNCTION__); @@ -736,9 +740,9 @@ QMargins QWindowsGeometryHint::frame(DWORD style, DWORD exStyle) qErrnoWarning("%s: AdjustWindowRectEx failed", __FUNCTION__); const QMargins result(qAbs(rect.left), qAbs(rect.top), qAbs(rect.right), qAbs(rect.bottom)); - qCDebug(lcQpaWindows).nospace() << __FUNCTION__ << " style= 0x" - << QString::number(style, 16) << " exStyle=0x" << QString::number(exStyle, 16) << ' ' << rect << ' ' << result; - + qCDebug(lcQpaWindows).nospace() << __FUNCTION__ << " style=" + << showbase << hex << style << " exStyle=" << exStyle << dec << noshowbase + << ' ' << rect << ' ' << result; return result; } @@ -857,12 +861,12 @@ QWindowCreationContext::QWindowCreationContext(const QWindow *w, } qCDebug(lcQpaWindows).nospace() - << __FUNCTION__ << ' ' << w << geometry - << " pos incl. frame" << QWindowsGeometryHint::positionIncludesFrame(w) - << " frame: " << frameWidth << 'x' << frameHeight << '+' + << __FUNCTION__ << ' ' << w << ' ' << geometry + << " pos incl. frame=" << QWindowsGeometryHint::positionIncludesFrame(w) + << " frame=" << frameWidth << 'x' << frameHeight << '+' << frameX << '+' << frameY - << " min" << geometryHint.minimumSize << " max" << geometryHint.maximumSize - << " custom margins " << customMargins; + << " min=" << geometryHint.minimumSize << " max=" << geometryHint.maximumSize + << " custom margins=" << customMargins; } /*! @@ -1426,10 +1430,10 @@ void QWindowsWindow::setGeometry_sys(const QRect &rect) const const QMargins margins = frameMarginsDp(); const QRect frameGeometry = rect + margins; - qCDebug(lcQpaWindows) << '>' << __FUNCTION__ << this << window() - << " \n from " << geometry_sys() << " frame: " - << margins << " to " <<rect - << " new frame: " << frameGeometry; + qCDebug(lcQpaWindows) << '>' << __FUNCTION__ << window() + << "\n from " << geometry_sys() << " frame: " + << margins << " to " <<rect + << " new frame: " << frameGeometry; bool result = false; #ifndef Q_OS_WINCE @@ -1450,8 +1454,8 @@ void QWindowsWindow::setGeometry_sys(const QRect &rect) const result = MoveWindow(m_data.hwnd, frameGeometry.x(), frameGeometry.y(), frameGeometry.width(), frameGeometry.height(), true); } - qCDebug(lcQpaWindows) << '<' << __FUNCTION__ << this << window() - << " \n resulting " << result << geometry_sys(); + qCDebug(lcQpaWindows) << '<' << __FUNCTION__ << window() + << "\n resulting " << result << geometry_sys(); } QRect QWindowsWindow::frameGeometry_sys() const @@ -2135,8 +2139,8 @@ void QWindowsWindow::setCursor(const QWindowsWindowCursor &c) #ifndef QT_NO_CURSOR if (c.handle() != m_cursor.handle()) { const bool apply = applyNewCursor(window()); - qCDebug(lcQpaWindows) <<window() << __FUNCTION__ - << "Shape=" << c.cursor().shape() << " doApply=" << apply; + qCDebug(lcQpaWindows) << window() << __FUNCTION__ + << c.cursor().shape() << " doApply=" << apply; m_cursor = c; if (apply) applyCursor(); 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/gl_integrations/xcb_glx/qglxintegration.cpp b/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp index 2bc9c00a94..397ee22987 100644 --- a/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp +++ b/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp @@ -483,7 +483,7 @@ bool QGLXContext::makeCurrent(QPlatformSurface *surface) success = glXMakeContextCurrent(m_display, glxDrawable, glxDrawable, m_context); } - if (success) { + if (success && surfaceClass == QSurface::Window) { int interval = surface->format().swapInterval(); QXcbScreen *screen = screenForPlatformSurface(surface); if (interval >= 0 && m_swapInterval != interval && screen) { diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp index 706b9c8e48..5d32eb7614 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,17 +295,17 @@ 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; if (has_randr_extension) { xcb_generic_error_t *error = NULL; // RRGetScreenResourcesCurrent is fast but it may return nothing if the @@ -370,9 +372,8 @@ 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; m_screens << screen; @@ -405,8 +406,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 +436,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 +580,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 +672,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 +692,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 +1089,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 +1351,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 9f0395b423..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); 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 376599578f..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, @@ -1515,11 +1516,13 @@ void QXcbKeyboard::handleKeyEvent(xcb_window_t sourceWindow, QEvent::Type type, QString QXcbKeyboard::lookupString(struct xkb_state *state, xcb_keycode_t code) const { - QByteArray chars; - chars.resize(1 + xkb_state_key_get_utf8(state, code, 0, 0)); - // equivalent of XLookupString - xkb_state_key_get_utf8(state, code, chars.data(), chars.size()); - return QString::fromUtf8(chars); + QVarLengthArray<char, 32> chars(32); + const int size = xkb_state_key_get_utf8(state, code, chars.data(), chars.size()); + if (Q_UNLIKELY(size + 1 > chars.size())) { // +1 for NUL + chars.resize(size + 1); + xkb_state_key_get_utf8(state, code, chars.data(), chars.size()); + } + return QString::fromUtf8(chars.constData(), size); } void QXcbKeyboard::handleKeyPressEvent(const xcb_key_press_event_t *event) diff --git a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp index 75ffaa37bb..dfb0a125e2 100644 --- a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp +++ b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp @@ -248,6 +248,9 @@ void *QXcbNativeInterface::nativeResourceForScreen(const QByteArray &resourceStr case NoFontHinting: result = xcbScreen->noFontHinting() ? this : 0; //qboolptr... break; + case RootWindow: + result = reinterpret_cast<void *>(xcbScreen->root()); + break; default: break; } @@ -361,6 +364,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 70b761ecce..fed4adabd3 100644 --- a/src/plugins/platforms/xcb/qxcbscreen.cpp +++ b/src/plugins/platforms/xcb/qxcbscreen.cpp @@ -48,11 +48,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) @@ -60,10 +82,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_pixelDensity(1) @@ -71,7 +92,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); @@ -89,10 +109,6 @@ QXcbScreen::QXcbScreen(QXcbConnection *connection, xcb_screen_t *scr, } const int dpr = int(devicePixelRatio()); - // On VNC, it can be that physical size is unknown while - // virtual size is known (probably back-calculated from DPI and resolution) - if (m_sizeMillimeters.isEmpty()) - m_sizeMillimeters = m_virtualSizeMillimeters; if (m_geometry.isEmpty()) { m_geometry = QRect(QPoint(), m_virtualSize/dpr); m_nativeGeometry = QRect(QPoint(), m_virtualSize); @@ -216,7 +232,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; @@ -334,6 +350,13 @@ QImage::Format QXcbScreen::format() const return QImage::Format_RGB32; } +QDpi QXcbScreen::virtualDpi() const +{ + return QDpi(Q_MM_PER_INCH * m_virtualSize.width() / m_virtualSizeMillimeters.width(), + Q_MM_PER_INCH * m_virtualSize.height() / m_virtualSizeMillimeters.height()); +} + + QDpi QXcbScreen::logicalDpi() const { static const int overrideDpi = qEnvironmentVariableIntValue("QT_FONT_DPI"); @@ -344,8 +367,7 @@ QDpi QXcbScreen::logicalDpi() const 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()); + return virtualDpi(); } @@ -401,7 +423,6 @@ void QXcbScreen::handleScreenChange(xcb_randr_screen_change_notify_event_t *chan return; m_rotation = change_event->rotation; - updateGeometry(change_event->timestamp); switch (m_rotation) { case XCB_RANDR_ROTATION_ROTATE_0: // xrandr --rotate normal m_orientation = Qt::LandscapeOrientation; @@ -437,6 +458,8 @@ void QXcbScreen::handleScreenChange(xcb_randr_screen_change_notify_event_t *chan case XCB_RANDR_ROTATION_REFLECT_Y: break; } + updateGeometry(change_event->timestamp); + QWindowSystemInterface::handleScreenGeometryChange(QPlatformScreen::screen(), geometry(), availableGeometry()); QWindowSystemInterface::handleScreenOrientationChange(QPlatformScreen::screen(), m_orientation); @@ -454,6 +477,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 = @@ -487,6 +513,15 @@ void QXcbScreen::updateGeometry(const QRect &geom, uint8_t rotation) break; } + // It can be that physical size is unknown while virtual size + // is known (probably back-calculated from DPI and resolution), + // e.g. on VNC or with some hardware. + if (m_sizeMillimeters.isEmpty()) { + QDpi dpi = virtualDpi(); + m_sizeMillimeters = QSizeF(Q_MM_PER_INCH * xGeometry.width() / dpi.first, + Q_MM_PER_INCH * xGeometry.width() / dpi.second); + } + xcb_get_property_reply_t * workArea = xcb_get_property_reply(xcb_connection(), xcb_get_property_unchecked(xcb_connection(), false, screen()->root, @@ -527,7 +562,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) { @@ -738,11 +773,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 9187c3330c..d4c7750ce0 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,11 +89,12 @@ 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; } QSizeF physicalVirtualSize() const { return m_virtualSizeMillimeters; } + QDpi virtualDpi() const; QDpi logicalDpi() const Q_DECL_OVERRIDE; qreal devicePixelRatio() const Q_DECL_OVERRIDE; qreal pixelDensity() const Q_DECL_OVERRIDE; @@ -88,10 +109,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; } @@ -132,7 +153,7 @@ private: 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; @@ -149,7 +170,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; @@ -163,7 +183,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 df64261e7a..7798655edc 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -390,7 +390,16 @@ void QXcbWindow::create() 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; @@ -443,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"); @@ -478,35 +492,49 @@ 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); @@ -1699,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); @@ -2597,6 +2632,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; diff --git a/src/plugins/platforms/xcb/qxcbwindow.h b/src/plugins/platforms/xcb/qxcbwindow.h index 4bdc5675db..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; 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); diff --git a/src/plugins/platforms/xcb/qxlibconvenience.cpp b/src/plugins/platforms/xcb/qxlibconvenience.cpp deleted file mode 100644 index f3c7d2b24e..0000000000 --- a/src/plugins/platforms/xcb/qxlibconvenience.cpp +++ /dev/null @@ -1,63 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifdef XCB_USE_XLIB - -#include "qxlibconvenience.h" - -// Some Xlib headers are heavy macro namespace polluters and conflict with Qt types. -// This unit makes it easier to deal with them by encapsulating these includes in this .cpp. -#include <X11/Xutil.h> - -QT_BEGIN_NAMESPACE - -xcb_keysym_t q_XLookupString(void *display, xcb_window_t window, xcb_window_t root, uint state, xcb_keycode_t code, int type, QByteArray *chars) -{ - KeySym sym = 0; - chars->resize(512); - XKeyEvent event; - memset(&event, 0, sizeof(event)); - event.type = type; - event.display = static_cast<Display*>(display); - event.window = window; - event.root = root; - event.state = state; - event.keycode = code; - int count = XLookupString(&event, chars->data(), chars->size(), &sym, 0); - chars->resize(count); - return sym; -} - -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/platforms/xcb/qxlibconvenience.h b/src/plugins/platforms/xcb/qxlibconvenience.h deleted file mode 100644 index 0e6e1c37ec..0000000000 --- a/src/plugins/platforms/xcb/qxlibconvenience.h +++ /dev/null @@ -1,49 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef XLIBUTILS_H -#define XLIBUTILS_H - -#ifdef XCB_USE_XLIB - -#include <xcb/xcb_keysyms.h> -#include <QByteArray> - -QT_BEGIN_NAMESPACE - -xcb_keysym_t q_XLookupString(void *display, xcb_window_t window, xcb_window_t root, uint state, xcb_keycode_t code, int type, QByteArray *chars); - -QT_END_NAMESPACE - -#endif // XCB_USE_XLIB -#endif |