summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/ios
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/platforms/ios')
-rw-r--r--src/plugins/platforms/ios/plugin.mm2
-rw-r--r--src/plugins/platforms/ios/qiosapplicationstate.mm12
-rw-r--r--src/plugins/platforms/ios/qiosbackingstore.h8
-rw-r--r--src/plugins/platforms/ios/qiosbackingstore.mm109
-rw-r--r--src/plugins/platforms/ios/qiosclipboard.mm4
-rw-r--r--src/plugins/platforms/ios/qioscontext.mm6
-rw-r--r--src/plugins/platforms/ios/qioseventdispatcher.mm6
-rw-r--r--src/plugins/platforms/ios/qiosfileengineassetslibrary.h7
-rw-r--r--src/plugins/platforms/ios/qiosfileengineassetslibrary.mm320
-rw-r--r--src/plugins/platforms/ios/qiosglobal.h2
-rw-r--r--src/plugins/platforms/ios/qiosglobal.mm4
-rw-r--r--src/plugins/platforms/ios/qiosinputcontext.mm2
-rw-r--r--src/plugins/platforms/ios/qiosintegration.mm15
-rw-r--r--src/plugins/platforms/ios/qiosmenu.mm4
-rw-r--r--src/plugins/platforms/ios/qiosscreen.mm8
-rw-r--r--src/plugins/platforms/ios/qiostextresponder.mm34
-rw-r--r--src/plugins/platforms/ios/qiosviewcontroller.mm6
-rw-r--r--src/plugins/platforms/ios/qioswindow.mm6
-rw-r--r--src/plugins/platforms/ios/quiaccessibilityelement.h4
-rw-r--r--src/plugins/platforms/ios/quiaccessibilityelement.mm26
-rw-r--r--src/plugins/platforms/ios/quiview.mm14
21 files changed, 469 insertions, 130 deletions
diff --git a/src/plugins/platforms/ios/plugin.mm b/src/plugins/platforms/ios/plugin.mm
index 41fe712f60..e68e1dfd6f 100644
--- a/src/plugins/platforms/ios/plugin.mm
+++ b/src/plugins/platforms/ios/plugin.mm
@@ -40,7 +40,7 @@ QT_BEGIN_NAMESPACE
class QIOSIntegrationPlugin : public QPlatformIntegrationPlugin
{
Q_OBJECT
- Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.2" FILE "ios.json")
+ Q_PLUGIN_METADATA(IID QPlatformIntegrationFactoryInterface_iid FILE "ios.json")
public:
QPlatformIntegration *create(const QString&, const QStringList&);
};
diff --git a/src/plugins/platforms/ios/qiosapplicationstate.mm b/src/plugins/platforms/ios/qiosapplicationstate.mm
index 92799f80c1..7a37e213bd 100644
--- a/src/plugins/platforms/ios/qiosapplicationstate.mm
+++ b/src/plugins/platforms/ios/qiosapplicationstate.mm
@@ -43,7 +43,7 @@
@implementation QIOSApplicationStateListener
-- (id) init
+- (id)init
{
self = [super init];
if (self) {
@@ -75,7 +75,7 @@
return self;
}
-- (void) dealloc
+- (void)dealloc
{
[[NSNotificationCenter defaultCenter]
removeObserver:self
@@ -92,12 +92,12 @@
[super dealloc];
}
-- (void) applicationDidBecomeActive
+- (void)applicationDidBecomeActive
{
[self handleApplicationStateChanged:UIApplicationStateActive];
}
-- (void) applicationWillResignActive
+- (void)applicationWillResignActive
{
// Note that UIApplication is still UIApplicationStateActive at this
// point, but since there is no separate notification for the inactive
@@ -105,12 +105,12 @@
[self handleApplicationStateChanged:UIApplicationStateInactive];
}
-- (void) applicationDidEnterBackground
+- (void)applicationDidEnterBackground
{
[self handleApplicationStateChanged:UIApplicationStateBackground];
}
-- (void) handleApplicationStateChanged:(UIApplicationState) uiApplicationState
+- (void)handleApplicationStateChanged:(UIApplicationState)uiApplicationState
{
// We may receive application state changes after QCoreApplication has
// gone down, as the block we schedule on the main queue keeps the
diff --git a/src/plugins/platforms/ios/qiosbackingstore.h b/src/plugins/platforms/ios/qiosbackingstore.h
index 68c77d9900..5d2ae429f1 100644
--- a/src/plugins/platforms/ios/qiosbackingstore.h
+++ b/src/plugins/platforms/ios/qiosbackingstore.h
@@ -39,6 +39,8 @@
QT_BEGIN_NAMESPACE
class QOpenGLPaintDevice;
+class QOpenGLFramebufferObject;
+class QOffscreenSurface;
class QIOSBackingStore : public QPlatformBackingStore
{
@@ -49,13 +51,19 @@ public:
QPaintDevice *paintDevice();
void beginPaint(const QRegion &);
+ void endPaint();
void flush(QWindow *window, const QRegion &region, const QPoint &offset);
void resize(const QSize &size, const QRegion &staticContents);
+ GLuint toTexture(const QRegion &dirtyRegion, QSize *textureSize, TextureFlags *flags) const;
+
+ void makeCurrent();
private:
QOpenGLContext *m_context;
QOpenGLPaintDevice *m_device;
+ QOpenGLFramebufferObject *m_fbo;
+ QOffscreenSurface *m_surface;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/ios/qiosbackingstore.mm b/src/plugins/platforms/ios/qiosbackingstore.mm
index acec95b0d3..875d06dc80 100644
--- a/src/plugins/platforms/ios/qiosbackingstore.mm
+++ b/src/plugins/platforms/ios/qiosbackingstore.mm
@@ -36,41 +36,117 @@
#include <QtGui/QOpenGLContext>
#include <QtGui/QOpenGLPaintDevice>
+#include <QtGui/QOpenGLFramebufferObject>
+#include <QtGui/QOffscreenSurface>
+#include <QtGui/private/qwindow_p.h>
#include <QtDebug>
+class QIOSPaintDevice : public QOpenGLPaintDevice
+{
+public:
+ QIOSPaintDevice(QIOSBackingStore *backingStore) : m_backingStore(backingStore) { }
+ void ensureActiveTarget() Q_DECL_OVERRIDE;
+
+private:
+ QIOSBackingStore *m_backingStore;
+};
+
+void QIOSPaintDevice::ensureActiveTarget()
+{
+ m_backingStore->makeCurrent();
+}
+
QIOSBackingStore::QIOSBackingStore(QWindow *window)
: QPlatformBackingStore(window)
, m_context(new QOpenGLContext)
, m_device(0)
+ , m_fbo(0)
+ , m_surface(0)
{
QSurfaceFormat fmt = window->requestedFormat();
- fmt.setDepthBufferSize(16);
- fmt.setStencilBufferSize(8);
+ // Due to sharing QIOSContext redirects our makeCurrent on window() attempts to
+ // the global share context. Hence it is essential to have a compatible format.
+ fmt.setDepthBufferSize(QSurfaceFormat::defaultFormat().depthBufferSize());
+ fmt.setStencilBufferSize(QSurfaceFormat::defaultFormat().stencilBufferSize());
+
+ if (fmt.depthBufferSize() == 0)
+ qWarning("No depth in default format, expect rendering errors");
- // Needed to prevent QOpenGLContext::makeCurrent() from failing
- window->setSurfaceType(QSurface::OpenGLSurface);
+ if (window->surfaceType() == QSurface::RasterSurface)
+ window->setSurfaceType(QSurface::OpenGLSurface);
m_context->setFormat(fmt);
m_context->setScreen(window->screen());
+ Q_ASSERT(QOpenGLContext::globalShareContext());
+ m_context->setShareContext(QOpenGLContext::globalShareContext());
m_context->create();
}
QIOSBackingStore::~QIOSBackingStore()
{
+ delete m_fbo;
+ delete m_surface;
delete m_context;
delete m_device;
}
+void QIOSBackingStore::makeCurrent()
+{
+ QSurface *surface = m_surface ? m_surface : static_cast<QSurface *>(window());
+ if (!m_context->makeCurrent(surface))
+ qWarning("QIOSBackingStore: makeCurrent() failed");
+ if (m_fbo)
+ m_fbo->bind();
+}
+
void QIOSBackingStore::beginPaint(const QRegion &)
{
- m_context->makeCurrent(window());
+ if (qt_window_private(window())->compositing) {
+ if (!m_fbo) {
+ delete m_device;
+ m_device = 0;
+ }
+ if (!m_surface) {
+ m_surface = new QOffscreenSurface;
+ m_surface->setFormat(m_context->format());
+ m_surface->create();
+ }
+ if (!m_context->makeCurrent(m_surface))
+ qWarning("QIOSBackingStore: Failed to make offscreen surface current");
+ const QSize size = window()->size() * window()->devicePixelRatio();
+ if (m_fbo && m_fbo->size() != size) {
+ delete m_fbo;
+ m_fbo = 0;
+ }
+ if (!m_fbo)
+ m_fbo = new QOpenGLFramebufferObject(size, QOpenGLFramebufferObject::CombinedDepthStencil);
+ } else if (m_fbo) {
+ delete m_fbo;
+ m_fbo = 0;
+ delete m_surface;
+ m_surface = 0;
+ delete m_device;
+ m_device = 0;
+ }
+
+ makeCurrent();
+
+ if (!m_device)
+ m_device = new QIOSPaintDevice(this);
+}
+
+void QIOSBackingStore::endPaint()
+{
+ if (m_fbo) {
+ m_fbo->release();
+ glFlush();
+ }
}
QPaintDevice *QIOSBackingStore::paintDevice()
{
- if (!m_device)
- m_device = new QOpenGLPaintDevice;
+ Q_ASSERT(m_device);
// Keep paint device size and device pixel ratio in sync with window
qreal devicePixelRatio = window()->devicePixelRatio();
@@ -82,6 +158,8 @@ QPaintDevice *QIOSBackingStore::paintDevice()
void QIOSBackingStore::flush(QWindow *window, const QRegion &region, const QPoint &offset)
{
+ Q_ASSERT(!qt_window_private(window)->compositing);
+
Q_UNUSED(region);
Q_UNUSED(offset);
@@ -111,4 +189,21 @@ void QIOSBackingStore::resize(const QSize &size, const QRegion &staticContents)
qWarning() << "QIOSBackingStore needs to have the same size as its window";
}
+GLuint QIOSBackingStore::toTexture(const QRegion &dirtyRegion, QSize *textureSize, TextureFlags *flags) const
+{
+ Q_ASSERT(qt_window_private(window())->compositing);
+ Q_UNUSED(dirtyRegion);
+
+ if (flags)
+ *flags = TextureFlip;
+
+ if (!m_fbo)
+ return 0;
+
+ if (textureSize)
+ *textureSize = m_fbo->size();
+
+ return m_fbo->texture();
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/ios/qiosclipboard.mm b/src/plugins/platforms/ios/qiosclipboard.mm
index 192ee67689..e0c6ec5d72 100644
--- a/src/plugins/platforms/ios/qiosclipboard.mm
+++ b/src/plugins/platforms/ios/qiosclipboard.mm
@@ -62,7 +62,7 @@
@implementation QUIClipboard
--(id)initWithQIOSClipboard:(QIOSClipboard *)qiosClipboard
+- (id)initWithQIOSClipboard:(QIOSClipboard *)qiosClipboard
{
self = [super init];
if (self) {
@@ -87,7 +87,7 @@
return self;
}
--(void)dealloc
+- (void)dealloc
{
[[NSNotificationCenter defaultCenter]
removeObserver:self
diff --git a/src/plugins/platforms/ios/qioscontext.mm b/src/plugins/platforms/ios/qioscontext.mm
index c7541fc51b..fe0ca33c13 100644
--- a/src/plugins/platforms/ios/qioscontext.mm
+++ b/src/plugins/platforms/ios/qioscontext.mm
@@ -116,7 +116,8 @@ static QString fboStatusString(GLenum status)
bool QIOSContext::makeCurrent(QPlatformSurface *surface)
{
- Q_ASSERT(surface && surface->surface()->surfaceType() == QSurface::OpenGLSurface);
+ Q_ASSERT(surface && (surface->surface()->surfaceType() == QSurface::OpenGLSurface
+ || surface->surface()->surfaceType() == QSurface::RasterGLSurface));
[EAGLContext setCurrentContext:m_eaglContext];
@@ -141,7 +142,8 @@ void QIOSContext::doneCurrent()
void QIOSContext::swapBuffers(QPlatformSurface *surface)
{
- Q_ASSERT(surface && surface->surface()->surfaceType() == QSurface::OpenGLSurface);
+ Q_ASSERT(surface && (surface->surface()->surfaceType() == QSurface::OpenGLSurface
+ || surface->surface()->surfaceType() == QSurface::RasterGLSurface));
if (surface->surface()->surfaceClass() == QSurface::Offscreen)
return; // Nothing to do
diff --git a/src/plugins/platforms/ios/qioseventdispatcher.mm b/src/plugins/platforms/ios/qioseventdispatcher.mm
index fc12e83a81..8e4b4c5875 100644
--- a/src/plugins/platforms/ios/qioseventdispatcher.mm
+++ b/src/plugins/platforms/ios/qioseventdispatcher.mm
@@ -293,7 +293,7 @@ static bool rootLevelRunLoopIntegration()
@implementation QIOSApplicationStateTracker
-+ (void) load
++ (void)load
{
[[NSNotificationCenter defaultCenter]
addObserver:self
@@ -323,7 +323,7 @@ static bool rootLevelRunLoopIntegration()
# error "Unknown processor family"
#endif
-+ (void) applicationDidFinishLaunching
++ (void)applicationDidFinishLaunching
{
if (!isQtApplication())
return;
@@ -377,7 +377,7 @@ static bool rootLevelRunLoopIntegration()
// four bits of the exit code (exit(3) will only pass on the lower 8 bits).
static const char kApplicationWillTerminateExitCode = SIGTERM | 0x80;
-+ (void) applicationWillTerminate
++ (void)applicationWillTerminate
{
if (!isQtApplication())
return;
diff --git a/src/plugins/platforms/ios/qiosfileengineassetslibrary.h b/src/plugins/platforms/ios/qiosfileengineassetslibrary.h
index 043e101a21..37bbc7bf23 100644
--- a/src/plugins/platforms/ios/qiosfileengineassetslibrary.h
+++ b/src/plugins/platforms/ios/qiosfileengineassetslibrary.h
@@ -55,10 +55,17 @@ public:
QString fileName(FileName file) const Q_DECL_OVERRIDE;
void setFileName(const QString &file) Q_DECL_OVERRIDE;
QStringList entryList(QDir::Filters filters, const QStringList &filterNames) const Q_DECL_OVERRIDE;
+
+#ifndef QT_NO_FILESYSTEMITERATOR
+ Iterator *beginEntryList(QDir::Filters filters, const QStringList &filterNames) Q_DECL_OVERRIDE;
+ Iterator *endEntryList() Q_DECL_OVERRIDE;
+#endif
+
void setError(QFile::FileError error, const QString &str) { QAbstractFileEngine::setError(error, str); }
private:
QString m_fileName;
+ QString m_assetUrl;
qint64 m_offset;
mutable QIOSAssetData *m_data;
diff --git a/src/plugins/platforms/ios/qiosfileengineassetslibrary.mm b/src/plugins/platforms/ios/qiosfileengineassetslibrary.mm
index 73bfc2a87f..44a7901160 100644
--- a/src/plugins/platforms/ios/qiosfileengineassetslibrary.mm
+++ b/src/plugins/platforms/ios/qiosfileengineassetslibrary.mm
@@ -38,6 +38,145 @@
#include <QtCore/QTimer>
#include <QtCore/private/qcoreapplication_p.h>
+#include <QtCore/qurl.h>
+#include <QtCore/qset.h>
+#include <QtCore/qthreadstorage.h>
+
+static QThreadStorage<QString> g_iteratorCurrentUrl;
+static QThreadStorage<QPointer<QIOSAssetData> > g_assetDataCache;
+
+static const int kBufferSize = 10;
+static ALAsset *kNoAsset = 0;
+
+static void ensureAuthorizationDialogNotBlocked()
+{
+ if ([ALAssetsLibrary authorizationStatus] != ALAuthorizationStatusNotDetermined)
+ return;
+ if (static_cast<QCoreApplicationPrivate *>(QObjectPrivate::get(qApp))->in_exec)
+ return;
+
+ // Since authorization status has not been determined, the user will be asked
+ // to authorize the app. But since main has not finished, the dialog will be held
+ // back until the launch completes. To avoid a dead-lock below, we start an event
+ // loop to complete the launch.
+ QEventLoop loop;
+ QTimer::singleShot(1, &loop, &QEventLoop::quit);
+ loop.exec();
+}
+
+// -------------------------------------------------------------------------
+
+class QIOSAssetEnumerator
+{
+public:
+ QIOSAssetEnumerator(ALAssetsLibrary *assetsLibrary, ALAssetsGroupType type)
+ : m_semWriteAsset(dispatch_semaphore_create(kBufferSize))
+ , m_semReadAsset(dispatch_semaphore_create(0))
+ , m_stop(false)
+ , m_assetsLibrary([assetsLibrary retain])
+ , m_type(type)
+ , m_buffer(QVector<ALAsset *>(kBufferSize))
+ , m_readIndex(0)
+ , m_writeIndex(0)
+ , m_nextAssetReady(false)
+ {
+ ensureAuthorizationDialogNotBlocked();
+ startEnumerate();
+ }
+
+ ~QIOSAssetEnumerator()
+ {
+ m_stop = true;
+
+ // Flush and autorelease remaining assets in the buffer
+ while (hasNext())
+ next();
+
+ // Documentation states that we need to balance out calls to 'wait'
+ // and 'signal'. Since the enumeration function always will be one 'wait'
+ // ahead, we need to signal m_semProceedToNextAsset one last time.
+ dispatch_semaphore_signal(m_semWriteAsset);
+ dispatch_release(m_semReadAsset);
+ dispatch_release(m_semWriteAsset);
+
+ [m_assetsLibrary autorelease];
+ }
+
+ bool hasNext()
+ {
+ if (!m_nextAssetReady) {
+ dispatch_semaphore_wait(m_semReadAsset, DISPATCH_TIME_FOREVER);
+ m_nextAssetReady = true;
+ }
+ return m_buffer[m_readIndex] != kNoAsset;
+ }
+
+ ALAsset *next()
+ {
+ Q_ASSERT(m_nextAssetReady);
+ Q_ASSERT(m_buffer[m_readIndex]);
+
+ ALAsset *asset = [m_buffer[m_readIndex] autorelease];
+ dispatch_semaphore_signal(m_semWriteAsset);
+
+ m_readIndex = (m_readIndex + 1) % kBufferSize;
+ m_nextAssetReady = false;
+ return asset;
+ }
+
+private:
+ dispatch_semaphore_t m_semWriteAsset;
+ dispatch_semaphore_t m_semReadAsset;
+ std::atomic_bool m_stop;
+
+ ALAssetsLibrary *m_assetsLibrary;
+ ALAssetsGroupType m_type;
+ QVector<ALAsset *> m_buffer;
+ int m_readIndex;
+ int m_writeIndex;
+ bool m_nextAssetReady;
+
+ void writeAsset(ALAsset *asset)
+ {
+ dispatch_semaphore_wait(m_semWriteAsset, DISPATCH_TIME_FOREVER);
+ m_buffer[m_writeIndex] = [asset retain];
+ dispatch_semaphore_signal(m_semReadAsset);
+ m_writeIndex = (m_writeIndex + 1) % kBufferSize;
+ }
+
+ void startEnumerate()
+ {
+ dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
+ [m_assetsLibrary enumerateGroupsWithTypes:m_type usingBlock:^(ALAssetsGroup *group, BOOL *stopEnumerate) {
+
+ if (!group) {
+ writeAsset(kNoAsset);
+ return;
+ }
+
+ if (m_stop) {
+ *stopEnumerate = true;
+ return;
+ }
+
+ [group enumerateAssetsUsingBlock:^(ALAsset *asset, NSUInteger index, BOOL *stopEnumerate) {
+ Q_UNUSED(index);
+ if (!asset || ![[asset valueForProperty:ALAssetPropertyType] isEqual:ALAssetTypePhoto])
+ return;
+
+ writeAsset(asset);
+ *stopEnumerate = m_stop;
+ }];
+ } failureBlock:^(NSError *error) {
+ NSLog(@"QIOSFileEngine: %@", error);
+ writeAsset(kNoAsset);
+ }];
+ });
+ }
+
+};
+
+// -------------------------------------------------------------------------
class QIOSAssetData : public QObject
{
@@ -47,35 +186,17 @@ public:
, m_assetUrl(assetUrl)
, m_assetLibrary(0)
{
- switch ([ALAssetsLibrary authorizationStatus]) {
- case ALAuthorizationStatusRestricted:
- case ALAuthorizationStatusDenied:
- engine->setError(QFile::PermissionsError, QLatin1String("Unauthorized access"));
- return;
- case ALAuthorizationStatusNotDetermined:
- if (!static_cast<QCoreApplicationPrivate *>(QObjectPrivate::get(qApp))->in_exec) {
- // Since authorization status has not been determined, the user will be asked
- // to authorize the app. But since main has not finished, the dialog will be held
- // back until the launch completes. To avoid a dead-lock below, we start an event
- // loop to complete the launch.
- QEventLoop loop;
- QTimer::singleShot(1, &loop, &QEventLoop::quit);
- loop.exec();
- }
- break;
- default:
- if (g_currentAssetData) {
- // It's a common pattern that QFiles pointing to the same path are created and destroyed
- // several times during a single event loop cycle. To avoid loading the same asset
- // over and over, we check if the last loaded asset has not been destroyed yet, and try to
- // reuse its data. Since QFile is (mostly) reentrant, we need to protect m_currentAssetData
- // from being modified by several threads at the same time.
- QMutexLocker lock(&g_mutex);
- if (g_currentAssetData && g_currentAssetData->m_assetUrl == assetUrl) {
- m_assetLibrary = [g_currentAssetData->m_assetLibrary retain];
- m_asset = [g_currentAssetData->m_asset retain];
- return;
- }
+ ensureAuthorizationDialogNotBlocked();
+
+ if (QIOSAssetData *assetData = g_assetDataCache.localData()) {
+ // It's a common pattern that QFiles pointing to the same path are created and destroyed
+ // several times during a single event loop cycle. To avoid loading the same asset
+ // over and over, we check if the last loaded asset has not been destroyed yet, and try to
+ // reuse its data.
+ if (assetData->m_assetUrl == assetUrl) {
+ m_assetLibrary = [assetData->m_assetLibrary retain];
+ m_asset = [assetData->m_asset retain];
+ return;
}
}
@@ -90,6 +211,26 @@ public:
NSURL *url = [NSURL URLWithString:assetUrl.toNSString()];
m_assetLibrary = [[ALAssetsLibrary alloc] init];
[m_assetLibrary assetForURL:url resultBlock:^(ALAsset *asset) {
+
+ if (!asset) {
+ // When an asset couldn't be loaded, chances are that it belongs to ALAssetsGroupPhotoStream.
+ // Such assets can be stored in the cloud and might need to be downloaded first. Unfortunately,
+ // forcing that to happen is hidden behind private APIs ([ALAsset requestDefaultRepresentation]).
+ // As a work-around, we search for it instead, since that will give us a pointer to the asset.
+ QIOSAssetEnumerator e(m_assetLibrary, ALAssetsGroupPhotoStream);
+ while (e.hasNext()) {
+ ALAsset *a = e.next();
+ QString url = QUrl::fromNSURL([a valueForProperty:ALAssetPropertyAssetURL]).toString();
+ if (url == assetUrl) {
+ asset = a;
+ break;
+ }
+ }
+ }
+
+ if (!asset)
+ engine->setError(QFile::OpenError, QLatin1String("could not open image"));
+
m_asset = [asset retain];
dispatch_semaphore_signal(semaphore);
} failureBlock:^(NSError *error) {
@@ -101,17 +242,15 @@ public:
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
dispatch_release(semaphore);
- QMutexLocker lock(&g_mutex);
- g_currentAssetData = this;
+ g_assetDataCache.setLocalData(this);
}
~QIOSAssetData()
{
- QMutexLocker lock(&g_mutex);
[m_assetLibrary release];
[m_asset release];
- if (this == g_currentAssetData)
- g_currentAssetData = 0;
+ if (g_assetDataCache.localData() == this)
+ g_assetDataCache.setLocalData(0);
}
ALAsset *m_asset;
@@ -119,21 +258,67 @@ public:
private:
QString m_assetUrl;
ALAssetsLibrary *m_assetLibrary;
+};
+
+// -------------------------------------------------------------------------
- static QBasicMutex g_mutex;
- static QPointer<QIOSAssetData> g_currentAssetData;
+#ifndef QT_NO_FILESYSTEMITERATOR
+
+class QIOSFileEngineIteratorAssetsLibrary : public QAbstractFileEngineIterator
+{
+public:
+ QIOSAssetEnumerator *m_enumerator;
+
+ QIOSFileEngineIteratorAssetsLibrary(
+ QDir::Filters filters, const QStringList &nameFilters)
+ : QAbstractFileEngineIterator(filters, nameFilters)
+ , m_enumerator(new QIOSAssetEnumerator([[[ALAssetsLibrary alloc] init] autorelease], ALAssetsGroupAll))
+ {
+ }
+
+ ~QIOSFileEngineIteratorAssetsLibrary()
+ {
+ delete m_enumerator;
+ g_iteratorCurrentUrl.setLocalData(QString());
+ }
+
+ QString next() Q_DECL_OVERRIDE
+ {
+ // Cache the URL that we are about to return, since QDir will immediately create a
+ // new file engine on the file and ask if it exists. Unless we do this, we end up
+ // creating a new ALAsset just to verify its existence, which will be especially
+ // costly for assets belonging to ALAssetsGroupPhotoStream.
+ ALAsset *asset = m_enumerator->next();
+ QString url = QUrl::fromNSURL([asset valueForProperty:ALAssetPropertyAssetURL]).toString();
+ g_iteratorCurrentUrl.setLocalData(url);
+ return url;
+ }
+
+ bool hasNext() const Q_DECL_OVERRIDE
+ {
+ return m_enumerator->hasNext();
+ }
+
+ QString currentFileName() const Q_DECL_OVERRIDE
+ {
+ return g_iteratorCurrentUrl.localData();
+ }
+
+ QFileInfo currentFileInfo() const
+ {
+ return QFileInfo(currentFileName());
+ }
};
-QBasicMutex QIOSAssetData::g_mutex;
-QPointer<QIOSAssetData> QIOSAssetData::g_currentAssetData = 0;
+#endif
// -------------------------------------------------------------------------
QIOSFileEngineAssetsLibrary::QIOSFileEngineAssetsLibrary(const QString &fileName)
- : m_fileName(fileName)
- , m_offset(0)
+ : m_offset(0)
, m_data(0)
{
+ setFileName(fileName);
}
QIOSFileEngineAssetsLibrary::~QIOSFileEngineAssetsLibrary()
@@ -143,18 +328,8 @@ QIOSFileEngineAssetsLibrary::~QIOSFileEngineAssetsLibrary()
ALAsset *QIOSFileEngineAssetsLibrary::loadAsset() const
{
- if (!m_data) {
- // QUrl::fromLocalFile() will remove double slashes. Since the asset url is passed around as a file
- // name in the app (and converted to/from a file url, e.g in QFileDialog), we need to check if we still
- // have two leading slashes after the scheme, and restore the second slash if not.
- QString assetUrl = m_fileName;
- const int index = 16; // "assets-library://"
- if (assetUrl[index] != QLatin1Char('/'))
- assetUrl.insert(index, '/');
-
- m_data = new QIOSAssetData(assetUrl, const_cast<QIOSFileEngineAssetsLibrary *>(this));
- }
-
+ if (!m_data)
+ m_data = new QIOSAssetData(m_assetUrl, const_cast<QIOSFileEngineAssetsLibrary *>(this));
return m_data->m_asset;
}
@@ -179,15 +354,21 @@ bool QIOSFileEngineAssetsLibrary::close()
QAbstractFileEngine::FileFlags QIOSFileEngineAssetsLibrary::fileFlags(QAbstractFileEngine::FileFlags type) const
{
QAbstractFileEngine::FileFlags flags = 0;
- if (!loadAsset())
+ const bool isDir = (m_assetUrl == QLatin1String("assets-library://"));
+ const bool exists = isDir || m_assetUrl == g_iteratorCurrentUrl.localData() || loadAsset();
+
+ if (!exists)
return flags;
if (type & FlagsMask)
flags |= ExistsFlag;
- if (type & PermsMask)
- flags |= ReadOwnerPerm | ReadUserPerm | ReadGroupPerm | ReadOtherPerm;
+ if (type & PermsMask) {
+ ALAuthorizationStatus status = [ALAssetsLibrary authorizationStatus];
+ if (status != ALAuthorizationStatusRestricted && status != ALAuthorizationStatusDenied)
+ flags |= ReadOwnerPerm | ReadUserPerm | ReadGroupPerm | ReadOtherPerm;
+ }
if (type & TypesMask)
- flags |= FileType;
+ flags |= isDir ? DirectoryType : FileType;
return flags;
}
@@ -245,11 +426,32 @@ void QIOSFileEngineAssetsLibrary::setFileName(const QString &file)
if (m_data)
close();
m_fileName = file;
+ // QUrl::fromLocalFile() will remove double slashes. Since the asset url is
+ // passed around as a file name in the app (and converted to/from a file url, e.g
+ // in QFileDialog), we need to ensure that m_assetUrl ends up being valid.
+ int index = file.indexOf(QLatin1String("asset.JPG?"));
+ if (index == -1)
+ m_assetUrl = QLatin1String("assets-library://");
+ else
+ m_assetUrl = QLatin1String("assets-library://asset/") + file.mid(index);
}
QStringList QIOSFileEngineAssetsLibrary::entryList(QDir::Filters filters, const QStringList &filterNames) const
{
- Q_UNUSED(filters);
- Q_UNUSED(filterNames);
- return QStringList();
+ return QAbstractFileEngine::entryList(filters, filterNames);
+}
+
+#ifndef QT_NO_FILESYSTEMITERATOR
+
+QAbstractFileEngine::Iterator *QIOSFileEngineAssetsLibrary::beginEntryList(
+ QDir::Filters filters, const QStringList &filterNames)
+{
+ return new QIOSFileEngineIteratorAssetsLibrary(filters, filterNames);
}
+
+QAbstractFileEngine::Iterator *QIOSFileEngineAssetsLibrary::endEntryList()
+{
+ return 0;
+}
+
+#endif
diff --git a/src/plugins/platforms/ios/qiosglobal.h b/src/plugins/platforms/ios/qiosglobal.h
index 86b784618f..544f9e0a42 100644
--- a/src/plugins/platforms/ios/qiosglobal.h
+++ b/src/plugins/platforms/ios/qiosglobal.h
@@ -68,7 +68,7 @@ int infoPlistValue(NSString* key, int defaultValue);
QT_END_NAMESPACE
@interface UIResponder (QtFirstResponder)
-+(id)currentFirstResponder;
++ (id)currentFirstResponder;
@end
class FirstResponderCandidate : public QScopedValueRollback<UIResponder *>
diff --git a/src/plugins/platforms/ios/qiosglobal.mm b/src/plugins/platforms/ios/qiosglobal.mm
index ef24abbfd9..f5b971391d 100644
--- a/src/plugins/platforms/ios/qiosglobal.mm
+++ b/src/plugins/platforms/ios/qiosglobal.mm
@@ -133,7 +133,7 @@ int infoPlistValue(NSString* key, int defaultValue)
@end
@implementation QtFirstResponderEvent
-- (void) dealloc
+- (void)dealloc
{
self.firstResponder = 0;
[super dealloc];
@@ -158,7 +158,7 @@ int infoPlistValue(NSString* key, int defaultValue)
@implementation UIResponder (QtFirstResponder)
-+(id)currentFirstResponder
++ (id)currentFirstResponder
{
QtFirstResponderEvent *event = [[[QtFirstResponderEvent alloc] init] autorelease];
[[UIApplication sharedApplication] sendAction:@selector(qt_findFirstResponder:event:) to:nil from:nil forEvent:event];
diff --git a/src/plugins/platforms/ios/qiosinputcontext.mm b/src/plugins/platforms/ios/qiosinputcontext.mm
index 037b28e91d..d03c589b2a 100644
--- a/src/plugins/platforms/ios/qiosinputcontext.mm
+++ b/src/plugins/platforms/ios/qiosinputcontext.mm
@@ -579,7 +579,7 @@ void QIOSInputContext::focusWindowChanged(QWindow *focusWindow)
void QIOSInputContext::update(Qt::InputMethodQueries updatedProperties)
{
// Mask for properties that we are interested in and see if any of them changed
- updatedProperties &= (Qt::ImEnabled | Qt::ImHints | Qt::ImQueryInput | Qt::ImReturnKeyType | Qt::ImPlatformData);
+ updatedProperties &= (Qt::ImEnabled | Qt::ImHints | Qt::ImQueryInput | Qt::ImEnterKeyType | Qt::ImPlatformData);
qImDebug() << "fw =" << qApp->focusWindow() << "fo =" << qApp->focusObject();
diff --git a/src/plugins/platforms/ios/qiosintegration.mm b/src/plugins/platforms/ios/qiosintegration.mm
index 7cd4280f5e..b4050b8f62 100644
--- a/src/plugins/platforms/ios/qiosintegration.mm
+++ b/src/plugins/platforms/ios/qiosintegration.mm
@@ -77,6 +77,15 @@ QIOSIntegration::QIOSIntegration()
"'applicationDidFinishLaunching' inside your UIApplication delegate.\n");
}
+ // The backingstore needs a global share context in order to support composition in
+ // QPlatformBackingStore.
+ qApp->setAttribute(Qt::AA_ShareOpenGLContexts, true);
+ // And that context must match the format used for the backingstore's context.
+ QSurfaceFormat fmt;
+ fmt.setDepthBufferSize(16);
+ fmt.setStencilBufferSize(8);
+ QSurfaceFormat::setDefaultFormat(fmt);
+
// Set current directory to app bundle folder
QDir::setCurrent(QString::fromUtf8([[[NSBundle mainBundle] bundlePath] UTF8String]));
@@ -137,6 +146,8 @@ bool QIOSIntegration::hasCapability(Capability cap) const
return false;
case ApplicationState:
return true;
+ case RasterGLSurface:
+ return true;
default:
return QPlatformIntegration::hasCapability(cap);
}
@@ -208,6 +219,10 @@ QPlatformServices *QIOSIntegration::services() const
QVariant QIOSIntegration::styleHint(StyleHint hint) const
{
switch (hint) {
+ case PasswordMaskDelay:
+ // this number is based on timing the native delay
+ // since there is no API to get it
+ return 2000;
case ShowIsMaximized:
return true;
case SetFocusOnTouchRelease:
diff --git a/src/plugins/platforms/ios/qiosmenu.mm b/src/plugins/platforms/ios/qiosmenu.mm
index 08fc8a5e9c..045d39e328 100644
--- a/src/plugins/platforms/ios/qiosmenu.mm
+++ b/src/plugins/platforms/ios/qiosmenu.mm
@@ -165,7 +165,7 @@ static NSString *const kSelectorPrefix = @"_qtMenuItem_";
[self reloadAllComponents];
}
--(void)listenForKeyboardWillHideNotification:(BOOL)listen
+- (void)listenForKeyboardWillHideNotification:(BOOL)listen
{
if (listen) {
[[NSNotificationCenter defaultCenter]
@@ -179,7 +179,7 @@ static NSString *const kSelectorPrefix = @"_qtMenuItem_";
}
}
--(void)dealloc
+- (void)dealloc
{
[self listenForKeyboardWillHideNotification:NO];
self.toolbar = 0;
diff --git a/src/plugins/platforms/ios/qiosscreen.mm b/src/plugins/platforms/ios/qiosscreen.mm
index 324133074b..3e16efcd22 100644
--- a/src/plugins/platforms/ios/qiosscreen.mm
+++ b/src/plugins/platforms/ios/qiosscreen.mm
@@ -104,12 +104,12 @@ static QIOSScreen* qtPlatformScreenFor(UIScreen *uiScreen)
@public
QIOSScreen *m_screen;
}
-- (id) initWithQIOSScreen:(QIOSScreen *)screen;
+- (id)initWithQIOSScreen:(QIOSScreen *)screen;
@end
@implementation QIOSOrientationListener
-- (id) initWithQIOSScreen:(QIOSScreen *)screen
+- (id)initWithQIOSScreen:(QIOSScreen *)screen
{
self = [super init];
if (self) {
@@ -123,7 +123,7 @@ static QIOSScreen* qtPlatformScreenFor(UIScreen *uiScreen)
return self;
}
-- (void) dealloc
+- (void)dealloc
{
[[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter]
@@ -132,7 +132,7 @@ static QIOSScreen* qtPlatformScreenFor(UIScreen *uiScreen)
[super dealloc];
}
-- (void) orientationChanged:(NSNotification *)notification
+- (void)orientationChanged:(NSNotification *)notification
{
Q_UNUSED(notification);
m_screen->updateProperties();
diff --git a/src/plugins/platforms/ios/qiostextresponder.mm b/src/plugins/platforms/ios/qiostextresponder.mm
index 3d0bac82c8..d86f545154 100644
--- a/src/plugins/platforms/ios/qiostextresponder.mm
+++ b/src/plugins/platforms/ios/qiostextresponder.mm
@@ -92,12 +92,12 @@
return [QUITextPosition positionWithIndex:(self.range.location + self.range.length)];
}
-- (NSRange) range
+- (NSRange)range
{
return _range;
}
--(BOOL)isEmpty
+- (BOOL)isEmpty
{
return (self.range.length == 0);
}
@@ -111,7 +111,7 @@
@implementation WrapperView
--(id)initWithView:(UIView *)view
+- (id)initWithView:(UIView *)view
{
if (self = [self init]) {
[self addSubview:view];
@@ -143,7 +143,7 @@
// retained, we ensure that all messages sent to the view during
// its lifetime in a window hierarcy will be able to traverse the
// responder chain.
--(void)willMoveToWindow:(UIWindow *)window
+- (void)willMoveToWindow:(UIWindow *)window
{
if (window)
[[self nextResponder] retain];
@@ -170,25 +170,25 @@
QVariantMap platformData = m_configuredImeState->value(Qt::ImPlatformData).toMap();
Qt::InputMethodHints hints = Qt::InputMethodHints(m_configuredImeState->value(Qt::ImHints).toUInt());
- Qt::ReturnKeyType returnKeyType = Qt::ReturnKeyType(m_configuredImeState->value(Qt::ImReturnKeyType).toUInt());
+ Qt::EnterKeyType enterKeyType = Qt::EnterKeyType(m_configuredImeState->value(Qt::ImEnterKeyType).toUInt());
- switch (returnKeyType) {
- case Qt::ReturnKeyEnter:
+ switch (enterKeyType) {
+ case Qt::EnterKeyReturn:
self.returnKeyType = UIReturnKeyDefault;
break;
- case Qt::ReturnKeyDone:
+ case Qt::EnterKeyDone:
self.returnKeyType = UIReturnKeyDone;
break;
- case Qt::ReturnKeyGo:
+ case Qt::EnterKeyGo:
self.returnKeyType = UIReturnKeyGo;
break;
- case Qt::ReturnKeySend:
+ case Qt::EnterKeySend:
self.returnKeyType = UIReturnKeySend;
break;
- case Qt::ReturnKeySearch:
+ case Qt::EnterKeySearch:
self.returnKeyType = UIReturnKeySearch;
break;
- case Qt::ReturnKeyNext:
+ case Qt::EnterKeyNext:
self.returnKeyType = UIReturnKeyNext;
break;
default:
@@ -255,7 +255,7 @@
}
// Based on what we set up in initWithInputContext above
- updatedProperties &= (Qt::ImHints | Qt::ImReturnKeyType | Qt::ImPlatformData);
+ updatedProperties &= (Qt::ImHints | Qt::ImEnterKeyType | Qt::ImPlatformData);
if (!updatedProperties)
return NO;
@@ -383,17 +383,17 @@
return m_inputContext->imeState().currentState.value(query);
}
--(id<UITextInputTokenizer>)tokenizer
+- (id<UITextInputTokenizer>)tokenizer
{
return [[[UITextInputStringTokenizer alloc] initWithTextInput:id<UITextInput>(self)] autorelease];
}
--(UITextPosition *)beginningOfDocument
+- (UITextPosition *)beginningOfDocument
{
return [QUITextPosition positionWithIndex:0];
}
--(UITextPosition *)endOfDocument
+- (UITextPosition *)endOfDocument
{
int endPosition = [self currentImeState:Qt::ImSurroundingText].toString().length();
return [QUITextPosition positionWithIndex:endPosition];
@@ -659,7 +659,7 @@
return [NSDictionary dictionaryWithObject:uifont forKey:UITextInputTextFontKey];
}
--(NSDictionary *)markedTextStyle
+- (NSDictionary *)markedTextStyle
{
return [NSDictionary dictionary];
}
diff --git a/src/plugins/platforms/ios/qiosviewcontroller.mm b/src/plugins/platforms/ios/qiosviewcontroller.mm
index 6667ec3dd8..4ea5fc7de1 100644
--- a/src/plugins/platforms/ios/qiosviewcontroller.mm
+++ b/src/plugins/platforms/ios/qiosviewcontroller.mm
@@ -288,13 +288,13 @@
// -------------------------------------------------------------------------
--(BOOL)shouldAutorotate
+- (BOOL)shouldAutorotate
{
return m_screen && m_screen->uiScreen() == [UIScreen mainScreen] && !self.lockedOrientation;
}
#if QT_IOS_PLATFORM_SDK_EQUAL_OR_ABOVE(__IPHONE_6_0)
--(NSUInteger)supportedInterfaceOrientations
+- (NSUInteger)supportedInterfaceOrientations
{
// As documented by Apple in the iOS 6.0 release notes, setStatusBarOrientation:animated:
// only works if the supportedInterfaceOrientations of the view controller is 0, making
@@ -307,7 +307,7 @@
#endif
#if QT_IOS_DEPLOYMENT_TARGET_BELOW(__IPHONE_6_0)
--(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
+- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
Q_UNUSED(interfaceOrientation);
return [self shouldAutorotate];
diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm
index 777a3c12c5..80fba00ffb 100644
--- a/src/plugins/platforms/ios/qioswindow.mm
+++ b/src/plugins/platforms/ios/qioswindow.mm
@@ -119,7 +119,8 @@ void QIOSWindow::setVisible(bool visible)
}
if (visible && shouldAutoActivateWindow()) {
- requestActivateWindow();
+ if (!window()->property("_q_showWithoutActivating").toBool())
+ requestActivateWindow();
} else if (!visible && [m_view isActiveWindow]) {
// Our window was active/focus window but now hidden, so relinquish
// focus to the next possible window in the stack.
@@ -145,6 +146,9 @@ void QIOSWindow::setVisible(bool visible)
bool QIOSWindow::shouldAutoActivateWindow() const
{
+ if (![m_view canBecomeFirstResponder])
+ return false;
+
// We don't want to do automatic window activation for popup windows
// that are unlikely to contain editable controls (to avoid hiding
// the keyboard while the popup is showing)
diff --git a/src/plugins/platforms/ios/quiaccessibilityelement.h b/src/plugins/platforms/ios/quiaccessibilityelement.h
index a690e12c7d..c76e3a6a1e 100644
--- a/src/plugins/platforms/ios/quiaccessibilityelement.h
+++ b/src/plugins/platforms/ios/quiaccessibilityelement.h
@@ -42,8 +42,8 @@
@property (readonly) QAccessible::Id axid;
-- (id) initWithId: (QAccessible::Id) anId withAccessibilityContainer: (id) view;
-+ (QMacAccessibilityElement *) elementWithId: (QAccessible::Id) anId withAccessibilityContainer: (id) view;
+- (id)initWithId:(QAccessible::Id)anId withAccessibilityContainer:(id)view;
++ (QMacAccessibilityElement *)elementWithId:(QAccessible::Id)anId withAccessibilityContainer:(id)view;
@end
diff --git a/src/plugins/platforms/ios/quiaccessibilityelement.mm b/src/plugins/platforms/ios/quiaccessibilityelement.mm
index 2cecfc1126..3bac1ca88d 100644
--- a/src/plugins/platforms/ios/quiaccessibilityelement.mm
+++ b/src/plugins/platforms/ios/quiaccessibilityelement.mm
@@ -37,7 +37,7 @@
@implementation QMacAccessibilityElement
-- (id) initWithId: (QAccessible::Id) anId withAccessibilityContainer: (id) view
+- (id)initWithId:(QAccessible::Id)anId withAccessibilityContainer:(id)view
{
Q_ASSERT((int)anId < 0);
self = [super initWithAccessibilityContainer: view];
@@ -47,7 +47,7 @@
return self;
}
-+ (id) elementWithId: (QAccessible::Id) anId withAccessibilityContainer: (id) view
++ (id)elementWithId:(QAccessible::Id)anId withAccessibilityContainer:(id)view
{
Q_ASSERT(anId);
if (!anId)
@@ -64,17 +64,17 @@
return element;
}
-- (void) invalidate
+- (void)invalidate
{
[self release];
}
-- (BOOL) isAccessibilityElement
+- (BOOL)isAccessibilityElement
{
return YES;
}
-- (NSString*) accessibilityLabel
+- (NSString*)accessibilityLabel
{
QAccessibleInterface *iface = QAccessible::accessibleInterface(self.axid);
if (!iface) {
@@ -85,7 +85,7 @@
return iface->text(QAccessible::Name).toNSString();
}
-- (NSString*) accessibilityHint
+- (NSString*)accessibilityHint
{
QAccessibleInterface *iface = QAccessible::accessibleInterface(self.axid);
if (!iface) {
@@ -95,7 +95,7 @@
return iface->text(QAccessible::Description).toNSString();
}
-- (NSString*) accessibilityValue
+- (NSString*)accessibilityValue
{
QAccessibleInterface *iface = QAccessible::accessibleInterface(self.axid);
if (!iface) {
@@ -119,7 +119,7 @@
return [super accessibilityHint];
}
-- (CGRect) accessibilityFrame
+- (CGRect)accessibilityFrame
{
QAccessibleInterface *iface = QAccessible::accessibleInterface(self.axid);
if (!iface) {
@@ -131,7 +131,7 @@
return CGRectMake(rect.x(), rect.y(), rect.width(), rect.height());
}
-- (UIAccessibilityTraits) accessibilityTraits
+- (UIAccessibilityTraits)accessibilityTraits
{
UIAccessibilityTraits traits = UIAccessibilityTraitNone;
@@ -156,7 +156,7 @@
return traits;
}
-- (BOOL) accessibilityActivate
+- (BOOL)accessibilityActivate
{
QAccessibleInterface *iface = QAccessible::accessibleInterface(self.axid);
if (QAccessibleActionInterface *action = iface->actionInterface()) {
@@ -171,21 +171,21 @@
return NO; // fall back to sending mouse clicks
}
-- (void) accessibilityIncrement
+- (void)accessibilityIncrement
{
QAccessibleInterface *iface = QAccessible::accessibleInterface(self.axid);
if (QAccessibleActionInterface *action = iface->actionInterface())
action->doAction(QAccessibleActionInterface::increaseAction());
}
-- (void) accessibilityDecrement
+- (void)accessibilityDecrement
{
QAccessibleInterface *iface = QAccessible::accessibleInterface(self.axid);
if (QAccessibleActionInterface *action = iface->actionInterface())
action->doAction(QAccessibleActionInterface::decreaseAction());
}
-- (BOOL) accessibilityScroll : (UIAccessibilityScrollDirection) direction
+- (BOOL)accessibilityScroll:(UIAccessibilityScrollDirection)direction
{
QAccessibleInterface *iface = QAccessible::accessibleInterface(self.axid);
QAccessibleActionInterface *action = iface->actionInterface();
diff --git a/src/plugins/platforms/ios/quiview.mm b/src/plugins/platforms/ios/quiview.mm
index 8be3515cb5..c6ef843b9f 100644
--- a/src/plugins/platforms/ios/quiview.mm
+++ b/src/plugins/platforms/ios/quiview.mm
@@ -50,7 +50,7 @@
return [CAEAGLLayer class];
}
--(id)initWithQIOSWindow:(QIOSWindow *)window
+- (id)initWithQIOSWindow:(QIOSWindow *)window
{
if (self = [self initWithFrame:toCGRect(window->geometry())])
m_qioswindow = window;
@@ -77,7 +77,7 @@
if (QIOSIntegration::instance()->debugWindowManagement()) {
static CGFloat hue = 0.0;
CGFloat lastHue = hue;
- for (CGFloat diff = 0; diff < 0.1 || diff > 0.9; diff = fabsf(hue - lastHue))
+ for (CGFloat diff = 0; diff < 0.1 || diff > 0.9; diff = fabs(hue - lastHue))
hue = drand48();
#define colorWithBrightness(br) \
@@ -194,7 +194,7 @@
- (BOOL)canBecomeFirstResponder
{
- return YES;
+ return !(m_qioswindow->window()->flags() & Qt::WindowDoesNotAcceptFocus);
}
- (BOOL)becomeFirstResponder
@@ -280,6 +280,12 @@
// -------------------------------------------------------------------------
+-(BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
+{
+ if (m_qioswindow->window()->flags() & Qt::WindowTransparentForInput)
+ return NO;
+ return [super pointInside:point withEvent:event];
+}
- (void)updateTouchList:(NSSet *)touches withState:(Qt::TouchPointState)state
{
@@ -310,7 +316,7 @@
}
}
-- (void) sendTouchEventWithTimestamp:(ulong)timeStamp
+- (void)sendTouchEventWithTimestamp:(ulong)timeStamp
{
// Send touch event synchronously
QIOSIntegration *iosIntegration = QIOSIntegration::instance();