summaryrefslogtreecommitdiffstats
path: root/src/plugins
diff options
context:
space:
mode:
authorFrederik Gladhorn <frederik.gladhorn@digia.com>2013-04-22 16:35:41 +0200
committerFrederik Gladhorn <frederik.gladhorn@digia.com>2013-04-22 16:35:43 +0200
commit4c231d5df3040dbf4545a9a77145ee0e1f9c380c (patch)
tree2cc5b71a5d2b464214cf5372776913fbe4622e1e /src/plugins
parent7df16fb4ccbe0476bc34274a77e98eec4e8d2d93 (diff)
parentd672ef07681a959d9559dd1e11e70db1f448a7f1 (diff)
Merge remote-tracking branch 'origin/stable' into dev
Diffstat (limited to 'src/plugins')
-rw-r--r--src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp10
-rw-r--r--src/plugins/platforminputcontexts/compose/generator/qtablegenerator.h4
-rw-r--r--src/plugins/platforms/android/src/androidjnimain.cpp56
-rw-r--r--src/plugins/platforms/android/src/opengl/qandroidopenglcontext.cpp14
-rw-r--r--src/plugins/platforms/android/src/opengl/qandroidopenglplatformwindow.cpp58
-rw-r--r--src/plugins/platforms/android/src/opengl/qandroidopenglplatformwindow.h13
-rw-r--r--src/plugins/platforms/android/src/opengl/qeglfshooks_android.cpp1
-rw-r--r--src/plugins/platforms/android/src/qandroidplatformintegration.cpp33
-rw-r--r--src/plugins/platforms/android/src/qandroidplatformintegration.h3
-rw-r--r--src/plugins/platforms/cocoa/main.mm3
-rw-r--r--src/plugins/platforms/cocoa/qcocoaaccessibility.mm8
-rw-r--r--src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm3
-rw-r--r--src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm5
-rw-r--r--src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm42
-rw-r--r--src/plugins/platforms/cocoa/qcocoaintegration.mm4
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenu.mm50
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenubar.mm2
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenuitem.mm7
-rw-r--r--src/plugins/platforms/cocoa/qcocoanativeinterface.mm9
-rw-r--r--src/plugins/platforms/cocoa/qcocoasystemsettings.mm4
-rw-r--r--src/plugins/platforms/cocoa/qcocoatheme.mm2
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.mm17
-rw-r--r--src/plugins/platforms/cocoa/qmacmime.mm6
-rw-r--r--src/plugins/platforms/cocoa/qnsview.h1
-rw-r--r--src/plugins/platforms/cocoa/qnsview.mm5
-rw-r--r--src/plugins/platforms/cocoa/qnsviewaccessibility.mm19
-rw-r--r--src/plugins/platforms/cocoa/qprintengine_mac.mm3
-rw-r--r--src/plugins/platforms/eglfs/qeglfsintegration.cpp3
-rw-r--r--src/plugins/platforms/eglfs/qeglfswindow.cpp6
-rw-r--r--src/plugins/platforms/eglfs/qeglfswindow.h6
-rw-r--r--src/plugins/platforms/ios/qiosapplicationdelegate.h3
-rw-r--r--src/plugins/platforms/ios/qiosapplicationdelegate.mm2
-rw-r--r--src/plugins/platforms/ios/qiosbackingstore.mm6
-rw-r--r--src/plugins/platforms/ios/qiosglobal.h2
-rw-r--r--src/plugins/platforms/ios/qiosglobal.mm8
-rw-r--r--src/plugins/platforms/ios/qiosscreen.mm2
-rw-r--r--src/plugins/platforms/ios/qioswindow.mm4
-rw-r--r--src/plugins/platforms/ios/qtmain.mm3
-rw-r--r--src/plugins/platforms/offscreen/qoffscreencommon.h2
-rw-r--r--src/plugins/platforms/offscreen/qoffscreenintegration.cpp4
-rw-r--r--src/plugins/platforms/offscreen/qoffscreenintegration.h4
-rw-r--r--src/plugins/platforms/qnx/qqnxwindow.cpp5
-rw-r--r--src/plugins/platforms/windows/accessible/qwindowsaccessibility.cpp4
-rw-r--r--src/plugins/platforms/windows/qwindowsbackingstore.cpp2
-rw-r--r--src/plugins/platforms/windows/qwindowsclipboard.cpp20
-rw-r--r--src/plugins/platforms/windows/qwindowsfontdatabase.cpp2
-rw-r--r--src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp3
-rw-r--r--src/plugins/platforms/windows/qwindowsglcontext.cpp10
-rw-r--r--src/plugins/platforms/windows/qwindowsintegration.cpp2
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.cpp13
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.h5
-rw-r--r--src/plugins/platforms/xcb/qxcbnativeinterface.cpp14
-rw-r--r--src/plugins/platforms/xcb/qxcbnativeinterface.h3
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.cpp14
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.h5
55 files changed, 393 insertions, 146 deletions
diff --git a/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp b/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp
index 3c61a69480..1113194136 100644
--- a/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp
+++ b/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp
@@ -252,14 +252,14 @@ void TableGenerator::parseIncludeInstruction(QString line)
processFile(line);
}
-ushort TableGenerator::keysymToUtf8(uint32_t sym)
+ushort TableGenerator::keysymToUtf8(quint32 sym)
{
QByteArray chars;
int bytes;
chars.resize(8);
if (needWorkaround(sym)) {
- uint32_t codepoint;
+ quint32 codepoint;
if (sym == XKB_KEY_KP_Space)
codepoint = XKB_KEY_space & 0x7f;
else
@@ -284,14 +284,14 @@ ushort TableGenerator::keysymToUtf8(uint32_t sym)
return ch->unicode();
}
-uint32_t TableGenerator::stringToKeysym(QString keysymName)
+quint32 TableGenerator::stringToKeysym(QString keysymName)
{
- uint32_t keysym;
+ quint32 keysym;
QByteArray keysymArray = keysymName.toLatin1();
const char *name = keysymArray.constData();
if ((keysym = xkb_keysym_from_name(name, (xkb_keysym_flags)0)) == XKB_KEY_NoSymbol)
- qWarning() << QString("Qt Warrning - invalid keysym: %1").arg(keysymName);
+ qWarning() << QString("Qt Warning - invalid keysym: %1").arg(keysymName);
return keysym;
}
diff --git a/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.h b/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.h
index 11e7b2b422..cc1db20432 100644
--- a/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.h
+++ b/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.h
@@ -109,8 +109,8 @@ protected:
bool findSystemComposeDir();
QString systemComposeDir();
- ushort keysymToUtf8(uint32_t sym);
- uint32_t stringToKeysym(QString keysymName);
+ ushort keysymToUtf8(quint32 sym);
+ quint32 stringToKeysym(QString keysymName);
void readLocaleMappings();
void initPossibleLocations();
diff --git a/src/plugins/platforms/android/src/androidjnimain.cpp b/src/plugins/platforms/android/src/androidjnimain.cpp
index 36d95b0816..162a8aa977 100644
--- a/src/plugins/platforms/android/src/androidjnimain.cpp
+++ b/src/plugins/platforms/android/src/androidjnimain.cpp
@@ -74,9 +74,7 @@
# include "qandroidopenglplatformwindow.h"
#endif
-#if __ANDROID_API__ > 8
-# include <android/native_window_jni.h>
-#endif
+#include <android/native_window_jni.h>
static jmethodID m_redrawSurfaceMethodID = 0;
@@ -543,32 +541,6 @@ static void terminateQt(JNIEnv *env, jclass /*clazz*/)
env->DeleteGlobalRef(m_bitmapDrawableClass);
}
-#ifdef ANDROID_PLUGIN_OPENGL
-#if __ANDROID_API__ < 9
-struct FakeNativeWindow
-{
- long long dummyNativeWindow;// force 64 bits alignment
-};
-
-class FakeSurface: public FakeNativeWindow
-{
-public:
- virtual void FakeSurfaceMethod()
- {
- fakeSurface = 0;
- }
-
- int fakeSurface;
-};
-
-EGLNativeWindowType ANativeWindow_fromSurface(JNIEnv *env, jobject jSurface)
-{
- FakeSurface *surface = static_cast<FakeSurface *>(env->GetIntField(jSurface, m_surfaceFieldID));
- return static_cast<EGLNativeWindowType>(static_cast<FakeNativeWindow*>(surface));
-}
-#endif // __ANDROID_API__ < 9
-#endif // ANDROID_PLUGIN_OPENGL
-
static void setSurface(JNIEnv *env, jobject /*thiz*/, jobject jSurface)
{
#ifndef ANDROID_PLUGIN_OPENGL
@@ -587,7 +559,6 @@ static void setSurface(JNIEnv *env, jobject /*thiz*/, jobject jSurface)
m_surfaceMutex.unlock();
m_androidPlatformIntegration->surfaceChanged();
} else if (m_androidPlatformIntegration && sameNativeWindow) {
- QAndroidOpenGLPlatformWindow *window = m_androidPlatformIntegration->primaryWindow();
QPlatformScreen *screen = m_androidPlatformIntegration->screen();
QSize size = QtAndroid::nativeWindowSize();
@@ -595,13 +566,19 @@ static void setSurface(JNIEnv *env, jobject /*thiz*/, jobject jSurface)
QWindowSystemInterface::handleScreenAvailableGeometryChange(screen->screen(), geometry);
QWindowSystemInterface::handleScreenGeometryChange(screen->screen(), geometry);
- if (window != 0) {
- window->lock();
- window->scheduleResize(size);
+ // Resize all top level windows, since they share the same surface
+ foreach (QWindow *w, QGuiApplication::topLevelWindows()) {
+ QAndroidOpenGLPlatformWindow *window =
+ static_cast<QAndroidOpenGLPlatformWindow *>(w->handle());
+
+ if (window != 0) {
+ window->lock();
+ window->scheduleResize(size);
- QWindowSystemInterface::handleExposeEvent(window->window(),
- QRegion(window->window()->geometry()));
- window->unlock();
+ QWindowSystemInterface::handleExposeEvent(window->window(),
+ QRegion(window->window()->geometry()));
+ window->unlock();
+ }
}
m_surfaceMutex.unlock();
@@ -753,12 +730,7 @@ static int registerNatives(JNIEnv *env)
#ifdef ANDROID_PLUGIN_OPENGL
FIND_AND_CHECK_CLASS("android/view/Surface");
-#if __ANDROID_API__ < 9
-# define ANDROID_VIEW_SURFACE_JNI_ID "mSurface"
-#else
-# define ANDROID_VIEW_SURFACE_JNI_ID "mNativeSurface"
-#endif
- GET_AND_CHECK_FIELD(m_surfaceFieldID, clazz, ANDROID_VIEW_SURFACE_JNI_ID, "I");
+ GET_AND_CHECK_FIELD(m_surfaceFieldID, clazz, "mNativeSurface", "I");
#endif
jmethodID methodID;
diff --git a/src/plugins/platforms/android/src/opengl/qandroidopenglcontext.cpp b/src/plugins/platforms/android/src/opengl/qandroidopenglcontext.cpp
index aa8ee57341..4d741807d0 100644
--- a/src/plugins/platforms/android/src/opengl/qandroidopenglcontext.cpp
+++ b/src/plugins/platforms/android/src/opengl/qandroidopenglcontext.cpp
@@ -62,16 +62,16 @@ void QAndroidOpenGLContext::swapBuffers(QPlatformSurface *surface)
{
QEglFSContext::swapBuffers(surface);
- QAndroidOpenGLPlatformWindow *primaryWindow = m_platformIntegration->primaryWindow();
- if (primaryWindow == surface) {
- primaryWindow->lock();
- QSize size = primaryWindow->scheduledResize();
+ if (surface->surface()->surfaceClass() == QSurface::Window) {
+ QAndroidOpenGLPlatformWindow *window = static_cast<QAndroidOpenGLPlatformWindow *>(surface);
+ window->lock();
+ QSize size = window->scheduledResize();
if (size.isValid()) {
QRect geometry(QPoint(0, 0), size);
- primaryWindow->setGeometry(geometry);
- primaryWindow->scheduleResize(QSize());
+ window->setGeometry(geometry);
+ window->scheduleResize(QSize());
}
- primaryWindow->unlock();
+ window->unlock();
}
}
diff --git a/src/plugins/platforms/android/src/opengl/qandroidopenglplatformwindow.cpp b/src/plugins/platforms/android/src/opengl/qandroidopenglplatformwindow.cpp
index 15c6559157..5362906e0e 100644
--- a/src/plugins/platforms/android/src/opengl/qandroidopenglplatformwindow.cpp
+++ b/src/plugins/platforms/android/src/opengl/qandroidopenglplatformwindow.cpp
@@ -45,11 +45,21 @@
QT_BEGIN_NAMESPACE
+EGLSurface QAndroidOpenGLPlatformWindow::m_staticSurface = 0;
+EGLNativeWindowType QAndroidOpenGLPlatformWindow::m_staticNativeWindow = 0;
+QReadWriteLock QAndroidOpenGLPlatformWindow::m_staticSurfaceLock;
+QBasicAtomicInt QAndroidOpenGLPlatformWindow::m_referenceCount = Q_BASIC_ATOMIC_INITIALIZER(0);
+
QAndroidOpenGLPlatformWindow::QAndroidOpenGLPlatformWindow(QWindow *window)
: QEglFSWindow(window)
{
}
+QAndroidOpenGLPlatformWindow::~QAndroidOpenGLPlatformWindow()
+{
+ destroy();
+}
+
bool QAndroidOpenGLPlatformWindow::isExposed() const
{
return QtAndroid::nativeWindow(false) != 0 && QEglFSWindow::isExposed();
@@ -60,11 +70,57 @@ void QAndroidOpenGLPlatformWindow::invalidateSurface()
QWindowSystemInterface::handleExposeEvent(window(), QRegion()); // Obscure event
QWindowSystemInterface::flushWindowSystemEvents();
QEglFSWindow::invalidateSurface();
+
+ m_window = 0;
+ m_surface = 0;
+
+ if (!m_referenceCount.deref()){
+ QWriteLocker locker(&m_staticSurfaceLock);
+
+ EGLDisplay display = (static_cast<QEglFSScreen *>(window()->screen()->handle()))->display();
+ eglDestroySurface(display, m_staticSurface);
+
+ m_staticSurface = 0;
+ m_staticNativeWindow = 0;
+ }
}
void QAndroidOpenGLPlatformWindow::resetSurface()
{
- QEglFSWindow::resetSurface();
+ m_referenceCount.ref();
+ if (m_staticSurface == 0) {
+ QWriteLocker locker(&m_staticSurfaceLock);
+ QEglFSWindow::resetSurface();
+ m_staticSurface = m_surface;
+ m_staticNativeWindow = m_window;
+ } else {
+ QReadLocker locker(&m_staticSurfaceLock);
+ Q_ASSERT(m_staticSurface != m_surface);
+ m_window = m_staticNativeWindow;
+ m_surface = m_staticSurface;
+ }
+
+ QWindowSystemInterface::handleExposeEvent(window(), QRegion(geometry())); // Expose event
+ QWindowSystemInterface::flushWindowSystemEvents();
+}
+
+void QAndroidOpenGLPlatformWindow::destroy()
+{
+ if (!m_referenceCount.deref()) {
+ QEglFSWindow::destroy();
+ } else {
+ m_window = 0;
+ m_surface = 0;
+ }
+}
+
+void QAndroidOpenGLPlatformWindow::raise()
+{
+}
+
+void QAndroidOpenGLPlatformWindow::setVisible(bool visible)
+{
+ QEglFSWindow::setVisible(visible);
QWindowSystemInterface::handleExposeEvent(window(), QRegion(geometry())); // Expose event
QWindowSystemInterface::flushWindowSystemEvents();
}
diff --git a/src/plugins/platforms/android/src/opengl/qandroidopenglplatformwindow.h b/src/plugins/platforms/android/src/opengl/qandroidopenglplatformwindow.h
index b835cb3246..36a110e1a8 100644
--- a/src/plugins/platforms/android/src/opengl/qandroidopenglplatformwindow.h
+++ b/src/plugins/platforms/android/src/opengl/qandroidopenglplatformwindow.h
@@ -44,6 +44,7 @@
#include "qeglfswindow.h"
#include <QtCore/qmutex.h>
+#include <QtCore/qreadwritelock.h>
QT_BEGIN_NAMESPACE
@@ -51,6 +52,7 @@ class QAndroidOpenGLPlatformWindow : public QEglFSWindow
{
public:
QAndroidOpenGLPlatformWindow(QWindow *window);
+ ~QAndroidOpenGLPlatformWindow();
QSize scheduledResize() const { return m_scheduledResize; }
void scheduleResize(const QSize &size) { m_scheduledResize = size; }
@@ -60,12 +62,23 @@ public:
bool isExposed() const;
+ void raise();
+
void invalidateSurface();
void resetSurface();
+ void setVisible(bool visible);
+
+ void destroy();
+
private:
QSize m_scheduledResize;
QMutex m_lock;
+
+ static QReadWriteLock m_staticSurfaceLock;
+ static EGLSurface m_staticSurface;
+ static EGLNativeWindowType m_staticNativeWindow;
+ static QBasicAtomicInt m_referenceCount;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/android/src/opengl/qeglfshooks_android.cpp b/src/plugins/platforms/android/src/opengl/qeglfshooks_android.cpp
index 4734d47eb3..005758d83d 100644
--- a/src/plugins/platforms/android/src/opengl/qeglfshooks_android.cpp
+++ b/src/plugins/platforms/android/src/opengl/qeglfshooks_android.cpp
@@ -96,6 +96,7 @@ QDpi QEglFSAndroidHooks::logicalDpi() const
EGLNativeWindowType QEglFSAndroidHooks::createNativeWindow(const QSize &size, const QSurfaceFormat &format)
{
+ Q_UNUSED(size);
ANativeWindow *window = QtAndroid::nativeWindow();
if (window != 0)
ANativeWindow_acquire(window);
diff --git a/src/plugins/platforms/android/src/qandroidplatformintegration.cpp b/src/plugins/platforms/android/src/qandroidplatformintegration.cpp
index cbd0f26835..3de6c47ad0 100644
--- a/src/plugins/platforms/android/src/qandroidplatformintegration.cpp
+++ b/src/plugins/platforms/android/src/qandroidplatformintegration.cpp
@@ -43,6 +43,7 @@
#include "qabstracteventdispatcher.h"
#include "androidjnimain.h"
#include <QtGui/private/qpixmap_raster_p.h>
+#include <QtGui/qguiapplication.h>
#include <qpa/qwindowsysteminterface.h>
#include <QThread>
#include <qpa/qplatformwindow.h>
@@ -85,9 +86,6 @@ void *QAndroidPlatformNativeInterface::nativeResourceForIntegration(const QByteA
QAndroidPlatformIntegration::QAndroidPlatformIntegration(const QStringList &paramList)
: m_touchDevice(0)
-#ifdef ANDROID_PLUGIN_OPENGL
- , m_primaryWindow(0)
-#endif
{
Q_UNUSED(paramList);
@@ -116,6 +114,7 @@ bool QAndroidPlatformIntegration::hasCapability(Capability cap) const
{
switch (cap) {
case ThreadedPixmaps: return true;
+ case NonFullScreenWindows: return false;
default:
#ifndef ANDROID_PLUGIN_OPENGL
return QPlatformIntegration::hasCapability(cap);
@@ -143,28 +142,32 @@ QAbstractEventDispatcher *QAndroidPlatformIntegration::guiThreadEventDispatcher(
#else // !ANDROID_PLUGIN_OPENGL
QPlatformWindow *QAndroidPlatformIntegration::createPlatformWindow(QWindow *window) const
{
- if (m_primaryWindow != 0) {
- qWarning("QAndroidPlatformIntegration::createPlatformWindow: Unsupported case: More than "
- "one top-level window created.");
- }
-
- m_primaryWindow = new QAndroidOpenGLPlatformWindow(window);
- m_primaryWindow->requestActivateWindow();
+ QAndroidOpenGLPlatformWindow *platformWindow = new QAndroidOpenGLPlatformWindow(window);
+ platformWindow->create();
+ platformWindow->requestActivateWindow();
QtAndroidMenu::setActiveTopLevelWindow(window);
- return m_primaryWindow;
+ return platformWindow;
}
void QAndroidPlatformIntegration::invalidateNativeSurface()
{
- if (m_primaryWindow != 0)
- m_primaryWindow->invalidateSurface();
+ foreach (QWindow *w, QGuiApplication::topLevelWindows()) {
+ QAndroidOpenGLPlatformWindow *window =
+ static_cast<QAndroidOpenGLPlatformWindow *>(w->handle());
+ if (window != 0)
+ window->invalidateSurface();
+ }
}
void QAndroidPlatformIntegration::surfaceChanged()
{
- if (m_primaryWindow != 0)
- m_primaryWindow->resetSurface();
+ foreach (QWindow *w, QGuiApplication::topLevelWindows()) {
+ QAndroidOpenGLPlatformWindow *window =
+ static_cast<QAndroidOpenGLPlatformWindow *>(w->handle());
+ if (window != 0)
+ window->resetSurface();
+ }
}
QPlatformOpenGLContext *QAndroidPlatformIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const
diff --git a/src/plugins/platforms/android/src/qandroidplatformintegration.h b/src/plugins/platforms/android/src/qandroidplatformintegration.h
index 3f8cc5a809..8da9fb2ff4 100644
--- a/src/plugins/platforms/android/src/qandroidplatformintegration.h
+++ b/src/plugins/platforms/android/src/qandroidplatformintegration.h
@@ -95,7 +95,6 @@ public:
QPlatformWindow *createPlatformWindow(QWindow *window) const;
void invalidateNativeSurface();
void surfaceChanged();
- QAndroidOpenGLPlatformWindow *primaryWindow() const { return m_primaryWindow; }
QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const;
#endif
@@ -138,8 +137,6 @@ private:
#ifndef ANDROID_PLUGIN_OPENGL
QAbstractEventDispatcher *m_eventDispatcher;
QAndroidPlatformScreen *m_primaryScreen;
-#else
- mutable QAndroidOpenGLPlatformWindow *m_primaryWindow;
#endif
QThread *m_mainThread;
diff --git a/src/plugins/platforms/cocoa/main.mm b/src/plugins/platforms/cocoa/main.mm
index 0eb4edef72..6adcb27817 100644
--- a/src/plugins/platforms/cocoa/main.mm
+++ b/src/plugins/platforms/cocoa/main.mm
@@ -59,6 +59,9 @@ public:
QPlatformIntegration * QCocoaIntegrationPlugin::create(const QString& system, const QStringList& paramList)
{
Q_UNUSED(paramList);
+
+ QCocoaAutoReleasePool pool;
+
if (system.toLower() == "cocoa")
return new QCocoaIntegration;
diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibility.mm b/src/plugins/platforms/cocoa/qcocoaaccessibility.mm
index 34192e85b0..25780e79f4 100644
--- a/src/plugins/platforms/cocoa/qcocoaaccessibility.mm
+++ b/src/plugins/platforms/cocoa/qcocoaaccessibility.mm
@@ -180,7 +180,8 @@ bool shouldBeIgnored(QAccessibleInterface *interface)
// state. Ignore interfaces with those flags set.
const QAccessible::State state = interface->state();
if (state.invisible ||
- state.offscreen)
+ state.offscreen ||
+ state.invalid)
return true;
// Some roles are not interesting. In particular, container roles should be
@@ -189,12 +190,13 @@ bool shouldBeIgnored(QAccessibleInterface *interface)
if (role == QAccessible::Border || // QFrame
role == QAccessible::Application || // We use the system-provided application element.
role == QAccessible::MenuItem || // The system also provides the menu items.
- role == QAccessible::ToolBar) // Access the tool buttons directly.
+ role == QAccessible::ToolBar || // Access the tool buttons directly.
+ role == QAccessible::Pane || // Scroll areas.
+ role == QAccessible::Client) // The default for QWidget.
return true;
NSString *mac_role = macRole(interface);
if (mac_role == NSAccessibilityWindowRole || // We use the system-provided window elements.
- mac_role == NSAccessibilityGroupRole ||
mac_role == NSAccessibilityUnknownRole)
return true;
diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm
index 1d6797e51a..f7c945c50d 100644
--- a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm
+++ b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm
@@ -151,6 +151,7 @@
[kids addObject: element];
[element release];
}
+ // ### maybe we should use NSAccessibilityUnignoredChildren(kids); this needs more profiling
return kids;
} else if ([attribute isEqualToString:NSAccessibilityFocusedAttribute]) {
@@ -256,7 +257,7 @@
// misc
- (BOOL)accessibilityIsIgnored {
- return false; //QCocoaAccessible::shouldBeIgnored(QAccessible::accessibleInterface(id));
+ return QCocoaAccessible::shouldBeIgnored(QAccessible::accessibleInterface(axid));
}
- (id)accessibilityHitTest:(NSPoint)point {
diff --git a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm
index 5c487b0bdd..2ac9a5dac9 100644
--- a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm
+++ b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm
@@ -741,11 +741,14 @@ void QCocoaEventDispatcherPrivate::endModalSession(QWindow *window)
// when we stop the _current_ modal session (which is the session on top of
// the stack, and might not belong to 'window').
int stackSize = cocoaModalSessionStack.size();
+ int endedSessions = 0;
for (int i=stackSize-1; i>=0; --i) {
QCocoaModalSessionInfo &info = cocoaModalSessionStack[i];
+ if (!info.window)
+ endedSessions++;
if (info.window == window) {
info.window = 0;
- if (i == stackSize-1) {
+ if (i + endedSessions == stackSize-1) {
// The top sessions ended. Interrupt the event dispatcher to
// start spinning the correct session immediately. Like in
// beginModalSession(), we call interrupt() before clearing
diff --git a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm
index 7093d27efe..071edb5b60 100644
--- a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm
+++ b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm
@@ -61,6 +61,8 @@
#include <stdlib.h>
#include <qabstracteventdispatcher.h>
#include "qcocoaautoreleasepool.h"
+#include <QFileSystemWatcher>
+#include <QDir>
#include <qpa/qplatformnativeinterface.h>
@@ -72,6 +74,30 @@ QT_FORWARD_DECLARE_CLASS(QFileInfo)
QT_FORWARD_DECLARE_CLASS(QWindow)
QT_USE_NAMESPACE
+class CachedEntries: public QObject {
+public:
+ CachedEntries(QDir::Filters filters) : mFilters(filters) {
+ QObject::connect(&mFSWatcher, &QFileSystemWatcher::directoryChanged, this, &CachedEntries::updateDirCache);
+ }
+ QString directory() const {
+ const QStringList &dirs = mFSWatcher.directories();
+ return (dirs.count() ? dirs[0] : QString());
+ }
+ QStringList entries() const {
+ return mQDirFilterEntryList;
+ }
+ void updateDirCache(const QString &path) {
+ mFSWatcher.removePaths(mFSWatcher.directories());
+ mFSWatcher.addPath(path);
+ mQDirFilterEntryList = QDir(path).entryList(mFilters);
+ }
+
+private:
+ QFileSystemWatcher mFSWatcher;
+ QStringList mQDirFilterEntryList;
+ QDir::Filters mFilters;
+};
+
typedef QSharedPointer<QFileDialogOptions> SharedPointerFileDialogOptions;
@class QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate);
@@ -91,9 +117,8 @@ typedef QSharedPointer<QFileDialogOptions> SharedPointerFileDialogOptions;
int mReturnCode;
SharedPointerFileDialogOptions mOptions;
- QString *mLastFilterCheckPath;
+ CachedEntries *mCachedEntries;
QString *mCurrentSelection;
- QStringList *mQDirFilterEntryList;
QStringList *mNameFilterDropDownList;
QStringList *mSelectedNameFilter;
}
@@ -137,8 +162,7 @@ typedef QSharedPointer<QFileDialogOptions> SharedPointerFileDialogOptions;
[mSavePanel setDelegate:self];
mReturnCode = -1;
mHelper = helper;
- mLastFilterCheckPath = new QString;
- mQDirFilterEntryList = new QStringList;
+ mCachedEntries = new CachedEntries(mOptions->filter());
mNameFilterDropDownList = new QStringList(mOptions->nameFilters());
QString selectedVisualNameFilter = mOptions->initiallySelectedNameFilter();
mSelectedNameFilter = new QStringList([self findStrippedFilterWithVisualFilterName:selectedVisualNameFilter]);
@@ -171,8 +195,7 @@ typedef QSharedPointer<QFileDialogOptions> SharedPointerFileDialogOptions;
- (void)dealloc
{
- delete mLastFilterCheckPath;
- delete mQDirFilterEntryList;
+ delete mCachedEntries;
delete mNameFilterDropDownList;
delete mSelectedNameFilter;
delete mCurrentSelection;
@@ -303,12 +326,11 @@ static QString strippedText(QString s)
QString qtFileName = QT_PREPEND_NAMESPACE(QCFString::toQString)(filename);
QFileInfo info(qtFileName.normalized(QT_PREPEND_NAMESPACE(QString::NormalizationForm_C)));
QString path = info.absolutePath();
- if (path != *mLastFilterCheckPath){
- *mLastFilterCheckPath = path;
- *mQDirFilterEntryList = info.dir().entryList(mOptions->filter());
+ if (mCachedEntries->directory() != path) {
+ mCachedEntries->updateDirCache(path);
}
// Check if the QDir filter accepts the file:
- if (!mQDirFilterEntryList->contains(info.fileName()))
+ if (!mCachedEntries->entries().contains(info.fileName()))
return NO;
// No filter means accept everything
diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm
index e2d867e623..821e10de52 100644
--- a/src/plugins/platforms/cocoa/qcocoaintegration.mm
+++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm
@@ -122,7 +122,9 @@ void QCocoaScreen::updateGeometry()
m_physicalSize = QSizeF(size.width, size.height);
m_logicalDpi.first = 72;
m_logicalDpi.second = 72;
- float refresh = CGDisplayModeGetRefreshRate(CGDisplayCopyDisplayMode(dpy));
+ CGDisplayModeRef displayMode = CGDisplayCopyDisplayMode(dpy);
+ float refresh = CGDisplayModeGetRefreshRate(displayMode);
+ CGDisplayModeRelease(displayMode);
if (refresh > 0)
m_refreshRate = refresh;
diff --git a/src/plugins/platforms/cocoa/qcocoamenu.mm b/src/plugins/platforms/cocoa/qcocoamenu.mm
index 0fe4c48510..bde9ded14f 100644
--- a/src/plugins/platforms/cocoa/qcocoamenu.mm
+++ b/src/plugins/platforms/cocoa/qcocoamenu.mm
@@ -97,7 +97,6 @@ static inline QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *getMenuLoader()
if (![menuItem tag])
return YES;
-
QCocoaMenuItem* cocoaItem = reinterpret_cast<QCocoaMenuItem *>([menuItem tag]);
return cocoaItem->isEnabled();
}
@@ -308,13 +307,54 @@ void QCocoaMenu::setVisible(bool visible)
void QCocoaMenu::showPopup(const QWindow *parentWindow, QPoint pos, const QPlatformMenuItem *item)
{
+ QCocoaAutoReleasePool pool;
+
QCocoaWindow *cocoaWindow = parentWindow ? static_cast<QCocoaWindow *>(parentWindow->handle()) : 0;
NSView *view = cocoaWindow ? cocoaWindow->contentView() : nil;
NSMenuItem *nsItem = item ? ((QCocoaMenuItem *)item)->nsItem() : nil;
- NSPoint nsPos = NSMakePoint(pos.x(), pos.y());
- [m_nativeMenu popUpMenuPositioningItem:nsItem atLocation:nsPos inView:view];
- // The call above blocks, and also swallows any mouse release event,
+ // Ideally, we would call -popUpMenuPositioningItem:atLocation:inView:.
+ // However, this showed not to work with modal windows where the menu items
+ // would appear disabled. So, we resort to a more artisanal solution. Note
+ // that this implies several things.
+ if (nsItem) {
+ // If we want to position the menu popup so that a specific item lies under
+ // the mouse cursor, we resort to NSPopUpButtonCell to do that. This is the
+ // typical use-case for a choice list, or non-editable combobox. We can't
+ // re-use the popUpContextMenu:withEvent:forView: logic below since it won't
+ // respect the menu's minimum width.
+ NSPopUpButtonCell *popupCell = [[[NSPopUpButtonCell alloc] initTextCell:@"" pullsDown:NO]
+ autorelease];
+ [popupCell setAltersStateOfSelectedItem:NO];
+ [popupCell setTransparent:YES];
+ [popupCell setMenu:m_nativeMenu];
+ [popupCell selectItem:nsItem];
+ NSRect cellFrame = NSMakeRect(pos.x(), pos.y(), m_nativeMenu.minimumWidth, 10);
+ [popupCell performClickWithFrame:cellFrame inView:view];
+ } else {
+ // Else, we need to transform 'pos' to window or screen coordinates.
+ NSPoint nsPos = NSMakePoint(pos.x() - 1, pos.y());
+ if (view) {
+ nsPos.y = view.frame.size.height - nsPos.y;
+ } else if (!QGuiApplication::screens().isEmpty()) {
+ QScreen *screen = QGuiApplication::screens().at(0);
+ nsPos.y = screen->availableVirtualSize().height() - nsPos.y;
+ }
+
+ // Finally, we need to synthesize an event.
+ NSEvent *menuEvent = [NSEvent mouseEventWithType:NSRightMouseDown
+ location:nsPos
+ modifierFlags:0
+ timestamp:0
+ windowNumber:view ? view.window.windowNumber : 0
+ context:nil
+ eventNumber:0
+ clickCount:1
+ pressure:1.0];
+ [NSMenu popUpContextMenu:m_nativeMenu withEvent:menuEvent forView:view];
+ }
+
+ // The calls above block, and also swallow any mouse release event,
// so we need to clear any mouse button that triggered the menu popup.
if ([view isKindOfClass:[QNSView class]])
[(QNSView *)view resetMouseButtons];
@@ -356,6 +396,8 @@ QList<QCocoaMenuItem *> QCocoaMenu::merged() const
void QCocoaMenu::syncModalState(bool modal)
{
+ QCocoaAutoReleasePool pool;
+
if (!m_enabled)
modal = true;
diff --git a/src/plugins/platforms/cocoa/qcocoamenubar.mm b/src/plugins/platforms/cocoa/qcocoamenubar.mm
index c0c8caed05..b880db16a2 100644
--- a/src/plugins/platforms/cocoa/qcocoamenubar.mm
+++ b/src/plugins/platforms/cocoa/qcocoamenubar.mm
@@ -114,6 +114,8 @@ void QCocoaMenuBar::insertMenu(QPlatformMenu *platformMenu, QPlatformMenu *befor
void QCocoaMenuBar::removeMenu(QPlatformMenu *platformMenu)
{
+ QCocoaAutoReleasePool pool;
+
QCocoaMenu *menu = static_cast<QCocoaMenu *>(platformMenu);
if (!m_menus.contains(menu)) {
qWarning() << Q_FUNC_INFO << "Trying to remove a menu that does not belong to the menubar";
diff --git a/src/plugins/platforms/cocoa/qcocoamenuitem.mm b/src/plugins/platforms/cocoa/qcocoamenuitem.mm
index dd99a6f3bc..350ef8a16a 100644
--- a/src/plugins/platforms/cocoa/qcocoamenuitem.mm
+++ b/src/plugins/platforms/cocoa/qcocoamenuitem.mm
@@ -218,8 +218,6 @@ NSMenuItem *QCocoaMenuItem::sync()
mergeItem = [loader aboutMenuItem];
else
mergeItem = [loader aboutQtMenuItem];
-
- m_merged = true;
} else if (m_text.startsWith(tr("Config"), Qt::CaseInsensitive)
|| m_text.startsWith(tr("Preference"), Qt::CaseInsensitive)
|| m_text.startsWith(tr("Options"), Qt::CaseInsensitive)
@@ -240,9 +238,9 @@ NSMenuItem *QCocoaMenuItem::sync()
if (mergeItem) {
m_merged = true;
+ [mergeItem retain];
[m_native release];
m_native = mergeItem;
- [m_native retain]; // balance out release!
[m_native setTag:reinterpret_cast<NSInteger>(this)];
} else if (m_merged) {
// was previously merged, but no longer
@@ -256,13 +254,12 @@ NSMenuItem *QCocoaMenuItem::sync()
m_native = [[NSMenuItem alloc] initWithTitle:QCFString::toNSString(m_text)
action:nil
keyEquivalent:@""];
- [m_native retain];
[m_native setTag:reinterpret_cast<NSInteger>(this)];
}
// [m_native setHidden:YES];
// [m_native setHidden:NO];
- [m_native setHidden: !m_isVisible];
+ [m_native setHidden: !m_isVisible];
[m_native setEnabled: m_enabled];
QString text = m_text;
QKeySequence accel = m_shortcut;
diff --git a/src/plugins/platforms/cocoa/qcocoanativeinterface.mm b/src/plugins/platforms/cocoa/qcocoanativeinterface.mm
index f0f1f56d90..84261ad273 100644
--- a/src/plugins/platforms/cocoa/qcocoanativeinterface.mm
+++ b/src/plugins/platforms/cocoa/qcocoanativeinterface.mm
@@ -85,10 +85,8 @@ void *QCocoaNativeInterface::nativeResourceForContext(const QByteArray &resource
void *QCocoaNativeInterface::nativeResourceForWindow(const QByteArray &resourceString, QWindow *window)
{
- if (!window->handle()) {
- qWarning("QCocoaNativeInterface::nativeResourceForWindow: Native window has not been created.");
+ if (!window->handle())
return 0;
- }
if (resourceString == "nsopenglcontext") {
return static_cast<QCocoaWindow *>(window->handle())->currentContext()->nsOpenGLContext();
@@ -228,6 +226,11 @@ void QCocoaNativeInterface::setWindowContentView(QPlatformWindow *window, void *
void QCocoaNativeInterface::registerTouchWindow(QWindow *window, bool enable)
{
+ // Make sure the QCocoaWindow is created when enabling. Disabling might
+ // happen on window destruction, don't (re)create the QCocoaWindow then.
+ if (enable)
+ window->create();
+
QCocoaWindow *cocoaWindow = static_cast<QCocoaWindow *>(window->handle());
if (cocoaWindow)
cocoaWindow->registerTouch(enable);
diff --git a/src/plugins/platforms/cocoa/qcocoasystemsettings.mm b/src/plugins/platforms/cocoa/qcocoasystemsettings.mm
index e613dbbd1b..af817bd4c5 100644
--- a/src/plugins/platforms/cocoa/qcocoasystemsettings.mm
+++ b/src/plugins/platforms/cocoa/qcocoasystemsettings.mm
@@ -176,7 +176,7 @@ QHash<QPlatformTheme::Palette, QPalette*> qt_mac_createRolePalettes()
QHash<QPlatformTheme::Palette, QPalette*> palettes;
QColor qc;
for (int i = 0; mac_widget_colors[i].paletteRole != QPlatformTheme::NPalettes; i++) {
- QPalette pal = *qt_mac_createSystemPalette();
+ QPalette &pal = *qt_mac_createSystemPalette();
if (mac_widget_colors[i].active != 0) {
qc = qt_mac_colorForThemeTextColor(mac_widget_colors[i].active);
pal.setColor(QPalette::Active, QPalette::Text, qc);
@@ -223,7 +223,7 @@ QHash<QPlatformTheme::Palette, QPalette*> qt_mac_createRolePalettes()
pal.setBrush(QPalette::Disabled, QPalette::Base,
pal.brush(QPalette::Active, QPalette::Base));
}
- palettes.insert(mac_widget_colors[i].paletteRole, new QPalette(pal));
+ palettes.insert(mac_widget_colors[i].paletteRole, &pal);
}
return palettes;
}
diff --git a/src/plugins/platforms/cocoa/qcocoatheme.mm b/src/plugins/platforms/cocoa/qcocoatheme.mm
index f8eed0ebf1..8337e00eb6 100644
--- a/src/plugins/platforms/cocoa/qcocoatheme.mm
+++ b/src/plugins/platforms/cocoa/qcocoatheme.mm
@@ -290,6 +290,8 @@ QVariant QCocoaTheme::themeHint(ThemeHint hint) const
sizes << 16 << 32 << 64 << 128;
return QVariant::fromValue(sizes);
}
+ case QPlatformTheme::PasswordMaskDelay:
+ return QVariant(QChar(kBulletUnicode));
default:
break;
}
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm
index 4e567c6c63..5ff1bf83ae 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.mm
+++ b/src/plugins/platforms/cocoa/qcocoawindow.mm
@@ -283,6 +283,10 @@ void QCocoaWindow::setVisible(bool visible)
parentCocoaWindow->m_activePopupWindow = window();
// QTBUG-30266: a window should not be resizable while a transient popup is open
// Since this isn't a native popup, the window manager doesn't close the popup when you click outside
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
+ if (QSysInfo::QSysInfo::MacintoshVersion >= QSysInfo::MV_10_7
+ && !([parentCocoaWindow->m_nsWindow styleMask] & NSFullScreenWindowMask))
+#endif
[parentCocoaWindow->m_nsWindow setStyleMask:
(parentCocoaWindow->windowStyleMask(parentCocoaWindow->m_windowFlags) & ~NSResizableWindowMask)];
}
@@ -346,7 +350,12 @@ void QCocoaWindow::setVisible(bool visible)
} else {
[m_contentView setHidden:YES];
}
- if (parentCocoaWindow && window()->type() == Qt::Popup)
+ if (parentCocoaWindow && window()->type() == Qt::Popup
+#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)
+#endif
+ )
// QTBUG-30266: a window should not be resizable while a transient popup is open
[parentCocoaWindow->m_nsWindow setStyleMask:parentCocoaWindow->windowStyleMask(parentCocoaWindow->m_windowFlags)];
}
@@ -471,6 +480,8 @@ void QCocoaWindow::setWindowIcon(const QIcon &icon)
NSButton *iconButton = [m_nsWindow standardWindowButton:NSWindowDocumentIconButton];
if (iconButton == nil) {
+ if (icon.isNull())
+ return;
NSString *title = QCFString::toNSString(window()->title());
[m_nsWindow setRepresentedURL:[NSURL fileURLWithPath:title]];
iconButton = [m_nsWindow standardWindowButton:NSWindowDocumentIconButton];
@@ -852,7 +863,7 @@ void QCocoaWindow::syncWindowState(Qt::WindowState newState)
// if content view width or height is 0 then the window animations will crash so
// do nothing except set the new state
NSRect contentRect = [contentView() frame];
- if (contentRect.size.width <= 0 || contentRect.size.height <= 0) {
+ if (contentRect.size.width < 0 || contentRect.size.height < 0) {
qWarning() << Q_FUNC_INFO << "invalid window content view size, check your window geometry";
m_synchedWindowState = newState;
return;
@@ -905,7 +916,7 @@ QCocoaMenuBar *QCocoaWindow::menubar() const
void QCocoaWindow::registerTouch(bool enable)
{
m_registerTouchCount += enable ? 1 : -1;
- if (m_registerTouchCount == 1)
+ if (enable && m_registerTouchCount == 1)
[m_contentView setAcceptsTouchEvents:YES];
else if (m_registerTouchCount == 0)
[m_contentView setAcceptsTouchEvents:NO];
diff --git a/src/plugins/platforms/cocoa/qmacmime.mm b/src/plugins/platforms/cocoa/qmacmime.mm
index 89539de331..51c39357ea 100644
--- a/src/plugins/platforms/cocoa/qmacmime.mm
+++ b/src/plugins/platforms/cocoa/qmacmime.mm
@@ -553,10 +553,8 @@ QVariant QMacPasteboardMimeTiff::convertToMime(const QString &mime, QList<QByteA
a.size(), kCFAllocatorNull);
QCFType<CGImageSourceRef> imageSource = CGImageSourceCreateWithData(tiffData, 0);
image = CGImageSourceCreateImageAtIndex(imageSource, 0, 0);
-
- // ### TODO (msorvig) QPixmap conversion
- //if (image != 0)
- // ret = QVariant(QPixmap::fromMacCGImageRef(image).toImage());
+ if (image != 0)
+ ret = QVariant(qt_mac_toQImage(image));
return ret;
}
diff --git a/src/plugins/platforms/cocoa/qnsview.h b/src/plugins/platforms/cocoa/qnsview.h
index e7ea3d8f8d..68145ec914 100644
--- a/src/plugins/platforms/cocoa/qnsview.h
+++ b/src/plugins/platforms/cocoa/qnsview.h
@@ -63,7 +63,6 @@ QT_END_NAMESPACE
QWindow *m_window;
QCocoaWindow *m_platformWindow;
Qt::MouseButtons m_buttons;
- QAccessibleInterface *m_accessibleRoot;
QString m_composingText;
bool m_sendKeyEvent;
QStringList *currentCustomDragTypes;
diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm
index 568cc4bebf..52e2d781ee 100644
--- a/src/plugins/platforms/cocoa/qnsview.mm
+++ b/src/plugins/platforms/cocoa/qnsview.mm
@@ -121,7 +121,6 @@ static QTouchDevice *touchDevice = 0;
m_window = window;
m_platformWindow = platformWindow;
- m_accessibleRoot = 0;
m_sendKeyEvent = false;
#ifdef QT_COCOA_ENABLE_ACCESSIBILITY_INSPECTOR
@@ -130,15 +129,13 @@ static QTouchDevice *touchDevice = 0;
static bool skipAccessibilityForInspectorWindows = false;
if (!skipAccessibilityForInspectorWindows) {
- m_accessibleRoot = window->accessibleRoot();
+ // m_accessibleRoot = window->accessibleRoot();
AccessibilityInspector *inspector = new AccessibilityInspector(window);
skipAccessibilityForInspectorWindows = true;
inspector->inspectWindow(window);
skipAccessibilityForInspectorWindows = false;
}
-#else
- m_accessibleRoot = window->accessibleRoot();
#endif
[self registerDragTypes];
diff --git a/src/plugins/platforms/cocoa/qnsviewaccessibility.mm b/src/plugins/platforms/cocoa/qnsviewaccessibility.mm
index e3b8cf6532..c43c0b5068 100644
--- a/src/plugins/platforms/cocoa/qnsviewaccessibility.mm
+++ b/src/plugins/platforms/cocoa/qnsviewaccessibility.mm
@@ -45,6 +45,7 @@
#include "qcocoahelpers.h"
#include "qcocoaaccessibility.h"
#include "qcocoaaccessibilityelement.h"
+#include <qpa/qplatformintegration.h>
#include <QtGui/private/qaccessible2_p.h>
#include <QtCore/QDebug>
@@ -60,22 +61,26 @@
}
- (id)accessibilityAttributeValue:(NSString *)attribute {
+
+ // activate accessibility updates
+ QGuiApplicationPrivate::platformIntegration()->accessibility()->setActive(true);
+
if ([attribute isEqualToString:NSAccessibilityRoleAttribute]) {
- if (m_accessibleRoot)
- return QCocoaAccessible::macRole(m_accessibleRoot);
+ if (m_window->accessibleRoot())
+ return QCocoaAccessible::macRole(m_window->accessibleRoot());
return NSAccessibilityUnknownRole;
} else if ([attribute isEqualToString:NSAccessibilityRoleDescriptionAttribute]) {
return NSAccessibilityRoleDescriptionForUIElement(self);
} else if ([attribute isEqualToString:NSAccessibilityChildrenAttribute]) {
- if (!m_accessibleRoot)
+ if (!m_window->accessibleRoot())
return [super accessibilityAttributeValue:attribute];
// Create QCocoaAccessibleElements for each child if the
// root accessible interface.
- int numKids = m_accessibleRoot->childCount();
+ int numKids = m_window->accessibleRoot()->childCount();
NSMutableArray *kids = [NSMutableArray arrayWithCapacity:numKids];
for (int i = 0; i < numKids; ++i) {
- QAccessibleInterface *child = m_accessibleRoot->child(i);
+ QAccessibleInterface *child = m_window->accessibleRoot()->child(i);
Q_ASSERT(child);
QAccessible::Id childAxid = QAccessible::uniqueId(child);
QCocoaAccessibleElement *element = [QCocoaAccessibleElement createElementWithId:childAxid parent:self];
@@ -90,10 +95,10 @@
}
- (id)accessibilityHitTest:(NSPoint)point {
- if (!m_accessibleRoot)
+ if (!m_window->accessibleRoot())
return [super accessibilityHitTest:point];
- QAccessibleInterface *childInterface = m_accessibleRoot->childAt(point.x, qt_mac_flipYCoordinate(point.y));
+ QAccessibleInterface *childInterface = m_window->accessibleRoot()->childAt(point.x, qt_mac_flipYCoordinate(point.y));
// No child found, meaning we hit the NSView
if (!childInterface) {
return [super accessibilityHitTest:point];
diff --git a/src/plugins/platforms/cocoa/qprintengine_mac.mm b/src/plugins/platforms/cocoa/qprintengine_mac.mm
index 4748005f1a..2dedf99582 100644
--- a/src/plugins/platforms/cocoa/qprintengine_mac.mm
+++ b/src/plugins/platforms/cocoa/qprintengine_mac.mm
@@ -364,6 +364,9 @@ int QMacPrintEngine::metric(QPaintDevice::PaintDeviceMetric m) const
case QPaintDevice::PdmDepth:
val = 24;
break;
+ case QPaintDevice::PdmDevicePixelRatio:
+ val = 1;
+ break;
default:
val = 0;
qWarning("QPrinter::metric: Invalid metric command");
diff --git a/src/plugins/platforms/eglfs/qeglfsintegration.cpp b/src/plugins/platforms/eglfs/qeglfsintegration.cpp
index 64e11b4e07..615b69f7d9 100644
--- a/src/plugins/platforms/eglfs/qeglfsintegration.cpp
+++ b/src/plugins/platforms/eglfs/qeglfsintegration.cpp
@@ -145,7 +145,8 @@ bool QEglFSIntegration::hasCapability(QPlatformIntegration::Capability cap) cons
QPlatformWindow *QEglFSIntegration::createPlatformWindow(QWindow *window) const
{
- QPlatformWindow *w = new QEglFSWindow(window);
+ QEglFSWindow *w = new QEglFSWindow(window);
+ w->create();
w->requestActivateWindow();
return w;
}
diff --git a/src/plugins/platforms/eglfs/qeglfswindow.cpp b/src/plugins/platforms/eglfs/qeglfswindow.cpp
index 68cef6253e..ebf8e4af85 100644
--- a/src/plugins/platforms/eglfs/qeglfswindow.cpp
+++ b/src/plugins/platforms/eglfs/qeglfswindow.cpp
@@ -59,10 +59,6 @@ QEglFSWindow::QEglFSWindow(QWindow *w)
#ifdef QEGL_EXTRA_DEBUG
qWarning("QEglWindow %p: %p 0x%x\n", this, w, uint(m_winid));
#endif
-
- setWindowState(Qt::WindowFullScreen);
-
- create();
}
QEglFSWindow::~QEglFSWindow()
@@ -72,6 +68,8 @@ QEglFSWindow::~QEglFSWindow()
void QEglFSWindow::create()
{
+ setWindowState(Qt::WindowFullScreen);
+
if (m_window)
return;
diff --git a/src/plugins/platforms/eglfs/qeglfswindow.h b/src/plugins/platforms/eglfs/qeglfswindow.h
index a351b4a6f4..67a64973ce 100644
--- a/src/plugins/platforms/eglfs/qeglfswindow.h
+++ b/src/plugins/platforms/eglfs/qeglfswindow.h
@@ -68,10 +68,12 @@ public:
virtual void invalidateSurface();
virtual void resetSurface();
-private:
- WId m_winid;
+protected:
EGLSurface m_surface;
EGLNativeWindowType m_window;
+
+private:
+ WId m_winid;
EGLConfig m_config;
QSurfaceFormat m_format;
};
diff --git a/src/plugins/platforms/ios/qiosapplicationdelegate.h b/src/plugins/platforms/ios/qiosapplicationdelegate.h
index 442b37f1b3..3d3ba58049 100644
--- a/src/plugins/platforms/ios/qiosapplicationdelegate.h
+++ b/src/plugins/platforms/ios/qiosapplicationdelegate.h
@@ -42,9 +42,12 @@
#import <UIKit/UIKit.h>
#import <QtGui/QtGui>
+#import "qiosviewcontroller.h"
+
@interface QIOSApplicationDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
+@property (strong, nonatomic) QIOSViewController *qiosViewController;
@end
diff --git a/src/plugins/platforms/ios/qiosapplicationdelegate.mm b/src/plugins/platforms/ios/qiosapplicationdelegate.mm
index 41a3fff84f..10cbe529c4 100644
--- a/src/plugins/platforms/ios/qiosapplicationdelegate.mm
+++ b/src/plugins/platforms/ios/qiosapplicationdelegate.mm
@@ -46,6 +46,7 @@
@implementation QIOSApplicationDelegate
@synthesize window;
+@synthesize qiosViewController;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
@@ -85,6 +86,7 @@
- (void)dealloc
{
+ [qiosViewController release];
[window release];
[super dealloc];
}
diff --git a/src/plugins/platforms/ios/qiosbackingstore.mm b/src/plugins/platforms/ios/qiosbackingstore.mm
index 566ff3a672..f3c1af2b2d 100644
--- a/src/plugins/platforms/ios/qiosbackingstore.mm
+++ b/src/plugins/platforms/ios/qiosbackingstore.mm
@@ -52,7 +52,11 @@ QIOSBackingStore::QIOSBackingStore(QWindow *window)
, m_context(new QOpenGLContext)
, m_device(0)
{
- m_context->setFormat(window->requestedFormat());
+ QSurfaceFormat fmt = window->requestedFormat();
+ fmt.setDepthBufferSize(16);
+ fmt.setStencilBufferSize(8);
+
+ m_context->setFormat(fmt);
m_context->setScreen(window->screen());
m_context->create();
}
diff --git a/src/plugins/platforms/ios/qiosglobal.h b/src/plugins/platforms/ios/qiosglobal.h
index 3be9f8bb21..fd328c9171 100644
--- a/src/plugins/platforms/ios/qiosglobal.h
+++ b/src/plugins/platforms/ios/qiosglobal.h
@@ -52,7 +52,7 @@ QT_BEGIN_NAMESPACE
class QPlatformScreen;
bool isQtApplication();
-QIOSViewController *rootViewController();
+QIOSViewController *qiosViewController();
CGRect toCGRect(const QRect &rect);
QRect fromCGRect(const CGRect &rect);
diff --git a/src/plugins/platforms/ios/qiosglobal.mm b/src/plugins/platforms/ios/qiosglobal.mm
index 5860078372..d26eca54e5 100644
--- a/src/plugins/platforms/ios/qiosglobal.mm
+++ b/src/plugins/platforms/ios/qiosglobal.mm
@@ -58,10 +58,14 @@ bool isQtApplication()
return isQt;
}
-QIOSViewController *rootViewController()
+QIOSViewController *qiosViewController()
{
+ // If Qt controls the application, we have created a root view controller were we place top-level
+ // QWindows. Note that in a mixed native application, our view controller might later be removed or
+ // added as a child of another controller. To protect against that, we keep an explicit pointer to the
+ // view controller in cases where this is the controller we need to access.
static QIOSViewController *c = isQtApplication() ?
- static_cast<QIOSViewController *>([UIApplication sharedApplication].delegate.window.rootViewController) : nil;
+ static_cast<QIOSApplicationDelegate *>([UIApplication sharedApplication].delegate).qiosViewController : nil;
return c;
}
diff --git a/src/plugins/platforms/ios/qiosscreen.mm b/src/plugins/platforms/ios/qiosscreen.mm
index d86ed5f090..b73f9c3cbc 100644
--- a/src/plugins/platforms/ios/qiosscreen.mm
+++ b/src/plugins/platforms/ios/qiosscreen.mm
@@ -142,7 +142,7 @@ QIOSScreen::QIOSScreen(unsigned int screenIndex)
if (isQtApplication()) {
// When in a non-mixed environment, let QScreen follow the current interface orientation:
- setPrimaryOrientation(toQtScreenOrientation(UIDeviceOrientation(rootViewController().interfaceOrientation)));
+ setPrimaryOrientation(toQtScreenOrientation(UIDeviceOrientation(qiosViewController().interfaceOrientation)));
}
[pool release];
diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm
index d7a2fa1a75..5edf81af93 100644
--- a/src/plugins/platforms/ios/qioswindow.mm
+++ b/src/plugins/platforms/ios/qioswindow.mm
@@ -375,7 +375,7 @@ void QIOSWindow::setVisible(bool visible)
requestActivateWindow();
} else {
// Activate top-most visible QWindow:
- NSArray *subviews = rootViewController().view.subviews;
+ NSArray *subviews = qiosViewController().view.subviews;
for (int i = int(subviews.count) - 1; i >= 0; --i) {
UIView *view = [subviews objectAtIndex:i];
if (!view.hidden) {
@@ -431,7 +431,7 @@ void QIOSWindow::setParent(const QPlatformWindow *parentWindow)
UIView *parentView = reinterpret_cast<UIView *>(parentWindow->winId());
[parentView addSubview:m_view];
} else if (isQtApplication()) {
- [rootViewController().view addSubview:m_view];
+ [qiosViewController().view addSubview:m_view];
}
}
diff --git a/src/plugins/platforms/ios/qtmain.mm b/src/plugins/platforms/ios/qtmain.mm
index 916224f936..19c98f2c59 100644
--- a/src/plugins/platforms/ios/qtmain.mm
+++ b/src/plugins/platforms/ios/qtmain.mm
@@ -56,7 +56,8 @@ extern int qt_main(int argc, char *argv[]);
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
- self.window.rootViewController = [[[QIOSViewController alloc] init] autorelease];
+ self.qiosViewController = [[[QIOSViewController alloc] init] autorelease];
+ self.window.rootViewController = self.qiosViewController;
#ifdef QT_DEBUG
self.window.backgroundColor = [UIColor cyanColor];
diff --git a/src/plugins/platforms/offscreen/qoffscreencommon.h b/src/plugins/platforms/offscreen/qoffscreencommon.h
index a5df7d05d3..28546aed88 100644
--- a/src/plugins/platforms/offscreen/qoffscreencommon.h
+++ b/src/plugins/platforms/offscreen/qoffscreencommon.h
@@ -73,12 +73,14 @@ public:
QScopedPointer<QPlatformCursor> m_cursor;
};
+#ifndef QT_NO_DRAGANDDROP
class QOffscreenDrag : public QPlatformDrag
{
public:
QMimeData *platformDropData() { return 0; }
Qt::DropAction drag(QDrag *) { return Qt::IgnoreAction; }
};
+#endif
class QOffscreenBackingStore : public QPlatformBackingStore
{
diff --git a/src/plugins/platforms/offscreen/qoffscreenintegration.cpp b/src/plugins/platforms/offscreen/qoffscreenintegration.cpp
index e3fcc7ebb0..5b74ad3b8d 100644
--- a/src/plugins/platforms/offscreen/qoffscreenintegration.cpp
+++ b/src/plugins/platforms/offscreen/qoffscreenintegration.cpp
@@ -106,7 +106,9 @@ QOffscreenIntegration::QOffscreenIntegration()
m_fontDatabase.reset(new QBasicFontDatabase());
#endif
+#ifndef QT_NO_DRAGANDDROP
m_drag.reset(new QOffscreenDrag);
+#endif
m_services.reset(new QPlatformServices);
QGuiApplicationPrivate::instance()->setEventDispatcher(m_eventDispatcher);
@@ -149,10 +151,12 @@ QPlatformFontDatabase *QOffscreenIntegration::fontDatabase() const
return m_fontDatabase.data();
}
+#ifndef QT_NO_DRAGANDDROP
QPlatformDrag *QOffscreenIntegration::drag() const
{
return m_drag.data();
}
+#endif
QPlatformServices *QOffscreenIntegration::services() const
{
diff --git a/src/plugins/platforms/offscreen/qoffscreenintegration.h b/src/plugins/platforms/offscreen/qoffscreenintegration.h
index eb03100ec9..b403ce83b3 100644
--- a/src/plugins/platforms/offscreen/qoffscreenintegration.h
+++ b/src/plugins/platforms/offscreen/qoffscreenintegration.h
@@ -60,7 +60,9 @@ public:
QPlatformWindow *createPlatformWindow(QWindow *window) const;
QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const;
+#ifndef QT_NO_DRAGANDDROP
QPlatformDrag *drag() const;
+#endif
QPlatformServices *services() const;
QPlatformFontDatabase *fontDatabase() const;
@@ -71,7 +73,9 @@ public:
private:
QAbstractEventDispatcher *m_eventDispatcher;
QScopedPointer<QPlatformFontDatabase> m_fontDatabase;
+#ifndef QT_NO_DRAGANDDROP
QScopedPointer<QPlatformDrag> m_drag;
+#endif
QScopedPointer<QPlatformServices> m_services;
};
diff --git a/src/plugins/platforms/qnx/qqnxwindow.cpp b/src/plugins/platforms/qnx/qqnxwindow.cpp
index f1bebee9b2..a351ec865a 100644
--- a/src/plugins/platforms/qnx/qqnxwindow.cpp
+++ b/src/plugins/platforms/qnx/qqnxwindow.cpp
@@ -172,6 +172,7 @@ void QQnxWindow::setGeometry(const QRect &rect)
{
const QRect oldGeometry = setGeometryHelper(rect);
+#if !defined(QT_NO_OPENGL)
// If this is an OpenGL window we need to request that the GL context updates
// the EGLsurface on which it is rendering. The surface will be recreated the
// next time QQnxGLContext::makeCurrent() is called.
@@ -184,6 +185,7 @@ void QQnxWindow::setGeometry(const QRect &rect)
if (m_platformOpenGLContext != 0 && bufferSize() != rect.size())
m_platformOpenGLContext->requestSurfaceChange();
}
+#endif
// Send a geometry change event to Qt (triggers resizeEvent() in QWindow/QWidget).
@@ -353,13 +355,12 @@ void QQnxWindow::setBufferSize(const QSize &size)
// Create window buffers if they do not exist
if (m_bufferSize.isEmpty()) {
+ val[0] = m_screen->nativeFormat();
#if !defined(QT_NO_OPENGL)
// Get pixel format from EGL config if using OpenGL;
// otherwise inherit pixel format of window's screen
if (m_platformOpenGLContext != 0) {
val[0] = platformWindowFormatToNativeFormat(m_platformOpenGLContext->format());
- } else {
- val[0] = m_screen->nativeFormat();
}
#endif
diff --git a/src/plugins/platforms/windows/accessible/qwindowsaccessibility.cpp b/src/plugins/platforms/windows/accessible/qwindowsaccessibility.cpp
index f222deeeac..63b4370dc2 100644
--- a/src/plugins/platforms/windows/accessible/qwindowsaccessibility.cpp
+++ b/src/plugins/platforms/windows/accessible/qwindowsaccessibility.cpp
@@ -52,7 +52,9 @@
#include <QtCore/qsettings.h>
#include <QtGui/qaccessible.h>
#include <QtGui/private/qaccessible2_p.h>
+#include <QtGui/private/qguiapplication_p.h>
#include <qpa/qplatformnativeinterface.h>
+#include <qpa/qplatformintegration.h>
#include <QtGui/qwindow.h>
#include <QtGui/qguiapplication.h>
@@ -245,6 +247,8 @@ bool QWindowsAccessibility::handleAccessibleObjectFromWindowRequest(HWND hwnd, W
if (static_cast<long>(lParam) == static_cast<long>(UiaRootObjectId)) {
/* For UI Automation */
} else if ((DWORD)lParam == DWORD(OBJID_CLIENT)) {
+ // Start handling accessibility internally
+ QGuiApplicationPrivate::platformIntegration()->accessibility()->setActive(true);
#if 1
// Ignoring all requests while starting up
// ### Maybe QPA takes care of this???
diff --git a/src/plugins/platforms/windows/qwindowsbackingstore.cpp b/src/plugins/platforms/windows/qwindowsbackingstore.cpp
index b40aefa225..dfbbe3069c 100644
--- a/src/plugins/platforms/windows/qwindowsbackingstore.cpp
+++ b/src/plugins/platforms/windows/qwindowsbackingstore.cpp
@@ -146,7 +146,7 @@ void QWindowsBackingStore::resize(const QSize &size, const QRegion &region)
#endif
QImage::Format format = QWindowsNativeImage::systemFormat();
if (format == QImage::Format_RGB32 && rasterWindow()->window()->format().hasAlpha())
- format = QImage::Format_ARGB32;
+ format = QImage::Format_ARGB32_Premultiplied;
m_image.reset(new QWindowsNativeImage(size.width(), size.height(), format));
}
}
diff --git a/src/plugins/platforms/windows/qwindowsclipboard.cpp b/src/plugins/platforms/windows/qwindowsclipboard.cpp
index b66a16ae58..cf6cb199c7 100644
--- a/src/plugins/platforms/windows/qwindowsclipboard.cpp
+++ b/src/plugins/platforms/windows/qwindowsclipboard.cpp
@@ -178,6 +178,20 @@ void QWindowsClipboard::unregisterViewer()
}
}
+static bool isProcessBeingDebugged(HWND hwnd)
+{
+ DWORD pid = 0;
+ if (!GetWindowThreadProcessId(hwnd, &pid) || !pid)
+ return false;
+ const HANDLE processHandle = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid);
+ if (!processHandle)
+ return false;
+ BOOL debugged = FALSE;
+ CheckRemoteDebuggerPresent(processHandle, &debugged);
+ CloseHandle(processHandle);
+ return debugged != FALSE;
+}
+
void QWindowsClipboard::propagateClipboardMessage(UINT message, WPARAM wParam, LPARAM lParam) const
{
if (!m_nextClipboardViewer)
@@ -189,6 +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
+ // 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);
}
diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp
index 5fa954cb12..7fedc27951 100644
--- a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp
+++ b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp
@@ -1173,7 +1173,7 @@ QFontEngine *QWindowsFontDatabase::fontEngine(const QByteArray &fontData, qreal
fontFile->Release();
fontEngine = new QWindowsFontEngineDirectWrite(directWriteFontFace, pixelSize,
- m_fontEngineData);
+ sharedFontData());
// Get font family from font data
fontEngine->fontDef.family = font.familyName();
diff --git a/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp b/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp
index 5b6ce695d8..c0f1b3a000 100644
--- a/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp
+++ b/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp
@@ -220,6 +220,7 @@ QWindowsFontEngineDirectWrite::QWindowsFontEngineDirectWrite(IDWriteFontFace *di
fontDef.pixelSize = pixelSize;
collectMetrics();
+ cache_cost = (m_ascent.toInt() + m_descent.toInt()) * m_xHeight.toInt() * 2000;
}
QWindowsFontEngineDirectWrite::~QWindowsFontEngineDirectWrite()
@@ -740,6 +741,8 @@ void QWindowsFontEngineDirectWrite::initFontInfo(const QFontDef &request,
if (familyNames != NULL)
familyNames->Release();
+ if (fontFamily)
+ fontFamily->Release();
if (FAILED(hr))
qErrnoWarning(hr, "initFontInfo: Failed to get family name");
diff --git a/src/plugins/platforms/windows/qwindowsglcontext.cpp b/src/plugins/platforms/windows/qwindowsglcontext.cpp
index da3e2a6a6a..ae66ef8a3d 100644
--- a/src/plugins/platforms/windows/qwindowsglcontext.cpp
+++ b/src/plugins/platforms/windows/qwindowsglcontext.cpp
@@ -1052,8 +1052,16 @@ bool QWindowsGLContext::makeCurrent(QPlatformSurface *surface)
// Do we already have a DC entry for that window?
QWindowsWindow *window = static_cast<QWindowsWindow *>(surface);
const HWND hwnd = window->handle();
- if (const QOpenGLContextData *contextData = findByHWND(m_windowContexts, hwnd))
+ if (const QOpenGLContextData *contextData = findByHWND(m_windowContexts, hwnd)) {
+ // Repeated calls to wglMakeCurrent when vsync is enabled in the driver will
+ // often result in 100% cpuload. This check is cheap and avoids the problem.
+ // This is reproducable on NVidia cards and Intel onboard chips.
+ if (wglGetCurrentContext() == contextData->renderingContext
+ && wglGetCurrentDC() == contextData->hdc) {
+ return true;
+ }
return wglMakeCurrent(contextData->hdc, contextData->renderingContext);
+ }
// Create a new entry.
const QOpenGLContextData newContext(m_renderingContext, hwnd, GetDC(hwnd));
if (!newContext.hdc)
diff --git a/src/plugins/platforms/windows/qwindowsintegration.cpp b/src/plugins/platforms/windows/qwindowsintegration.cpp
index 03e4925c3b..73df3ec032 100644
--- a/src/plugins/platforms/windows/qwindowsintegration.cpp
+++ b/src/plugins/platforms/windows/qwindowsintegration.cpp
@@ -113,6 +113,8 @@ public:
Q_INVOKABLE QString registerWindowClass(const QString &classNameIn, void *eventProc) const;
+ Q_INVOKABLE void beep() { MessageBeep(MB_OK); } // For QApplication
+
bool asyncExpose() const;
void setAsyncExpose(bool value);
diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp
index 9b2b67619d..2a5e08cf41 100644
--- a/src/plugins/platforms/windows/qwindowswindow.cpp
+++ b/src/plugins/platforms/windows/qwindowswindow.cpp
@@ -1802,6 +1802,19 @@ QWindowsWindow *QWindowsWindow::childAt(const QPoint &clientPoint, unsigned cwex
}
#ifndef Q_OS_WINCE
+void QWindowsWindow::setAlertState(bool enabled)
+{
+ if (isAlertState() == enabled)
+ return;
+ if (enabled) {
+ alertWindow(0);
+ setFlag(AlertState);
+ } else {
+ stopAlertWindow();
+ clearFlag(AlertState);
+ }
+}
+
void QWindowsWindow::alertWindow(int durationMs)
{
DWORD timeOutMs = GetCaretBlinkTime();
diff --git a/src/plugins/platforms/windows/qwindowswindow.h b/src/plugins/platforms/windows/qwindowswindow.h
index 1148440f05..2117ca50b8 100644
--- a/src/plugins/platforms/windows/qwindowswindow.h
+++ b/src/plugins/platforms/windows/qwindowswindow.h
@@ -132,7 +132,8 @@ public:
SynchronousGeometryChangeEvent = 0x400,
WithinSetStyle = 0x800,
WithinDestroy = 0x1000,
- TouchRegistered = 0x2000
+ TouchRegistered = 0x2000,
+ AlertState = 0x4000
};
struct WindowData
@@ -255,6 +256,8 @@ public:
void setWindowIcon(const QIcon &icon);
#ifndef Q_OS_WINCE
+ void setAlertState(bool enabled);
+ bool isAlertState() const { return testFlag(AlertState); }
void alertWindow(int durationMs = 0);
void stopAlertWindow();
#endif
diff --git a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp
index 08e72ed5ce..6241898462 100644
--- a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp
+++ b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp
@@ -57,6 +57,10 @@
#include "qglxintegration.h"
#endif
+#ifndef XCB_USE_XLIB
+# include <stdio.h>
+#endif
+
QT_BEGIN_NAMESPACE
class QXcbResourceMap : public QMap<QByteArray, QXcbNativeInterface::ResourceType>
@@ -84,6 +88,16 @@ QXcbNativeInterface::QXcbNativeInterface() :
{
}
+void QXcbNativeInterface::beep() // For QApplication::beep()
+{
+#ifdef XCB_USE_XLIB
+ ::Display *display = (::Display *)nativeResourceForScreen(QByteArrayLiteral("display"), QGuiApplication::primaryScreen());
+ XBell(display, 0);
+#else
+ fputc(7, stdout);
+#endif
+}
+
void *QXcbNativeInterface::nativeResourceForContext(const QByteArray &resourceString, QOpenGLContext *context)
{
QByteArray lowerCaseResource = resourceString.toLower();
diff --git a/src/plugins/platforms/xcb/qxcbnativeinterface.h b/src/plugins/platforms/xcb/qxcbnativeinterface.h
index 75d42ac6b0..db0fa3e2ca 100644
--- a/src/plugins/platforms/xcb/qxcbnativeinterface.h
+++ b/src/plugins/platforms/xcb/qxcbnativeinterface.h
@@ -53,6 +53,7 @@ class QXcbConnection;
class QXcbNativeInterface : public QPlatformNativeInterface
{
+ Q_OBJECT
public:
enum ResourceType {
Display,
@@ -89,6 +90,8 @@ public:
static void *eglContextForContext(QOpenGLContext *context);
static void *glxContextForContext(QOpenGLContext *context);
+ Q_INVOKABLE void beep();
+
private:
const QByteArray m_genericEventFilterType;
diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp
index 5af6a9ec9d..68ccbfb8c0 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.cpp
+++ b/src/plugins/platforms/xcb/qxcbwindow.cpp
@@ -189,6 +189,7 @@ QXcbWindow::QXcbWindow(QWindow *window)
, m_usingSyncProtocol(false)
, m_deferredActivation(false)
, m_embedded(false)
+ , m_alertState(false)
, m_netWmUserTimeWindow(XCB_NONE)
, m_dirtyFrameMargins(false)
#if defined(XCB_USE_EGL)
@@ -2047,4 +2048,17 @@ void QXcbWindow::setMask(const QRegion &region)
#endif // !QT_NO_SHAPE
+void QXcbWindow::setAlertState(bool enabled)
+{
+ if (m_alertState == enabled)
+ return;
+ const NetWmStates oldState = netWmStates();
+ m_alertState = enabled;
+ if (enabled) {
+ setNetWmStates(oldState | NetWmStateDemandsAttention);
+ } else {
+ setNetWmStates(oldState & ~NetWmStateDemandsAttention);
+ }
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/xcb/qxcbwindow.h b/src/plugins/platforms/xcb/qxcbwindow.h
index f4bd2d96ff..300596845e 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.h
+++ b/src/plugins/platforms/xcb/qxcbwindow.h
@@ -56,7 +56,6 @@ QT_BEGIN_NAMESPACE
class QXcbScreen;
class QXcbEGLSurface;
class QIcon;
-
class QXcbWindow : public QXcbObject, public QPlatformWindow
{
public:
@@ -120,6 +119,9 @@ public:
void setMask(const QRegion &region);
#endif // !QT_NO_SHAPE
+ void setAlertState(bool enabled);
+ bool isAlertState() const { return m_alertState; }
+
xcb_window_t xcb_window() const { return m_window; }
uint depth() const { return m_depth; }
QImage::Format imageFormat() const { return m_imageFormat; }
@@ -194,6 +196,7 @@ private:
bool m_deferredExpose;
bool m_configureNotifyPending;
bool m_embedded;
+ bool m_alertState;
xcb_window_t m_netWmUserTimeWindow;
QSurfaceFormat m_format;