diff options
author | Frederik Gladhorn <frederik.gladhorn@digia.com> | 2013-10-04 00:42:24 +0200 |
---|---|---|
committer | Frederik Gladhorn <frederik.gladhorn@digia.com> | 2013-10-04 00:44:18 +0200 |
commit | d8fc0da235b2bd566b2b6f1e21218afdf2f34eb3 (patch) | |
tree | c0ca819521ed6901a83ab476fa822a886691d806 /src/plugins | |
parent | 3649a6e61d823289d18be19387d7e3923dd90bd0 (diff) | |
parent | cdf0c5905b3477c6cd01c519f883b7bb55447120 (diff) |
Merge remote-tracking branch 'origin/stable' into dev
Conflicts:
src/plugins/platforms/minimal/qminimalintegration.cpp
src/plugins/platforms/offscreen/qoffscreenintegration.cpp
Change-Id: Ica85deeab5c5038ac004718e25194b1157343480
Diffstat (limited to 'src/plugins')
46 files changed, 447 insertions, 178 deletions
diff --git a/src/plugins/platforms/android/src/qandroidplatformintegration.cpp b/src/plugins/platforms/android/src/qandroidplatformintegration.cpp index 358c3caf89..9ce382bd53 100644 --- a/src/plugins/platforms/android/src/qandroidplatformintegration.cpp +++ b/src/plugins/platforms/android/src/qandroidplatformintegration.cpp @@ -100,10 +100,6 @@ QAndroidPlatformIntegration::QAndroidPlatformIntegration(const QStringList ¶ { Q_UNUSED(paramList); -#ifndef ANDROID_PLUGIN_OPENGL - m_eventDispatcher = createUnixEventDispatcher(); -#endif - m_androidPlatformNativeInterface = new QAndroidPlatformNativeInterface(); #ifndef ANDROID_PLUGIN_OPENGL @@ -150,9 +146,9 @@ QPlatformWindow *QAndroidPlatformIntegration::createPlatformWindow(QWindow *wind return new QAndroidPlatformWindow(window); } -QAbstractEventDispatcher *QAndroidPlatformIntegration::guiThreadEventDispatcher() const +QAbstractEventDispatcher *QAndroidPlatformIntegration::createEventDispatcher() const { - return m_eventDispatcher; + return createUnixEventDispatcher(); } #else // !ANDROID_PLUGIN_OPENGL QPlatformWindow *QAndroidPlatformIntegration::createPlatformWindow(QWindow *window) const diff --git a/src/plugins/platforms/android/src/qandroidplatformintegration.h b/src/plugins/platforms/android/src/qandroidplatformintegration.h index e7bb55b3d5..5ebdf9e65c 100644 --- a/src/plugins/platforms/android/src/qandroidplatformintegration.h +++ b/src/plugins/platforms/android/src/qandroidplatformintegration.h @@ -93,7 +93,7 @@ public: #ifndef ANDROID_PLUGIN_OPENGL QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const; QPlatformWindow *createPlatformWindow(QWindow *window) const; - QAbstractEventDispatcher *guiThreadEventDispatcher() const; + QAbstractEventDispatcher *createEventDispatcher() const; QAndroidPlatformScreen *screen() { return m_primaryScreen; } #else QPlatformWindow *createPlatformWindow(QWindow *window) const; @@ -147,7 +147,6 @@ private: QTouchDevice *m_touchDevice; #ifndef ANDROID_PLUGIN_OPENGL - QAbstractEventDispatcher *m_eventDispatcher; QAndroidPlatformScreen *m_primaryScreen; #endif diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.h b/src/plugins/platforms/cocoa/qcocoaintegration.h index 8620ef4267..111329aaee 100644 --- a/src/plugins/platforms/cocoa/qcocoaintegration.h +++ b/src/plugins/platforms/cocoa/qcocoaintegration.h @@ -108,7 +108,7 @@ public: QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const; QPlatformBackingStore *createPlatformBackingStore(QWindow *widget) const; - QAbstractEventDispatcher *guiThreadEventDispatcher() const; + QAbstractEventDispatcher *createEventDispatcher() const; QPlatformFontDatabase *fontDatabase() const; QPlatformNativeInterface *nativeInterface() const; @@ -130,7 +130,6 @@ public: private: QScopedPointer<QPlatformFontDatabase> mFontDb; - QAbstractEventDispatcher *mEventDispatcher; QScopedPointer<QPlatformInputContext> mInputContext; #ifndef QT_NO_ACCESSIBILITY diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm index 365fa92470..8ce72e08b5 100644 --- a/src/plugins/platforms/cocoa/qcocoaintegration.mm +++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm @@ -216,7 +216,6 @@ QPixmap QCocoaScreen::grabWindow(WId window, int x, int y, int width, int height QCocoaIntegration::QCocoaIntegration() : mFontDb(new QCoreTextFontDatabase()) - , mEventDispatcher(new QCocoaEventDispatcher()) , mInputContext(new QCocoaInputContext) #ifndef QT_NO_ACCESSIBILITY , mAccessibility(new QCocoaAccessibility) @@ -384,9 +383,9 @@ QPlatformBackingStore *QCocoaIntegration::createPlatformBackingStore(QWindow *wi return new QCocoaBackingStore(window); } -QAbstractEventDispatcher *QCocoaIntegration::guiThreadEventDispatcher() const +QAbstractEventDispatcher *QCocoaIntegration::createEventDispatcher() const { - return mEventDispatcher; + return new QCocoaEventDispatcher; } QPlatformFontDatabase *QCocoaIntegration::fontDatabase() const diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index 671214f424..54cf8a79fe 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -400,15 +400,17 @@ void QCocoaWindow::setVisible(bool visible) } else { [m_contentView setHidden:YES]; } - if (parentCocoaWindow && window()->type() == Qt::Popup - && m_resizableTransientParent + if (parentCocoaWindow && window()->type() == Qt::Popup) { + parentCocoaWindow->m_activePopupWindow = 0; + if (m_resizableTransientParent #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7 - && QSysInfo::QSysInfo::MacintoshVersion >= QSysInfo::MV_10_7 - && !([parentCocoaWindow->m_nsWindow styleMask] & NSFullScreenWindowMask) + && QSysInfo::QSysInfo::MacintoshVersion >= QSysInfo::MV_10_7 + && !([parentCocoaWindow->m_nsWindow styleMask] & NSFullScreenWindowMask) #endif - ) - // QTBUG-30266: a window should not be resizable while a transient popup is open - [parentCocoaWindow->m_nsWindow setStyleMask:[parentCocoaWindow->m_nsWindow styleMask] | NSResizableWindowMask]; + ) + // QTBUG-30266: a window should not be resizable while a transient popup is open + [parentCocoaWindow->m_nsWindow setStyleMask:[parentCocoaWindow->m_nsWindow styleMask] | NSResizableWindowMask]; + } } } diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index ab098b08bf..8813a934bf 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -1026,20 +1026,21 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent) NSTimeInterval timestamp = [theEvent timestamp]; ulong qt_timestamp = timestamp * 1000; - // Set keyboard modifiers depending on event phase. A two-finger trackpad flick - // generates a stream of scroll events. We want the keyboard modifier state to - // be the state at the beginning of the flick in order to avoid changing the - // interpretation of the events mid-stream. One example of this happening would - // be when pressing cmd after scrolling in Qt Creator: not taking the phase into - // account causes the end of the event stream to be interpreted as font size changes. - #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7 if ([theEvent respondsToSelector:@selector(scrollingDeltaX)]) { - NSEventPhase phase = [theEvent phase]; - if (phase == NSEventPhaseBegan || phase == NSEventPhaseNone) { + // Prevent keyboard modifier state from changing during scroll event streams. + // A two-finger trackpad flick generates a stream of scroll events. We want + // the keyboard modifier state to be the state at the beginning of the + // flick in order to avoid changing the interpretation of the events + // mid-stream. One example of this happening would be when pressing cmd + // after scrolling in Qt Creator: not taking the phase into account causes + // the end of the event stream to be interpreted as font size changes. + NSEventPhase momentumPhase = [theEvent momentumPhase]; + if (momentumPhase == NSEventPhaseNone) { currentWheelModifiers = [QNSView convertKeyModifiers:[theEvent modifierFlags]]; } + NSEventPhase phase = [theEvent phase]; Qt::ScrollPhase ph = Qt::ScrollUpdate; #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_8 if (QSysInfo::QSysInfo::MacintoshVersion >= QSysInfo::MV_10_8) { @@ -1058,7 +1059,7 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent) QWindowSystemInterface::handleWheelEvent(m_window, qt_timestamp, qt_windowPoint, qt_screenPoint, pixelDelta, angleDelta, currentWheelModifiers, ph); - if (phase == NSEventPhaseEnded || phase == NSEventPhaseCancelled || phase == NSEventPhaseNone) { + if (momentumPhase == NSEventPhaseEnded || momentumPhase == NSEventPhaseCancelled || momentumPhase == NSEventPhaseNone) { currentWheelModifiers = Qt::NoModifier; } } else diff --git a/src/plugins/platforms/directfb/qdirectfbintegration.cpp b/src/plugins/platforms/directfb/qdirectfbintegration.cpp index 9e8120a29e..7ca7da8bcd 100644 --- a/src/plugins/platforms/directfb/qdirectfbintegration.cpp +++ b/src/plugins/platforms/directfb/qdirectfbintegration.cpp @@ -61,9 +61,7 @@ QT_BEGIN_NAMESPACE QDirectFbIntegration::QDirectFbIntegration() : m_fontDb(new QGenericUnixFontDatabase()) - , m_eventDispatcher(createUnixEventDispatcher()) { - QGuiApplicationPrivate::instance()->setEventDispatcher(m_eventDispatcher); } void QDirectFbIntegration::initialize() @@ -129,9 +127,9 @@ QPlatformWindow *QDirectFbIntegration::createPlatformWindow(QWindow *window) con return dfbWindow; } -QAbstractEventDispatcher *QDirectFbIntegration::guiThreadEventDispatcher() const +QAbstractEventDispatcher *QDirectFbIntegration::createEventDispatcher() const { - return m_eventDispatcher; + return createUnixEventDispatcher(); } QPlatformBackingStore *QDirectFbIntegration::createPlatformBackingStore(QWindow *window) const diff --git a/src/plugins/platforms/directfb/qdirectfbintegration.h b/src/plugins/platforms/directfb/qdirectfbintegration.h index b96e6d96de..5822202eea 100644 --- a/src/plugins/platforms/directfb/qdirectfbintegration.h +++ b/src/plugins/platforms/directfb/qdirectfbintegration.h @@ -65,7 +65,7 @@ public: QPlatformPixmap *createPlatformPixmap(QPlatformPixmap::PixelType type) const; QPlatformWindow *createPlatformWindow(QWindow *window) const; QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const; - QAbstractEventDispatcher *guiThreadEventDispatcher() const; + QAbstractEventDispatcher *createEventDispatcher() const; QPlatformFontDatabase *fontDatabase() const; @@ -80,7 +80,6 @@ protected: QScopedPointer<QDirectFbInput> m_input; QScopedPointer<QThread> m_inputRunner; QScopedPointer<QPlatformFontDatabase> m_fontDb; - QAbstractEventDispatcher *m_eventDispatcher; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglfs/qeglfsintegration.cpp b/src/plugins/platforms/eglfs/qeglfsintegration.cpp index ff06ac223b..a6d964dcb0 100644 --- a/src/plugins/platforms/eglfs/qeglfsintegration.cpp +++ b/src/plugins/platforms/eglfs/qeglfsintegration.cpp @@ -78,12 +78,9 @@ QT_BEGIN_NAMESPACE static void *eglContextForContext(QOpenGLContext *context); QEglFSIntegration::QEglFSIntegration() - : mEventDispatcher(createUnixEventDispatcher()), - mFontDb(new QGenericUnixFontDatabase), - mServices(new QGenericUnixServices) + : mFontDb(new QGenericUnixFontDatabase) + , mServices(new QGenericUnixServices) { - QGuiApplicationPrivate::instance()->setEventDispatcher(mEventDispatcher); - #if !defined(QT_NO_EVDEV) && (!defined(Q_OS_ANDROID) || defined(Q_OS_ANDROID_NO_SDK)) new QEvdevKeyboardManager(QLatin1String("EvdevKeyboard"), QString() /* spec */, this); new QEvdevMouseManager(QLatin1String("EvdevMouse"), QString() /* spec */, this); @@ -168,9 +165,9 @@ QPlatformFontDatabase *QEglFSIntegration::fontDatabase() const return mFontDb.data(); } -QAbstractEventDispatcher *QEglFSIntegration::guiThreadEventDispatcher() const +QAbstractEventDispatcher *QEglFSIntegration::createEventDispatcher() const { - return mEventDispatcher; + return createUnixEventDispatcher(); } QVariant QEglFSIntegration::styleHint(QPlatformIntegration::StyleHint hint) const diff --git a/src/plugins/platforms/eglfs/qeglfsintegration.h b/src/plugins/platforms/eglfs/qeglfsintegration.h index c6265bb970..4e24e2f2f7 100644 --- a/src/plugins/platforms/eglfs/qeglfsintegration.h +++ b/src/plugins/platforms/eglfs/qeglfsintegration.h @@ -67,7 +67,7 @@ public: QPlatformFontDatabase *fontDatabase() const; QPlatformServices *services() const; - QAbstractEventDispatcher *guiThreadEventDispatcher() const; + QAbstractEventDispatcher *createEventDispatcher() const; QVariant styleHint(QPlatformIntegration::StyleHint hint) const; @@ -87,7 +87,6 @@ public: private: EGLDisplay mDisplay; - QAbstractEventDispatcher *mEventDispatcher; QScopedPointer<QPlatformFontDatabase> mFontDb; QScopedPointer<QPlatformServices> mServices; QEglFSScreen *mScreen; diff --git a/src/plugins/platforms/eglfs/qeglfswindow.cpp b/src/plugins/platforms/eglfs/qeglfswindow.cpp index ac2e7e72fb..17ab68f747 100644 --- a/src/plugins/platforms/eglfs/qeglfswindow.cpp +++ b/src/plugins/platforms/eglfs/qeglfswindow.cpp @@ -114,8 +114,9 @@ void QEglFSWindow::create() } window()->setSurfaceType(QSurface::OpenGLSurface); - setGeometry(screen()->availableGeometry()); - QWindowSystemInterface::handleExposeEvent(window(), QRegion(screen()->availableGeometry())); + m_flags |= HasNativeWindow; + setGeometry(QRect()); // will become fullscreen + QWindowSystemInterface::handleExposeEvent(window(), geometry()); EGLDisplay display = static_cast<QEglFSScreen *>(screen())->display(); QSurfaceFormat platformFormat = QEglFSHooks::hooks()->surfaceFormatFor(window()->requestedFormat()); @@ -124,7 +125,6 @@ void QEglFSWindow::create() resetSurface(); - m_flags |= HasNativeWindow; if (screen()->primarySurface() == EGL_NO_SURFACE) { screen()->setPrimarySurface(m_surface); m_flags |= IsRasterRoot; @@ -212,6 +212,17 @@ void QEglFSWindow::setGeometry(const QRect &r) QWindowSystemInterface::handleGeometryChange(window(), rect); } +QRect QEglFSWindow::geometry() const +{ + // For yet-to-become-fullscreen windows report the geometry covering the entire + // screen. This is particularly important for Quick where the root object may get + // sized to some geometry queried before calling create(). + if (!m_flags.testFlag(Created) && screen()->primarySurface() == EGL_NO_SURFACE) + return screen()->availableGeometry(); + + return QPlatformWindow::geometry(); +} + WId QEglFSWindow::winId() const { return m_wid; diff --git a/src/plugins/platforms/eglfs/qeglfswindow.h b/src/plugins/platforms/eglfs/qeglfswindow.h index a5a25409b2..71c0ed5c27 100644 --- a/src/plugins/platforms/eglfs/qeglfswindow.h +++ b/src/plugins/platforms/eglfs/qeglfswindow.h @@ -58,6 +58,7 @@ public: ~QEglFSWindow(); void setGeometry(const QRect &); + QRect geometry() const; WId winId() const; void setVisible(bool visible); void requestActivateWindow(); diff --git a/src/plugins/platforms/ios/ios.pro b/src/plugins/platforms/ios/ios.pro index 9b53974998..72716e6a4c 100644 --- a/src/plugins/platforms/ios/ios.pro +++ b/src/plugins/platforms/ios/ios.pro @@ -20,7 +20,8 @@ OBJECTIVE_SOURCES = \ qioscontext.mm \ qiosinputcontext.mm \ qiostheme.mm \ - qiosglobal.mm + qiosglobal.mm \ + qiosservices.mm HEADERS = \ qiosintegration.h \ @@ -34,6 +35,7 @@ HEADERS = \ qioscontext.h \ qiosinputcontext.h \ qiostheme.h \ - qiosglobal.h + qiosglobal.h \ + qiosservices.h #HEADERS = qiossoftwareinputhandler.h diff --git a/src/plugins/platforms/ios/qioseventdispatcher.mm b/src/plugins/platforms/ios/qioseventdispatcher.mm index 6148338000..3de7c996f5 100644 --- a/src/plugins/platforms/ios/qioseventdispatcher.mm +++ b/src/plugins/platforms/ios/qioseventdispatcher.mm @@ -148,8 +148,10 @@ namespace // Add memory guard at the end of the reserved stack, so that any stack // overflow during the user's main will trigger an exception at that point, // and not when we return and find that the current stack has been smashed. + // We allow read though, so that garbage-collection can pass through our + // stack in its mark phase without triggering access violations. uintptr_t memoryGuardStart = qAlignUp(memoryStart, kPageSize); - if (mprotect((void*)memoryGuardStart, kPageSize, PROT_NONE)) + if (mprotect((void*)memoryGuardStart, kPageSize, PROT_READ)) qWarning() << "Failed to add memory guard:" << strerror(errno); // We don't consider the memory guard part of the usable stack space diff --git a/src/plugins/platforms/ios/qiosintegration.h b/src/plugins/platforms/ios/qiosintegration.h index 4aaf98f839..c655d8d3bf 100644 --- a/src/plugins/platforms/ios/qiosintegration.h +++ b/src/plugins/platforms/ios/qiosintegration.h @@ -50,10 +50,13 @@ QT_BEGIN_NAMESPACE +class QIOSServices; + class QIOSIntegration : public QPlatformIntegration, public QPlatformNativeInterface { public: QIOSIntegration(); + ~QIOSIntegration(); bool hasCapability(Capability cap) const; @@ -64,13 +67,14 @@ public: QPlatformFontDatabase *fontDatabase() const; QPlatformInputContext *inputContext() const; + QPlatformServices *services() const Q_DECL_OVERRIDE; QVariant styleHint(StyleHint hint) const; QStringList themeNames() const; QPlatformTheme *createPlatformTheme(const QString &name) const; - QAbstractEventDispatcher *guiThreadEventDispatcher() const; + QAbstractEventDispatcher *createEventDispatcher() const; QPlatformNativeInterface *nativeInterface() const; void *nativeResourceForWindow(const QByteArray &resource, QWindow *window); @@ -82,6 +86,7 @@ private: QPlatformScreen *m_screen; QTouchDevice *m_touchDevice; QIOSApplicationState m_applicationState; + QIOSServices *m_platformServices; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qiosintegration.mm b/src/plugins/platforms/ios/qiosintegration.mm index d854bf7723..b9bb82a326 100644 --- a/src/plugins/platforms/ios/qiosintegration.mm +++ b/src/plugins/platforms/ios/qiosintegration.mm @@ -48,6 +48,7 @@ #include "qioscontext.h" #include "qiosinputcontext.h" #include "qiostheme.h" +#include "qiosservices.h" #include <QtPlatformSupport/private/qcoretextfontdatabase_p.h> #include <QDir> @@ -60,6 +61,7 @@ QIOSIntegration::QIOSIntegration() : m_fontDatabase(new QCoreTextFontDatabase) , m_inputContext(new QIOSInputContext) , m_screen(new QIOSScreen(QIOSScreen::MainScreen)) + , m_platformServices(new QIOSServices) { if (![UIApplication sharedApplication]) { qWarning() @@ -81,6 +83,21 @@ QIOSIntegration::QIOSIntegration() QWindowSystemInterface::registerTouchDevice(m_touchDevice); } +QIOSIntegration::~QIOSIntegration() +{ + delete m_fontDatabase; + m_fontDatabase = 0; + + delete m_inputContext; + m_inputContext = 0; + + delete m_screen; + m_screen = 0; + + delete m_platformServices; + m_platformServices = 0; +} + bool QIOSIntegration::hasCapability(Capability cap) const { switch (cap) { @@ -113,7 +130,7 @@ QPlatformOpenGLContext *QIOSIntegration::createPlatformOpenGLContext(QOpenGLCont return new QIOSContext(context); } -QAbstractEventDispatcher *QIOSIntegration::guiThreadEventDispatcher() const +QAbstractEventDispatcher *QIOSIntegration::createEventDispatcher() const { if (isQtApplication()) return new QIOSEventDispatcher; @@ -131,6 +148,11 @@ QPlatformInputContext *QIOSIntegration::inputContext() const return m_inputContext; } +QPlatformServices *QIOSIntegration::services() const +{ + return m_platformServices; +} + QVariant QIOSIntegration::styleHint(StyleHint hint) const { switch (hint) { diff --git a/src/plugins/platforms/ios/qiosservices.h b/src/plugins/platforms/ios/qiosservices.h new file mode 100644 index 0000000000..692b3a0b99 --- /dev/null +++ b/src/plugins/platforms/ios/qiosservices.h @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** 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 Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/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 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QIOSSERVICES_H +#define QIOSSERVICES_H +#include <qpa/qplatformservices.h> + +QT_BEGIN_NAMESPACE + +class QIOSServices : public QPlatformServices +{ +public: + bool openUrl(const QUrl &url); + bool openDocument(const QUrl &url); +}; + +QT_END_NAMESPACE + +#endif // QIOSSERVICES_H diff --git a/src/plugins/platforms/ios/qiosservices.mm b/src/plugins/platforms/ios/qiosservices.mm new file mode 100644 index 0000000000..32203aeb71 --- /dev/null +++ b/src/plugins/platforms/ios/qiosservices.mm @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** 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 Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/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 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qiosservices.h" + +#include <QtCore/qurl.h> + +#import <UIKit/UIApplication.h> + +QT_BEGIN_NAMESPACE + +bool QIOSServices::openUrl(const QUrl &url) +{ + if (url.scheme().isEmpty()) + return openDocument(url); + + NSURL *nsUrl = url.toNSURL(); + + if (![[UIApplication sharedApplication] canOpenURL:nsUrl]) + return false; + + return [[UIApplication sharedApplication] openURL:nsUrl]; +} + +bool QIOSServices::openDocument(const QUrl &url) +{ + // FIXME: Implement using UIDocumentInteractionController + return QPlatformServices::openDocument(url); +} + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/kms/qkmsintegration.cpp b/src/plugins/platforms/kms/qkmsintegration.cpp index 539363722d..80c5887a28 100644 --- a/src/plugins/platforms/kms/qkmsintegration.cpp +++ b/src/plugins/platforms/kms/qkmsintegration.cpp @@ -65,10 +65,8 @@ QT_BEGIN_NAMESPACE QKmsIntegration::QKmsIntegration() : QPlatformIntegration(), m_fontDatabase(new QGenericUnixFontDatabase()), - m_eventDispatcher(createUnixEventDispatcher()), m_nativeInterface(new QKmsNativeInterface) { - QGuiApplicationPrivate::instance()->setEventDispatcher(m_eventDispatcher); setenv("EGL_PLATFORM", "drm",1); m_vtHandler = new QKmsVTHandler; @@ -152,9 +150,9 @@ void QKmsIntegration::addScreen(QKmsScreen *screen) screenAdded(screen); } -QAbstractEventDispatcher *QKmsIntegration::guiThreadEventDispatcher() const +QAbstractEventDispatcher *QKmsIntegration::createEventDispatcher() const { - return m_eventDispatcher; + return createUnixEventDispatcher(); } QPlatformNativeInterface *QKmsIntegration::nativeInterface() const diff --git a/src/plugins/platforms/kms/qkmsintegration.h b/src/plugins/platforms/kms/qkmsintegration.h index 5069753aa5..0a626e6bd2 100644 --- a/src/plugins/platforms/kms/qkmsintegration.h +++ b/src/plugins/platforms/kms/qkmsintegration.h @@ -67,7 +67,7 @@ public: QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const; QPlatformFontDatabase *fontDatabase() const; - QAbstractEventDispatcher *guiThreadEventDispatcher() const; + QAbstractEventDispatcher *createEventDispatcher() const; QPlatformNativeInterface *nativeInterface() const; @@ -84,7 +84,6 @@ private: QList<QPlatformScreen *> m_screens; QList<QKmsDevice *> m_devices; QPlatformFontDatabase *m_fontDatabase; - QAbstractEventDispatcher *m_eventDispatcher; QPlatformNativeInterface *m_nativeInterface; QKmsVTHandler *m_vtHandler; QDeviceDiscovery *m_deviceDiscovery; diff --git a/src/plugins/platforms/linuxfb/qlinuxfbintegration.cpp b/src/plugins/platforms/linuxfb/qlinuxfbintegration.cpp index 99914fa36d..aa2687da30 100644 --- a/src/plugins/platforms/linuxfb/qlinuxfbintegration.cpp +++ b/src/plugins/platforms/linuxfb/qlinuxfbintegration.cpp @@ -54,11 +54,8 @@ QT_BEGIN_NAMESPACE QLinuxFbIntegration::QLinuxFbIntegration(const QStringList ¶mList) - : m_fontDb(new QGenericUnixFontDatabase()), - m_eventDispatcher(createUnixEventDispatcher()) + : m_fontDb(new QGenericUnixFontDatabase()) { - QGuiApplicationPrivate::instance()->setEventDispatcher(m_eventDispatcher); - m_primaryScreen = new QLinuxFbScreen; if (m_primaryScreen->initialize(paramList)) screenAdded(m_primaryScreen); @@ -92,9 +89,9 @@ QPlatformWindow *QLinuxFbIntegration::createPlatformWindow(QWindow *window) cons return new QFbWindow(window); } -QAbstractEventDispatcher *QLinuxFbIntegration::guiThreadEventDispatcher() const +QAbstractEventDispatcher *QLinuxFbIntegration::createEventDispatcher() const { - return m_eventDispatcher; + return createUnixEventDispatcher(); } QList<QPlatformScreen *> QLinuxFbIntegration::screens() const diff --git a/src/plugins/platforms/linuxfb/qlinuxfbintegration.h b/src/plugins/platforms/linuxfb/qlinuxfbintegration.h index 1d91d364ff..6de9ac9992 100644 --- a/src/plugins/platforms/linuxfb/qlinuxfbintegration.h +++ b/src/plugins/platforms/linuxfb/qlinuxfbintegration.h @@ -61,14 +61,13 @@ public: QPlatformPixmap *createPlatformPixmap(QPlatformPixmap::PixelType type) const; QPlatformWindow *createPlatformWindow(QWindow *window) const; QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const; - QAbstractEventDispatcher *guiThreadEventDispatcher() const; + QAbstractEventDispatcher *createEventDispatcher() const; QList<QPlatformScreen *> screens() const; QPlatformFontDatabase *fontDatabase() const; private: QLinuxFbScreen *m_primaryScreen; QPlatformFontDatabase *m_fontDb; - QAbstractEventDispatcher *m_eventDispatcher; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/minimal/qminimalintegration.cpp b/src/plugins/platforms/minimal/qminimalintegration.cpp index 29bd223f3f..bb2c5f53c3 100644 --- a/src/plugins/platforms/minimal/qminimalintegration.cpp +++ b/src/plugins/platforms/minimal/qminimalintegration.cpp @@ -56,16 +56,8 @@ QT_BEGIN_NAMESPACE -QMinimalIntegration::QMinimalIntegration() : -#if defined(Q_OS_WINRT) - m_eventDispatcher(new QEventDispatcherWinRT()) -#elif defined(Q_OS_WIN) - m_eventDispatcher(new QEventDispatcherWin32()) -#else - m_eventDispatcher(createUnixEventDispatcher()) -#endif +QMinimalIntegration::QMinimalIntegration() { - QGuiApplicationPrivate::instance()->setEventDispatcher(m_eventDispatcher); QMinimalScreen *mPrimaryScreen = new QMinimalScreen(); mPrimaryScreen->mGeometry = QRect(0, 0, 240, 320); @@ -97,9 +89,17 @@ QPlatformBackingStore *QMinimalIntegration::createPlatformBackingStore(QWindow * return new QMinimalBackingStore(window); } -QAbstractEventDispatcher *QMinimalIntegration::guiThreadEventDispatcher() const +QAbstractEventDispatcher *QMinimalIntegration::createEventDispatcher() const { - return m_eventDispatcher; +#ifdef Q_OS_WIN +#ifndef Q_OS_WINRT + return new QEventDispatcherWin32; +#else // !Q_OS_WINRT + return new QEventDispatcherWinRT; +#endif // Q_OS_WINRT +#else + return createUnixEventDispatcher(); +#endif } QT_END_NAMESPACE diff --git a/src/plugins/platforms/minimal/qminimalintegration.h b/src/plugins/platforms/minimal/qminimalintegration.h index ef39e32fa7..7dc01e1d51 100644 --- a/src/plugins/platforms/minimal/qminimalintegration.h +++ b/src/plugins/platforms/minimal/qminimalintegration.h @@ -73,10 +73,7 @@ public: QPlatformWindow *createPlatformWindow(QWindow *window) const; QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const; - QAbstractEventDispatcher *guiThreadEventDispatcher() const; - -private: - QAbstractEventDispatcher *m_eventDispatcher; + QAbstractEventDispatcher *createEventDispatcher() const; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/minimalegl/qminimaleglintegration.cpp b/src/plugins/platforms/minimalegl/qminimaleglintegration.cpp index 4a1ac0f307..21c23250e4 100644 --- a/src/plugins/platforms/minimalegl/qminimaleglintegration.cpp +++ b/src/plugins/platforms/minimalegl/qminimaleglintegration.cpp @@ -110,7 +110,7 @@ QPlatformFontDatabase *QMinimalEglIntegration::fontDatabase() const return mFontDb; } -QAbstractEventDispatcher *QMinimalEglIntegration::guiThreadEventDispatcher() const +QAbstractEventDispatcher *QMinimalEglIntegration::createEventDispatcher() const { return createUnixEventDispatcher(); } diff --git a/src/plugins/platforms/minimalegl/qminimaleglintegration.h b/src/plugins/platforms/minimalegl/qminimaleglintegration.h index dba7504033..58b8f28ac9 100644 --- a/src/plugins/platforms/minimalegl/qminimaleglintegration.h +++ b/src/plugins/platforms/minimalegl/qminimaleglintegration.h @@ -63,7 +63,7 @@ public: QPlatformFontDatabase *fontDatabase() const; - QAbstractEventDispatcher *guiThreadEventDispatcher() const; + QAbstractEventDispatcher *createEventDispatcher() const; QVariant styleHint(QPlatformIntegration::StyleHint hint) const; diff --git a/src/plugins/platforms/offscreen/qoffscreenintegration.cpp b/src/plugins/platforms/offscreen/qoffscreenintegration.cpp index aafa90c0fd..76881db6fc 100644 --- a/src/plugins/platforms/offscreen/qoffscreenintegration.cpp +++ b/src/plugins/platforms/offscreen/qoffscreenintegration.cpp @@ -99,18 +99,12 @@ public: QOffscreenIntegration::QOffscreenIntegration() { #if defined(Q_OS_UNIX) - m_eventDispatcher = createUnixEventDispatcher(); #if defined(Q_OS_MAC) m_fontDatabase.reset(new QPlatformFontDatabase()); #else m_fontDatabase.reset(new QGenericUnixFontDatabase()); #endif #elif defined(Q_OS_WIN) -#ifndef Q_OS_WINRT - m_eventDispatcher = new QOffscreenEventDispatcher<QEventDispatcherWin32>(); -#else - m_eventDispatcher = new QOffscreenEventDispatcher<QEventDispatcherWinRT>(); -#endif m_fontDatabase.reset(new QBasicFontDatabase()); #endif @@ -119,7 +113,6 @@ QOffscreenIntegration::QOffscreenIntegration() #endif m_services.reset(new QPlatformServices); - QGuiApplicationPrivate::instance()->setEventDispatcher(m_eventDispatcher); screenAdded(new QOffscreenScreen); } @@ -149,9 +142,19 @@ QPlatformBackingStore *QOffscreenIntegration::createPlatformBackingStore(QWindow return new QOffscreenBackingStore(window); } -QAbstractEventDispatcher *QOffscreenIntegration::guiThreadEventDispatcher() const +QAbstractEventDispatcher *QOffscreenIntegration::createEventDispatcher() const { - return m_eventDispatcher; +#if defined(Q_OS_UNIX) + return createUnixEventDispatcher(); +#elif defined(Q_OS_WIN) +#ifndef Q_OS_WINRT + return new QOffscreenEventDispatcher<QEventDispatcherWin32>(); +#else // !Q_OS_WINRT + return new QOffscreenEventDispatcher<QEventDispatcherWinRT>(); +#endif // Q_OS_WINRT +#else + return 0; +#endif } QPlatformFontDatabase *QOffscreenIntegration::fontDatabase() const diff --git a/src/plugins/platforms/offscreen/qoffscreenintegration.h b/src/plugins/platforms/offscreen/qoffscreenintegration.h index b403ce83b3..c7cdb5fdd6 100644 --- a/src/plugins/platforms/offscreen/qoffscreenintegration.h +++ b/src/plugins/platforms/offscreen/qoffscreenintegration.h @@ -66,12 +66,11 @@ public: QPlatformServices *services() const; QPlatformFontDatabase *fontDatabase() const; - QAbstractEventDispatcher *guiThreadEventDispatcher() const; + QAbstractEventDispatcher *createEventDispatcher() const; static QOffscreenIntegration *createOffscreenIntegration(); private: - QAbstractEventDispatcher *m_eventDispatcher; QScopedPointer<QPlatformFontDatabase> m_fontDatabase; #ifndef QT_NO_DRAGANDDROP QScopedPointer<QPlatformDrag> m_drag; diff --git a/src/plugins/platforms/openwfd/qopenwfdintegration.cpp b/src/plugins/platforms/openwfd/qopenwfdintegration.cpp index aeea035a3a..382ce82dc9 100644 --- a/src/plugins/platforms/openwfd/qopenwfdintegration.cpp +++ b/src/plugins/platforms/openwfd/qopenwfdintegration.cpp @@ -63,9 +63,7 @@ QOpenWFDIntegration::QOpenWFDIntegration() : QPlatformIntegration() , mPrinterSupport(new QGenericUnixPrinterSupport) - , mEventDispatcher(createUnixEventDispatcher()) { - QGuiApplicationPrivate::instance()->setEventDispatcher(mEventDispatcher); int numberOfDevices = wfdEnumerateDevices(0,0,0); WFDint devices[numberOfDevices]; @@ -119,9 +117,9 @@ QPlatformBackingStore *QOpenWFDIntegration::createPlatformBackingStore(QWindow * return new QOpenWFDBackingStore(window); } -QAbstractEventDispatcher *QOpenWFDIntegration::guiThreadEventDispatcher() const +QAbstractEventDispatcher *QOpenWFDIntegration::createEventDispatcher() const { - return mEventDispatcher; + return createUnixEventDispatcher(); } QPlatformFontDatabase *QOpenWFDIntegration::fontDatabase() const diff --git a/src/plugins/platforms/openwfd/qopenwfdintegration.h b/src/plugins/platforms/openwfd/qopenwfdintegration.h index 7118933841..9af91deeac 100644 --- a/src/plugins/platforms/openwfd/qopenwfdintegration.h +++ b/src/plugins/platforms/openwfd/qopenwfdintegration.h @@ -62,7 +62,7 @@ public: QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const; //This should not be a factory interface, but rather a accessor - QAbstractEventDispatcher *guiThreadEventDispatcher() const; + QAbstractEventDispatcher *createEventDispatcher() const; QPlatformFontDatabase *fontDatabase() const; @@ -78,7 +78,6 @@ private: QPlatformFontDatabase *mFontDatabase; QPlatformNativeInterface *mNativeInterface; QPlatformPrinterSupport *mPrinterSupport; - QAbstractEventDispatcher *mEventDispatcher; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/qnx/qqnxintegration.cpp b/src/plugins/platforms/qnx/qqnxintegration.cpp index bd627fef0b..36a2194b56 100644 --- a/src/plugins/platforms/qnx/qqnxintegration.cpp +++ b/src/plugins/platforms/qnx/qqnxintegration.cpp @@ -294,6 +294,9 @@ QQnxIntegration::~QQnxIntegration() delete m_bpsEventFilter; #endif + // In case the event-dispatcher was never transferred to QCoreApplication + delete m_eventDispatcher; + delete m_screenEventHandler; // Destroy all displays @@ -386,10 +389,15 @@ void QQnxIntegration::moveToScreen(QWindow *window, int screen) platformWindow->setScreen(platformScreen); } -QAbstractEventDispatcher *QQnxIntegration::guiThreadEventDispatcher() const +QAbstractEventDispatcher *QQnxIntegration::createEventDispatcher() const { qIntegrationDebug() << Q_FUNC_INFO; - return m_eventDispatcher; + + // We transfer ownersip of the event-dispatcher to QtCoreApplication + QAbstractEventDispatcher *eventDispatcher = m_eventDispatcher; + m_eventDispatcher = 0; + + return eventDispatcher; } QPlatformNativeInterface *QQnxIntegration::nativeInterface() const diff --git a/src/plugins/platforms/qnx/qqnxintegration.h b/src/plugins/platforms/qnx/qqnxintegration.h index dd8973b767..ab0d6a3156 100644 --- a/src/plugins/platforms/qnx/qqnxintegration.h +++ b/src/plugins/platforms/qnx/qqnxintegration.h @@ -107,7 +107,7 @@ public: bool supportsNavigatorEvents() const; - QAbstractEventDispatcher *guiThreadEventDispatcher() const; + QAbstractEventDispatcher *createEventDispatcher() const; QPlatformFontDatabase *fontDatabase() const { return m_fontDatabase; } @@ -158,7 +158,7 @@ private: #endif QQnxServices *m_services; QPlatformFontDatabase *m_fontDatabase; - QAbstractEventDispatcher *m_eventDispatcher; + mutable QAbstractEventDispatcher *m_eventDispatcher; #if defined(Q_OS_BLACKBERRY) QQnxBpsEventFilter *m_bpsEventFilter; #endif diff --git a/src/plugins/platforms/windows/accessible/iaccessible2.h b/src/plugins/platforms/windows/accessible/iaccessible2.h index a391d495f9..9c922dce36 100644 --- a/src/plugins/platforms/windows/accessible/iaccessible2.h +++ b/src/plugins/platforms/windows/accessible/iaccessible2.h @@ -331,9 +331,21 @@ private: { wchar_t *constRelationString = 0; switch (relation) { + case QAccessible::Label: + constRelationString = IA2_RELATION_LABEL_FOR; + break; + case QAccessible::Labelled: + constRelationString = IA2_RELATION_LABELLED_BY; + break; + case QAccessible::Controller: + constRelationString = IA2_RELATION_CONTROLLER_FOR; + break; case QAccessible::Controlled: constRelationString = IA2_RELATION_CONTROLLED_BY; break; + case QAccessible::AllRelations: + constRelationString = ( L"AllRelations" ); + break; } if (constRelationString) { diff --git a/src/plugins/platforms/windows/qwindowsclipboard.cpp b/src/plugins/platforms/windows/qwindowsclipboard.cpp index cf6cb199c7..51e0d0e803 100644 --- a/src/plugins/platforms/windows/qwindowsclipboard.cpp +++ b/src/plugins/platforms/windows/qwindowsclipboard.cpp @@ -203,13 +203,12 @@ void QWindowsClipboard::propagateClipboardMessage(UINT message, WPARAM wParam, L qWarning("%s: Cowardly refusing to send clipboard message to hung application...", Q_FUNC_INFO); return; } - // Also refuse if the process is being debugged, specifically, if it is + // Do not block if the process is being debugged, specifically, if it is // displaying a runtime assert, which is not caught by isHungAppWindow(). - if (isProcessBeingDebugged(m_nextClipboardViewer)) { - qWarning("%s: Cowardly refusing to send clipboard message to application under debugger...", Q_FUNC_INFO); - return; - } - SendMessage(m_nextClipboardViewer, message, wParam, lParam); + if (isProcessBeingDebugged(m_nextClipboardViewer)) + PostMessage(m_nextClipboardViewer, message, wParam, lParam); + else + SendMessage(m_nextClipboardViewer, message, wParam, lParam); } /*! diff --git a/src/plugins/platforms/windows/qwindowscursor.cpp b/src/plugins/platforms/windows/qwindowscursor.cpp index 5b2a3acbae..5e7944a4cf 100644 --- a/src/plugins/platforms/windows/qwindowscursor.cpp +++ b/src/plugins/platforms/windows/qwindowscursor.cpp @@ -45,7 +45,7 @@ #include "qwindowswindow.h" #include "qwindowsscreen.h" -#include <QtGui/QPixmap> +#include <QtGui/QBitmap> #include <QtGui/QImage> #include <QtGui/QBitmap> #include <QtGui/QGuiApplication> @@ -61,6 +61,30 @@ Q_GUI_EXPORT HBITMAP qt_pixmapToWinHBITMAP(const QPixmap &p, int hbitmapFormat = Q_GUI_EXPORT HBITMAP qt_createIconMask(const QBitmap &bitmap); /*! + \class QWindowsCursorCacheKey + \brief Cache key for storing values in a QHash with a QCursor as key. + + \internal + \ingroup qt-lighthouse-win +*/ + +QWindowsCursorCacheKey::QWindowsCursorCacheKey(const QCursor &c) + : shape(c.shape()), bitmapCacheKey(0), maskCacheKey(0) +{ + if (shape == Qt::BitmapCursor) { + const qint64 pixmapCacheKey = c.pixmap().cacheKey(); + if (pixmapCacheKey) { + bitmapCacheKey = pixmapCacheKey; + } else { + Q_ASSERT(c.bitmap()); + Q_ASSERT(c.mask()); + bitmapCacheKey = c.bitmap()->cacheKey(); + maskCacheKey = c.mask()->cacheKey(); + } + } +} + +/*! \class QWindowsCursor \brief Platform cursor implementation @@ -388,9 +412,10 @@ HCURSOR QWindowsCursor::createSystemCursor(const QCursor &c) QWindowsWindowCursor QWindowsCursor::standardWindowCursor(Qt::CursorShape shape) { - StandardCursorCache::iterator it = m_standardCursorCache.find(shape); - if (it == m_standardCursorCache.end()) - it = m_standardCursorCache.insert(shape, QWindowsWindowCursor(QCursor(shape))); + const QWindowsCursorCacheKey key(shape); + CursorCache::iterator it = m_cursorCache.find(key); + if (it == m_cursorCache.end()) + it = m_cursorCache.insert(key, QWindowsWindowCursor(QCursor(shape))); return it.value(); } @@ -400,10 +425,10 @@ QWindowsWindowCursor QWindowsCursor::standardWindowCursor(Qt::CursorShape shape) QWindowsWindowCursor QWindowsCursor::pixmapWindowCursor(const QCursor &c) { - const qint64 cacheKey = c.pixmap().cacheKey(); - PixmapCursorCache::iterator it = m_pixmapCursorCache.find(cacheKey); - if (it == m_pixmapCursorCache.end()) - it = m_pixmapCursorCache.insert(cacheKey, QWindowsWindowCursor(c)); + const QWindowsCursorCacheKey cacheKey(c); + CursorCache::iterator it = m_cursorCache.find(cacheKey); + if (it == m_cursorCache.end()) + it = m_cursorCache.insert(cacheKey, QWindowsWindowCursor(c)); return it.value(); } diff --git a/src/plugins/platforms/windows/qwindowscursor.h b/src/plugins/platforms/windows/qwindowscursor.h index 1e818bc9b8..b366d9a06a 100644 --- a/src/plugins/platforms/windows/qwindowscursor.h +++ b/src/plugins/platforms/windows/qwindowscursor.h @@ -52,6 +52,27 @@ QT_BEGIN_NAMESPACE class QWindowsWindowCursorData; +struct QWindowsCursorCacheKey +{ + explicit QWindowsCursorCacheKey(const QCursor &c); + explicit QWindowsCursorCacheKey(Qt::CursorShape s) : shape(s), bitmapCacheKey(0), maskCacheKey(0) {} + QWindowsCursorCacheKey() : shape(Qt::CustomCursor), bitmapCacheKey(0), maskCacheKey(0) {} + + Qt::CursorShape shape; + qint64 bitmapCacheKey; + qint64 maskCacheKey; +}; + +inline bool operator==(const QWindowsCursorCacheKey &k1, const QWindowsCursorCacheKey &k2) +{ + return k1.shape == k2.shape && k1.bitmapCacheKey == k2.bitmapCacheKey && k1.maskCacheKey == k2.maskCacheKey; +} + +inline uint qHash(const QWindowsCursorCacheKey &k, uint seed) Q_DECL_NOTHROW +{ + return (uint(k.shape) + uint(k.bitmapCacheKey) + uint(k.maskCacheKey)) ^ seed; +} + class QWindowsWindowCursor { public: @@ -86,11 +107,9 @@ public: QWindowsWindowCursor pixmapWindowCursor(const QCursor &c); private: - typedef QHash<Qt::CursorShape, QWindowsWindowCursor> StandardCursorCache; - typedef QHash<qint64, QWindowsWindowCursor> PixmapCursorCache; + typedef QHash<QWindowsCursorCacheKey, QWindowsWindowCursor> CursorCache; - StandardCursorCache m_standardCursorCache; - PixmapCursorCache m_pixmapCursorCache; + CursorCache m_cursorCache; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/windows/qwindowsintegration.cpp b/src/plugins/platforms/windows/qwindowsintegration.cpp index d7ac4cfc1e..b6e75929f8 100644 --- a/src/plugins/platforms/windows/qwindowsintegration.cpp +++ b/src/plugins/platforms/windows/qwindowsintegration.cpp @@ -315,7 +315,6 @@ struct QWindowsIntegrationPrivate QWindowsDrag m_drag; # endif #endif - QWindowsGuiEventDispatcher *m_eventDispatcher; #if defined(QT_OPENGL_ES_2) QEGLStaticContextPtr m_staticEGLContext; #elif !defined(QT_NO_OPENGL) @@ -356,7 +355,6 @@ static inline unsigned parseOptions(const QStringList ¶mList) QWindowsIntegrationPrivate::QWindowsIntegrationPrivate(const QStringList ¶mList) : m_options(parseOptions(paramList)) , m_fontDatabase(0) - , m_eventDispatcher(new QWindowsGuiEventDispatcher) { } @@ -369,7 +367,6 @@ QWindowsIntegrationPrivate::~QWindowsIntegrationPrivate() QWindowsIntegration::QWindowsIntegration(const QStringList ¶mList) : d(new QWindowsIntegrationPrivate(paramList)) { - QGuiApplicationPrivate::instance()->setEventDispatcher(d->m_eventDispatcher); #ifndef QT_NO_CLIPBOARD d->m_clipboard.registerViewer(); #endif @@ -635,9 +632,9 @@ QPlatformSessionManager *QWindowsIntegration::createPlatformSessionManager(const } #endif -QAbstractEventDispatcher * QWindowsIntegration::guiThreadEventDispatcher() const +QAbstractEventDispatcher * QWindowsIntegration::createEventDispatcher() const { - return d->m_eventDispatcher; + return new QWindowsGuiEventDispatcher; } QStringList QWindowsIntegration::themeNames() const diff --git a/src/plugins/platforms/windows/qwindowsintegration.h b/src/plugins/platforms/windows/qwindowsintegration.h index 6643b1642e..97916a479b 100644 --- a/src/plugins/platforms/windows/qwindowsintegration.h +++ b/src/plugins/platforms/windows/qwindowsintegration.h @@ -74,7 +74,7 @@ public: #ifndef QT_NO_OPENGL virtual QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const; #endif - virtual QAbstractEventDispatcher *guiThreadEventDispatcher() const; + virtual QAbstractEventDispatcher *createEventDispatcher() const; #ifndef QT_NO_CLIPBOARD virtual QPlatformClipboard *clipboard() const; # ifndef QT_NO_DRAGANDDROP diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index 7077eaf4b0..be739d0551 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -1260,11 +1260,11 @@ void QWindowsWindow::setGeometry(const QRect &rectIn) const QWindowsGeometryHint hint(window(), m_data.customMargins); if (!hint.validSize(newSize)) { qWarning("%s: Attempt to set a size (%dx%d) violating the constraints" - "(%dx%d - %dx%d) on window '%s'.", __FUNCTION__, + "(%dx%d - %dx%d) on window %s/'%s'.", __FUNCTION__, newSize.width(), newSize.height(), hint.minimumSize.width(), hint.minimumSize.height(), hint.maximumSize.width(), hint.maximumSize.height(), - qPrintable(window()->objectName())); + window()->metaObject()->className(), qPrintable(window()->objectName())); } } if (m_data.hwnd) { @@ -1273,13 +1273,13 @@ void QWindowsWindow::setGeometry(const QRect &rectIn) // notify and warn. setGeometry_sys(rect); if (m_data.geometry != rect) { - qWarning("%s: Unable to set geometry %dx%d+%d+%d on '%s'." + qWarning("%s: Unable to set geometry %dx%d+%d+%d on %s/'%s'." " Resulting geometry: %dx%d+%d+%d " "(frame: %d, %d, %d, %d, custom margin: %d, %d, %d, %d" ", minimum size: %dx%d, maximum size: %dx%d).", __FUNCTION__, rect.width(), rect.height(), rect.x(), rect.y(), - qPrintable(window()->objectName()), + window()->metaObject()->className(), qPrintable(window()->objectName()), m_data.geometry.width(), m_data.geometry.height(), m_data.geometry.x(), m_data.geometry.y(), m_data.frame.left(), m_data.frame.top(), @@ -1838,8 +1838,9 @@ bool QWindowsWindow::setMouseGrabEnabled(bool grab) return false; } if (!isVisible() && grab) { - qWarning("%s: Not setting mouse grab for invisible window %s", - __FUNCTION__, qPrintable(window()->objectName())); + qWarning("%s: Not setting mouse grab for invisible window %s/'%s'", + __FUNCTION__, window()->metaObject()->className(), + qPrintable(window()->objectName())); return false; } // release grab or an explicit grab overriding autocapture: Clear flag. @@ -2091,8 +2092,10 @@ EGLSurface QWindowsWindow::ensureEglSurfaceHandle(const QWindowsWindow::QWindows m_staticEglContext = staticContext; m_eglSurface = eglCreateWindowSurface(staticContext->display(), config, (EGLNativeWindowType)m_data.hwnd, NULL); if (m_eglSurface == EGL_NO_SURFACE) - qWarning("%s: Could not create the egl surface (eglCreateWindowSurface failed): error = 0x%x\n", - Q_FUNC_INFO, eglGetError()); + qWarning("%s: Could not create the egl surface for %s/'%s' (eglCreateWindowSurface failed): error = 0x%x\n", + Q_FUNC_INFO, window()->metaObject()->className(), + qPrintable(window()->objectName()), eglGetError()); + if (QWindowsContext::verboseGL) qDebug("%s: Created EGL surface %p, this = %p", __FUNCTION__, m_eglSurface, this); diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp index d6f64d29fd..433758e065 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection.cpp @@ -290,16 +290,7 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGra qFatal("QXcbConnection: Could not connect to display %s", m_displayName.constData()); m_reader = new QXcbEventReader(this); - connect(m_reader, SIGNAL(eventPending()), this, SLOT(processXcbEvents()), Qt::QueuedConnection); - connect(m_reader, SIGNAL(finished()), this, SLOT(processXcbEvents())); - if (!m_reader->startThread()) { - QSocketNotifier *notifier = new QSocketNotifier(xcb_get_file_descriptor(xcb_connection()), QSocketNotifier::Read, this); - connect(notifier, SIGNAL(activated(int)), this, SLOT(processXcbEvents())); - - QAbstractEventDispatcher *dispatcher = QGuiApplicationPrivate::eventDispatcher; - connect(dispatcher, SIGNAL(aboutToBlock()), this, SLOT(processXcbEvents())); - connect(dispatcher, SIGNAL(awake()), this, SLOT(processXcbEvents())); - } + m_reader->start(); xcb_extension_t *extensions[] = { &xcb_shm_id, &xcb_xfixes_id, &xcb_randr_id, &xcb_shape_id, &xcb_sync_id, @@ -977,14 +968,27 @@ QXcbEventReader::QXcbEventReader(QXcbConnection *connection) #endif } -bool QXcbEventReader::startThread() +void QXcbEventReader::start() { if (m_xcb_poll_for_queued_event) { + connect(this, SIGNAL(eventPending()), m_connection, SLOT(processXcbEvents()), Qt::QueuedConnection); + connect(this, SIGNAL(finished()), m_connection, SLOT(processXcbEvents())); QThread::start(); - return true; + } else { + // Must be done after we have an event-dispatcher. By posting a method invocation + // we are sure that by the time the method is called we have an event-dispatcher. + QMetaObject::invokeMethod(this, "registerForEvents", Qt::QueuedConnection); } +} - return false; +void QXcbEventReader::registerForEvents() +{ + QSocketNotifier *notifier = new QSocketNotifier(xcb_get_file_descriptor(m_connection->xcb_connection()), QSocketNotifier::Read, this); + connect(notifier, SIGNAL(activated(int)), m_connection, SLOT(processXcbEvents())); + + QAbstractEventDispatcher *dispatcher = QGuiApplicationPrivate::eventDispatcher; + connect(dispatcher, SIGNAL(aboutToBlock()), m_connection, SLOT(processXcbEvents())); + connect(dispatcher, SIGNAL(awake()), m_connection, SLOT(processXcbEvents())); } void QXcbEventReader::run() diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h index 7cabe67a68..0e52b2ec46 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.h +++ b/src/plugins/platforms/xcb/qxcbconnection.h @@ -298,11 +298,14 @@ public: QXcbEventArray *lock(); void unlock(); - bool startThread(); + void start(); signals: void eventPending(); +private slots: + void registerForEvents(); + private: void addEvent(xcb_generic_event_t *event); @@ -574,6 +577,8 @@ private: QByteArray m_startupId; QXcbSystemTrayTracker *m_systemTrayTracker; + + friend class QXcbEventReader; }; #define DISPLAY_FROM_XCB(object) ((Display *)(object->connection()->xlib_display())) diff --git a/src/plugins/platforms/xcb/qxcbcursor.cpp b/src/plugins/platforms/xcb/qxcbcursor.cpp index 756c3c22dd..11848d503b 100644 --- a/src/plugins/platforms/xcb/qxcbcursor.cpp +++ b/src/plugins/platforms/xcb/qxcbcursor.cpp @@ -272,6 +272,26 @@ static const char * const cursorNames[] = { "link" }; +#ifndef QT_NO_CURSOR + +QXcbCursorCacheKey::QXcbCursorCacheKey(const QCursor &c) + : shape(c.shape()), bitmapCacheKey(0), maskCacheKey(0) +{ + if (shape == Qt::BitmapCursor) { + const qint64 pixmapCacheKey = c.pixmap().cacheKey(); + if (pixmapCacheKey) { + bitmapCacheKey = pixmapCacheKey; + } else { + Q_ASSERT(c.bitmap()); + Q_ASSERT(c.mask()); + bitmapCacheKey = c.bitmap()->cacheKey(); + maskCacheKey = c.mask()->cacheKey(); + } + } +} + +#endif // !QT_NO_CURSOR + QXcbCursor::QXcbCursor(QXcbConnection *conn, QXcbScreen *screen) : QXcbObject(conn), m_screen(screen), m_gtkCursorThemeInitialized(false) { @@ -318,9 +338,7 @@ QXcbCursor::~QXcbCursor() if (!--cursorCount) xcb_close_font(conn, cursorFont); - foreach (xcb_cursor_t cursor, m_bitmapCursorMap) - xcb_free_cursor(conn, cursor); - foreach (xcb_cursor_t cursor, m_shapeCursorMap) + foreach (xcb_cursor_t cursor, m_cursorHash) xcb_free_cursor(conn, cursor); } @@ -336,17 +354,13 @@ void QXcbCursor::changeCursor(QCursor *cursor, QWindow *widget) xcb_cursor_t c = XCB_CURSOR_NONE; if (cursor) { - if (cursor->shape() == Qt::BitmapCursor) { - qint64 id = cursor->pixmap().cacheKey(); - if (!m_bitmapCursorMap.contains(id)) - m_bitmapCursorMap.insert(id, createBitmapCursor(cursor)); - c = m_bitmapCursorMap.value(id); - } else { - int id = cursor->shape(); - if (!m_shapeCursorMap.contains(id)) - m_shapeCursorMap.insert(id, createFontCursor(cursor->shape())); - c = m_shapeCursorMap.value(id); + const QXcbCursorCacheKey key(*cursor); + CursorHash::iterator it = m_cursorHash.find(key); + if (it == m_cursorHash.end()) { + const Qt::CursorShape shape = cursor->shape(); + it = m_cursorHash.insert(key, shape == Qt::BitmapCursor ? createBitmapCursor(cursor) : createFontCursor(shape)); } + c = it.value(); } w->setCursor(c); diff --git a/src/plugins/platforms/xcb/qxcbcursor.h b/src/plugins/platforms/xcb/qxcbcursor.h index 081300868c..f224aae4e0 100644 --- a/src/plugins/platforms/xcb/qxcbcursor.h +++ b/src/plugins/platforms/xcb/qxcbcursor.h @@ -47,6 +47,31 @@ QT_BEGIN_NAMESPACE +#ifndef QT_NO_CURSOR + +struct QXcbCursorCacheKey +{ + explicit QXcbCursorCacheKey(const QCursor &c); + explicit QXcbCursorCacheKey(Qt::CursorShape s) : shape(s), bitmapCacheKey(0), maskCacheKey(0) {} + QXcbCursorCacheKey() : shape(Qt::CustomCursor), bitmapCacheKey(0), maskCacheKey(0) {} + + Qt::CursorShape shape; + qint64 bitmapCacheKey; + qint64 maskCacheKey; +}; + +inline bool operator==(const QXcbCursorCacheKey &k1, const QXcbCursorCacheKey &k2) +{ + return k1.shape == k2.shape && k1.bitmapCacheKey == k2.bitmapCacheKey && k1.maskCacheKey == k2.maskCacheKey; +} + +inline uint qHash(const QXcbCursorCacheKey &k, uint seed) Q_DECL_NOTHROW +{ + return (uint(k.shape) + uint(k.bitmapCacheKey) + uint(k.maskCacheKey)) ^ seed; +} + +#endif // !QT_NO_CURSOR + class QXcbCursor : public QXcbObject, public QPlatformCursor { public: @@ -62,6 +87,8 @@ public: private: #ifndef QT_NO_CURSOR + typedef QHash<QXcbCursorCacheKey, xcb_cursor_t> CursorHash; + xcb_cursor_t createFontCursor(int cshape); xcb_cursor_t createBitmapCursor(QCursor *cursor); xcb_cursor_t createNonStandardCursor(int cshape); @@ -69,8 +96,7 @@ private: QXcbScreen *m_screen; #ifndef QT_NO_CURSOR - QMap<int, xcb_cursor_t> m_shapeCursorMap; - QMap<qint64, xcb_cursor_t> m_bitmapCursorMap; + CursorHash m_cursorHash; #endif #ifdef XCB_USE_XLIB static void cursorThemePropertyChanged(QXcbScreen *screen, diff --git a/src/plugins/platforms/xcb/qxcbintegration.cpp b/src/plugins/platforms/xcb/qxcbintegration.cpp index cef81ddfec..2249446242 100644 --- a/src/plugins/platforms/xcb/qxcbintegration.cpp +++ b/src/plugins/platforms/xcb/qxcbintegration.cpp @@ -124,12 +124,9 @@ static bool runningUnderDebugger() #endif QXcbIntegration::QXcbIntegration(const QStringList ¶meters, int &argc, char **argv) - : m_eventDispatcher(createUnixEventDispatcher()) - , m_services(new QGenericUnixServices) + : m_services(new QGenericUnixServices) , m_instanceName(0) { - QGuiApplicationPrivate::instance()->setEventDispatcher(m_eventDispatcher); - #ifdef XCB_USE_XLIB XInitThreads(); #endif @@ -176,9 +173,6 @@ QXcbIntegration::QXcbIntegration(const QStringList ¶meters, int &argc, char m_fontDatabase.reset(new QGenericUnixFontDatabase()); m_inputContext.reset(QPlatformInputContextFactory::create()); -#if !defined(QT_NO_ACCESSIBILITY) && !defined(QT_NO_ACCESSIBILITY_ATSPI_BRIDGE) - m_accessibility.reset(new QSpiAccessibleBridge()); -#endif } QXcbIntegration::~QXcbIntegration() @@ -293,9 +287,9 @@ bool QXcbIntegration::hasCapability(QPlatformIntegration::Capability cap) const } } -QAbstractEventDispatcher *QXcbIntegration::guiThreadEventDispatcher() const +QAbstractEventDispatcher *QXcbIntegration::createEventDispatcher() const { - return m_eventDispatcher; + return createUnixEventDispatcher(); } void QXcbIntegration::moveToScreen(QWindow *window, int screen) @@ -336,6 +330,14 @@ QPlatformInputContext *QXcbIntegration::inputContext() const #ifndef QT_NO_ACCESSIBILITY QPlatformAccessibility *QXcbIntegration::accessibility() const { +#if !defined(QT_NO_ACCESSIBILITY_ATSPI_BRIDGE) + if (!m_accessibility) { + Q_ASSERT_X(QCoreApplication::eventDispatcher(), "QXcbIntegration", + "Initializing accessibility without event-dispatcher!"); + m_accessibility.reset(new QSpiAccessibleBridge()); + } +#endif + return m_accessibility.data(); } #endif diff --git a/src/plugins/platforms/xcb/qxcbintegration.h b/src/plugins/platforms/xcb/qxcbintegration.h index 7ca7befc64..008d03fbcb 100644 --- a/src/plugins/platforms/xcb/qxcbintegration.h +++ b/src/plugins/platforms/xcb/qxcbintegration.h @@ -67,7 +67,7 @@ public: QPlatformOffscreenSurface *createPlatformOffscreenSurface(QOffscreenSurface *surface) const; bool hasCapability(Capability cap) const; - QAbstractEventDispatcher *guiThreadEventDispatcher() const; + QAbstractEventDispatcher *createEventDispatcher() const; void moveToScreen(QWindow *window, int screen); @@ -112,10 +112,9 @@ private: QScopedPointer<QXcbNativeInterface> m_nativeInterface; QScopedPointer<QPlatformInputContext> m_inputContext; - QAbstractEventDispatcher *m_eventDispatcher; #ifndef QT_NO_ACCESSIBILITY - QScopedPointer<QPlatformAccessibility> m_accessibility; + mutable QScopedPointer<QPlatformAccessibility> m_accessibility; #endif QScopedPointer<QPlatformServices> m_services; diff --git a/src/plugins/platforms/xcb/qxcbsessionmanager.h b/src/plugins/platforms/xcb/qxcbsessionmanager.h index 0dca36d16f..28eb287097 100644 --- a/src/plugins/platforms/xcb/qxcbsessionmanager.h +++ b/src/plugins/platforms/xcb/qxcbsessionmanager.h @@ -43,6 +43,15 @@ #ifndef QXCBSESSIONMANAGER_H #define QXCBSESSIONMANAGER_H +// +// W A R N I N G +// ------------- +// +// This file is part of the QPA API and is not meant to be used +// in applications. Usage of this API may make your code +// source and binary incompatible with future versions of Qt. +// + #include <qpa/qplatformsessionmanager.h> QT_BEGIN_NAMESPACE |