From 0575baac5e21cbe38a6ceabaa6b17862cbfee7d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 1 Nov 2012 22:22:56 +0100 Subject: Don't link QtPlatformSupport to CoreFoundation or Carbon MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move the Carbon dependency to the Cocoa platform plugin instead, where it's actually used. CoreFoundation was not used by any plugins and could be removed completely. Change-Id: I1c825cdf94e2cc348ea13519b894fd868be0d14a Reviewed-by: Morten Johan Sørvig --- src/platformsupport/platformsupport.pro | 2 +- src/plugins/platforms/cocoa/cocoa.pro | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/platformsupport/platformsupport.pro b/src/platformsupport/platformsupport.pro index 57d9b422f4..469c76ffae 100644 --- a/src/platformsupport/platformsupport.pro +++ b/src/platformsupport/platformsupport.pro @@ -2,7 +2,7 @@ TARGET = QtPlatformSupport QT = core-private gui-private CONFIG += static internal_module -mac:LIBS += -lz -framework CoreFoundation -framework Carbon +mac:LIBS += -lz load(qt_module) diff --git a/src/plugins/platforms/cocoa/cocoa.pro b/src/plugins/platforms/cocoa/cocoa.pro index 83e2a88e6a..6ed26f9e6c 100644 --- a/src/plugins/platforms/cocoa/cocoa.pro +++ b/src/plugins/platforms/cocoa/cocoa.pro @@ -78,7 +78,7 @@ HEADERS += qcocoaintegration.h \ RESOURCES += qcocoaresources.qrc -LIBS += -framework Cocoa -framework IOKit +LIBS += -framework Cocoa -framework Carbon -framework IOKit QT += core-private gui-private platformsupport-private -- cgit v1.2.3 From 8cbdb25ee63ad702fdd91aae264b093bf3927a5c Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Tue, 30 Oct 2012 14:55:46 +0100 Subject: iOS: copy brute-force port of Qt4 uikit plugin into Qt5. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The plugin has been renamed from uikit to ios. Other than that, the plugin will now build, but do nothing. Most of the Qt4 code is preserved, with a rough translation into the Qt5 qpa API. A lot of code has simply been commented out so far, and most lacking at the moment is the event dispatcher which will need to be rewritten, and the opengl paint device implementation. But it should suffice as a starting ground. Also: The plugin will currently not automatically build when building Qt, this needs to be enabled from configure first. Change-Id: I0d229a453a8477618e06554655bffc5505203b44 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/ios.json | 3 + src/plugins/platforms/ios/ios.pro | 27 ++ src/plugins/platforms/ios/main.mm | 69 ++++ src/plugins/platforms/ios/qiosbackingstore.h | 65 +++ src/plugins/platforms/ios/qiosbackingstore.mm | 139 +++++++ src/plugins/platforms/ios/qioseventdispatcher.h | 110 +++++ src/plugins/platforms/ios/qioseventdispatcher.mm | 154 +++++++ src/plugins/platforms/ios/qiosintegration.h | 75 ++++ src/plugins/platforms/ios/qiosintegration.mm | 106 +++++ src/plugins/platforms/ios/qiosscreen.h | 76 ++++ src/plugins/platforms/ios/qiosscreen.mm | 120 ++++++ .../platforms/ios/qiossoftwareinputhandler.h | 73 ++++ src/plugins/platforms/ios/qioswindow.h | 135 +++++++ src/plugins/platforms/ios/qioswindow.mm | 449 +++++++++++++++++++++ 14 files changed, 1601 insertions(+) create mode 100644 src/plugins/platforms/ios/ios.json create mode 100644 src/plugins/platforms/ios/ios.pro create mode 100644 src/plugins/platforms/ios/main.mm create mode 100644 src/plugins/platforms/ios/qiosbackingstore.h create mode 100644 src/plugins/platforms/ios/qiosbackingstore.mm create mode 100644 src/plugins/platforms/ios/qioseventdispatcher.h create mode 100644 src/plugins/platforms/ios/qioseventdispatcher.mm create mode 100644 src/plugins/platforms/ios/qiosintegration.h create mode 100644 src/plugins/platforms/ios/qiosintegration.mm create mode 100644 src/plugins/platforms/ios/qiosscreen.h create mode 100644 src/plugins/platforms/ios/qiosscreen.mm create mode 100644 src/plugins/platforms/ios/qiossoftwareinputhandler.h create mode 100644 src/plugins/platforms/ios/qioswindow.h create mode 100644 src/plugins/platforms/ios/qioswindow.mm (limited to 'src') diff --git a/src/plugins/platforms/ios/ios.json b/src/plugins/platforms/ios/ios.json new file mode 100644 index 0000000000..f0b766dae1 --- /dev/null +++ b/src/plugins/platforms/ios/ios.json @@ -0,0 +1,3 @@ +{ + "Keys": [ "ios" ] +} diff --git a/src/plugins/platforms/ios/ios.pro b/src/plugins/platforms/ios/ios.pro new file mode 100644 index 0000000000..39f72e9719 --- /dev/null +++ b/src/plugins/platforms/ios/ios.pro @@ -0,0 +1,27 @@ +TARGET = qios +include(../../qpluginbase.pri) +QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/platforms + +QT += opengl +QT += core-private gui-private platformsupport-private opengl-private widgets-private +LIBS += -framework Cocoa -framework UIKit + +OBJECTIVE_SOURCES = main.mm \ + qiosintegration.mm \ + qioswindow.mm \ + qiosscreen.mm \ + qioseventdispatcher.mm \ + qiosbackingstore.mm + +OBJECTIVE_HEADERS = qiosintegration.h \ + qioswindow.h \ + qiosscreen.h \ + qioseventdispatcher.h \ + qiosbackingstore.h + +#HEADERS = qiossoftwareinputhandler.h + +#include(../fontdatabases/coretext/coretext.pri) + +target.path += $$[QT_INSTALL_PLUGINS]/platforms +INSTALLS += target diff --git a/src/plugins/platforms/ios/main.mm b/src/plugins/platforms/ios/main.mm new file mode 100644 index 0000000000..b09fbce1f4 --- /dev/null +++ b/src/plugins/platforms/ios/main.mm @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include "qiosintegration.h" + +QT_BEGIN_NAMESPACE + +class QIOSIntegrationPlugin : public QPlatformIntegrationPlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.1" FILE "ios.json") + public: + QPlatformIntegration *create(const QString&, const QStringList&); +}; + +QPlatformIntegration * QIOSIntegrationPlugin::create(const QString& system, const QStringList& paramList) +{ + Q_UNUSED(paramList); + if (system.toLower() == "ios") + return new QIOSIntegration; + + return 0; +} + +QT_END_NAMESPACE + +#include "main.moc" + + diff --git a/src/plugins/platforms/ios/qiosbackingstore.h b/src/plugins/platforms/ios/qiosbackingstore.h new file mode 100644 index 0000000000..cb0e9cbedb --- /dev/null +++ b/src/plugins/platforms/ios/qiosbackingstore.h @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QIOSBACKINGSTORE_H +#define QIOSBACKINGSTORE_H + +#include +#include + +QT_BEGIN_NAMESPACE + +class QIOSBackingStore : public QPlatformBackingStore +{ +public: + QIOSBackingStore(QWindow *window); + + QPaintDevice *paintDevice(); + void flush(QWindow *window, const QRegion ®ion, const QPoint &offset); + void resize(const QSize &size, const QRegion &staticContents); + +private: + QPaintDevice *mPaintDevice; +}; + +QT_END_NAMESPACE + +#endif // QIOSBACKINGSTORE_H diff --git a/src/plugins/platforms/ios/qiosbackingstore.mm b/src/plugins/platforms/ios/qiosbackingstore.mm new file mode 100644 index 0000000000..32ddce38d2 --- /dev/null +++ b/src/plugins/platforms/ios/qiosbackingstore.mm @@ -0,0 +1,139 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qiosbackingstore.h" +#include "qioswindow.h" + +#include +#include + +#include + +class EAGLPaintDevice; + +@interface PaintDeviceHelper : NSObject { + EAGLPaintDevice *device; +} + +@property (nonatomic, assign) EAGLPaintDevice *device; + +- (void)eaglView:(EAGLView *)view usesFramebuffer:(GLuint)buffer; + +@end + +class EAGLPaintDevice : public QGLPaintDevice +{ +public: + EAGLPaintDevice(QWindow *window) + :QGLPaintDevice(), mWindow(window) + { +#if defined(QT_OPENGL_ES_2) + helper = [[PaintDeviceHelper alloc] init]; + helper.device = this; + EAGLView *view = static_cast(window->handle())->nativeView(); + view.delegate = helper; + m_thisFBO = view.fbo; +#endif + } + + ~EAGLPaintDevice() + { +#if defined(QT_OPENGL_ES_2) + [helper release]; +#endif + } + + void setFramebuffer(GLuint buffer) { m_thisFBO = buffer; } + int devType() const { return QInternal::OpenGL; } + QSize size() const { return mWindow->geometry().size(); } + QGLContext* context() const { + // Todo: siplify this: + return QGLContext::fromOpenGLContext( + static_cast(mWindow->handle())->glContext()->context()); + } + + QPaintEngine *paintEngine() const { return qt_qgl_paint_engine(); } + +private: + QWindow *mWindow; + PaintDeviceHelper *helper; +}; + +@implementation PaintDeviceHelper +@synthesize device; + +- (void)eaglView:(EAGLView *)view usesFramebuffer:(GLuint)buffer +{ + Q_UNUSED(view) + if (device) + device->setFramebuffer(buffer); +} + +@end + +QT_BEGIN_NAMESPACE + +QIOSBackingStore::QIOSBackingStore(QWindow *window) + : QPlatformBackingStore(window), mPaintDevice(new EAGLPaintDevice(window)) +{ +} + +QPaintDevice *QIOSBackingStore::paintDevice() +{ + return mPaintDevice; +} + +void QIOSBackingStore::flush(QWindow *window, const QRegion ®ion, const QPoint &offset) +{ + Q_UNUSED(region); + Q_UNUSED(offset); + qDebug() << __FUNCTION__ << "not implemented"; + //static_cast(window->handle())->glContext()->swapBuffers(); +} + +void QIOSBackingStore::resize(const QSize &size, const QRegion &staticContents) +{ + Q_UNUSED(size); + Q_UNUSED(staticContents); + qDebug() << __FUNCTION__ << "not implemented"; +} + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qioseventdispatcher.h b/src/plugins/platforms/ios/qioseventdispatcher.h new file mode 100644 index 0000000000..3e70397e63 --- /dev/null +++ b/src/plugins/platforms/ios/qioseventdispatcher.h @@ -0,0 +1,110 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/**************************************************************************** +** +** Copyright (c) 2007-2008, Apple, Inc. +** +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are met: +** +** * Redistributions of source code must retain the above copyright notice, +** this list of conditions and the following disclaimer. +** +** * Redistributions in binary form must reproduce the above copyright notice, +** this list of conditions and the following disclaimer in the documentation +** and/or other materials provided with the distribution. +** +** * Neither the name of Apple, Inc. nor the names of its contributors +** may be used to endorse or promote products derived from this software +** without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +** EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +** PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +****************************************************************************/ + +#ifndef QEVENTDISPATCHER_IOS_P_H +#define QEVENTDISPATCHER_IOS_P_H + +#include + +QT_BEGIN_NAMESPACE + +class QIOSEventDispatcher : public QAbstractEventDispatcher +{ + Q_OBJECT + +public: + explicit QIOSEventDispatcher(QObject *parent = 0); ~QIOSEventDispatcher(); + + bool processEvents(QEventLoop::ProcessEventsFlags flags); + bool hasPendingEvents(); + + void registerSocketNotifier(QSocketNotifier *notifier); + void unregisterSocketNotifier(QSocketNotifier *notifier); + + void registerTimer(int timerId, int interval, Qt::TimerType timerType, QObject *object); + bool unregisterTimer(int timerId); + bool unregisterTimers(QObject *object); + QList registeredTimers(QObject *object) const; + + int remainingTime(int timerId); + + void wakeUp(); + void interrupt(); + void flush(); +}; + +QT_END_NAMESPACE + +#endif // QEVENTDISPATCHER_IOS_P_H diff --git a/src/plugins/platforms/ios/qioseventdispatcher.mm b/src/plugins/platforms/ios/qioseventdispatcher.mm new file mode 100644 index 0000000000..246c29adde --- /dev/null +++ b/src/plugins/platforms/ios/qioseventdispatcher.mm @@ -0,0 +1,154 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/**************************************************************************** +** +** Copyright (c) 2007-2008, Apple, Inc. +** +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are met: +** +** * Redistributions of source code must retain the above copyright notice, +** this list of conditions and the following disclaimer. +** +** * Redistributions in binary form must reproduce the above copyright notice, +** this list of conditions and the following disclaimer in the documentation +** and/or other materials provided with the distribution. +** +** * Neither the name of Apple, Inc. nor the names of its contributors +** may be used to endorse or promote products derived from this software +** without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +** EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +** PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +****************************************************************************/ + +#include "qioseventdispatcher.h" +#include + +QT_BEGIN_NAMESPACE +QT_USE_NAMESPACE + +QIOSEventDispatcher::QIOSEventDispatcher(QObject *parent) +{ + Q_UNUSED(parent); + qDebug() << __FUNCTION__ << "eventdispatcher not implemented"; +} + +QIOSEventDispatcher::~QIOSEventDispatcher() +{} + +bool QIOSEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags) +{ + Q_UNUSED(flags); + return false; +} + +bool QIOSEventDispatcher::hasPendingEvents() +{ + return false; +} + +void QIOSEventDispatcher::registerSocketNotifier(QSocketNotifier *notifier) +{ + Q_UNUSED(notifier); +} + +void QIOSEventDispatcher::unregisterSocketNotifier(QSocketNotifier *notifier) +{ + Q_UNUSED(notifier); +} + +void QIOSEventDispatcher::registerTimer(int timerId, int interval, Qt::TimerType timerType, QObject *object) +{ + Q_UNUSED(timerId); + Q_UNUSED(interval); + Q_UNUSED(timerType); + Q_UNUSED(object); +} + +bool QIOSEventDispatcher::unregisterTimer(int timerId) +{ + Q_UNUSED(timerId); + return false; +} + +bool QIOSEventDispatcher::unregisterTimers(QObject *object) +{ + Q_UNUSED(object); + return false; +} + +QList QIOSEventDispatcher::registeredTimers(QObject *object) const +{ + Q_UNUSED(object); + return QList(); +} + +int QIOSEventDispatcher::remainingTime(int timerId) +{ + Q_UNUSED(timerId); + return 0; +} + +void QIOSEventDispatcher::wakeUp() +{} + +void QIOSEventDispatcher::interrupt() +{} + +void QIOSEventDispatcher::flush() +{} + +QT_END_NAMESPACE + diff --git a/src/plugins/platforms/ios/qiosintegration.h b/src/plugins/platforms/ios/qiosintegration.h new file mode 100644 index 0000000000..b71379e417 --- /dev/null +++ b/src/plugins/platforms/ios/qiosintegration.h @@ -0,0 +1,75 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QPLATFORMINTEGRATION_UIKIT_H +#define QPLATFORMINTEGRATION_UIKIT_H + +#include + +QT_BEGIN_NAMESPACE + +class QIOSIntegration : public QPlatformIntegration +{ +public: + QIOSIntegration(); + ~QIOSIntegration(); + + static QIOSIntegration *instance(); + + QPlatformPixmap *createPlatformPixmap(QPlatformPixmap::PixelType type) const; + QPlatformWindow *createPlatformWindow(QWindow *window) const; + QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const; + + QList screens() const; + + QPlatformFontDatabase *fontDatabase() const; + + QAbstractEventDispatcher *guiThreadEventDispatcher() const; + +private: + QList mScreens; + QPlatformFontDatabase *mFontDb; +}; + +QT_END_NAMESPACE + +#endif + diff --git a/src/plugins/platforms/ios/qiosintegration.mm b/src/plugins/platforms/ios/qiosintegration.mm new file mode 100644 index 0000000000..bd63384004 --- /dev/null +++ b/src/plugins/platforms/ios/qiosintegration.mm @@ -0,0 +1,106 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qiosIntegration.h" +#include "qioswindow.h" +#include "qiosbackingstore.h" +#include "qiosscreen.h" +#include "qioseventdispatcher.h" + +#include + +#include + +QT_BEGIN_NAMESPACE + +static QIOSIntegration *m_instance = 0; + +QIOSIntegration * QIOSIntegration::instance() +{ + return m_instance; +} + +QIOSIntegration::QIOSIntegration() + :mFontDb(new QCoreTextFontDatabase) +{ + if (!m_instance) + m_instance = this; + mScreens << new QIOSScreen(0); +} + +QIOSIntegration::~QIOSIntegration() +{ +} + +QPlatformPixmap *QIOSIntegration::createPlatformPixmap(QPlatformPixmap::PixelType type) const +{ + Q_UNUSED(type); + qDebug() << __FUNCTION__ << "not yet implemented"; + return 0; + //return new QRasterPixmapData(type); +} + +QPlatformWindow *QIOSIntegration::createPlatformWindow(QWindow *window) const +{ + return new QIOSWindow(window); +} + +QList QIOSIntegration::screens() const +{ + return mScreens; +} + +QPlatformBackingStore *QIOSIntegration::createPlatformBackingStore(QWindow *window) const +{ + return new QIOSBackingStore(window); +} + +QAbstractEventDispatcher *QIOSIntegration::guiThreadEventDispatcher() const +{ + return new QIOSEventDispatcher(); +} + +QPlatformFontDatabase * QIOSIntegration::fontDatabase() const +{ + return mFontDb; +} + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qiosscreen.h b/src/plugins/platforms/ios/qiosscreen.h new file mode 100644 index 0000000000..628d764f53 --- /dev/null +++ b/src/plugins/platforms/ios/qiosscreen.h @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QIOSSCREEN_H +#define QIOSSCREEN_H + +#include + +#include + +QT_BEGIN_NAMESPACE + +class QIOSScreen : public QPlatformScreen +{ +public: + QIOSScreen(int screenIndex); + ~QIOSScreen(); + + QRect geometry() const { return m_geometry; } + int depth() const { return m_depth; } + QImage::Format format() const { return m_format; } + QSizeF physicalSize() const { return m_physicalSize; } + + UIScreen *uiScreen() const; + + void updateInterfaceOrientation(); +private: + QRect m_geometry; + int m_depth; + QImage::Format m_format; + QSize m_physicalSize; + int m_index; +}; + +QT_END_NAMESPACE + + +#endif diff --git a/src/plugins/platforms/ios/qiosscreen.mm b/src/plugins/platforms/ios/qiosscreen.mm new file mode 100644 index 0000000000..5d9841734a --- /dev/null +++ b/src/plugins/platforms/ios/qiosscreen.mm @@ -0,0 +1,120 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qiosscreen.h" +#include "qioswindow.h" + +#include + +#include + +QT_BEGIN_NAMESPACE + +QIOSScreen::QIOSScreen(int screenIndex) + : QPlatformScreen(), + m_index(screenIndex) +{ + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + CGRect bounds = [uiScreen() bounds]; + CGFloat scale = [uiScreen() scale]; + updateInterfaceOrientation(); + + m_format = QImage::Format_ARGB32_Premultiplied; + + m_depth = 24; + + const qreal inch = 25.4; + qreal unscaledDpi = 160.; + int dragDistance = 12 * scale; + if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) { + unscaledDpi = 132.; + dragDistance = 10 * scale; + } + m_physicalSize = QSize(qRound(bounds.size.width * inch / unscaledDpi), qRound(bounds.size.height * inch / unscaledDpi)); + + //qApp->setStartDragDistance(dragDistance); + + /* + QFont font; // system font is helvetica, so that is fine already + font.setPixelSize([UIFont systemFontSize] * scale); + qApp->setFont(font); + */ + + [pool release]; +} + +QIOSScreen::~QIOSScreen() +{ +} + +UIScreen *QIOSScreen::uiScreen() const +{ + return [[UIScreen screens] objectAtIndex:m_index]; +} + +void QIOSScreen::updateInterfaceOrientation() +{ + qDebug() << __FUNCTION__ << "not implemented"; + /* + CGRect bounds = [uiScreen() bounds]; + CGFloat scale = [uiScreen() scale]; + switch ([[UIApplication sharedApplication] statusBarOrientation]) { + case UIInterfaceOrientationPortrait: + case UIInterfaceOrientationPortraitUpsideDown: + m_geometry = QRect(bounds.origin.x * scale, bounds.origin.y * scale, + bounds.size.width * scale, bounds.size.height * scale);; + break; + case UIInterfaceOrientationLandscapeLeft: + case UIInterfaceOrientationLandscapeRight: + m_geometry = QRect(bounds.origin.x * scale, bounds.origin.y * scale, + bounds.size.height * scale, bounds.size.width * scale); + break; + } + foreach (QWidget *widget, qApp->topLevelWidgets()) { + QIOSWindow *platformWindow = static_cast(widget->platformWindow()); + if (platformWindow && platformWindow->platformScreen() == this) { + platformWindow->updateGeometryAndOrientation(); + } + } + */ +} + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qiossoftwareinputhandler.h b/src/plugins/platforms/ios/qiossoftwareinputhandler.h new file mode 100644 index 0000000000..bbad656b93 --- /dev/null +++ b/src/plugins/platforms/ios/qiossoftwareinputhandler.h @@ -0,0 +1,73 @@ + + +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QIOSSOFTWAREINPUTHANDLER_H +#define QIOSSOFTWAREINPUTHANDLER_H + +#include +#include +#include + +QT_BEGIN_NAMESPACE + +class QIOSSoftwareInputHandler : public QObject +{ + Q_OBJECT + +public: + QIOSSoftwareInputHandler() : mCurrentFocusWidget(0), mCurrentFocusObject(0) {} + bool eventFilter(QObject *obj, QEvent *event); + +private slots: + void activeFocusChanged(bool focus); + +private: + bool closeSoftwareInputPanel(QWidget *widget); + + QPointer mCurrentFocusWidget; + QPointer mCurrentFocusObject; +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h new file mode 100644 index 0000000000..f43f3db4f9 --- /dev/null +++ b/src/plugins/platforms/ios/qioswindow.h @@ -0,0 +1,135 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QIOSWINDOW_H +#define QIOSWINDOW_H + +#include + +#import +#import +#import +#import +#import +#import + +@interface EAGLView : UIView +{ + QPlatformWindow *mWindow; + EAGLContext *mContext; + + GLint mFramebufferWidth; + GLint mFramebufferHeight; + + GLuint mFramebuffer, mColorRenderbuffer, mDepthRenderbuffer; + + id delegate; + // ------- Text Input ---------- + UITextAutocapitalizationType autocapitalizationType; + UITextAutocorrectionType autocorrectionType; + BOOL enablesReturnKeyAutomatically; + UIKeyboardAppearance keyboardAppearance; + UIKeyboardType keyboardType; + UIReturnKeyType returnKeyType; + BOOL secureTextEntry; +} + +- (void)setContext:(EAGLContext *)newContext; +- (void)presentFramebuffer; +- (void)deleteFramebuffer; +- (void)createFramebuffer; +- (void)makeCurrent; +- (void)setWindow:(QPlatformWindow *)window; +- (void)sendMouseEventForTouches:(NSSet *)touches withEvent:(UIEvent *)event fakeButtons:(Qt::MouseButtons)buttons; + +@property (readonly,getter=fbo) GLint fbo; +@property (nonatomic, assign) id delegate; + +// ------- Text Input ---------- + +@property(nonatomic) UITextAutocapitalizationType autocapitalizationType; +@property(nonatomic) UITextAutocorrectionType autocorrectionType; +@property(nonatomic) BOOL enablesReturnKeyAutomatically; +@property(nonatomic) UIKeyboardAppearance keyboardAppearance; +@property(nonatomic) UIKeyboardType keyboardType; +@property(nonatomic) UIReturnKeyType returnKeyType; +@property(nonatomic, getter=isSecureTextEntry) BOOL secureTextEntry; + +@end + +@protocol EAGLViewDelegate +- (void)eaglView:(EAGLView *)view usesFramebuffer:(GLuint)buffer; +@end + +class EAGLPlatformContext; + +QT_BEGIN_NAMESPACE + +class QIOSScreen; + +class QIOSWindow : public QPlatformWindow +{ +public: + explicit QIOSWindow(QWindow *window); + ~QIOSWindow(); + + UIWindow *nativeWindow() const { return mWindow; } + EAGLView *nativeView() const { return mView; } + void setGeometry(const QRect &rect); + + UIWindow *ensureNativeWindow(); + + QPlatformOpenGLContext *glContext() const; + + QIOSScreen *platformScreen() const { return mScreen; } + + void updateGeometryAndOrientation(); +private: + QIOSScreen *mScreen; + UIWindow *mWindow; + CGRect mFrame; + EAGLView *mView; + mutable EAGLPlatformContext *mContext; +}; + +QT_END_NAMESPACE + +#endif // QIOSWINDOW_H diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm new file mode 100644 index 0000000000..c63c22dbaa --- /dev/null +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -0,0 +1,449 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#import + +#include "qioswindow.h" + +#include "qiosscreen.h" + +#include +#include +#include +#include + +#include + +static GLint stencilBits() +{ + static GLint bits; + static bool initialized = false; + if (!initialized) { + glGetIntegerv(GL_STENCIL_BITS, &bits); + initialized = true; + } + return bits; +} + +/* +static GLint depthBits() +{ + // we can choose between GL_DEPTH24_STENCIL8_OES and GL_DEPTH_COMPONENT16 + return stencilBits() > 0 ? 24 : 16; +} +*/ + +class EAGLPlatformContext : public QPlatformOpenGLContext +{ +public: + EAGLPlatformContext(EAGLView *view) + : mView(view) + { + /* + mFormat.setWindowApi(QPlatformWindowFormat::OpenGL); + mFormat.setDepthBufferSize(depthBits()); + mFormat.setAccumBufferSize(0); + mFormat.setRedBufferSize(8); + mFormat.setGreenBufferSize(8); + mFormat.setBlueBufferSize(8); + mFormat.setAlphaBufferSize(8); + mFormat.setStencilBufferSize(stencilBits()); + mFormat.setSamples(0); + mFormat.setSampleBuffers(false); + mFormat.setDoubleBuffer(true); + mFormat.setDepth(true); + mFormat.setRgba(true); + mFormat.setAlpha(true); + mFormat.setAccum(false); + mFormat.setStencil(stencilBits() > 0); + mFormat.setStereo(false); + mFormat.setDirectRendering(false); + */ + +#if defined(QT_OPENGL_ES_2) + EAGLContext *aContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; +#else + EAGLContext *aContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1]; +#endif + [mView setContext:aContext]; + } + + ~EAGLPlatformContext() { } + + bool makeCurrent(QPlatformSurface *surface) + { + Q_UNUSED(surface); + qDebug() << __FUNCTION__ << "not implemented"; + //QPlatformOpenGLContext::makeCurrent(); + //[mView makeCurrent]; + return false; + } + + void doneCurrent() + { + qDebug() << __FUNCTION__ << "not implemented"; + //QPlatformOpenGLContext::doneCurrent(); + } + + void swapBuffers(QPlatformSurface *surface) + { + Q_UNUSED(surface); + qDebug() << __FUNCTION__ << "not implemented"; + //[mView presentFramebuffer]; + } + + QFunctionPointer getProcAddress(const QByteArray& ) { return 0; } + + QSurfaceFormat format() const + { + return mFormat; + } + +private: + EAGLView *mView; + + QSurfaceFormat mFormat; +}; + +@implementation EAGLView + +@synthesize delegate; + ++ (Class)layerClass +{ + return [CAEAGLLayer class]; +} + +- (id)initWithFrame:(CGRect)frame +{ + if ((self = [super initWithFrame:frame])) { + CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer; + eaglLayer.opaque = TRUE; + eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys: + [NSNumber numberWithBool:YES], kEAGLDrawablePropertyRetainedBacking, + kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat, + nil]; + autocapitalizationType = UITextAutocapitalizationTypeNone; + autocorrectionType = UITextAutocorrectionTypeNo; + enablesReturnKeyAutomatically = NO; + keyboardAppearance = UIKeyboardAppearanceDefault; + keyboardType = UIKeyboardTypeDefault; + returnKeyType = UIReturnKeyDone; + secureTextEntry = NO; + } + return self; +} + +- (void)setContext:(EAGLContext *)newContext +{ + if (mContext != newContext) + { + [self deleteFramebuffer]; + [mContext release]; + mContext = [newContext retain]; + [EAGLContext setCurrentContext:nil]; + } +} + +- (void)presentFramebuffer +{ + if (mContext) { + [EAGLContext setCurrentContext:mContext]; + glBindRenderbuffer(GL_RENDERBUFFER, mColorRenderbuffer); + [mContext presentRenderbuffer:GL_RENDERBUFFER]; + } +} + +- (void)deleteFramebuffer +{ + if (mContext) + { + [EAGLContext setCurrentContext:mContext]; + if (mFramebuffer) { + glDeleteFramebuffers(1, &mFramebuffer); + mFramebuffer = 0; + } + if (mColorRenderbuffer) { + glDeleteRenderbuffers(1, &mColorRenderbuffer); + mColorRenderbuffer = 0; + } + if (mDepthRenderbuffer) { + glDeleteRenderbuffers(1, &mDepthRenderbuffer); + mDepthRenderbuffer = 0; + } + } +} + +- (void)createFramebuffer +{ + if (mContext && !mFramebuffer) + { + [EAGLContext setCurrentContext:mContext]; + glGenFramebuffers(1, &mFramebuffer); + glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer); + + glGenRenderbuffers(1, &mColorRenderbuffer); + glBindRenderbuffer(GL_RENDERBUFFER, mColorRenderbuffer); + [mContext renderbufferStorage:GL_RENDERBUFFER fromDrawable:(CAEAGLLayer *)self.layer]; + glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &mFramebufferWidth); + glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &mFramebufferHeight); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, mColorRenderbuffer); + + glGenRenderbuffers(1, &mDepthRenderbuffer); + glBindRenderbuffer(GL_RENDERBUFFER, mDepthRenderbuffer); + if (stencilBits() > 0) { + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, mFramebufferWidth, mFramebufferHeight); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, mDepthRenderbuffer); + } else { + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, mFramebufferWidth, mFramebufferHeight); + } + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, mDepthRenderbuffer); + + if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) + NSLog(@"Failed to make complete framebuffer object %x", glCheckFramebufferStatus(GL_FRAMEBUFFER)); + if (delegate && [delegate respondsToSelector:@selector(eaglView:usesFramebuffer:)]) { + [delegate eaglView:self usesFramebuffer:mFramebuffer]; + } + } +} + +- (void)makeCurrent +{ + if (mContext) + { + [EAGLContext setCurrentContext:mContext]; + if (!mFramebuffer) + [self createFramebuffer]; + glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer); + glViewport(0, 0, mFramebufferWidth, mFramebufferHeight); + } +} + +- (GLint)fbo +{ + return mFramebuffer; +} + +- (void)setWindow:(QPlatformWindow *)window +{ + mWindow = window; +} + +- (void)sendMouseEventForTouches:(NSSet *)touches withEvent:(UIEvent *)event fakeButtons:(Qt::MouseButtons)buttons +{ + UITouch *touch = [touches anyObject]; + CGPoint locationInView = [touch locationInView:self]; + CGFloat scaleFactor = [self contentScaleFactor]; + QPoint p(locationInView.x * scaleFactor, locationInView.y * scaleFactor); + // TODO handle global touch point? for status bar? + QWindowSystemInterface::handleMouseEvent(mWindow->window(), (ulong)(event.timestamp*1000), + p, p, buttons); +} + +- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event +{ + [self sendMouseEventForTouches:touches withEvent:event fakeButtons:Qt::LeftButton]; +} + +- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event +{ + [self sendMouseEventForTouches:touches withEvent:event fakeButtons:Qt::LeftButton]; +} + +- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event +{ + [self sendMouseEventForTouches:touches withEvent:event fakeButtons:Qt::NoButton]; +} + +- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event +{ + [self sendMouseEventForTouches:touches withEvent:event fakeButtons:Qt::NoButton]; +} + +// ------- Text Input ---------- + +@synthesize autocapitalizationType; +@synthesize autocorrectionType; +@synthesize enablesReturnKeyAutomatically; +@synthesize keyboardAppearance; +@synthesize keyboardType; +@synthesize returnKeyType; +@synthesize secureTextEntry; + +- (BOOL)canBecomeFirstResponder +{ + return YES; +} + +- (BOOL)hasText +{ + return YES; +} + +- (void)insertText:(NSString *)text +{ + QString string = QString::fromUtf8([text UTF8String]); + int key = 0; + if ([text isEqualToString:@"\n"]) + key = (int)Qt::Key_Return; + + // Send key event to window system interface + QWindowSystemInterface::handleKeyEvent( + 0, QEvent::KeyPress, key, Qt::NoModifier, string, false, int(string.length())); + QWindowSystemInterface::handleKeyEvent( + 0, QEvent::KeyRelease, key, Qt::NoModifier, string, false, int(string.length())); +} + +- (void)deleteBackward +{ + // Send key event to window system interface + QWindowSystemInterface::handleKeyEvent( + 0, QEvent::KeyPress, (int)Qt::Key_Backspace, Qt::NoModifier); + QWindowSystemInterface::handleKeyEvent( + 0, QEvent::KeyRelease, (int)Qt::Key_Backspace, Qt::NoModifier); +} + +@end + +QT_BEGIN_NAMESPACE + +QIOSWindow::QIOSWindow(QWindow *window) : + QPlatformWindow(window), + mWindow(nil), + mContext(0) +{ + mScreen = static_cast(QPlatformScreen::platformScreenForWindow(window)); + mView = [[EAGLView alloc] init]; +} + +QIOSWindow::~QIOSWindow() +{ + delete mContext; mContext = 0; + [mView release]; + [mWindow release]; +} + +void QIOSWindow::setGeometry(const QRect &rect) +{ + // Not supported. Only a single "full screen" window is supported + QPlatformWindow::setGeometry(rect); +} + +UIWindow *QIOSWindow::ensureNativeWindow() +{ + if (!mWindow) { + mWindow = [[UIWindow alloc] init]; + updateGeometryAndOrientation(); + // window + mWindow.screen = mScreen->uiScreen(); + // for some reason setting the screen resets frame.origin, so we need to set the frame afterwards + mWindow.frame = mFrame; + + // view + [mView deleteFramebuffer]; + mView.frame = CGRectMake(0, 0, mWindow.bounds.size.width, mWindow.bounds.size.height); // fill + [mView setContentScaleFactor:[mWindow.screen scale]]; + [mView setMultipleTouchEnabled:YES]; + [mView setWindow:this]; + [mWindow addSubview:mView]; + [mWindow setNeedsDisplay]; + [mWindow makeKeyAndVisible]; + } + return mWindow; +} + +void QIOSWindow::updateGeometryAndOrientation() +{ + if (!mWindow) + return; + mFrame = [mScreen->uiScreen() applicationFrame]; + CGRect screen = [mScreen->uiScreen() bounds]; + QRect geom; + CGFloat angle = 0; + switch ([[UIApplication sharedApplication] statusBarOrientation]) { + case UIInterfaceOrientationPortrait: + geom = QRect(mFrame.origin.x, mFrame.origin.y, mFrame.size.width, mFrame.size.height); + break; + case UIInterfaceOrientationPortraitUpsideDown: + geom = QRect(screen.size.width - mFrame.origin.x - mFrame.size.width, + screen.size.height - mFrame.origin.y - mFrame.size.height, + mFrame.size.width, + mFrame.size.height); + angle = M_PI; + break; + case UIInterfaceOrientationLandscapeLeft: + geom = QRect(screen.size.height - mFrame.origin.y - mFrame.size.height, + mFrame.origin.x, + mFrame.size.height, + mFrame.size.width); + angle = -M_PI/2.; + break; + case UIInterfaceOrientationLandscapeRight: + geom = QRect(mFrame.origin.y, + screen.size.width - mFrame.origin.x - mFrame.size.width, + mFrame.size.height, + mFrame.size.width); + angle = +M_PI/2.; + break; + } + + CGFloat scale = [mScreen->uiScreen() scale]; + geom = QRect(geom.x() * scale, geom.y() * scale, + geom.width() * scale, geom.height() * scale); + + if (angle != 0) { + [mView layer].transform = CATransform3DMakeRotation(angle, 0, 0, 1.); + } else { + [mView layer].transform = CATransform3DIdentity; + } + [mView setNeedsDisplay]; + window()->setGeometry(geom); +} + +QPlatformOpenGLContext *QIOSWindow::glContext() const +{ + if (!mContext) { + mContext = new EAGLPlatformContext(mView); + } + return mContext; +} + +QT_END_NAMESPACE -- cgit v1.2.3 From 5d6c57fcba2da07551277901300f98e12eb22020 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Mon, 29 Oct 2012 13:28:10 +0100 Subject: iOS: fix build issue, dont link against cocoa MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make sure the libraries dont depend on Cocoa. This will be picked up by libtool, and make all apps and examples link against cocoa too (which will ofcourse fail) Change-Id: I5654bb08c4ed376fc7ee74da422d903270a8af38 Reviewed-by: Morten Johan Sørvig --- src/gui/gui.pro | 4 +--- src/plugins/platforms/ios/qioseventdispatcher.h | 2 +- src/plugins/platforms/ios/qioseventdispatcher.mm | 2 +- src/widgets/kernel/mac.pri | 2 +- 4 files changed, 4 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/gui/gui.pro b/src/gui/gui.pro index 058cfe92ec..f21c7a5ce7 100644 --- a/src/gui/gui.pro +++ b/src/gui/gui.pro @@ -18,9 +18,7 @@ testcocoon { load(testcocoon) } -mac { - LIBS_PRIVATE += -framework Cocoa -} +mac:!ios: LIBS_PRIVATE += -framework Cocoa CONFIG += simd diff --git a/src/plugins/platforms/ios/qioseventdispatcher.h b/src/plugins/platforms/ios/qioseventdispatcher.h index 3e70397e63..479ec1d0a0 100644 --- a/src/plugins/platforms/ios/qioseventdispatcher.h +++ b/src/plugins/platforms/ios/qioseventdispatcher.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the plugins of the Qt Toolkit. diff --git a/src/plugins/platforms/ios/qioseventdispatcher.mm b/src/plugins/platforms/ios/qioseventdispatcher.mm index 246c29adde..12f448488e 100644 --- a/src/plugins/platforms/ios/qioseventdispatcher.mm +++ b/src/plugins/platforms/ios/qioseventdispatcher.mm @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the plugins of the Qt Toolkit. diff --git a/src/widgets/kernel/mac.pri b/src/widgets/kernel/mac.pri index 5474a41f15..4c507ae80e 100644 --- a/src/widgets/kernel/mac.pri +++ b/src/widgets/kernel/mac.pri @@ -1,4 +1,4 @@ -!x11::mac { +!x11:mac:!ios { LIBS_PRIVATE += -framework Carbon -framework Cocoa -lz *-mwerks:INCLUDEPATH += compat } -- cgit v1.2.3 From 8224e5ac7f5f69a64b6ad62bb60277a274bcc60e Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Mon, 29 Oct 2012 10:26:40 +0100 Subject: iOS: Don't reference QMacStyle from QStyleOption as we don't build it MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit QMacStyle is not buildt as a part of iOS. So make sure we dont reference it from QStyleOption Change-Id: I98e779c576d0607402e45a19b457144a6bdfc73b Reviewed-by: Tor Arne Vestbø --- src/widgets/styles/qstyleoption.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/widgets/styles/qstyleoption.cpp b/src/widgets/styles/qstyleoption.cpp index 01e51d594d..eff6837c5a 100644 --- a/src/widgets/styles/qstyleoption.cpp +++ b/src/widgets/styles/qstyleoption.cpp @@ -206,7 +206,7 @@ void QStyleOption::init(const QWidget *widget) if (!(state & QStyle::State_Active) && !qt_mac_can_clickThrough(widget)) state &= ~QStyle::State_Enabled; #endif -#ifdef Q_OS_MAC +#if defined(Q_OS_MAC) && !defined(Q_OS_IOS) switch (QMacStyle::widgetSizePolicy(widget)) { case QMacStyle::SizeSmall: state |= QStyle::State_Small; -- cgit v1.2.3 From 3bc4afc223bcd56245797a0bd3628f02a992301c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 1 Nov 2012 12:31:50 +0100 Subject: iOS: Move Q_OS_IOS out of makesespec to qsystemdetection.h We treat iOS as a variant of Mac OS, so for iOS both Q_OS_MAC and Q_OS_IOS will be defined. This matches what Apple assumes in the header file TargetConditionals.h Change-Id: I55cc851401b748297478e4c32e84e0f6e1fdfc28 Reviewed-by: Thiago Macieira --- src/corelib/global/qsystemdetection.h | 6 ++++++ src/corelib/kernel/qcore_mac_p.h | 2 ++ src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm | 2 ++ 3 files changed, 10 insertions(+) (limited to 'src') diff --git a/src/corelib/global/qsystemdetection.h b/src/corelib/global/qsystemdetection.h index eb7aa2e64f..86c724ebb5 100644 --- a/src/corelib/global/qsystemdetection.h +++ b/src/corelib/global/qsystemdetection.h @@ -50,6 +50,8 @@ The operating system, must be one of: (Q_OS_x) DARWIN - Darwin OS (synonym for Q_OS_MAC) + MAC - Mac OS X or iOS (iPhoneOS) + IOS - iOS (treated as a variant of Mac OS) MSDOS - MS-DOS and Windows OS2 - OS/2 OS2EMX - XFree86 on OS/2 (not PM) @@ -166,6 +168,10 @@ # elif defined(Q_OS_DARWIN32) # define Q_OS_MAC32 # endif +# include +# if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE +# define Q_OS_IOS +# endif #endif #if defined(Q_OS_WIN) diff --git a/src/corelib/kernel/qcore_mac_p.h b/src/corelib/kernel/qcore_mac_p.h index b833eb4962..361a6c2c67 100644 --- a/src/corelib/kernel/qcore_mac_p.h +++ b/src/corelib/kernel/qcore_mac_p.h @@ -63,6 +63,8 @@ #include #endif +#include "qglobal.h" + #ifndef Q_OS_IOS #include #endif diff --git a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm index ef5bdbbf0d..fbd836f763 100644 --- a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm +++ b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm @@ -39,6 +39,8 @@ ** ****************************************************************************/ +#include "qglobal.h" + #ifndef Q_OS_IOS #import #import -- cgit v1.2.3 From e5111d5e021e8168fa9deb00abae5c403a5313e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 1 Nov 2012 16:11:35 +0100 Subject: iOS: Build ios platform plugin when appropriate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Defining QT_QPA_DEFAULT_PLATFORM_NAME in qplatformdefs.h is not neccecary, as qconfig.h will already have this define written by configure. Change-Id: I89d9191533f6b4e6bfd5eade6cc0dced02b50f81 Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/platforms.pro | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/plugins/platforms/platforms.pro b/src/plugins/platforms/platforms.pro index 173757568f..a60a3626fa 100644 --- a/src/plugins/platforms/platforms.pro +++ b/src/plugins/platforms/platforms.pro @@ -6,7 +6,10 @@ contains(QT_CONFIG, xcb) { SUBDIRS += xcb } -mac:!ios: SUBDIRS += cocoa +mac { + ios: SUBDIRS += ios + else: SUBDIRS += cocoa +} win32: SUBDIRS += windows -- cgit v1.2.3 From f2168f2688d44ccb604d761fdbe199c69de0dcb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 1 Nov 2012 16:31:06 +0100 Subject: iOS: Build platform plugin like other platform plugins MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ... by loading(qt_plugin) Change-Id: I9be438b72be986a991a81c2cf1a3e5047bcf0a60 Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/ios/ios.pro | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/plugins/platforms/ios/ios.pro b/src/plugins/platforms/ios/ios.pro index 39f72e9719..66af44cbe8 100644 --- a/src/plugins/platforms/ios/ios.pro +++ b/src/plugins/platforms/ios/ios.pro @@ -1,6 +1,7 @@ TARGET = qios -include(../../qpluginbase.pri) -QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/platforms + +load(qt_plugin) +DESTDIR = $$QT.gui.plugins/platforms QT += opengl QT += core-private gui-private platformsupport-private opengl-private widgets-private @@ -21,7 +22,5 @@ OBJECTIVE_HEADERS = qiosintegration.h \ #HEADERS = qiossoftwareinputhandler.h -#include(../fontdatabases/coretext/coretext.pri) - target.path += $$[QT_INSTALL_PLUGINS]/platforms INSTALLS += target -- cgit v1.2.3 From cb25d67f01d129d877ffb56d15f7c5e32f4955ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 1 Nov 2012 22:30:37 +0100 Subject: iOS: Don't link ios platform plugin to Cocoa MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I2348b19617d3e342cd344bf7d0fa894118cbfae8 Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/ios/ios.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/plugins/platforms/ios/ios.pro b/src/plugins/platforms/ios/ios.pro index 66af44cbe8..d274fda8bd 100644 --- a/src/plugins/platforms/ios/ios.pro +++ b/src/plugins/platforms/ios/ios.pro @@ -5,7 +5,7 @@ DESTDIR = $$QT.gui.plugins/platforms QT += opengl QT += core-private gui-private platformsupport-private opengl-private widgets-private -LIBS += -framework Cocoa -framework UIKit +LIBS += -framework UIKit OBJECTIVE_SOURCES = main.mm \ qiosintegration.mm \ -- cgit v1.2.3 From 8716c42ee2a3d5ca42eab5850f711fd5feabb9ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 1 Nov 2012 23:01:56 +0100 Subject: iOS: Add missing QuartzCore dependency to platform plugin MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Ic69a5a7faa9b7f9907d0325260b6b6e2389a4c3a Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/ios/ios.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/plugins/platforms/ios/ios.pro b/src/plugins/platforms/ios/ios.pro index d274fda8bd..2cc730f061 100644 --- a/src/plugins/platforms/ios/ios.pro +++ b/src/plugins/platforms/ios/ios.pro @@ -5,7 +5,7 @@ DESTDIR = $$QT.gui.plugins/platforms QT += opengl QT += core-private gui-private platformsupport-private opengl-private widgets-private -LIBS += -framework UIKit +LIBS += -framework UIKit -framework QuartzCore OBJECTIVE_SOURCES = main.mm \ qiosintegration.mm \ -- cgit v1.2.3 From f6dc54ded4957f7afdbed9f84516099b067648ff Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Thu, 15 Nov 2012 10:09:31 +0100 Subject: iOS: network should not link against CoreServices on iOS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Ia3e21a3d73f696f0e77c427bdb263333646c48d3 Reviewed-by: Tor Arne Vestbø --- src/network/kernel/kernel.pri | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/network/kernel/kernel.pri b/src/network/kernel/kernel.pri index 57df8c8bc8..580e0b31b3 100644 --- a/src/network/kernel/kernel.pri +++ b/src/network/kernel/kernel.pri @@ -39,7 +39,11 @@ win32: { } integrity:SOURCES += kernel/qdnslookup_unix.cpp kernel/qhostinfo_unix.cpp kernel/qnetworkinterface_unix.cpp -mac:LIBS_PRIVATE += -framework SystemConfiguration -framework CoreFoundation -framework CoreServices +mac { + LIBS_PRIVATE += -framework SystemConfiguration -framework CoreFoundation + !ios: LIBS_PRIVATE += -framework CoreServices +} + mac:!ios:SOURCES += kernel/qnetworkproxy_mac.cpp else:win32:SOURCES += kernel/qnetworkproxy_win.cpp else:blackberry:SOURCES += kernel/qnetworkproxy_blackberry.cpp -- cgit v1.2.3 From c7fbff7bf255f9fc0123f37fc475bd8ae8cf38e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Tue, 4 Dec 2012 15:50:49 +0100 Subject: iOS: Add required public dependencies of the CoreText font database CoreText and CoreGraphics are available on iOS as stand-alone frameworks, but on Mac OS X they are part of the ApplicationServices umbrella framework. Mac OS 10.8 actually introduced both as stand-alone frameworks, but for simplicity we link to ApplicationServices, as there's still symlinks from ApplicationServices to the real frameworks. Change-Id: I7f7ef795629cc37da85857d5c42283754acc4474 Reviewed-by: Richard Moe Gustavsen --- src/platformsupport/fontdatabases/mac/coretext.pri | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src') diff --git a/src/platformsupport/fontdatabases/mac/coretext.pri b/src/platformsupport/fontdatabases/mac/coretext.pri index f7977964fe..d1abf123aa 100644 --- a/src/platformsupport/fontdatabases/mac/coretext.pri +++ b/src/platformsupport/fontdatabases/mac/coretext.pri @@ -1,2 +1,10 @@ HEADERS += $$PWD/qcoretextfontdatabase_p.h $$PWD/qfontengine_coretext_p.h OBJECTIVE_SOURCES += $$PWD/qfontengine_coretext.mm $$PWD/qcoretextfontdatabase.mm + +ios: \ + # On iOS CoreText and CoreGraphics are stand-alone frameworks + LIBS += -framework CoreText -framework CoreGraphics +else: \ + # On Mac OS they are part of the ApplicationServices umbrella framework, + # even in 10.8 where they were also made available stand-alone. + LIBS += -framework ApplicationServices -- cgit v1.2.3 From 8c0014907893e0ac7c0b0c33d54415830f36ddaa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 13 Dec 2012 16:46:29 +0100 Subject: iOS: Don't include QtPrintSupport dialogs on iOS It pulls in a dependency on Cocoa. Change-Id: I293063adfdef8b92f80ffda0c66ac6e6d12958ff Reviewed-by: Richard Moe Gustavsen --- src/printsupport/dialogs/dialogs.pri | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/printsupport/dialogs/dialogs.pri b/src/printsupport/dialogs/dialogs.pri index 9db975e202..9659046f60 100644 --- a/src/printsupport/dialogs/dialogs.pri +++ b/src/printsupport/dialogs/dialogs.pri @@ -8,7 +8,7 @@ HEADERS += \ dialogs/qprintdialog.h \ dialogs/qprintpreviewdialog.h -mac { +mac:!ios { OBJECTIVE_SOURCES += dialogs/qpagesetupdialog_mac.mm \ dialogs/qprintdialog_mac.mm LIBS += -framework Cocoa -- cgit v1.2.3 From 9c8ce6afb0bb19e0cb5902b65efbd1a1b55344eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Fri, 2 Nov 2012 15:44:46 +0100 Subject: iOS: Don't add to OBJECTIVE_HEADERS, there's no such thing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We should add to HEADERS, so that moc will realize it needs to run on the headers. Change-Id: I582e989e4faf0835c4bf9a677cbd8ac075559319 Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/ios/ios.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/plugins/platforms/ios/ios.pro b/src/plugins/platforms/ios/ios.pro index 2cc730f061..c6c104f2f3 100644 --- a/src/plugins/platforms/ios/ios.pro +++ b/src/plugins/platforms/ios/ios.pro @@ -14,7 +14,7 @@ OBJECTIVE_SOURCES = main.mm \ qioseventdispatcher.mm \ qiosbackingstore.mm -OBJECTIVE_HEADERS = qiosintegration.h \ +HEADERS = qiosintegration.h \ qioswindow.h \ qiosscreen.h \ qioseventdispatcher.h \ -- cgit v1.2.3 From 3020d06fdb9fd4e539876c9fb1945b50d55cc21d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Sun, 4 Nov 2012 17:19:09 +0100 Subject: iOS: Change member variable style to be consistent with Qt's de facto standard Change-Id: Idd65ad9cbb77114466c5b69a799b98a7fee5068f Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qiosbackingstore.h | 2 +- src/plugins/platforms/ios/qiosbackingstore.mm | 12 +- src/plugins/platforms/ios/qiosintegration.h | 4 +- src/plugins/platforms/ios/qiosintegration.mm | 8 +- .../platforms/ios/qiossoftwareinputhandler.h | 6 +- src/plugins/platforms/ios/qioswindow.h | 26 +-- src/plugins/platforms/ios/qioswindow.mm | 186 ++++++++++----------- 7 files changed, 122 insertions(+), 122 deletions(-) (limited to 'src') diff --git a/src/plugins/platforms/ios/qiosbackingstore.h b/src/plugins/platforms/ios/qiosbackingstore.h index cb0e9cbedb..d83a5c21ad 100644 --- a/src/plugins/platforms/ios/qiosbackingstore.h +++ b/src/plugins/platforms/ios/qiosbackingstore.h @@ -57,7 +57,7 @@ public: void resize(const QSize &size, const QRegion &staticContents); private: - QPaintDevice *mPaintDevice; + QPaintDevice *m_paintDevice; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qiosbackingstore.mm b/src/plugins/platforms/ios/qiosbackingstore.mm index 32ddce38d2..20f7c1f2d1 100644 --- a/src/plugins/platforms/ios/qiosbackingstore.mm +++ b/src/plugins/platforms/ios/qiosbackingstore.mm @@ -63,7 +63,7 @@ class EAGLPaintDevice : public QGLPaintDevice { public: EAGLPaintDevice(QWindow *window) - :QGLPaintDevice(), mWindow(window) + :QGLPaintDevice(), m_window(window) { #if defined(QT_OPENGL_ES_2) helper = [[PaintDeviceHelper alloc] init]; @@ -83,17 +83,17 @@ public: void setFramebuffer(GLuint buffer) { m_thisFBO = buffer; } int devType() const { return QInternal::OpenGL; } - QSize size() const { return mWindow->geometry().size(); } + QSize size() const { return m_window->geometry().size(); } QGLContext* context() const { // Todo: siplify this: return QGLContext::fromOpenGLContext( - static_cast(mWindow->handle())->glContext()->context()); + static_cast(m_window->handle())->glContext()->context()); } QPaintEngine *paintEngine() const { return qt_qgl_paint_engine(); } private: - QWindow *mWindow; + QWindow *m_window; PaintDeviceHelper *helper; }; @@ -112,13 +112,13 @@ private: QT_BEGIN_NAMESPACE QIOSBackingStore::QIOSBackingStore(QWindow *window) - : QPlatformBackingStore(window), mPaintDevice(new EAGLPaintDevice(window)) + : QPlatformBackingStore(window), m_paintDevice(new EAGLPaintDevice(window)) { } QPaintDevice *QIOSBackingStore::paintDevice() { - return mPaintDevice; + return m_paintDevice; } void QIOSBackingStore::flush(QWindow *window, const QRegion ®ion, const QPoint &offset) diff --git a/src/plugins/platforms/ios/qiosintegration.h b/src/plugins/platforms/ios/qiosintegration.h index b71379e417..f44403fbba 100644 --- a/src/plugins/platforms/ios/qiosintegration.h +++ b/src/plugins/platforms/ios/qiosintegration.h @@ -65,8 +65,8 @@ public: QAbstractEventDispatcher *guiThreadEventDispatcher() const; private: - QList mScreens; - QPlatformFontDatabase *mFontDb; + QList m_screens; + QPlatformFontDatabase *m_fontDb; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qiosintegration.mm b/src/plugins/platforms/ios/qiosintegration.mm index bd63384004..98b08ed72a 100644 --- a/src/plugins/platforms/ios/qiosintegration.mm +++ b/src/plugins/platforms/ios/qiosintegration.mm @@ -59,11 +59,11 @@ QIOSIntegration * QIOSIntegration::instance() } QIOSIntegration::QIOSIntegration() - :mFontDb(new QCoreTextFontDatabase) + :m_fontDb(new QCoreTextFontDatabase) { if (!m_instance) m_instance = this; - mScreens << new QIOSScreen(0); + m_screens << new QIOSScreen(0); } QIOSIntegration::~QIOSIntegration() @@ -85,7 +85,7 @@ QPlatformWindow *QIOSIntegration::createPlatformWindow(QWindow *window) const QList QIOSIntegration::screens() const { - return mScreens; + return m_screens; } QPlatformBackingStore *QIOSIntegration::createPlatformBackingStore(QWindow *window) const @@ -100,7 +100,7 @@ QAbstractEventDispatcher *QIOSIntegration::guiThreadEventDispatcher() const QPlatformFontDatabase * QIOSIntegration::fontDatabase() const { - return mFontDb; + return m_fontDb; } QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qiossoftwareinputhandler.h b/src/plugins/platforms/ios/qiossoftwareinputhandler.h index bbad656b93..99e8fac61b 100644 --- a/src/plugins/platforms/ios/qiossoftwareinputhandler.h +++ b/src/plugins/platforms/ios/qiossoftwareinputhandler.h @@ -55,7 +55,7 @@ class QIOSSoftwareInputHandler : public QObject Q_OBJECT public: - QIOSSoftwareInputHandler() : mCurrentFocusWidget(0), mCurrentFocusObject(0) {} + QIOSSoftwareInputHandler() : m_CurrentFocusWidget(0), m_CurrentFocusObject(0) {} bool eventFilter(QObject *obj, QEvent *event); private slots: @@ -64,8 +64,8 @@ private slots: private: bool closeSoftwareInputPanel(QWidget *widget); - QPointer mCurrentFocusWidget; - QPointer mCurrentFocusObject; + QPointer m_currentFocusWidget; + QPointer m_currentFocusObject; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h index f43f3db4f9..2d3d5b072f 100644 --- a/src/plugins/platforms/ios/qioswindow.h +++ b/src/plugins/platforms/ios/qioswindow.h @@ -53,13 +53,13 @@ @interface EAGLView : UIView { - QPlatformWindow *mWindow; - EAGLContext *mContext; + QPlatformWindow *m_window; + EAGLContext *m_context; - GLint mFramebufferWidth; - GLint mFramebufferHeight; + GLint m_framebufferWidth; + GLint m_framebufferHeight; - GLuint mFramebuffer, mColorRenderbuffer, mDepthRenderbuffer; + GLuint m_framebuffer, m_colorRenderbuffer, m_depthRenderbuffer; id delegate; // ------- Text Input ---------- @@ -111,23 +111,23 @@ public: explicit QIOSWindow(QWindow *window); ~QIOSWindow(); - UIWindow *nativeWindow() const { return mWindow; } - EAGLView *nativeView() const { return mView; } + UIWindow *nativeWindow() const { return m_window; } + EAGLView *nativeView() const { return m_view; } void setGeometry(const QRect &rect); UIWindow *ensureNativeWindow(); QPlatformOpenGLContext *glContext() const; - QIOSScreen *platformScreen() const { return mScreen; } + QIOSScreen *platformScreen() const { return m_screen; } void updateGeometryAndOrientation(); private: - QIOSScreen *mScreen; - UIWindow *mWindow; - CGRect mFrame; - EAGLView *mView; - mutable EAGLPlatformContext *mContext; + QIOSScreen *m_screen; + UIWindow *m_window; + CGRect m_frame; + EAGLView *m_view; + mutable EAGLPlatformContext *m_context; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index c63c22dbaa..28aaaf2189 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -75,7 +75,7 @@ class EAGLPlatformContext : public QPlatformOpenGLContext { public: EAGLPlatformContext(EAGLView *view) - : mView(view) + : m_view(view) { /* mFormat.setWindowApi(QPlatformWindowFormat::OpenGL); @@ -103,7 +103,7 @@ public: #else EAGLContext *aContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1]; #endif - [mView setContext:aContext]; + [m_view setContext:aContext]; } ~EAGLPlatformContext() { } @@ -113,7 +113,7 @@ public: Q_UNUSED(surface); qDebug() << __FUNCTION__ << "not implemented"; //QPlatformOpenGLContext::makeCurrent(); - //[mView makeCurrent]; + //[m_view makeCurrent]; return false; } @@ -127,7 +127,7 @@ public: { Q_UNUSED(surface); qDebug() << __FUNCTION__ << "not implemented"; - //[mView presentFramebuffer]; + //[m_view presentFramebuffer]; } QFunctionPointer getProcAddress(const QByteArray& ) { return 0; } @@ -138,7 +138,7 @@ public: } private: - EAGLView *mView; + EAGLView *m_view; QSurfaceFormat mFormat; }; @@ -174,97 +174,97 @@ private: - (void)setContext:(EAGLContext *)newContext { - if (mContext != newContext) + if (m_context != newContext) { [self deleteFramebuffer]; - [mContext release]; - mContext = [newContext retain]; + [m_context release]; + m_context = [newContext retain]; [EAGLContext setCurrentContext:nil]; } } - (void)presentFramebuffer { - if (mContext) { - [EAGLContext setCurrentContext:mContext]; - glBindRenderbuffer(GL_RENDERBUFFER, mColorRenderbuffer); - [mContext presentRenderbuffer:GL_RENDERBUFFER]; + if (m_context) { + [EAGLContext setCurrentContext:m_context]; + glBindRenderbuffer(GL_RENDERBUFFER, m_colorRenderbuffer); + [m_context presentRenderbuffer:GL_RENDERBUFFER]; } } - (void)deleteFramebuffer { - if (mContext) + if (m_context) { - [EAGLContext setCurrentContext:mContext]; - if (mFramebuffer) { - glDeleteFramebuffers(1, &mFramebuffer); - mFramebuffer = 0; + [EAGLContext setCurrentContext:m_context]; + if (m_framebuffer) { + glDeleteFramebuffers(1, &m_framebuffer); + m_framebuffer = 0; } - if (mColorRenderbuffer) { - glDeleteRenderbuffers(1, &mColorRenderbuffer); - mColorRenderbuffer = 0; + if (m_colorRenderbuffer) { + glDeleteRenderbuffers(1, &m_colorRenderbuffer); + m_colorRenderbuffer = 0; } - if (mDepthRenderbuffer) { - glDeleteRenderbuffers(1, &mDepthRenderbuffer); - mDepthRenderbuffer = 0; + if (m_depthRenderbuffer) { + glDeleteRenderbuffers(1, &m_depthRenderbuffer); + m_depthRenderbuffer = 0; } } } - (void)createFramebuffer { - if (mContext && !mFramebuffer) + if (m_context && !m_framebuffer) { - [EAGLContext setCurrentContext:mContext]; - glGenFramebuffers(1, &mFramebuffer); - glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer); - - glGenRenderbuffers(1, &mColorRenderbuffer); - glBindRenderbuffer(GL_RENDERBUFFER, mColorRenderbuffer); - [mContext renderbufferStorage:GL_RENDERBUFFER fromDrawable:(CAEAGLLayer *)self.layer]; - glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &mFramebufferWidth); - glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &mFramebufferHeight); - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, mColorRenderbuffer); - - glGenRenderbuffers(1, &mDepthRenderbuffer); - glBindRenderbuffer(GL_RENDERBUFFER, mDepthRenderbuffer); + [EAGLContext setCurrentContext:m_context]; + glGenFramebuffers(1, &m_framebuffer); + glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffer); + + glGenRenderbuffers(1, &m_colorRenderbuffer); + glBindRenderbuffer(GL_RENDERBUFFER, m_colorRenderbuffer); + [m_context renderbufferStorage:GL_RENDERBUFFER fromDrawable:(CAEAGLLayer *)self.layer]; + glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &m_framebufferWidth); + glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &m_framebufferHeight); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_colorRenderbuffer); + + glGenRenderbuffers(1, &m_depthRenderbuffer); + glBindRenderbuffer(GL_RENDERBUFFER, m_depthRenderbuffer); if (stencilBits() > 0) { - glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, mFramebufferWidth, mFramebufferHeight); - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, mDepthRenderbuffer); + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, m_framebufferWidth, m_framebufferHeight); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_depthRenderbuffer); } else { - glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, mFramebufferWidth, mFramebufferHeight); + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, m_framebufferWidth, m_framebufferHeight); } - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, mDepthRenderbuffer); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_depthRenderbuffer); if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) NSLog(@"Failed to make complete framebuffer object %x", glCheckFramebufferStatus(GL_FRAMEBUFFER)); if (delegate && [delegate respondsToSelector:@selector(eaglView:usesFramebuffer:)]) { - [delegate eaglView:self usesFramebuffer:mFramebuffer]; + [delegate eaglView:self usesFramebuffer:m_framebuffer]; } } } - (void)makeCurrent { - if (mContext) + if (m_context) { - [EAGLContext setCurrentContext:mContext]; - if (!mFramebuffer) + [EAGLContext setCurrentContext:m_context]; + if (!m_framebuffer) [self createFramebuffer]; - glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer); - glViewport(0, 0, mFramebufferWidth, mFramebufferHeight); + glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffer); + glViewport(0, 0, m_framebufferWidth, m_framebufferHeight); } } - (GLint)fbo { - return mFramebuffer; + return m_framebuffer; } - (void)setWindow:(QPlatformWindow *)window { - mWindow = window; + m_window = window; } - (void)sendMouseEventForTouches:(NSSet *)touches withEvent:(UIEvent *)event fakeButtons:(Qt::MouseButtons)buttons @@ -274,7 +274,7 @@ private: CGFloat scaleFactor = [self contentScaleFactor]; QPoint p(locationInView.x * scaleFactor, locationInView.y * scaleFactor); // TODO handle global touch point? for status bar? - QWindowSystemInterface::handleMouseEvent(mWindow->window(), (ulong)(event.timestamp*1000), + QWindowSystemInterface::handleMouseEvent(m_window->window(), (ulong)(event.timestamp*1000), p, p, buttons); } @@ -347,18 +347,18 @@ QT_BEGIN_NAMESPACE QIOSWindow::QIOSWindow(QWindow *window) : QPlatformWindow(window), - mWindow(nil), - mContext(0) + m_window(nil), + m_context(0) { - mScreen = static_cast(QPlatformScreen::platformScreenForWindow(window)); - mView = [[EAGLView alloc] init]; + m_screen = static_cast(QPlatformScreen::platformScreenForWindow(window)); + m_view = [[EAGLView alloc] init]; } QIOSWindow::~QIOSWindow() { - delete mContext; mContext = 0; - [mView release]; - [mWindow release]; + delete m_context; m_context = 0; + [m_view release]; + [m_window release]; } void QIOSWindow::setGeometry(const QRect &rect) @@ -369,81 +369,81 @@ void QIOSWindow::setGeometry(const QRect &rect) UIWindow *QIOSWindow::ensureNativeWindow() { - if (!mWindow) { - mWindow = [[UIWindow alloc] init]; + if (!m_window) { + m_window = [[UIWindow alloc] init]; updateGeometryAndOrientation(); // window - mWindow.screen = mScreen->uiScreen(); + m_window.screen = m_screen->uiScreen(); // for some reason setting the screen resets frame.origin, so we need to set the frame afterwards - mWindow.frame = mFrame; + m_window.frame = m_frame; // view - [mView deleteFramebuffer]; - mView.frame = CGRectMake(0, 0, mWindow.bounds.size.width, mWindow.bounds.size.height); // fill - [mView setContentScaleFactor:[mWindow.screen scale]]; - [mView setMultipleTouchEnabled:YES]; - [mView setWindow:this]; - [mWindow addSubview:mView]; - [mWindow setNeedsDisplay]; - [mWindow makeKeyAndVisible]; + [m_view deleteFramebuffer]; + m_view.frame = CGRectMake(0, 0, m_window.bounds.size.width, m_window.bounds.size.height); // fill + [m_view setContentScaleFactor:[m_window.screen scale]]; + [m_view setMultipleTouchEnabled:YES]; + [m_view setWindow:this]; + [m_window addSubview:m_view]; + [m_window setNeedsDisplay]; + [m_window makeKeyAndVisible]; } - return mWindow; + return m_window; } void QIOSWindow::updateGeometryAndOrientation() { - if (!mWindow) + if (!m_window) return; - mFrame = [mScreen->uiScreen() applicationFrame]; - CGRect screen = [mScreen->uiScreen() bounds]; + m_frame = [m_screen->uiScreen() applicationFrame]; + CGRect screen = [m_screen->uiScreen() bounds]; QRect geom; CGFloat angle = 0; switch ([[UIApplication sharedApplication] statusBarOrientation]) { case UIInterfaceOrientationPortrait: - geom = QRect(mFrame.origin.x, mFrame.origin.y, mFrame.size.width, mFrame.size.height); + geom = QRect(m_frame.origin.x, m_frame.origin.y, m_frame.size.width, m_frame.size.height); break; case UIInterfaceOrientationPortraitUpsideDown: - geom = QRect(screen.size.width - mFrame.origin.x - mFrame.size.width, - screen.size.height - mFrame.origin.y - mFrame.size.height, - mFrame.size.width, - mFrame.size.height); + geom = QRect(screen.size.width - m_frame.origin.x - m_frame.size.width, + screen.size.height - m_frame.origin.y - m_frame.size.height, + m_frame.size.width, + m_frame.size.height); angle = M_PI; break; case UIInterfaceOrientationLandscapeLeft: - geom = QRect(screen.size.height - mFrame.origin.y - mFrame.size.height, - mFrame.origin.x, - mFrame.size.height, - mFrame.size.width); + geom = QRect(screen.size.height - m_frame.origin.y - m_frame.size.height, + m_frame.origin.x, + m_frame.size.height, + m_frame.size.width); angle = -M_PI/2.; break; case UIInterfaceOrientationLandscapeRight: - geom = QRect(mFrame.origin.y, - screen.size.width - mFrame.origin.x - mFrame.size.width, - mFrame.size.height, - mFrame.size.width); + geom = QRect(m_frame.origin.y, + screen.size.width - m_frame.origin.x - m_frame.size.width, + m_frame.size.height, + m_frame.size.width); angle = +M_PI/2.; break; } - CGFloat scale = [mScreen->uiScreen() scale]; + CGFloat scale = [m_screen->uiScreen() scale]; geom = QRect(geom.x() * scale, geom.y() * scale, geom.width() * scale, geom.height() * scale); if (angle != 0) { - [mView layer].transform = CATransform3DMakeRotation(angle, 0, 0, 1.); + [m_view layer].transform = CATransform3DMakeRotation(angle, 0, 0, 1.); } else { - [mView layer].transform = CATransform3DIdentity; + [m_view layer].transform = CATransform3DIdentity; } - [mView setNeedsDisplay]; + [m_view setNeedsDisplay]; window()->setGeometry(geom); } QPlatformOpenGLContext *QIOSWindow::glContext() const { - if (!mContext) { - mContext = new EAGLPlatformContext(mView); + if (!m_context) { + m_context = new EAGLPlatformContext(m_view); } - return mContext; + return m_context; } QT_END_NAMESPACE -- cgit v1.2.3 From 6d36a83b419e0b0bc0270e45983ed2bbfa453996 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Sun, 4 Nov 2012 18:56:45 +0100 Subject: iOS: Get rid of singleton instance accessor in platform plugin None of the other platform plugins have one, and it's not used anywhere. Change-Id: Id46ab5f75c9819511c3e9d123d0338c3c8799869 Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qiosintegration.h | 2 -- src/plugins/platforms/ios/qiosintegration.mm | 9 --------- 2 files changed, 11 deletions(-) (limited to 'src') diff --git a/src/plugins/platforms/ios/qiosintegration.h b/src/plugins/platforms/ios/qiosintegration.h index f44403fbba..ef839a89b0 100644 --- a/src/plugins/platforms/ios/qiosintegration.h +++ b/src/plugins/platforms/ios/qiosintegration.h @@ -52,8 +52,6 @@ public: QIOSIntegration(); ~QIOSIntegration(); - static QIOSIntegration *instance(); - QPlatformPixmap *createPlatformPixmap(QPlatformPixmap::PixelType type) const; QPlatformWindow *createPlatformWindow(QWindow *window) const; QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const; diff --git a/src/plugins/platforms/ios/qiosintegration.mm b/src/plugins/platforms/ios/qiosintegration.mm index 98b08ed72a..1b03b410cb 100644 --- a/src/plugins/platforms/ios/qiosintegration.mm +++ b/src/plugins/platforms/ios/qiosintegration.mm @@ -51,18 +51,9 @@ QT_BEGIN_NAMESPACE -static QIOSIntegration *m_instance = 0; - -QIOSIntegration * QIOSIntegration::instance() -{ - return m_instance; -} - QIOSIntegration::QIOSIntegration() :m_fontDb(new QCoreTextFontDatabase) { - if (!m_instance) - m_instance = this; m_screens << new QIOSScreen(0); } -- cgit v1.2.3 From 14e93f7e8e0ef58b0e47bfe277d52b2fa8f24ee7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Sun, 4 Nov 2012 19:01:44 +0100 Subject: iOS: Add screen like other platform plugins We may add support for external displays at a later point, but for now we follow the same pattern as the other platform plugins. Either way we should call screenAdded() to let the platform integration know about the screen. Change-Id: Id01785a5262df0180caf957c7de8ecbbf169f233 Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qiosintegration.h | 4 +--- src/plugins/platforms/ios/qiosintegration.mm | 9 ++------- 2 files changed, 3 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/plugins/platforms/ios/qiosintegration.h b/src/plugins/platforms/ios/qiosintegration.h index ef839a89b0..8b2ac70a9f 100644 --- a/src/plugins/platforms/ios/qiosintegration.h +++ b/src/plugins/platforms/ios/qiosintegration.h @@ -56,15 +56,13 @@ public: QPlatformWindow *createPlatformWindow(QWindow *window) const; QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const; - QList screens() const; - QPlatformFontDatabase *fontDatabase() const; QAbstractEventDispatcher *guiThreadEventDispatcher() const; private: - QList m_screens; QPlatformFontDatabase *m_fontDb; + QPlatformScreen *m_screen; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qiosintegration.mm b/src/plugins/platforms/ios/qiosintegration.mm index 1b03b410cb..68a9bf343f 100644 --- a/src/plugins/platforms/ios/qiosintegration.mm +++ b/src/plugins/platforms/ios/qiosintegration.mm @@ -52,9 +52,9 @@ QT_BEGIN_NAMESPACE QIOSIntegration::QIOSIntegration() - :m_fontDb(new QCoreTextFontDatabase) + :m_fontDb(new QCoreTextFontDatabase), m_screen(new QIOSScreen(0)) { - m_screens << new QIOSScreen(0); + screenAdded(m_screen); } QIOSIntegration::~QIOSIntegration() @@ -74,11 +74,6 @@ QPlatformWindow *QIOSIntegration::createPlatformWindow(QWindow *window) const return new QIOSWindow(window); } -QList QIOSIntegration::screens() const -{ - return m_screens; -} - QPlatformBackingStore *QIOSIntegration::createPlatformBackingStore(QWindow *window) const { return new QIOSBackingStore(window); -- cgit v1.2.3 From 5e85aa9ab4c30c123de6431679d3870a4b7836c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Sun, 4 Nov 2012 19:39:45 +0100 Subject: iOS: Keep UIScreen* for current QIOSScreen instead of looking up each time Also, add enum for screen numbers, for better code readability. Change-Id: Id5162c34e80ff5efb149ae86b49f51df183d1c1d Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qiosintegration.mm | 2 +- src/plugins/platforms/ios/qiosscreen.h | 7 ++++--- src/plugins/platforms/ios/qiosscreen.mm | 12 ++++++------ 3 files changed, 11 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/plugins/platforms/ios/qiosintegration.mm b/src/plugins/platforms/ios/qiosintegration.mm index 68a9bf343f..7a6dec43d4 100644 --- a/src/plugins/platforms/ios/qiosintegration.mm +++ b/src/plugins/platforms/ios/qiosintegration.mm @@ -52,7 +52,7 @@ QT_BEGIN_NAMESPACE QIOSIntegration::QIOSIntegration() - :m_fontDb(new QCoreTextFontDatabase), m_screen(new QIOSScreen(0)) + :m_fontDb(new QCoreTextFontDatabase), m_screen(new QIOSScreen(QIOSScreen::MainScreen)) { screenAdded(m_screen); } diff --git a/src/plugins/platforms/ios/qiosscreen.h b/src/plugins/platforms/ios/qiosscreen.h index 628d764f53..98771b9ac2 100644 --- a/src/plugins/platforms/ios/qiosscreen.h +++ b/src/plugins/platforms/ios/qiosscreen.h @@ -51,9 +51,11 @@ QT_BEGIN_NAMESPACE class QIOSScreen : public QPlatformScreen { public: - QIOSScreen(int screenIndex); + QIOSScreen(unsigned int screenIndex); ~QIOSScreen(); + enum ScreenIndex { MainScreen = 0 }; + QRect geometry() const { return m_geometry; } int depth() const { return m_depth; } QImage::Format format() const { return m_format; } @@ -63,14 +65,13 @@ public: void updateInterfaceOrientation(); private: + UIScreen *m_uiScreen; QRect m_geometry; int m_depth; QImage::Format m_format; QSize m_physicalSize; - int m_index; }; QT_END_NAMESPACE - #endif diff --git a/src/plugins/platforms/ios/qiosscreen.mm b/src/plugins/platforms/ios/qiosscreen.mm index 5d9841734a..64b9022a29 100644 --- a/src/plugins/platforms/ios/qiosscreen.mm +++ b/src/plugins/platforms/ios/qiosscreen.mm @@ -48,13 +48,13 @@ QT_BEGIN_NAMESPACE -QIOSScreen::QIOSScreen(int screenIndex) - : QPlatformScreen(), - m_index(screenIndex) +QIOSScreen::QIOSScreen(unsigned int screenIndex) + : QPlatformScreen() + , m_uiScreen([[UIScreen screens] objectAtIndex:qMin(screenIndex, [[UIScreen screens] count] - 1)]) { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - CGRect bounds = [uiScreen() bounds]; - CGFloat scale = [uiScreen() scale]; + CGRect bounds = [m_uiScreen bounds]; + CGFloat scale = [m_uiScreen scale]; updateInterfaceOrientation(); m_format = QImage::Format_ARGB32_Premultiplied; @@ -87,7 +87,7 @@ QIOSScreen::~QIOSScreen() UIScreen *QIOSScreen::uiScreen() const { - return [[UIScreen screens] objectAtIndex:m_index]; + return m_uiScreen; } void QIOSScreen::updateInterfaceOrientation() -- cgit v1.2.3 From 422eed16eb22772357aab06feb12c59f5d188b2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Sun, 4 Nov 2012 19:43:57 +0100 Subject: iOS: Style nitpicking, rename m_fontDb to m_fontDatabase Change-Id: I9d92843af9018d51b73fadcc7c20d792fad772fa Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qiosintegration.h | 2 +- src/plugins/platforms/ios/qiosintegration.mm | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/plugins/platforms/ios/qiosintegration.h b/src/plugins/platforms/ios/qiosintegration.h index 8b2ac70a9f..d744cf377a 100644 --- a/src/plugins/platforms/ios/qiosintegration.h +++ b/src/plugins/platforms/ios/qiosintegration.h @@ -61,7 +61,7 @@ public: QAbstractEventDispatcher *guiThreadEventDispatcher() const; private: - QPlatformFontDatabase *m_fontDb; + QPlatformFontDatabase *m_fontDatabase; QPlatformScreen *m_screen; }; diff --git a/src/plugins/platforms/ios/qiosintegration.mm b/src/plugins/platforms/ios/qiosintegration.mm index 7a6dec43d4..d3e9572f83 100644 --- a/src/plugins/platforms/ios/qiosintegration.mm +++ b/src/plugins/platforms/ios/qiosintegration.mm @@ -52,7 +52,8 @@ QT_BEGIN_NAMESPACE QIOSIntegration::QIOSIntegration() - :m_fontDb(new QCoreTextFontDatabase), m_screen(new QIOSScreen(QIOSScreen::MainScreen)) + : m_fontDatabase(new QCoreTextFontDatabase) + , m_screen(new QIOSScreen(QIOSScreen::MainScreen)) { screenAdded(m_screen); } @@ -86,7 +87,7 @@ QAbstractEventDispatcher *QIOSIntegration::guiThreadEventDispatcher() const QPlatformFontDatabase * QIOSIntegration::fontDatabase() const { - return m_fontDb; + return m_fontDatabase; } QT_END_NAMESPACE -- cgit v1.2.3 From a685df05841a3dd45095e40ca0f40ab796bfc86f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Sun, 4 Nov 2012 21:59:00 +0100 Subject: iOS: Add ability to get the UIView for a QWindow through QPlatformNativeInterface Change-Id: Iab2742bbaa97ff345871ad07ef0162b12248506a Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qiosintegration.h | 6 +++++- src/plugins/platforms/ios/qiosintegration.mm | 20 ++++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/plugins/platforms/ios/qiosintegration.h b/src/plugins/platforms/ios/qiosintegration.h index d744cf377a..d72eefa1fa 100644 --- a/src/plugins/platforms/ios/qiosintegration.h +++ b/src/plugins/platforms/ios/qiosintegration.h @@ -43,10 +43,11 @@ #define QPLATFORMINTEGRATION_UIKIT_H #include +#include QT_BEGIN_NAMESPACE -class QIOSIntegration : public QPlatformIntegration +class QIOSIntegration : public QPlatformIntegration, public QPlatformNativeInterface { public: QIOSIntegration(); @@ -59,6 +60,9 @@ public: QPlatformFontDatabase *fontDatabase() const; QAbstractEventDispatcher *guiThreadEventDispatcher() const; + QPlatformNativeInterface *nativeInterface() const; + + void *nativeResourceForWindow(const QByteArray &resource, QWindow *window); private: QPlatformFontDatabase *m_fontDatabase; diff --git a/src/plugins/platforms/ios/qiosintegration.mm b/src/plugins/platforms/ios/qiosintegration.mm index d3e9572f83..0c876bf1b2 100644 --- a/src/plugins/platforms/ios/qiosintegration.mm +++ b/src/plugins/platforms/ios/qiosintegration.mm @@ -90,4 +90,24 @@ QPlatformFontDatabase * QIOSIntegration::fontDatabase() const return m_fontDatabase; } +QPlatformNativeInterface *QIOSIntegration::nativeInterface() const +{ + return const_cast(this); +} + +void *QIOSIntegration::nativeResourceForWindow(const QByteArray &resource, QWindow *window) +{ + if (!window || !window->handle()) + return 0; + + QByteArray lowerCaseResource = resource.toLower(); + + QIOSWindow *platformWindow = static_cast(window->handle()); + + if (lowerCaseResource == "uiview") + return platformWindow->nativeView(); + + return 0; +} + QT_END_NAMESPACE -- cgit v1.2.3 From 145abdc4429f636b365ce6ebd51f81e216bc7fa3 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Mon, 5 Nov 2012 10:53:59 +0100 Subject: iOS: QIOSEventDispatcher: add runloop source for processing events MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I6cd649a493dab9a982d71921f19d2a9252fc14b0 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qioseventdispatcher.h | 9 +++- src/plugins/platforms/ios/qioseventdispatcher.mm | 61 +++++++++++++++++++++--- 2 files changed, 63 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/plugins/platforms/ios/qioseventdispatcher.h b/src/plugins/platforms/ios/qioseventdispatcher.h index 479ec1d0a0..db3eb85ffc 100644 --- a/src/plugins/platforms/ios/qioseventdispatcher.h +++ b/src/plugins/platforms/ios/qioseventdispatcher.h @@ -77,6 +77,7 @@ #define QEVENTDISPATCHER_IOS_P_H #include +#include QT_BEGIN_NAMESPACE @@ -85,7 +86,8 @@ class QIOSEventDispatcher : public QAbstractEventDispatcher Q_OBJECT public: - explicit QIOSEventDispatcher(QObject *parent = 0); ~QIOSEventDispatcher(); + explicit QIOSEventDispatcher(QObject *parent = 0); + ~QIOSEventDispatcher(); bool processEvents(QEventLoop::ProcessEventsFlags flags); bool hasPendingEvents(); @@ -103,6 +105,11 @@ public: void wakeUp(); void interrupt(); void flush(); + +private: + CFRunLoopSourceRef m_postedEventsSource; + static void postedEventsSourceCallback(void *info); + void processPostedEvents(); }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qioseventdispatcher.mm b/src/plugins/platforms/ios/qioseventdispatcher.mm index 12f448488e..85854f711e 100644 --- a/src/plugins/platforms/ios/qioseventdispatcher.mm +++ b/src/plugins/platforms/ios/qioseventdispatcher.mm @@ -75,42 +75,80 @@ #include "qioseventdispatcher.h" #include +#include QT_BEGIN_NAMESPACE QT_USE_NAMESPACE +static Boolean runLoopSourceEqualCallback(const void *info1, const void *info2) +{ + return info1 == info2; +} + +void QIOSEventDispatcher::postedEventsSourceCallback(void *info) +{ + QIOSEventDispatcher *self = static_cast(info); + self->processPostedEvents(); +} + +void QIOSEventDispatcher::processPostedEvents() +{ + qDebug() << __FUNCTION__ << "called"; + QWindowSystemInterface::sendWindowSystemEvents(QEventLoop::AllEvents); +} + QIOSEventDispatcher::QIOSEventDispatcher(QObject *parent) + : QAbstractEventDispatcher(parent) { - Q_UNUSED(parent); - qDebug() << __FUNCTION__ << "eventdispatcher not implemented"; + CFRunLoopRef mainRunLoop = CFRunLoopGetMain(); + + CFRunLoopSourceContext context; + bzero(&context, sizeof(CFRunLoopSourceContext)); + context.equal = runLoopSourceEqualCallback; + context.info = this; + + // source used to send posted events: + context.perform = QIOSEventDispatcher::postedEventsSourceCallback; + m_postedEventsSource = CFRunLoopSourceCreate(kCFAllocatorDefault, 0, &context); + Q_ASSERT(m_postedEventsSource); + CFRunLoopAddSource(mainRunLoop, m_postedEventsSource, kCFRunLoopCommonModes); } QIOSEventDispatcher::~QIOSEventDispatcher() -{} +{ + CFRunLoopRef mainRunLoop = CFRunLoopGetMain(); + CFRunLoopRemoveSource(mainRunLoop, m_postedEventsSource, kCFRunLoopCommonModes); + CFRelease(m_postedEventsSource); +} bool QIOSEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags) { Q_UNUSED(flags); + qDebug() << __FUNCTION__ << "not implemented"; return false; } bool QIOSEventDispatcher::hasPendingEvents() { + qDebug() << __FUNCTION__ << "not implemented"; return false; } void QIOSEventDispatcher::registerSocketNotifier(QSocketNotifier *notifier) { + qDebug() << __FUNCTION__ << "not implemented"; Q_UNUSED(notifier); } void QIOSEventDispatcher::unregisterSocketNotifier(QSocketNotifier *notifier) { + qDebug() << __FUNCTION__ << "not implemented"; Q_UNUSED(notifier); } void QIOSEventDispatcher::registerTimer(int timerId, int interval, Qt::TimerType timerType, QObject *object) { + qDebug() << __FUNCTION__ << "not implemented"; Q_UNUSED(timerId); Q_UNUSED(interval); Q_UNUSED(timerType); @@ -119,36 +157,47 @@ void QIOSEventDispatcher::registerTimer(int timerId, int interval, Qt::TimerType bool QIOSEventDispatcher::unregisterTimer(int timerId) { + qDebug() << __FUNCTION__ << "not implemented"; Q_UNUSED(timerId); return false; } bool QIOSEventDispatcher::unregisterTimers(QObject *object) { + qDebug() << __FUNCTION__ << "not implemented"; Q_UNUSED(object); return false; } QList QIOSEventDispatcher::registeredTimers(QObject *object) const { + qDebug() << __FUNCTION__ << "not implemented"; Q_UNUSED(object); return QList(); } int QIOSEventDispatcher::remainingTime(int timerId) { + qDebug() << __FUNCTION__ << "not implemented"; Q_UNUSED(timerId); return 0; } void QIOSEventDispatcher::wakeUp() -{} +{ + CFRunLoopSourceSignal(m_postedEventsSource); + CFRunLoopWakeUp(CFRunLoopGetMain()); +} void QIOSEventDispatcher::interrupt() -{} +{ + qDebug() << __FUNCTION__ << "not implemented"; +} void QIOSEventDispatcher::flush() -{} +{ + qDebug() << __FUNCTION__ << "not implemented"; +} QT_END_NAMESPACE -- cgit v1.2.3 From 407cf7341e70feeb24ff63ad11bd2e79dac5823f Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Mon, 5 Nov 2012 14:07:47 +0100 Subject: iOS: QIOSEventDispatcher: implement timer support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I1966a64e6535f32005681db37b4fe5d89dafc70c Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qioseventdispatcher.h | 15 ++- src/plugins/platforms/ios/qioseventdispatcher.mm | 136 ++++++++++++++++++++--- 2 files changed, 132 insertions(+), 19 deletions(-) (limited to 'src') diff --git a/src/plugins/platforms/ios/qioseventdispatcher.h b/src/plugins/platforms/ios/qioseventdispatcher.h index db3eb85ffc..da8464f5ee 100644 --- a/src/plugins/platforms/ios/qioseventdispatcher.h +++ b/src/plugins/platforms/ios/qioseventdispatcher.h @@ -77,6 +77,7 @@ #define QEVENTDISPATCHER_IOS_P_H #include +#include #include QT_BEGIN_NAMESPACE @@ -107,9 +108,19 @@ public: void flush(); private: - CFRunLoopSourceRef m_postedEventsSource; - static void postedEventsSourceCallback(void *info); + CFRunLoopSourceRef m_postedEventsRunLoopSource; + CFRunLoopSourceRef m_blockingTimerRunLoopSource; + + QTimerInfoList m_timerInfoList; + CFRunLoopTimerRef m_runLoopTimerRef; + void processPostedEvents(); + void maybeStartCFRunLoopTimer(); + void maybeStopCFRunLoopTimer(); + + static void postedEventsRunLoopCallback(void *info); + static void nonBlockingTimerRunLoopCallback(CFRunLoopTimerRef, void *info); + static void blockingTimerRunLoopCallback(void *info); }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qioseventdispatcher.mm b/src/plugins/platforms/ios/qioseventdispatcher.mm index 85854f711e..191e80668d 100644 --- a/src/plugins/platforms/ios/qioseventdispatcher.mm +++ b/src/plugins/platforms/ios/qioseventdispatcher.mm @@ -76,6 +76,7 @@ #include "qioseventdispatcher.h" #include #include +#include QT_BEGIN_NAMESPACE QT_USE_NAMESPACE @@ -85,40 +86,134 @@ static Boolean runLoopSourceEqualCallback(const void *info1, const void *info2) return info1 == info2; } -void QIOSEventDispatcher::postedEventsSourceCallback(void *info) +void QIOSEventDispatcher::postedEventsRunLoopCallback(void *info) { QIOSEventDispatcher *self = static_cast(info); self->processPostedEvents(); } +void QIOSEventDispatcher::nonBlockingTimerRunLoopCallback(CFRunLoopTimerRef, void *info) +{ + // The (one and only) CFRunLoopTimer has fired, which means that at least + // one QTimer should now fire as well. Note that CFRunLoopTimer's callback will + // never recurse. So if the app starts a new QEventLoop within this callback, other + // timers will stop working. The work-around is to forward the callback to a + // dedicated CFRunLoopSource that can recurse: + QIOSEventDispatcher *self = static_cast(info); + CFRunLoopSourceSignal(self->m_blockingTimerRunLoopSource); +} + +void QIOSEventDispatcher::blockingTimerRunLoopCallback(void *info) +{ + // TODO: + // We also need to block this new timer source + // along with the posted event source when calling processEvents() + // "manually" to prevent livelock deep in CFRunLoop. + + QIOSEventDispatcher *self = static_cast(info); + self->m_timerInfoList.activateTimers(); + self->maybeStartCFRunLoopTimer(); +} + +void QIOSEventDispatcher::maybeStartCFRunLoopTimer() +{ + // Find out when the next registered timer should fire, and schedule + // runLoopTimer accordingly. If the runLoopTimer does not yet exist, and + // at least one timer is registered, start by creating the timer: + if (m_timerInfoList.isEmpty()) { + Q_ASSERT(m_runLoopTimerRef == 0); + return; + } + + CFAbsoluteTime ttf = CFAbsoluteTimeGetCurrent(); + CFTimeInterval interval; + + if (m_runLoopTimerRef == 0) { + // start the CFRunLoopTimer + CFTimeInterval oneyear = CFTimeInterval(3600. * 24. * 365.); + + // calculate when the next timer should fire: + struct timespec tv; + if (m_timerInfoList.timerWait(tv)) { + interval = qMax(tv.tv_sec + tv.tv_nsec / 1000000000., 0.0000001); + } else { + // this shouldn't really happen, but in case it does, set the timer + // to fire a some point in the distant future: + interval = oneyear; + } + + ttf += interval; + CFRunLoopTimerContext info = { 0, this, 0, 0, 0 }; + // create the timer with a large interval, as recommended by the CFRunLoopTimerSetNextFireDate() + // documentation, since we will adjust the timer's time-to-fire as needed to keep Qt timers working + m_runLoopTimerRef = CFRunLoopTimerCreate(0, ttf, oneyear, 0, 0, QIOSEventDispatcher::nonBlockingTimerRunLoopCallback, &info); + Q_ASSERT(m_runLoopTimerRef != 0); + + CFRunLoopAddTimer(CFRunLoopGetMain(), m_runLoopTimerRef, kCFRunLoopCommonModes); + } else { + struct timespec tv; + // Calculate when the next timer should fire: + if (m_timerInfoList.timerWait(tv)) { + interval = qMax(tv.tv_sec + tv.tv_nsec / 1000000000., 0.0000001); + } else { + // no timers can fire, but we cannot stop the CFRunLoopTimer, set the timer to fire at some + // point in the distant future (the timer interval is one year) + interval = CFRunLoopTimerGetInterval(m_runLoopTimerRef); + } + + ttf += interval; + CFRunLoopTimerSetNextFireDate(m_runLoopTimerRef, ttf); + } +} + +void QIOSEventDispatcher::maybeStopCFRunLoopTimer() +{ + if (m_runLoopTimerRef == 0) + return; + + CFRunLoopTimerInvalidate(m_runLoopTimerRef); + CFRelease(m_runLoopTimerRef); + m_runLoopTimerRef = 0; +} + void QIOSEventDispatcher::processPostedEvents() { - qDebug() << __FUNCTION__ << "called"; QWindowSystemInterface::sendWindowSystemEvents(QEventLoop::AllEvents); } QIOSEventDispatcher::QIOSEventDispatcher(QObject *parent) : QAbstractEventDispatcher(parent) + , m_runLoopTimerRef(0) { CFRunLoopRef mainRunLoop = CFRunLoopGetMain(); - CFRunLoopSourceContext context; bzero(&context, sizeof(CFRunLoopSourceContext)); context.equal = runLoopSourceEqualCallback; context.info = this; - // source used to send posted events: - context.perform = QIOSEventDispatcher::postedEventsSourceCallback; - m_postedEventsSource = CFRunLoopSourceCreate(kCFAllocatorDefault, 0, &context); - Q_ASSERT(m_postedEventsSource); - CFRunLoopAddSource(mainRunLoop, m_postedEventsSource, kCFRunLoopCommonModes); + // source used to handle timers: + context.perform = QIOSEventDispatcher::blockingTimerRunLoopCallback; + m_blockingTimerRunLoopSource = CFRunLoopSourceCreate(kCFAllocatorDefault, 0, &context); + Q_ASSERT(m_blockingTimerRunLoopSource); + CFRunLoopAddSource(mainRunLoop, m_blockingTimerRunLoopSource, kCFRunLoopCommonModes); + + // source used to handle posted events: + context.perform = QIOSEventDispatcher::postedEventsRunLoopCallback; + m_postedEventsRunLoopSource = CFRunLoopSourceCreate(kCFAllocatorDefault, 0, &context); + Q_ASSERT(m_postedEventsRunLoopSource); + CFRunLoopAddSource(mainRunLoop, m_postedEventsRunLoopSource, kCFRunLoopCommonModes); } QIOSEventDispatcher::~QIOSEventDispatcher() { CFRunLoopRef mainRunLoop = CFRunLoopGetMain(); - CFRunLoopRemoveSource(mainRunLoop, m_postedEventsSource, kCFRunLoopCommonModes); - CFRelease(m_postedEventsSource); + CFRunLoopRemoveSource(mainRunLoop, m_postedEventsRunLoopSource, kCFRunLoopCommonModes); + CFRelease(m_postedEventsRunLoopSource); + + qDeleteAll(m_timerInfoList); + maybeStopCFRunLoopTimer(); + CFRunLoopRemoveSource(CFRunLoopGetMain(), m_blockingTimerRunLoopSource, kCFRunLoopCommonModes); + CFRelease(m_blockingTimerRunLoopSource); } bool QIOSEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags) @@ -146,13 +241,20 @@ void QIOSEventDispatcher::unregisterSocketNotifier(QSocketNotifier *notifier) Q_UNUSED(notifier); } -void QIOSEventDispatcher::registerTimer(int timerId, int interval, Qt::TimerType timerType, QObject *object) +void QIOSEventDispatcher::registerTimer(int timerId, int interval, Qt::TimerType timerType, QObject *obj) { - qDebug() << __FUNCTION__ << "not implemented"; - Q_UNUSED(timerId); - Q_UNUSED(interval); - Q_UNUSED(timerType); - Q_UNUSED(object); +#ifndef QT_NO_DEBUG + if (timerId < 1 || interval < 0 || !obj) { + qWarning("QIOSEventDispatcher::registerTimer: invalid arguments"); + return; + } else if (obj->thread() != thread() || thread() != QThread::currentThread()) { + qWarning("QIOSEventDispatcher: timers cannot be started from another thread"); + return; + } +#endif + + m_timerInfoList.registerTimer(timerId, interval, timerType, obj); + maybeStartCFRunLoopTimer(); } bool QIOSEventDispatcher::unregisterTimer(int timerId) @@ -185,7 +287,7 @@ int QIOSEventDispatcher::remainingTime(int timerId) void QIOSEventDispatcher::wakeUp() { - CFRunLoopSourceSignal(m_postedEventsSource); + CFRunLoopSourceSignal(m_postedEventsRunLoopSource); CFRunLoopWakeUp(CFRunLoopGetMain()); } -- cgit v1.2.3 From 44c3ef790e6105b913b514dfda64fd5957df78af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Mon, 5 Nov 2012 13:59:53 +0100 Subject: iOS: Fix build on case sensitive filesystems Change-Id: Ic7a2b38ffcc2bd83e268c5caf5bec17006879969 Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qiosintegration.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/plugins/platforms/ios/qiosintegration.mm b/src/plugins/platforms/ios/qiosintegration.mm index 0c876bf1b2..0c324d5275 100644 --- a/src/plugins/platforms/ios/qiosintegration.mm +++ b/src/plugins/platforms/ios/qiosintegration.mm @@ -39,7 +39,7 @@ ** ****************************************************************************/ -#include "qiosIntegration.h" +#include "qiosintegration.h" #include "qioswindow.h" #include "qiosbackingstore.h" #include "qiosscreen.h" -- cgit v1.2.3 From 05d0f60ebefaeb7721ac572f1253c2c7b2f42dec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Sun, 4 Nov 2012 23:30:50 +0100 Subject: iOS: Flesh out initial QPlatformScreen implementation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We check the device's model identifier to tweak the screen values based on the precense of older iPhone/iPod touch models, or the iPad Mini. This does not work when running under the simulator, which reports its model identifier as the architecture of the host platform. There doesn't appear to be any APIs to get the simulated device of the simulator, but if this becomes an issue we can always look at the UIDevice model and screen resolution and apply a few heuristics. We do not update the screen geometry on orientation-changes. This matches what UIScreen reports for bounds, but may not be the most intuitive solution from a Qt perspective compared to the way other platform-plugins work. Change-Id: I74783e053601de9ce805f8b52b944c116f9a1e3e Reviewed-by: Richard Moe Gustavsen Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/ios/qiosscreen.h | 13 ++-- src/plugins/platforms/ios/qiosscreen.mm | 105 +++++++++++++++++--------------- 2 files changed, 61 insertions(+), 57 deletions(-) (limited to 'src') diff --git a/src/plugins/platforms/ios/qiosscreen.h b/src/plugins/platforms/ios/qiosscreen.h index 98771b9ac2..8af7779f9d 100644 --- a/src/plugins/platforms/ios/qiosscreen.h +++ b/src/plugins/platforms/ios/qiosscreen.h @@ -52,24 +52,21 @@ class QIOSScreen : public QPlatformScreen { public: QIOSScreen(unsigned int screenIndex); - ~QIOSScreen(); enum ScreenIndex { MainScreen = 0 }; - QRect geometry() const { return m_geometry; } - int depth() const { return m_depth; } - QImage::Format format() const { return m_format; } - QSizeF physicalSize() const { return m_physicalSize; } + QRect geometry() const; + int depth() const; + QImage::Format format() const; + QSizeF physicalSize() const; UIScreen *uiScreen() const; - void updateInterfaceOrientation(); private: UIScreen *m_uiScreen; QRect m_geometry; int m_depth; - QImage::Format m_format; - QSize m_physicalSize; + QSizeF m_physicalSize; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qiosscreen.mm b/src/plugins/platforms/ios/qiosscreen.mm index 64b9022a29..93b22953e2 100644 --- a/src/plugins/platforms/ios/qiosscreen.mm +++ b/src/plugins/platforms/ios/qiosscreen.mm @@ -42,79 +42,86 @@ #include "qiosscreen.h" #include "qioswindow.h" -#include - -#include +#include QT_BEGIN_NAMESPACE +/*! + Returns the model identifier of the device. + + When running under the simulator, the identifier will not + match the simulated device, but will be x86_64 or i386. +*/ +static QString deviceModelIdentifier() +{ + static const char key[] = "hw.machine"; + + size_t size; + sysctlbyname(key, NULL, &size, NULL, 0); + + char value[size]; + sysctlbyname(key, &value, &size, NULL, 0); + + return QString::fromLatin1(value); +} + QIOSScreen::QIOSScreen(unsigned int screenIndex) : QPlatformScreen() , m_uiScreen([[UIScreen screens] objectAtIndex:qMin(screenIndex, [[UIScreen screens] count] - 1)]) { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - CGRect bounds = [m_uiScreen bounds]; - CGFloat scale = [m_uiScreen scale]; - updateInterfaceOrientation(); - m_format = QImage::Format_ARGB32_Premultiplied; + QString deviceIdentifier = deviceModelIdentifier(); - m_depth = 24; - - const qreal inch = 25.4; - qreal unscaledDpi = 160.; - int dragDistance = 12 * scale; - if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) { - unscaledDpi = 132.; - dragDistance = 10 * scale; + if (deviceIdentifier == QStringLiteral("iPhone2,1") /* iPhone 3GS */ + || deviceIdentifier == QStringLiteral("iPod3,1") /* iPod touch 3G */) { + m_depth = 18; + } else { + m_depth = 24; } - m_physicalSize = QSize(qRound(bounds.size.width * inch / unscaledDpi), qRound(bounds.size.height * inch / unscaledDpi)); - //qApp->setStartDragDistance(dragDistance); + int unscaledDpi = 163; // Regular iPhone DPI + if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad + && deviceIdentifier != QStringLiteral("iPad2,5") /* iPad Mini */) { + unscaledDpi = 132; + }; + + // UIScreen does not report different bounds for different orientations. We + // match this behavior by staying with a fixed QScreen geometry. + CGRect bounds = [m_uiScreen bounds]; + m_geometry = QRect(bounds.origin.x, bounds.origin.y, bounds.size.width, bounds.size.height); - /* - QFont font; // system font is helvetica, so that is fine already - font.setPixelSize([UIFont systemFontSize] * scale); - qApp->setFont(font); - */ + const qreal millimetersPerInch = 25.4; + m_physicalSize = QSizeF(m_geometry.size()) / unscaledDpi * millimetersPerInch; [pool release]; } -QIOSScreen::~QIOSScreen() +QRect QIOSScreen::geometry() const { + // FIXME: Do we need to reimplement availableGeometry() to take the + // system statusbar into account? + return m_geometry; } -UIScreen *QIOSScreen::uiScreen() const +int QIOSScreen::depth() const { - return m_uiScreen; + return m_depth; } -void QIOSScreen::updateInterfaceOrientation() +QImage::Format QIOSScreen::format() const { - qDebug() << __FUNCTION__ << "not implemented"; - /* - CGRect bounds = [uiScreen() bounds]; - CGFloat scale = [uiScreen() scale]; - switch ([[UIApplication sharedApplication] statusBarOrientation]) { - case UIInterfaceOrientationPortrait: - case UIInterfaceOrientationPortraitUpsideDown: - m_geometry = QRect(bounds.origin.x * scale, bounds.origin.y * scale, - bounds.size.width * scale, bounds.size.height * scale);; - break; - case UIInterfaceOrientationLandscapeLeft: - case UIInterfaceOrientationLandscapeRight: - m_geometry = QRect(bounds.origin.x * scale, bounds.origin.y * scale, - bounds.size.height * scale, bounds.size.width * scale); - break; - } - foreach (QWidget *widget, qApp->topLevelWidgets()) { - QIOSWindow *platformWindow = static_cast(widget->platformWindow()); - if (platformWindow && platformWindow->platformScreen() == this) { - platformWindow->updateGeometryAndOrientation(); - } - } - */ + return QImage::Format_ARGB32_Premultiplied; +} + +QSizeF QIOSScreen::physicalSize() const +{ + return m_physicalSize; +} + +UIScreen *QIOSScreen::uiScreen() const +{ + return m_uiScreen; } QT_END_NAMESPACE -- cgit v1.2.3 From 458382f35b62c98a283bb08770029f21827b9ae6 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Tue, 6 Nov 2012 11:00:58 +0100 Subject: iOS: call UIApplicationMain from event dispatcher, and add application delegate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This change will let you call QApplication::exec() instead of UiApplicationMain from main. Also added an application delegate that we will need sooner or later for catching application activation events. Change-Id: I4edba5ce2059a804782d67c160755fc0e2e5267d Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/ios.pro | 6 +- .../platforms/ios/qiosapplicationdelegate.h | 50 ++++++++++++ .../platforms/ios/qiosapplicationdelegate.mm | 89 ++++++++++++++++++++++ src/plugins/platforms/ios/qioseventdispatcher.mm | 58 ++++++-------- 4 files changed, 165 insertions(+), 38 deletions(-) create mode 100644 src/plugins/platforms/ios/qiosapplicationdelegate.h create mode 100644 src/plugins/platforms/ios/qiosapplicationdelegate.mm (limited to 'src') diff --git a/src/plugins/platforms/ios/ios.pro b/src/plugins/platforms/ios/ios.pro index c6c104f2f3..76f5e3420e 100644 --- a/src/plugins/platforms/ios/ios.pro +++ b/src/plugins/platforms/ios/ios.pro @@ -12,13 +12,15 @@ OBJECTIVE_SOURCES = main.mm \ qioswindow.mm \ qiosscreen.mm \ qioseventdispatcher.mm \ - qiosbackingstore.mm + qiosbackingstore.mm \ + qiosapplicationdelegate.mm HEADERS = qiosintegration.h \ qioswindow.h \ qiosscreen.h \ qioseventdispatcher.h \ - qiosbackingstore.h + qiosbackingstore.h \ + qiosapplicationdelegate.h #HEADERS = qiossoftwareinputhandler.h diff --git a/src/plugins/platforms/ios/qiosapplicationdelegate.h b/src/plugins/platforms/ios/qiosapplicationdelegate.h new file mode 100644 index 0000000000..10e415831d --- /dev/null +++ b/src/plugins/platforms/ios/qiosapplicationdelegate.h @@ -0,0 +1,50 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#import +#import + +@interface QIOSApplicationDelegate : UIResponder + +@property (strong, nonatomic) UIWindow *window; + +@end + diff --git a/src/plugins/platforms/ios/qiosapplicationdelegate.mm b/src/plugins/platforms/ios/qiosapplicationdelegate.mm new file mode 100644 index 0000000000..d88b2b83f1 --- /dev/null +++ b/src/plugins/platforms/ios/qiosapplicationdelegate.mm @@ -0,0 +1,89 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#import "qiosapplicationdelegate.h" +#include + +@implementation QIOSApplicationDelegate + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions +{ + Q_UNUSED(application) + Q_UNUSED(launchOptions) + self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; + + // Override point for customization after application launch. + self.window.backgroundColor = [UIColor whiteColor]; + [self.window makeKeyAndVisible]; + return YES; +} + +- (void)applicationWillResignActive:(UIApplication *)application +{ + Q_UNUSED(application) +} + +- (void)applicationDidEnterBackground:(UIApplication *)application +{ + Q_UNUSED(application) +} + +- (void)applicationWillEnterForeground:(UIApplication *)application +{ + Q_UNUSED(application) + // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. +} + +- (void)applicationDidBecomeActive:(UIApplication *)application +{ + Q_UNUSED(application) + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. +} + +- (void)applicationWillTerminate:(UIApplication *)application +{ + Q_UNUSED(application) + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. +} + +@end + + diff --git a/src/plugins/platforms/ios/qioseventdispatcher.mm b/src/plugins/platforms/ios/qioseventdispatcher.mm index 191e80668d..64f853233d 100644 --- a/src/plugins/platforms/ios/qioseventdispatcher.mm +++ b/src/plugins/platforms/ios/qioseventdispatcher.mm @@ -39,44 +39,13 @@ ** ****************************************************************************/ -/**************************************************************************** -** -** Copyright (c) 2007-2008, Apple, Inc. -** -** All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are met: -** -** * Redistributions of source code must retain the above copyright notice, -** this list of conditions and the following disclaimer. -** -** * Redistributions in binary form must reproduce the above copyright notice, -** this list of conditions and the following disclaimer in the documentation -** and/or other materials provided with the distribution. -** -** * Neither the name of Apple, Inc. nor the names of its contributors -** may be used to endorse or promote products derived from this software -** without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -** EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -** PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -** -****************************************************************************/ - #include "qioseventdispatcher.h" +#import "qiosapplicationdelegate.h" #include #include #include +#include +#include QT_BEGIN_NAMESPACE QT_USE_NAMESPACE @@ -218,8 +187,25 @@ QIOSEventDispatcher::~QIOSEventDispatcher() bool QIOSEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags) { - Q_UNUSED(flags); - qDebug() << __FUNCTION__ << "not implemented"; + UIApplication *uiApplication = [UIApplication sharedApplication]; + bool excludeUserEvents = flags & QEventLoop::ExcludeUserInputEvents; + bool execFlagSet = (flags & QEventLoop::DialogExec) || (flags & QEventLoop::EventLoopExec); + bool useExecMode = execFlagSet && !excludeUserEvents; + + if (useExecMode) { + if (!uiApplication) { + // No UIApplication has been started yet. We therefore start it now. Note that application + // developers are free to call UIApplicationMain themselves instead of QApplication::exec() + @autoreleasepool { + QCoreApplicationPrivate *qAppPriv = static_cast(QObjectPrivate::get(qApp)); + return UIApplicationMain(qAppPriv->argc, qAppPriv->argv, nil, NSStringFromClass([QIOSApplicationDelegate class])); + } + } else { + // todo: start NSRunLoop... + } + } else { + // todo: manual processEvents... + } return false; } -- cgit v1.2.3 From ac8d906a3a61b3dd43aaf546e5f83e25d117631c Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Tue, 6 Nov 2012 14:52:22 +0100 Subject: iOS: support killing timers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implement the remaining timer functions in the event dispatcher Change-Id: Ie323962c898a2ee95ea60a8ca63b93cbd4544fd1 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qioseventdispatcher.mm | 54 ++++++++++++++++++------ 1 file changed, 42 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/plugins/platforms/ios/qioseventdispatcher.mm b/src/plugins/platforms/ios/qioseventdispatcher.mm index 64f853233d..a7f01a33a9 100644 --- a/src/plugins/platforms/ios/qioseventdispatcher.mm +++ b/src/plugins/platforms/ios/qioseventdispatcher.mm @@ -245,30 +245,60 @@ void QIOSEventDispatcher::registerTimer(int timerId, int interval, Qt::TimerType bool QIOSEventDispatcher::unregisterTimer(int timerId) { - qDebug() << __FUNCTION__ << "not implemented"; - Q_UNUSED(timerId); - return false; +#ifndef QT_NO_DEBUG + if (timerId < 1) { + qWarning("QIOSEventDispatcher::unregisterTimer: invalid argument"); + return false; + } else if (thread() != QThread::currentThread()) { + qWarning("QObject::killTimer: timers cannot be stopped from another thread"); + return false; + } +#endif + + bool returnValue = m_timerInfoList.unregisterTimer(timerId); + m_timerInfoList.isEmpty() ? maybeStopCFRunLoopTimer() : maybeStartCFRunLoopTimer(); + return returnValue; } bool QIOSEventDispatcher::unregisterTimers(QObject *object) { - qDebug() << __FUNCTION__ << "not implemented"; - Q_UNUSED(object); - return false; +#ifndef QT_NO_DEBUG + if (!object) { + qWarning("QIOSEventDispatcher::unregisterTimers: invalid argument"); + return false; + } else if (object->thread() != thread() || thread() != QThread::currentThread()) { + qWarning("QObject::killTimers: timers cannot be stopped from another thread"); + return false; + } +#endif + + bool returnValue = m_timerInfoList.unregisterTimers(object); + m_timerInfoList.isEmpty() ? maybeStopCFRunLoopTimer() : maybeStartCFRunLoopTimer(); + return returnValue; } QList QIOSEventDispatcher::registeredTimers(QObject *object) const { - qDebug() << __FUNCTION__ << "not implemented"; - Q_UNUSED(object); - return QList(); +#ifndef QT_NO_DEBUG + if (!object) { + qWarning("QIOSEventDispatcher:registeredTimers: invalid argument"); + return QList(); + } +#endif + + return m_timerInfoList.registeredTimers(object); } int QIOSEventDispatcher::remainingTime(int timerId) { - qDebug() << __FUNCTION__ << "not implemented"; - Q_UNUSED(timerId); - return 0; +#ifndef QT_NO_DEBUG + if (timerId < 1) { + qWarning("QIOSEventDispatcher::remainingTime: invalid argument"); + return -1; + } +#endif + + return m_timerInfoList.timerRemainingTime(timerId); } void QIOSEventDispatcher::wakeUp() -- cgit v1.2.3 From 3c4f48f9e2ad9163d012d4afb36037d7efea8e3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Tue, 6 Nov 2012 16:24:19 +0100 Subject: iOS: Implement QPlatformOpenGLContext The iOS platform GL context is an EAGLContext, which is wrapped by the new class QIOSContext. The class takes care of makeCurrent() and swapBuffers(), but defers framebuffer management to the corresponding QIOSWindow. At the moment only a single framebuffer is created, and changing the geometry of the QWindow does not trigger any sort of invalidation of the buffers. The implementation assumes OpenGL ES2.x support. Though strictly speaking we could support ES1 for QtGui, it serves little purpose as Qt Quick 2 requires ES2. This patch also disabled touch event synthesization until we have figured out where we will maintain the connection to UIWindow. QPlatformOpenGLContext::getProcAddress() for getting extensions is implemented by using dlsym() to look up the symbol. This should not present any issues for App Store deployment, like dlopen() would. Change-Id: I166f800f3ecc0d180133c590465371ac1642b0ec Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/ios.pro | 6 +- src/plugins/platforms/ios/qiosbackingstore.mm | 1 + src/plugins/platforms/ios/qioscontext.h | 76 +++++ src/plugins/platforms/ios/qioscontext.mm | 124 ++++++++ src/plugins/platforms/ios/qiosintegration.h | 2 + src/plugins/platforms/ios/qiosintegration.mm | 13 +- src/plugins/platforms/ios/qioswindow.h | 97 ++----- src/plugins/platforms/ios/qioswindow.mm | 400 +++++++------------------- 8 files changed, 343 insertions(+), 376 deletions(-) create mode 100644 src/plugins/platforms/ios/qioscontext.h create mode 100644 src/plugins/platforms/ios/qioscontext.mm (limited to 'src') diff --git a/src/plugins/platforms/ios/ios.pro b/src/plugins/platforms/ios/ios.pro index 76f5e3420e..22b0fec9e8 100644 --- a/src/plugins/platforms/ios/ios.pro +++ b/src/plugins/platforms/ios/ios.pro @@ -13,14 +13,16 @@ OBJECTIVE_SOURCES = main.mm \ qiosscreen.mm \ qioseventdispatcher.mm \ qiosbackingstore.mm \ - qiosapplicationdelegate.mm + qiosapplicationdelegate.mm \ + qioscontext.mm HEADERS = qiosintegration.h \ qioswindow.h \ qiosscreen.h \ qioseventdispatcher.h \ qiosbackingstore.h \ - qiosapplicationdelegate.h + qiosapplicationdelegate.h \ + qioscontext.h #HEADERS = qiossoftwareinputhandler.h diff --git a/src/plugins/platforms/ios/qiosbackingstore.mm b/src/plugins/platforms/ios/qiosbackingstore.mm index 20f7c1f2d1..2ffa43b5d1 100644 --- a/src/plugins/platforms/ios/qiosbackingstore.mm +++ b/src/plugins/platforms/ios/qiosbackingstore.mm @@ -133,6 +133,7 @@ void QIOSBackingStore::resize(const QSize &size, const QRegion &staticContents) { Q_UNUSED(size); Q_UNUSED(staticContents); + qDebug() << __FUNCTION__ << "not implemented"; } diff --git a/src/plugins/platforms/ios/qioscontext.h b/src/plugins/platforms/ios/qioscontext.h new file mode 100644 index 0000000000..102aaaa387 --- /dev/null +++ b/src/plugins/platforms/ios/qioscontext.h @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QIOSCONTEXT_H +#define QIOSCONTEXT_H + +#include + +@class EAGLContext; + +QT_BEGIN_NAMESPACE + +class QIOSContext : public QPlatformOpenGLContext +{ +public: + QIOSContext(QOpenGLContext *context); + ~QIOSContext(); + + QSurfaceFormat format() const; + + void swapBuffers(QPlatformSurface *surface); + + bool makeCurrent(QPlatformSurface *surface); + void doneCurrent(); + + GLuint defaultFramebufferObject(QPlatformSurface *) const; + QFunctionPointer getProcAddress(const QByteArray &procName); + + EAGLContext *nativeContext() const; + +private: + EAGLContext *m_eaglContext; + QSurfaceFormat m_format; +}; + +QT_END_NAMESPACE + +#endif // QIOSCONTEXT_H diff --git a/src/plugins/platforms/ios/qioscontext.mm b/src/plugins/platforms/ios/qioscontext.mm new file mode 100644 index 0000000000..e512b3d4c8 --- /dev/null +++ b/src/plugins/platforms/ios/qioscontext.mm @@ -0,0 +1,124 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qioscontext.h" +#include "qioswindow.h" + +#include + +#include + +#import +#import + +QIOSContext::QIOSContext(QOpenGLContext *context) + : QPlatformOpenGLContext() + , m_eaglContext([[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]) +{ + // Start out with the requested format + QSurfaceFormat format = context->format(); + + format.setRenderableType(QSurfaceFormat::OpenGLES); + format.setMajorVersion(2); + format.setMinorVersion(0); + + // Even though iOS internally double-buffers its rendering, we + // report single-buffered here since the buffer remains unchanged + // when swapping unlesss you manually clear it yourself. + format.setSwapBehavior(QSurfaceFormat::SingleBuffer); + + m_format = format; +} + +QIOSContext::~QIOSContext() +{ + [m_eaglContext release]; +} + +QSurfaceFormat QIOSContext::format() const +{ + return m_format; +} + +bool QIOSContext::makeCurrent(QPlatformSurface *surface) +{ + Q_ASSERT(surface && surface->surface()->surfaceType() == QSurface::OpenGLSurface); + + [EAGLContext setCurrentContext:m_eaglContext]; + glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebufferObject(surface)); + + return true; +} + +void QIOSContext::doneCurrent() +{ + [EAGLContext setCurrentContext:nil]; +} + +void QIOSContext::swapBuffers(QPlatformSurface *surface) +{ + Q_ASSERT(surface && surface->surface()->surfaceType() == QSurface::OpenGLSurface); + + [EAGLContext setCurrentContext:m_eaglContext]; + + GLint renderbuffer; + glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebufferObject(surface)); + glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, + GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &renderbuffer); + glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer); + + [m_eaglContext presentRenderbuffer:GL_RENDERBUFFER]; +} + +GLuint QIOSContext::defaultFramebufferObject(QPlatformSurface *surface) const +{ + return static_cast(surface)->framebufferObject(*const_cast(this)); +} + +QFunctionPointer QIOSContext::getProcAddress(const QByteArray& functionName) +{ + return reinterpret_cast(dlsym(RTLD_NEXT, functionName.constData())); +} + +EAGLContext *QIOSContext::nativeContext() const +{ + return m_eaglContext; +} diff --git a/src/plugins/platforms/ios/qiosintegration.h b/src/plugins/platforms/ios/qiosintegration.h index d72eefa1fa..e411ce2905 100644 --- a/src/plugins/platforms/ios/qiosintegration.h +++ b/src/plugins/platforms/ios/qiosintegration.h @@ -57,6 +57,8 @@ public: QPlatformWindow *createPlatformWindow(QWindow *window) const; QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const; + QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const; + QPlatformFontDatabase *fontDatabase() const; QAbstractEventDispatcher *guiThreadEventDispatcher() const; diff --git a/src/plugins/platforms/ios/qiosintegration.mm b/src/plugins/platforms/ios/qiosintegration.mm index 0c324d5275..b9fef71abc 100644 --- a/src/plugins/platforms/ios/qiosintegration.mm +++ b/src/plugins/platforms/ios/qiosintegration.mm @@ -44,6 +44,7 @@ #include "qiosbackingstore.h" #include "qiosscreen.h" #include "qioseventdispatcher.h" +#include "qioscontext.h" #include @@ -65,21 +66,31 @@ QIOSIntegration::~QIOSIntegration() QPlatformPixmap *QIOSIntegration::createPlatformPixmap(QPlatformPixmap::PixelType type) const { Q_UNUSED(type); + qDebug() << __FUNCTION__ << "not yet implemented"; return 0; - //return new QRasterPixmapData(type); } QPlatformWindow *QIOSIntegration::createPlatformWindow(QWindow *window) const { + qDebug() << __FUNCTION__ << "Creating platform window"; return new QIOSWindow(window); } QPlatformBackingStore *QIOSIntegration::createPlatformBackingStore(QWindow *window) const { + qDebug() << __FUNCTION__ << "Creating platform backingstore"; return new QIOSBackingStore(window); } +// Used when the QWindow's surface type is set by the client to QSurface::OpenGLSurface +QPlatformOpenGLContext *QIOSIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const +{ + Q_UNUSED(context); + qDebug() << __FUNCTION__ << "Creating platform opengl context"; + return new QIOSContext(context); +} + QAbstractEventDispatcher *QIOSIntegration::guiThreadEventDispatcher() const { return new QIOSEventDispatcher(); diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h index 2d3d5b072f..d8f49db55b 100644 --- a/src/plugins/platforms/ios/qioswindow.h +++ b/src/plugins/platforms/ios/qioswindow.h @@ -1,38 +1,38 @@ /**************************************************************************** ** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal ** ** This file is part of the plugins of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** ** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. ** ** ** $QT_END_LICENSE$ @@ -45,24 +45,11 @@ #include #import -#import -#import -#import -#import -#import + +class QIOSContext; @interface EAGLView : UIView { - QPlatformWindow *m_window; - EAGLContext *m_context; - - GLint m_framebufferWidth; - GLint m_framebufferHeight; - - GLuint m_framebuffer, m_colorRenderbuffer, m_depthRenderbuffer; - - id delegate; - // ------- Text Input ---------- UITextAutocapitalizationType autocapitalizationType; UITextAutocorrectionType autocorrectionType; BOOL enablesReturnKeyAutomatically; @@ -72,19 +59,8 @@ BOOL secureTextEntry; } -- (void)setContext:(EAGLContext *)newContext; -- (void)presentFramebuffer; -- (void)deleteFramebuffer; -- (void)createFramebuffer; -- (void)makeCurrent; -- (void)setWindow:(QPlatformWindow *)window; - (void)sendMouseEventForTouches:(NSSet *)touches withEvent:(UIEvent *)event fakeButtons:(Qt::MouseButtons)buttons; -@property (readonly,getter=fbo) GLint fbo; -@property (nonatomic, assign) id delegate; - -// ------- Text Input ---------- - @property(nonatomic) UITextAutocapitalizationType autocapitalizationType; @property(nonatomic) UITextAutocorrectionType autocorrectionType; @property(nonatomic) BOOL enablesReturnKeyAutomatically; @@ -95,39 +71,22 @@ @end -@protocol EAGLViewDelegate -- (void)eaglView:(EAGLView *)view usesFramebuffer:(GLuint)buffer; -@end - -class EAGLPlatformContext; - QT_BEGIN_NAMESPACE -class QIOSScreen; - class QIOSWindow : public QPlatformWindow { public: explicit QIOSWindow(QWindow *window); ~QIOSWindow(); - UIWindow *nativeWindow() const { return m_window; } - EAGLView *nativeView() const { return m_view; } void setGeometry(const QRect &rect); - UIWindow *ensureNativeWindow(); + GLuint framebufferObject(const QIOSContext &context) const; - QPlatformOpenGLContext *glContext() const; - - QIOSScreen *platformScreen() const { return m_screen; } + EAGLView *nativeView() const { return m_view; } - void updateGeometryAndOrientation(); private: - QIOSScreen *m_screen; - UIWindow *m_window; - CGRect m_frame; EAGLView *m_view; - mutable EAGLPlatformContext *m_context; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 28aaaf2189..46612ae699 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -1,152 +1,57 @@ /**************************************************************************** ** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal ** ** This file is part of the plugins of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** ** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ -#import - #include "qioswindow.h" - +#include "qioscontext.h" #include "qiosscreen.h" -#include +#import + #include -#include #include #include -static GLint stencilBits() -{ - static GLint bits; - static bool initialized = false; - if (!initialized) { - glGetIntegerv(GL_STENCIL_BITS, &bits); - initialized = true; - } - return bits; -} - -/* -static GLint depthBits() -{ - // we can choose between GL_DEPTH24_STENCIL8_OES and GL_DEPTH_COMPONENT16 - return stencilBits() > 0 ? 24 : 16; -} -*/ - -class EAGLPlatformContext : public QPlatformOpenGLContext -{ -public: - EAGLPlatformContext(EAGLView *view) - : m_view(view) - { - /* - mFormat.setWindowApi(QPlatformWindowFormat::OpenGL); - mFormat.setDepthBufferSize(depthBits()); - mFormat.setAccumBufferSize(0); - mFormat.setRedBufferSize(8); - mFormat.setGreenBufferSize(8); - mFormat.setBlueBufferSize(8); - mFormat.setAlphaBufferSize(8); - mFormat.setStencilBufferSize(stencilBits()); - mFormat.setSamples(0); - mFormat.setSampleBuffers(false); - mFormat.setDoubleBuffer(true); - mFormat.setDepth(true); - mFormat.setRgba(true); - mFormat.setAlpha(true); - mFormat.setAccum(false); - mFormat.setStencil(stencilBits() > 0); - mFormat.setStereo(false); - mFormat.setDirectRendering(false); - */ - -#if defined(QT_OPENGL_ES_2) - EAGLContext *aContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; -#else - EAGLContext *aContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1]; -#endif - [m_view setContext:aContext]; - } - - ~EAGLPlatformContext() { } - - bool makeCurrent(QPlatformSurface *surface) - { - Q_UNUSED(surface); - qDebug() << __FUNCTION__ << "not implemented"; - //QPlatformOpenGLContext::makeCurrent(); - //[m_view makeCurrent]; - return false; - } - - void doneCurrent() - { - qDebug() << __FUNCTION__ << "not implemented"; - //QPlatformOpenGLContext::doneCurrent(); - } - - void swapBuffers(QPlatformSurface *surface) - { - Q_UNUSED(surface); - qDebug() << __FUNCTION__ << "not implemented"; - //[m_view presentFramebuffer]; - } - - QFunctionPointer getProcAddress(const QByteArray& ) { return 0; } - - QSurfaceFormat format() const - { - return mFormat; - } - -private: - EAGLView *m_view; - - QSurfaceFormat mFormat; -}; - @implementation EAGLView -@synthesize delegate; - + (Class)layerClass { return [CAEAGLLayer class]; @@ -155,12 +60,14 @@ private: - (id)initWithFrame:(CGRect)frame { if ((self = [super initWithFrame:frame])) { - CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer; + // Set up EAGL layer + CAEAGLLayer *eaglLayer = static_cast(self.layer); eaglLayer.opaque = TRUE; eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys: - [NSNumber numberWithBool:YES], kEAGLDrawablePropertyRetainedBacking, - kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat, - nil]; + [NSNumber numberWithBool:YES], kEAGLDrawablePropertyRetainedBacking, + kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat, nil]; + + // Set up text input autocapitalizationType = UITextAutocapitalizationTypeNone; autocorrectionType = UITextAutocorrectionTypeNo; enablesReturnKeyAutomatically = NO; @@ -169,113 +76,28 @@ private: returnKeyType = UIReturnKeyDone; secureTextEntry = NO; } - return self; -} - -- (void)setContext:(EAGLContext *)newContext -{ - if (m_context != newContext) - { - [self deleteFramebuffer]; - [m_context release]; - m_context = [newContext retain]; - [EAGLContext setCurrentContext:nil]; - } -} - -- (void)presentFramebuffer -{ - if (m_context) { - [EAGLContext setCurrentContext:m_context]; - glBindRenderbuffer(GL_RENDERBUFFER, m_colorRenderbuffer); - [m_context presentRenderbuffer:GL_RENDERBUFFER]; - } -} -- (void)deleteFramebuffer -{ - if (m_context) - { - [EAGLContext setCurrentContext:m_context]; - if (m_framebuffer) { - glDeleteFramebuffers(1, &m_framebuffer); - m_framebuffer = 0; - } - if (m_colorRenderbuffer) { - glDeleteRenderbuffers(1, &m_colorRenderbuffer); - m_colorRenderbuffer = 0; - } - if (m_depthRenderbuffer) { - glDeleteRenderbuffers(1, &m_depthRenderbuffer); - m_depthRenderbuffer = 0; - } - } -} - -- (void)createFramebuffer -{ - if (m_context && !m_framebuffer) - { - [EAGLContext setCurrentContext:m_context]; - glGenFramebuffers(1, &m_framebuffer); - glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffer); - - glGenRenderbuffers(1, &m_colorRenderbuffer); - glBindRenderbuffer(GL_RENDERBUFFER, m_colorRenderbuffer); - [m_context renderbufferStorage:GL_RENDERBUFFER fromDrawable:(CAEAGLLayer *)self.layer]; - glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &m_framebufferWidth); - glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &m_framebufferHeight); - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_colorRenderbuffer); - - glGenRenderbuffers(1, &m_depthRenderbuffer); - glBindRenderbuffer(GL_RENDERBUFFER, m_depthRenderbuffer); - if (stencilBits() > 0) { - glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, m_framebufferWidth, m_framebufferHeight); - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_depthRenderbuffer); - } else { - glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, m_framebufferWidth, m_framebufferHeight); - } - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_depthRenderbuffer); - - if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) - NSLog(@"Failed to make complete framebuffer object %x", glCheckFramebufferStatus(GL_FRAMEBUFFER)); - if (delegate && [delegate respondsToSelector:@selector(eaglView:usesFramebuffer:)]) { - [delegate eaglView:self usesFramebuffer:m_framebuffer]; - } - } -} - -- (void)makeCurrent -{ - if (m_context) - { - [EAGLContext setCurrentContext:m_context]; - if (!m_framebuffer) - [self createFramebuffer]; - glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffer); - glViewport(0, 0, m_framebufferWidth, m_framebufferHeight); - } + return self; } -- (GLint)fbo +- (void)sendMouseEventForTouches:(NSSet *)touches withEvent:(UIEvent *)event fakeButtons:(Qt::MouseButtons)buttons { - return m_framebuffer; -} + Q_UNUSED(touches); + Q_UNUSED(event); + Q_UNUSED(buttons); -- (void)setWindow:(QPlatformWindow *)window -{ - m_window = window; -} + // FIXME: Reintroduce relation to UIWindow + qDebug() << __FUNCTION__ << "not implemented"; -- (void)sendMouseEventForTouches:(NSSet *)touches withEvent:(UIEvent *)event fakeButtons:(Qt::MouseButtons)buttons -{ +#if 0 UITouch *touch = [touches anyObject]; CGPoint locationInView = [touch locationInView:self]; CGFloat scaleFactor = [self contentScaleFactor]; QPoint p(locationInView.x * scaleFactor, locationInView.y * scaleFactor); + // TODO handle global touch point? for status bar? - QWindowSystemInterface::handleMouseEvent(m_window->window(), (ulong)(event.timestamp*1000), - p, p, buttons); + QWindowSystemInterface::handleMouseEvent(m_window->window(), (ulong)(event.timestamp*1000), p, p, buttons); +#endif } - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event @@ -298,8 +120,6 @@ private: [self sendMouseEventForTouches:touches withEvent:event fakeButtons:Qt::NoButton]; } -// ------- Text Input ---------- - @synthesize autocapitalizationType; @synthesize autocorrectionType; @synthesize enablesReturnKeyAutomatically; @@ -343,107 +163,79 @@ private: @end + QT_BEGIN_NAMESPACE -QIOSWindow::QIOSWindow(QWindow *window) : - QPlatformWindow(window), - m_window(nil), - m_context(0) +QIOSWindow::QIOSWindow(QWindow *window) + : QPlatformWindow(window) + , m_view([[EAGLView alloc] init]) { - m_screen = static_cast(QPlatformScreen::platformScreenForWindow(window)); - m_view = [[EAGLView alloc] init]; } QIOSWindow::~QIOSWindow() { - delete m_context; m_context = 0; [m_view release]; - [m_window release]; } void QIOSWindow::setGeometry(const QRect &rect) { - // Not supported. Only a single "full screen" window is supported QPlatformWindow::setGeometry(rect); -} -UIWindow *QIOSWindow::ensureNativeWindow() -{ - if (!m_window) { - m_window = [[UIWindow alloc] init]; - updateGeometryAndOrientation(); - // window - m_window.screen = m_screen->uiScreen(); - // for some reason setting the screen resets frame.origin, so we need to set the frame afterwards - m_window.frame = m_frame; - - // view - [m_view deleteFramebuffer]; - m_view.frame = CGRectMake(0, 0, m_window.bounds.size.width, m_window.bounds.size.height); // fill - [m_view setContentScaleFactor:[m_window.screen scale]]; - [m_view setMultipleTouchEnabled:YES]; - [m_view setWindow:this]; - [m_window addSubview:m_view]; - [m_window setNeedsDisplay]; - [m_window makeKeyAndVisible]; - } - return m_window; + qDebug() << __FUNCTION__ << "not implemented"; } -void QIOSWindow::updateGeometryAndOrientation() +GLuint QIOSWindow::framebufferObject(const QIOSContext &context) const { - if (!m_window) - return; - m_frame = [m_screen->uiScreen() applicationFrame]; - CGRect screen = [m_screen->uiScreen() bounds]; - QRect geom; - CGFloat angle = 0; - switch ([[UIApplication sharedApplication] statusBarOrientation]) { - case UIInterfaceOrientationPortrait: - geom = QRect(m_frame.origin.x, m_frame.origin.y, m_frame.size.width, m_frame.size.height); - break; - case UIInterfaceOrientationPortraitUpsideDown: - geom = QRect(screen.size.width - m_frame.origin.x - m_frame.size.width, - screen.size.height - m_frame.origin.y - m_frame.size.height, - m_frame.size.width, - m_frame.size.height); - angle = M_PI; - break; - case UIInterfaceOrientationLandscapeLeft: - geom = QRect(screen.size.height - m_frame.origin.y - m_frame.size.height, - m_frame.origin.x, - m_frame.size.height, - m_frame.size.width); - angle = -M_PI/2.; - break; - case UIInterfaceOrientationLandscapeRight: - geom = QRect(m_frame.origin.y, - screen.size.width - m_frame.origin.x - m_frame.size.width, - m_frame.size.height, - m_frame.size.width); - angle = +M_PI/2.; - break; - } + static GLuint framebuffer = 0; - CGFloat scale = [m_screen->uiScreen() scale]; - geom = QRect(geom.x() * scale, geom.y() * scale, - geom.width() * scale, geom.height() * scale); + // FIXME: Cache context and recreate framebuffer if window + // is used with a different context then last time. - if (angle != 0) { - [m_view layer].transform = CATransform3DMakeRotation(angle, 0, 0, 1.); - } else { - [m_view layer].transform = CATransform3DIdentity; - } - [m_view setNeedsDisplay]; - window()->setGeometry(geom); -} + if (!framebuffer) { + EAGLContext* eaglContext = context.nativeContext(); -QPlatformOpenGLContext *QIOSWindow::glContext() const -{ - if (!m_context) { - m_context = new EAGLPlatformContext(m_view); + [EAGLContext setCurrentContext:eaglContext]; + + // Create the framebuffer and bind it + glGenFramebuffers(1, &framebuffer); + glBindFramebuffer(GL_FRAMEBUFFER, framebuffer); + + GLint width; + GLint height; + + // Create a color renderbuffer, allocate storage for it, + // and attach it to the framebuffer’s color attachment point. + GLuint colorRenderbuffer; + glGenRenderbuffers(1, &colorRenderbuffer); + glBindRenderbuffer(GL_RENDERBUFFER, colorRenderbuffer); + [eaglContext renderbufferStorage:GL_RENDERBUFFER fromDrawable:static_cast(m_view.layer)]; + glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &width); + glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &height); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRenderbuffer); + + QSurfaceFormat requestedFormat = context.format(); + if (requestedFormat.depthBufferSize() > 0 || requestedFormat.stencilBufferSize() > 0) { + // Create a depth or depth/stencil renderbuffer, allocate storage for it, + // and attach it to the framebuffer’s depth attachment point. + GLuint depthRenderbuffer; + glGenRenderbuffers(1, &depthRenderbuffer); + glBindRenderbuffer(GL_RENDERBUFFER, depthRenderbuffer); + + // FIXME: Support more fine grained control over depth/stencil buffer sizes + if (requestedFormat.stencilBufferSize() > 0) { + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, width, height); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, depthRenderbuffer); + } else { + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, width, height); + } + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthRenderbuffer); + } + + if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) + NSLog(@"Failed to make complete framebuffer object %x", glCheckFramebufferStatus(GL_FRAMEBUFFER)); } - return m_context; + + return framebuffer; } QT_END_NAMESPACE -- cgit v1.2.3 From 09187f602c8ac84c9982bb2e433af5524ac2d37d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Tue, 6 Nov 2012 12:01:50 +0100 Subject: iOS: Implement QIOSBackingStore in terms of a QOpenGLPaintDevice We build on top of the QPlatformOpenGLContext implementation to get automatic support for QBackingStore-based painting. Since the OpenGL renderer does not clear the backingstore between frames, we actually also get support for partial updates, and we get the benefit of an accelerated paint engine for Qt Quick 1 without setting a GLWidget as the viewport, which would cause issues such as an extra QWindow. This patch also removes the dependency to QtOpenGL and QtWidgets, which were leftovers from the Qt4 platform plugin. In Qt5 the needed GL bits are in QtGui. Change-Id: Id9b736bfb2e4aec56c0fa9f5b7b4d8bff8e3d1dc Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/ios.pro | 3 +- src/plugins/platforms/ios/qiosbackingstore.h | 57 +++++----- src/plugins/platforms/ios/qiosbackingstore.mm | 147 ++++++++++---------------- src/plugins/platforms/ios/qiosintegration.mm | 1 + 4 files changed, 89 insertions(+), 119 deletions(-) (limited to 'src') diff --git a/src/plugins/platforms/ios/ios.pro b/src/plugins/platforms/ios/ios.pro index 22b0fec9e8..2fe6a4cb3f 100644 --- a/src/plugins/platforms/ios/ios.pro +++ b/src/plugins/platforms/ios/ios.pro @@ -3,8 +3,7 @@ TARGET = qios load(qt_plugin) DESTDIR = $$QT.gui.plugins/platforms -QT += opengl -QT += core-private gui-private platformsupport-private opengl-private widgets-private +QT += core-private gui-private platformsupport-private LIBS += -framework UIKit -framework QuartzCore OBJECTIVE_SOURCES = main.mm \ diff --git a/src/plugins/platforms/ios/qiosbackingstore.h b/src/plugins/platforms/ios/qiosbackingstore.h index d83a5c21ad..c110f0e4d1 100644 --- a/src/plugins/platforms/ios/qiosbackingstore.h +++ b/src/plugins/platforms/ios/qiosbackingstore.h @@ -1,38 +1,38 @@ /**************************************************************************** ** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal ** ** This file is part of the plugins of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** ** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. ** ** ** $QT_END_LICENSE$ @@ -42,7 +42,6 @@ #ifndef QIOSBACKINGSTORE_H #define QIOSBACKINGSTORE_H -#include #include QT_BEGIN_NAMESPACE @@ -51,13 +50,19 @@ class QIOSBackingStore : public QPlatformBackingStore { public: QIOSBackingStore(QWindow *window); + ~QIOSBackingStore(); QPaintDevice *paintDevice(); + + void beginPaint(const QRegion &); + void endPaint(); + void flush(QWindow *window, const QRegion ®ion, const QPoint &offset); void resize(const QSize &size, const QRegion &staticContents); private: - QPaintDevice *m_paintDevice; + QOpenGLContext *m_context; + QPaintDevice *m_device; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qiosbackingstore.mm b/src/plugins/platforms/ios/qiosbackingstore.mm index 2ffa43b5d1..71f14fdd91 100644 --- a/src/plugins/platforms/ios/qiosbackingstore.mm +++ b/src/plugins/platforms/ios/qiosbackingstore.mm @@ -1,38 +1,38 @@ /**************************************************************************** ** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal ** ** This file is part of the plugins of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** ** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. ** ** ** $QT_END_LICENSE$ @@ -42,91 +42,54 @@ #include "qiosbackingstore.h" #include "qioswindow.h" -#include -#include +#include +#include #include -class EAGLPaintDevice; - -@interface PaintDeviceHelper : NSObject { - EAGLPaintDevice *device; -} - -@property (nonatomic, assign) EAGLPaintDevice *device; - -- (void)eaglView:(EAGLView *)view usesFramebuffer:(GLuint)buffer; - -@end - -class EAGLPaintDevice : public QGLPaintDevice +QIOSBackingStore::QIOSBackingStore(QWindow *window) + : QPlatformBackingStore(window) + , m_context(new QOpenGLContext) + , m_device(0) { -public: - EAGLPaintDevice(QWindow *window) - :QGLPaintDevice(), m_window(window) - { -#if defined(QT_OPENGL_ES_2) - helper = [[PaintDeviceHelper alloc] init]; - helper.device = this; - EAGLView *view = static_cast(window->handle())->nativeView(); - view.delegate = helper; - m_thisFBO = view.fbo; -#endif - } - - ~EAGLPaintDevice() - { -#if defined(QT_OPENGL_ES_2) - [helper release]; -#endif - } - - void setFramebuffer(GLuint buffer) { m_thisFBO = buffer; } - int devType() const { return QInternal::OpenGL; } - QSize size() const { return m_window->geometry().size(); } - QGLContext* context() const { - // Todo: siplify this: - return QGLContext::fromOpenGLContext( - static_cast(m_window->handle())->glContext()->context()); - } - - QPaintEngine *paintEngine() const { return qt_qgl_paint_engine(); } - -private: - QWindow *m_window; - PaintDeviceHelper *helper; -}; - -@implementation PaintDeviceHelper -@synthesize device; + m_context->setFormat(window->requestedFormat()); + m_context->setScreen(window->screen()); + m_context->create(); +} -- (void)eaglView:(EAGLView *)view usesFramebuffer:(GLuint)buffer +QIOSBackingStore::~QIOSBackingStore() { - Q_UNUSED(view) - if (device) - device->setFramebuffer(buffer); + delete m_context; } -@end - -QT_BEGIN_NAMESPACE - -QIOSBackingStore::QIOSBackingStore(QWindow *window) - : QPlatformBackingStore(window), m_paintDevice(new EAGLPaintDevice(window)) +void QIOSBackingStore::beginPaint(const QRegion &) { + // Needed to prevent QOpenGLContext::makeCurrent() from failing + window()->setSurfaceType(QSurface::OpenGLSurface); + + m_context->makeCurrent(window()); + m_device = new QOpenGLPaintDevice(window()->size()); } QPaintDevice *QIOSBackingStore::paintDevice() { - return m_paintDevice; + return m_device; } void QIOSBackingStore::flush(QWindow *window, const QRegion ®ion, const QPoint &offset) { Q_UNUSED(region); Q_UNUSED(offset); - qDebug() << __FUNCTION__ << "not implemented"; - //static_cast(window->handle())->glContext()->swapBuffers(); + + m_context->swapBuffers(window); +} + +void QIOSBackingStore::endPaint() +{ + delete m_device; + + // Calling makeDone() on the context here would be an option, + // but is not needed, and would actually add some overhead. } void QIOSBackingStore::resize(const QSize &size, const QRegion &staticContents) @@ -134,7 +97,9 @@ void QIOSBackingStore::resize(const QSize &size, const QRegion &staticContents) Q_UNUSED(size); Q_UNUSED(staticContents); - qDebug() << __FUNCTION__ << "not implemented"; + // We don't need to resize the QOpenGLPaintDevice, as it's just a thin wrapper + // around the OpenGL paint-engine, and the real geometry is handled by the + // context and window. } QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qiosintegration.mm b/src/plugins/platforms/ios/qiosintegration.mm index b9fef71abc..8abe3c4273 100644 --- a/src/plugins/platforms/ios/qiosintegration.mm +++ b/src/plugins/platforms/ios/qiosintegration.mm @@ -77,6 +77,7 @@ QPlatformWindow *QIOSIntegration::createPlatformWindow(QWindow *window) const return new QIOSWindow(window); } +// Used when the QWindow's surface type is set by the client to QSurface::RasterSurface QPlatformBackingStore *QIOSIntegration::createPlatformBackingStore(QWindow *window) const { qDebug() << __FUNCTION__ << "Creating platform backingstore"; -- cgit v1.2.3 From 19de726725dc123f478ecb2b122d03862c725650 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Wed, 7 Nov 2012 09:31:00 +0100 Subject: iOS: create top-level UIWindow and UIViewController MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Create a UIWIndow with a view controller and a view where we can reparent our QIOSWindow views inside. Change-Id: Ic90707d3ebe1af970a3aa2aa0f8c0f4be192456a Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiosapplicationdelegate.mm | 18 ++++++++++++++++++ src/plugins/platforms/ios/qioswindow.mm | 6 ++++++ 2 files changed, 24 insertions(+) (limited to 'src') diff --git a/src/plugins/platforms/ios/qiosapplicationdelegate.mm b/src/plugins/platforms/ios/qiosapplicationdelegate.mm index d88b2b83f1..6fed4c1a23 100644 --- a/src/plugins/platforms/ios/qiosapplicationdelegate.mm +++ b/src/plugins/platforms/ios/qiosapplicationdelegate.mm @@ -40,6 +40,7 @@ ****************************************************************************/ #import "qiosapplicationdelegate.h" +#include "qioswindow.h" #include @implementation QIOSApplicationDelegate @@ -48,7 +49,24 @@ { Q_UNUSED(application) Q_UNUSED(launchOptions) + + // If this application delegate is instanciated, it means that + // this plugin also created UIApplication. We then also create a + // window with a view controller, and set all QWindow views + // as children of the controller view: self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; + UIViewController *controller = [[UIViewController alloc] init]; + self.window.rootViewController = controller; + controller.view = [[UIView alloc] init]; + + QWindowList windows = QGuiApplication::topLevelWindows(); + for (int i=0; i(windows[i]->handle())) { + UIView *winView = w->nativeView(); + if (winView && !winView.superview) + [controller.view addSubview:winView]; + } + } // Override point for customization after application launch. self.window.backgroundColor = [UIColor whiteColor]; diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 46612ae699..2888228f18 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -42,6 +42,7 @@ #include "qioswindow.h" #include "qioscontext.h" #include "qiosscreen.h" +#include "qiosapplicationdelegate.h" #import @@ -170,6 +171,11 @@ QIOSWindow::QIOSWindow(QWindow *window) : QPlatformWindow(window) , m_view([[EAGLView alloc] init]) { + UIApplication *uiApplication = [UIApplication sharedApplication]; + if (uiApplication) { + if ([uiApplication.delegate isMemberOfClass:[QIOSApplicationDelegate class]]) + [uiApplication.delegate.window.rootViewController.view addSubview:m_view]; + } } QIOSWindow::~QIOSWindow() -- cgit v1.2.3 From ea1e5ccd621115d8103ceac962ac89dc0db65b70 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Wed, 7 Nov 2012 16:34:43 +0100 Subject: iOS: implement QEventLoop support in the event dispatcher MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With this patch you can now expect the following code to work: QEventLoop l; QTimer::singleShot(1000, &l, SLOT(quit())); l.exec(); Change-Id: Ic73e37affaadf8a859787d84ac02c15621ac7a29 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qioseventdispatcher.h | 2 ++ src/plugins/platforms/ios/qioseventdispatcher.mm | 8 ++++++-- 2 files changed, 8 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/plugins/platforms/ios/qioseventdispatcher.h b/src/plugins/platforms/ios/qioseventdispatcher.h index da8464f5ee..88d5127855 100644 --- a/src/plugins/platforms/ios/qioseventdispatcher.h +++ b/src/plugins/platforms/ios/qioseventdispatcher.h @@ -108,6 +108,8 @@ public: void flush(); private: + bool m_interrupted; + CFRunLoopSourceRef m_postedEventsRunLoopSource; CFRunLoopSourceRef m_blockingTimerRunLoopSource; diff --git a/src/plugins/platforms/ios/qioseventdispatcher.mm b/src/plugins/platforms/ios/qioseventdispatcher.mm index a7f01a33a9..4268b02b6d 100644 --- a/src/plugins/platforms/ios/qioseventdispatcher.mm +++ b/src/plugins/platforms/ios/qioseventdispatcher.mm @@ -152,6 +152,7 @@ void QIOSEventDispatcher::processPostedEvents() QIOSEventDispatcher::QIOSEventDispatcher(QObject *parent) : QAbstractEventDispatcher(parent) + , m_interrupted(false) , m_runLoopTimerRef(0) { CFRunLoopRef mainRunLoop = CFRunLoopGetMain(); @@ -187,6 +188,8 @@ QIOSEventDispatcher::~QIOSEventDispatcher() bool QIOSEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags) { + m_interrupted = false; + UIApplication *uiApplication = [UIApplication sharedApplication]; bool excludeUserEvents = flags & QEventLoop::ExcludeUserInputEvents; bool execFlagSet = (flags & QEventLoop::DialogExec) || (flags & QEventLoop::EventLoopExec); @@ -201,7 +204,8 @@ bool QIOSEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags) return UIApplicationMain(qAppPriv->argc, qAppPriv->argv, nil, NSStringFromClass([QIOSApplicationDelegate class])); } } else { - // todo: start NSRunLoop... + NSRunLoop *runLoop = [NSRunLoop currentRunLoop]; + while ([runLoop runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]] && !m_interrupted); } } else { // todo: manual processEvents... @@ -309,7 +313,7 @@ void QIOSEventDispatcher::wakeUp() void QIOSEventDispatcher::interrupt() { - qDebug() << __FUNCTION__ << "not implemented"; + m_interrupted = true; } void QIOSEventDispatcher::flush() -- cgit v1.2.3 From 0dbee6a5e1e3945dab404f8784df24a9260f0d52 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Wed, 7 Nov 2012 22:57:17 +0100 Subject: iOS: send mouse events (from touch events) from EAGLView MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Ia6c955f2c5bcde8e41d5908bfb8fd52bd449b3ec Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qioswindow.h | 3 +++ src/plugins/platforms/ios/qioswindow.mm | 21 ++++++++++----------- 2 files changed, 13 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h index d8f49db55b..c2bf1bb6f0 100644 --- a/src/plugins/platforms/ios/qioswindow.h +++ b/src/plugins/platforms/ios/qioswindow.h @@ -47,6 +47,7 @@ #import class QIOSContext; +class QIOSWindow; @interface EAGLView : UIView { @@ -57,8 +58,10 @@ class QIOSContext; UIKeyboardType keyboardType; UIReturnKeyType returnKeyType; BOOL secureTextEntry; + QIOSWindow *m_qioswindow; } +- (id)initWithQIOSWindow:(QIOSWindow *)qioswindow; - (void)sendMouseEventForTouches:(NSSet *)touches withEvent:(UIEvent *)event fakeButtons:(Qt::MouseButtons)buttons; @property(nonatomic) UITextAutocapitalizationType autocapitalizationType; diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 2888228f18..59508d83f3 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -58,6 +58,14 @@ return [CAEAGLLayer class]; } +-(id)initWithQIOSWindow:(QIOSWindow *)qioswindow +{ + if (self = [super init]) { + m_qioswindow = qioswindow; + } + return self; +} + - (id)initWithFrame:(CGRect)frame { if ((self = [super initWithFrame:frame])) { @@ -83,22 +91,13 @@ - (void)sendMouseEventForTouches:(NSSet *)touches withEvent:(UIEvent *)event fakeButtons:(Qt::MouseButtons)buttons { - Q_UNUSED(touches); - Q_UNUSED(event); - Q_UNUSED(buttons); - - // FIXME: Reintroduce relation to UIWindow - qDebug() << __FUNCTION__ << "not implemented"; - -#if 0 UITouch *touch = [touches anyObject]; CGPoint locationInView = [touch locationInView:self]; CGFloat scaleFactor = [self contentScaleFactor]; QPoint p(locationInView.x * scaleFactor, locationInView.y * scaleFactor); // TODO handle global touch point? for status bar? - QWindowSystemInterface::handleMouseEvent(m_window->window(), (ulong)(event.timestamp*1000), p, p, buttons); -#endif + QWindowSystemInterface::handleMouseEvent(m_qioswindow->window(), (ulong)(event.timestamp*1000), p, p, buttons); } - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event @@ -169,7 +168,7 @@ QT_BEGIN_NAMESPACE QIOSWindow::QIOSWindow(QWindow *window) : QPlatformWindow(window) - , m_view([[EAGLView alloc] init]) + , m_view([[EAGLView alloc] initWithQIOSWindow:this]) { UIApplication *uiApplication = [UIApplication sharedApplication]; if (uiApplication) { -- cgit v1.2.3 From 6bbe89e2b858564493468c7c5bd9c978c374751a Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Wed, 7 Nov 2012 19:48:38 +0100 Subject: iOS: support stand-alone qApp->processEvents calls MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rough implementation to support stand-alone processEvent calls. We probably need to revisit this code to fix corner-cases later on. Change-Id: I72d5639dab599b4d0017aaa52b922f4185a50337 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qioseventdispatcher.mm | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/plugins/platforms/ios/qioseventdispatcher.mm b/src/plugins/platforms/ios/qioseventdispatcher.mm index 4268b02b6d..252e375a54 100644 --- a/src/plugins/platforms/ios/qioseventdispatcher.mm +++ b/src/plugins/platforms/ios/qioseventdispatcher.mm @@ -189,6 +189,7 @@ QIOSEventDispatcher::~QIOSEventDispatcher() bool QIOSEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags) { m_interrupted = false; + bool eventsProcessed = false; UIApplication *uiApplication = [UIApplication sharedApplication]; bool excludeUserEvents = flags & QEventLoop::ExcludeUserInputEvents; @@ -207,10 +208,13 @@ bool QIOSEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags) NSRunLoop *runLoop = [NSRunLoop currentRunLoop]; while ([runLoop runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]] && !m_interrupted); } + eventsProcessed = true; } else { - // todo: manual processEvents... + if (!(flags & QEventLoop::WaitForMoreEvents)) + wakeUp(); + eventsProcessed = [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]; } - return false; + return eventsProcessed; } bool QIOSEventDispatcher::hasPendingEvents() @@ -313,6 +317,7 @@ void QIOSEventDispatcher::wakeUp() void QIOSEventDispatcher::interrupt() { + wakeUp(); m_interrupted = true; } -- cgit v1.2.3 From caacccaaf0fbc0a4f4f88af7dadbfece175776d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Wed, 7 Nov 2012 17:30:46 +0100 Subject: iOS: Unset EAGL context if it's current when destroying QIOSContext Change-Id: Ie0b27e6b0dafa2a7283b44d6676871fce15cc42a Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qioscontext.mm | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/plugins/platforms/ios/qioscontext.mm b/src/plugins/platforms/ios/qioscontext.mm index e512b3d4c8..8beb588b03 100644 --- a/src/plugins/platforms/ios/qioscontext.mm +++ b/src/plugins/platforms/ios/qioscontext.mm @@ -70,6 +70,9 @@ QIOSContext::QIOSContext(QOpenGLContext *context) QIOSContext::~QIOSContext() { + if ([EAGLContext currentContext] == m_eaglContext) + doneCurrent(); + [m_eaglContext release]; } -- cgit v1.2.3 From 231796c98d317f845209e2b470fa34e00aac3c7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 8 Nov 2012 14:48:18 +0100 Subject: iOS: Set background color of UIWindow and root UIView to burn your eyes Convenient to aid debugging during development of the platform plugin. Change-Id: Id429ca95e0452385ee8def1fe4a1bb7de175ba3e Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qiosapplicationdelegate.mm | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/plugins/platforms/ios/qiosapplicationdelegate.mm b/src/plugins/platforms/ios/qiosapplicationdelegate.mm index 6fed4c1a23..1b3dc18dd7 100644 --- a/src/plugins/platforms/ios/qiosapplicationdelegate.mm +++ b/src/plugins/platforms/ios/qiosapplicationdelegate.mm @@ -68,8 +68,10 @@ } } - // Override point for customization after application launch. - self.window.backgroundColor = [UIColor whiteColor]; + // Aid debugging during development + self.window.backgroundColor = [UIColor cyanColor]; + controller.view.backgroundColor = [UIColor magentaColor]; + [self.window makeKeyAndVisible]; return YES; } -- cgit v1.2.3 From 3bc6d7470a88bf1da12aa768c9527fe08d52757a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 8 Nov 2012 15:09:00 +0100 Subject: iOS: Pass QWindow geometry to initWithFrame on window creation Allows the optimal pattern of setting the geometry of the QWindow before showing (and hence creating) it. Change-Id: I29206b5d9a70df0b01e8df8f7df8f35cced51121 Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qioswindow.mm | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 59508d83f3..ce0ea6e0e1 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -51,6 +51,11 @@ #include +static CGRect toCGRect(const QRect &rect) +{ + return CGRectMake(rect.x(), rect.y(), rect.width(), rect.height()); +} + @implementation EAGLView + (Class)layerClass @@ -58,11 +63,11 @@ return [CAEAGLLayer class]; } --(id)initWithQIOSWindow:(QIOSWindow *)qioswindow +-(id)initWithQIOSWindow:(QIOSWindow *)window { - if (self = [super init]) { - m_qioswindow = qioswindow; - } + if (self = [super initWithFrame:toCGRect(window->geometry())]) + m_qioswindow = window; + return self; } -- cgit v1.2.3 From e936561a164ce582785eafcfa70ed2924f7bc954 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Sun, 11 Nov 2012 10:22:20 +0100 Subject: iOS: Add Q_IMPORT_PLUGIN(QIOSIntegrationPlugin) into the plugin itself MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since the plugin will always be linked in statically, we add this necessary registration code into the plugin itself rather than putting this burden onto the client application. Change-Id: I8691d8080e41bdf0644bb960b5c7102e79a0f0d5 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/main.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/plugins/platforms/ios/main.mm b/src/plugins/platforms/ios/main.mm index b09fbce1f4..6a04770e3e 100644 --- a/src/plugins/platforms/ios/main.mm +++ b/src/plugins/platforms/ios/main.mm @@ -66,4 +66,4 @@ QT_END_NAMESPACE #include "main.moc" - +Q_IMPORT_PLUGIN(QIOSIntegrationPlugin) -- cgit v1.2.3 From 8d7238f57e9a85524ea550917f051b9eb9927922 Mon Sep 17 00:00:00 2001 From: Morten Johan Sorvig Date: Wed, 7 Nov 2012 22:11:35 +0100 Subject: iOS: Use default createPlatformPixmap implementation No need to implement this one, the standard implementation creates a raster pixmap. Change-Id: I9bb25188bd95159d76e760b2be6870e0bede7b56 Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qiosintegration.h | 1 - src/plugins/platforms/ios/qiosintegration.mm | 8 -------- 2 files changed, 9 deletions(-) (limited to 'src') diff --git a/src/plugins/platforms/ios/qiosintegration.h b/src/plugins/platforms/ios/qiosintegration.h index e411ce2905..11c17aced9 100644 --- a/src/plugins/platforms/ios/qiosintegration.h +++ b/src/plugins/platforms/ios/qiosintegration.h @@ -53,7 +53,6 @@ public: QIOSIntegration(); ~QIOSIntegration(); - QPlatformPixmap *createPlatformPixmap(QPlatformPixmap::PixelType type) const; QPlatformWindow *createPlatformWindow(QWindow *window) const; QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const; diff --git a/src/plugins/platforms/ios/qiosintegration.mm b/src/plugins/platforms/ios/qiosintegration.mm index 8abe3c4273..d00d4a077f 100644 --- a/src/plugins/platforms/ios/qiosintegration.mm +++ b/src/plugins/platforms/ios/qiosintegration.mm @@ -63,14 +63,6 @@ QIOSIntegration::~QIOSIntegration() { } -QPlatformPixmap *QIOSIntegration::createPlatformPixmap(QPlatformPixmap::PixelType type) const -{ - Q_UNUSED(type); - - qDebug() << __FUNCTION__ << "not yet implemented"; - return 0; -} - QPlatformWindow *QIOSIntegration::createPlatformWindow(QWindow *window) const { qDebug() << __FUNCTION__ << "Creating platform window"; -- cgit v1.2.3 From 3d81b43aa462c66e11f772398550e76ce4cee6de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 8 Nov 2012 17:12:54 +0100 Subject: iOS: Implement QPlatformScreen::availableGeometry() This will sadly not work as expected until we've found a way to kick off the iOS event loop before QApplication is initialized, as UIScreen does not seem to report the correct applicationFrame (taking the status bar into account) until after the UIApplication has been set up by UIApplicationMain(). Change-Id: I0eaa3b8bca4129d1c4183a202ad2ecd0d8bc52d0 Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qiosscreen.h | 1 + src/plugins/platforms/ios/qiosscreen.mm | 8 ++++++-- 2 files changed, 7 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/plugins/platforms/ios/qiosscreen.h b/src/plugins/platforms/ios/qiosscreen.h index 8af7779f9d..8d67b1ecdf 100644 --- a/src/plugins/platforms/ios/qiosscreen.h +++ b/src/plugins/platforms/ios/qiosscreen.h @@ -56,6 +56,7 @@ public: enum ScreenIndex { MainScreen = 0 }; QRect geometry() const; + QRect availableGeometry() const; int depth() const; QImage::Format format() const; QSizeF physicalSize() const; diff --git a/src/plugins/platforms/ios/qiosscreen.mm b/src/plugins/platforms/ios/qiosscreen.mm index 93b22953e2..effd19070a 100644 --- a/src/plugins/platforms/ios/qiosscreen.mm +++ b/src/plugins/platforms/ios/qiosscreen.mm @@ -99,11 +99,15 @@ QIOSScreen::QIOSScreen(unsigned int screenIndex) QRect QIOSScreen::geometry() const { - // FIXME: Do we need to reimplement availableGeometry() to take the - // system statusbar into account? return m_geometry; } +QRect QIOSScreen::availableGeometry() const +{ + CGRect frame = m_uiScreen.applicationFrame; + return QRect(frame.origin.x, frame.origin.y, frame.size.width, frame.size.height); +} + int QIOSScreen::depth() const { return m_depth; -- cgit v1.2.3 From e123056c47e33759e740ea2e25771e0cc1899c13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Fri, 9 Nov 2012 17:08:46 +0100 Subject: iOS: Implement QIOSWindow::setGeometry() and pick up UIView geometry changes The best way to pick up geometry changes of the UIView seems to be to override layoutSubviews(), but that will only be called if the size of the UIView changes, not when the position (center) changes. This means that the position reflected by the QWindow will not always be in sync with the position of the native UIView. Fortunately the position of a QWindow is not used for anything critical in Qt itself. Another issue is that the frame property of a UIView is only valid if the transform of the UIView is set to the identity transform. We try to catch cases where this is not the case, and warn the user about this. We could in theory react to changes in the UIView geometry by only updating the size, since this is also reflected through the bounds property of the UIView. This is left for when we know more about how these things interact in practice. Change-Id: I079162c059d377a77569fe3974e261d2e0671fd5 Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qioswindow.h | 1 + src/plugins/platforms/ios/qioswindow.mm | 43 ++++++++++++++++++++++++++++++++- 2 files changed, 43 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h index c2bf1bb6f0..d16e17124d 100644 --- a/src/plugins/platforms/ios/qioswindow.h +++ b/src/plugins/platforms/ios/qioswindow.h @@ -83,6 +83,7 @@ public: ~QIOSWindow(); void setGeometry(const QRect &rect); + void updateGeometry(const QRect &rect); GLuint framebufferObject(const QIOSContext &context) const; diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index ce0ea6e0e1..feabaeb47a 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -56,6 +56,11 @@ static CGRect toCGRect(const QRect &rect) return CGRectMake(rect.x(), rect.y(), rect.width(), rect.height()); } +static QRect fromCGRect(const CGRect &rect) +{ + return QRect(rect.origin.x, rect.origin.y, rect.size.width, rect.size.height); +} + @implementation EAGLView + (Class)layerClass @@ -94,6 +99,24 @@ static CGRect toCGRect(const QRect &rect) return self; } +- (void)layoutSubviews +{ + // This method is the de facto way to know that view has been resized, + // or otherwise needs invalidation of its buffers. Note though that we + // do not get this callback when the view just changes its position, so + // the position of our QWindow (and platform window) will only get updated + // when the size is also changed. + + if (CGAffineTransformIsIdentity(self.transform)) { + // Reflect the new size (and possibly also position) in the QWindow + m_qioswindow->updateGeometry(fromCGRect(self.frame)); + } else { + qWarning() << "QIOSPlatformWindow's UIView has transform set, ignoring geometry updates"; + } + + [super layoutSubviews]; +} + - (void)sendMouseEventForTouches:(NSSet *)touches withEvent:(UIEvent *)event fakeButtons:(Qt::MouseButtons)buttons { UITouch *touch = [touches anyObject]; @@ -189,9 +212,27 @@ QIOSWindow::~QIOSWindow() void QIOSWindow::setGeometry(const QRect &rect) { + if (!CGAffineTransformIsIdentity(m_view.transform)) { + qWarning() << "Setting the geometry of a QWindow with a transform set on the UIView is not supported"; + return; + } + + // Since we don't support transformations on the UIView, we can set the frame + // directly and let UIKit deal with translating that into bounds and center. + m_view.frame = toCGRect(rect); + + updateGeometry(rect); +} + +void QIOSWindow::updateGeometry(const QRect &rect) +{ + // The baseclass implementation will store the geometry, and allows use to + // re-use the baseclass geometry() implementation, which just returns rect. QPlatformWindow::setGeometry(rect); - qDebug() << __FUNCTION__ << "not implemented"; + // We inform Qt about new geometry, which will trigger resize and + // expose events for the application. + QWindowSystemInterface::handleGeometryChange(window(), rect); } GLuint QIOSWindow::framebufferObject(const QIOSContext &context) const -- cgit v1.2.3 From 3241f37711bd35988c7a21cc8a4833ec2fa3132d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Fri, 9 Nov 2012 17:20:47 +0100 Subject: iOS: Implement QPlatformWindow::setWindowState() In both maximized and fullscreen modes we assume that we can use the availableGeometry() of the QScreen, but of course this depends on us showing or hiding the statusbar first, as well as QScreen actually returning the right availableGeometry when the statusbar is shown. The latter is not the case right now, as we initialize QScreen before UIApplication has been set up and UIScreen has had a chance to init itself based on the precense of a statusbar or not. Change-Id: Id44dee3550f7135ffe2852b377bb6c7b6d522d68 Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qioswindow.h | 2 ++ src/plugins/platforms/ios/qioswindow.mm | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+) (limited to 'src') diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h index d16e17124d..4e1970d4d4 100644 --- a/src/plugins/platforms/ios/qioswindow.h +++ b/src/plugins/platforms/ios/qioswindow.h @@ -85,6 +85,8 @@ public: void setGeometry(const QRect &rect); void updateGeometry(const QRect &rect); + void setWindowState(Qt::WindowState state); + GLuint framebufferObject(const QIOSContext &context) const; EAGLView *nativeView() const { return m_view; } diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index feabaeb47a..cccd5ab133 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -203,6 +203,8 @@ QIOSWindow::QIOSWindow(QWindow *window) if ([uiApplication.delegate isMemberOfClass:[QIOSApplicationDelegate class]]) [uiApplication.delegate.window.rootViewController.view addSubview:m_view]; } + + setWindowState(window->windowState()); } QIOSWindow::~QIOSWindow() @@ -235,6 +237,22 @@ void QIOSWindow::updateGeometry(const QRect &rect) QWindowSystemInterface::handleGeometryChange(window(), rect); } +void QIOSWindow::setWindowState(Qt::WindowState state) +{ + // FIXME: Figure out where or how we should disable/enable the statusbar. + // Perhaps setting QWindow to maximized should also mean that we'll show + // the statusbar, and vice versa for fullscreen? + + switch (state) { + case Qt::WindowMaximized: + case Qt::WindowFullScreen: + setGeometry(QRect(QPoint(0, 0), window()->screen()->availableSize())); + break; + default: + break; + } +} + GLuint QIOSWindow::framebufferObject(const QIOSContext &context) const { static GLuint framebuffer = 0; -- cgit v1.2.3 From e71ca36161626020f7c641dcc83c0c02dc4d561b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Sun, 11 Nov 2012 16:32:54 +0100 Subject: iOS: Ensure UIApplicationMain is started before QApplication by wrapping main() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For the typical Qt app the developer will have an existing main() that looks something like: int main(int argc, char *argv[]) { QGuiApplication app(argc, argv); return app.exec(); } To support this, we provide our own 'main' function in the qtmain static library that we link into the application, which calls UIApplicationMain and redirects to the 'main' function of the application after the event loop has started spinning. For this to work, the applications 'main' function needs to manually be renamed 'qt_main' for now. In a later patch, this renaming will happen automatically by redefining main from either a header file, or more likely, from the Makefile created by qmake. For the case of an iOS developer wanting to use Qt in their existing app the main will look something like: int main(int argc, char *argv[]) { @autoreleasepool { return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); } } This is supported right now by just linking in libqios.a without libqiosmain.a. QGuiApplication should then be created e.g inside the native apps application delegate (but QGuiApplication::exec should not be called). In the future, we plan to but use a wrapper library that brings in all the Qt dependencies into one single static library. This library will not link against qtmain, so there won't be a symbol clash if the -ObjC linker option is used. We should then add the required magic to the future Objective-C convenience wrapper for QML to bring up a QGuiApplication, which would allow using Qt from storyboards and NIBs. This would also be the place to inject our own application delegate into the mix, while proxying the delegate callbacks to the user's application delegate. Change-Id: Iba5ade114b27216be8285f36100fd735a08b9d59 Reviewed-by: Tor Arne Vestbø Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/ios.pro | 30 +------ src/plugins/platforms/ios/main.mm | 69 --------------- src/plugins/platforms/ios/plugin.mm | 69 +++++++++++++++ src/plugins/platforms/ios/plugin.pro | 30 +++++++ .../platforms/ios/qiosapplicationdelegate.h | 3 + .../platforms/ios/qiosapplicationdelegate.mm | 31 ++----- src/plugins/platforms/ios/qioseventdispatcher.mm | 14 +--- src/plugins/platforms/ios/qiosintegration.mm | 12 +++ src/plugins/platforms/ios/qioswindow.mm | 9 +- src/plugins/platforms/ios/qtmain.mm | 98 ++++++++++++++++++++++ src/plugins/platforms/ios/qtmain.pro | 8 ++ 11 files changed, 234 insertions(+), 139 deletions(-) delete mode 100644 src/plugins/platforms/ios/main.mm create mode 100644 src/plugins/platforms/ios/plugin.mm create mode 100644 src/plugins/platforms/ios/plugin.pro create mode 100644 src/plugins/platforms/ios/qtmain.mm create mode 100644 src/plugins/platforms/ios/qtmain.pro (limited to 'src') diff --git a/src/plugins/platforms/ios/ios.pro b/src/plugins/platforms/ios/ios.pro index 2fe6a4cb3f..842ff17f1c 100644 --- a/src/plugins/platforms/ios/ios.pro +++ b/src/plugins/platforms/ios/ios.pro @@ -1,29 +1,3 @@ -TARGET = qios +TEMPLATE = subdirs -load(qt_plugin) -DESTDIR = $$QT.gui.plugins/platforms - -QT += core-private gui-private platformsupport-private -LIBS += -framework UIKit -framework QuartzCore - -OBJECTIVE_SOURCES = main.mm \ - qiosintegration.mm \ - qioswindow.mm \ - qiosscreen.mm \ - qioseventdispatcher.mm \ - qiosbackingstore.mm \ - qiosapplicationdelegate.mm \ - qioscontext.mm - -HEADERS = qiosintegration.h \ - qioswindow.h \ - qiosscreen.h \ - qioseventdispatcher.h \ - qiosbackingstore.h \ - qiosapplicationdelegate.h \ - qioscontext.h - -#HEADERS = qiossoftwareinputhandler.h - -target.path += $$[QT_INSTALL_PLUGINS]/platforms -INSTALLS += target +SUBDIRS += plugin.pro qtmain.pro diff --git a/src/plugins/platforms/ios/main.mm b/src/plugins/platforms/ios/main.mm deleted file mode 100644 index 6a04770e3e..0000000000 --- a/src/plugins/platforms/ios/main.mm +++ /dev/null @@ -1,69 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include -#include "qiosintegration.h" - -QT_BEGIN_NAMESPACE - -class QIOSIntegrationPlugin : public QPlatformIntegrationPlugin -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.1" FILE "ios.json") - public: - QPlatformIntegration *create(const QString&, const QStringList&); -}; - -QPlatformIntegration * QIOSIntegrationPlugin::create(const QString& system, const QStringList& paramList) -{ - Q_UNUSED(paramList); - if (system.toLower() == "ios") - return new QIOSIntegration; - - return 0; -} - -QT_END_NAMESPACE - -#include "main.moc" - -Q_IMPORT_PLUGIN(QIOSIntegrationPlugin) diff --git a/src/plugins/platforms/ios/plugin.mm b/src/plugins/platforms/ios/plugin.mm new file mode 100644 index 0000000000..3701ac7e28 --- /dev/null +++ b/src/plugins/platforms/ios/plugin.mm @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include "qiosintegration.h" + +QT_BEGIN_NAMESPACE + +class QIOSIntegrationPlugin : public QPlatformIntegrationPlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.1" FILE "ios.json") + public: + QPlatformIntegration *create(const QString&, const QStringList&); +}; + +QPlatformIntegration * QIOSIntegrationPlugin::create(const QString& system, const QStringList& paramList) +{ + Q_UNUSED(paramList); + if (system.toLower() == "ios") + return new QIOSIntegration; + + return 0; +} + +QT_END_NAMESPACE + +#include "plugin.moc" + +Q_IMPORT_PLUGIN(QIOSIntegrationPlugin) diff --git a/src/plugins/platforms/ios/plugin.pro b/src/plugins/platforms/ios/plugin.pro new file mode 100644 index 0000000000..8a2f63442d --- /dev/null +++ b/src/plugins/platforms/ios/plugin.pro @@ -0,0 +1,30 @@ +TARGET = qios + +load(qt_plugin) + +QT += core-private gui-private platformsupport-private +LIBS += -framework UIKit -framework QuartzCore + +OBJECTIVE_SOURCES = \ + plugin.mm \ + qiosintegration.mm \ + qioswindow.mm \ + qiosscreen.mm \ + qioseventdispatcher.mm \ + qiosbackingstore.mm \ + qiosapplicationdelegate.mm \ + qioscontext.mm + +HEADERS = \ + qiosintegration.h \ + qioswindow.h \ + qiosscreen.h \ + qioseventdispatcher.h \ + qiosbackingstore.h \ + qiosapplicationdelegate.h \ + qioscontext.h + +#HEADERS = qiossoftwareinputhandler.h + +target.path += $$[QT_INSTALL_PLUGINS]/platforms +INSTALLS += target diff --git a/src/plugins/platforms/ios/qiosapplicationdelegate.h b/src/plugins/platforms/ios/qiosapplicationdelegate.h index 10e415831d..442b37f1b3 100644 --- a/src/plugins/platforms/ios/qiosapplicationdelegate.h +++ b/src/plugins/platforms/ios/qiosapplicationdelegate.h @@ -48,3 +48,6 @@ @end +@interface QIOSMainWrapperApplicationDelegate : QIOSApplicationDelegate +@end + diff --git a/src/plugins/platforms/ios/qiosapplicationdelegate.mm b/src/plugins/platforms/ios/qiosapplicationdelegate.mm index 1b3dc18dd7..41a3fff84f 100644 --- a/src/plugins/platforms/ios/qiosapplicationdelegate.mm +++ b/src/plugins/platforms/ios/qiosapplicationdelegate.mm @@ -45,34 +45,13 @@ @implementation QIOSApplicationDelegate +@synthesize window; + - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { Q_UNUSED(application) Q_UNUSED(launchOptions) - // If this application delegate is instanciated, it means that - // this plugin also created UIApplication. We then also create a - // window with a view controller, and set all QWindow views - // as children of the controller view: - self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; - UIViewController *controller = [[UIViewController alloc] init]; - self.window.rootViewController = controller; - controller.view = [[UIView alloc] init]; - - QWindowList windows = QGuiApplication::topLevelWindows(); - for (int i=0; i(windows[i]->handle())) { - UIView *winView = w->nativeView(); - if (winView && !winView.superview) - [controller.view addSubview:winView]; - } - } - - // Aid debugging during development - self.window.backgroundColor = [UIColor cyanColor]; - controller.view.backgroundColor = [UIColor magentaColor]; - - [self.window makeKeyAndVisible]; return YES; } @@ -104,6 +83,12 @@ // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. } +- (void)dealloc +{ + [window release]; + [super dealloc]; +} + @end diff --git a/src/plugins/platforms/ios/qioseventdispatcher.mm b/src/plugins/platforms/ios/qioseventdispatcher.mm index 252e375a54..9d455370c0 100644 --- a/src/plugins/platforms/ios/qioseventdispatcher.mm +++ b/src/plugins/platforms/ios/qioseventdispatcher.mm @@ -191,23 +191,13 @@ bool QIOSEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags) m_interrupted = false; bool eventsProcessed = false; - UIApplication *uiApplication = [UIApplication sharedApplication]; bool excludeUserEvents = flags & QEventLoop::ExcludeUserInputEvents; bool execFlagSet = (flags & QEventLoop::DialogExec) || (flags & QEventLoop::EventLoopExec); bool useExecMode = execFlagSet && !excludeUserEvents; if (useExecMode) { - if (!uiApplication) { - // No UIApplication has been started yet. We therefore start it now. Note that application - // developers are free to call UIApplicationMain themselves instead of QApplication::exec() - @autoreleasepool { - QCoreApplicationPrivate *qAppPriv = static_cast(QObjectPrivate::get(qApp)); - return UIApplicationMain(qAppPriv->argc, qAppPriv->argv, nil, NSStringFromClass([QIOSApplicationDelegate class])); - } - } else { - NSRunLoop *runLoop = [NSRunLoop currentRunLoop]; - while ([runLoop runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]] && !m_interrupted); - } + NSRunLoop *runLoop = [NSRunLoop currentRunLoop]; + while ([runLoop runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]] && !m_interrupted); eventsProcessed = true; } else { if (!(flags & QEventLoop::WaitForMoreEvents)) diff --git a/src/plugins/platforms/ios/qiosintegration.mm b/src/plugins/platforms/ios/qiosintegration.mm index d00d4a077f..fed278bffe 100644 --- a/src/plugins/platforms/ios/qiosintegration.mm +++ b/src/plugins/platforms/ios/qiosintegration.mm @@ -56,6 +56,18 @@ QIOSIntegration::QIOSIntegration() : m_fontDatabase(new QCoreTextFontDatabase) , m_screen(new QIOSScreen(QIOSScreen::MainScreen)) { + if (![UIApplication sharedApplication]) { + qWarning() + << "Error: You are creating QApplication before calling UIApplicationMain.\n" + << "If you are writing a native iOS application, and only want to use Qt for\n" + << "parts of the application, a good place to create QApplication is from within\n" + << "'applicationDidFinishLaunching' inside your UIApplication delegate.\n" + << "If you instead create a cross-platform Qt application and do not intend to call\n" + << "UIApplicationMain, you need to link in libqtmain.a, and substitute main with qt_main.\n" + << "This is normally done automatically by qmake.\n"; + exit(-1); + } + screenAdded(m_screen); } diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index cccd5ab133..5701ac8aa2 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -198,13 +198,8 @@ QIOSWindow::QIOSWindow(QWindow *window) : QPlatformWindow(window) , m_view([[EAGLView alloc] initWithQIOSWindow:this]) { - UIApplication *uiApplication = [UIApplication sharedApplication]; - if (uiApplication) { - if ([uiApplication.delegate isMemberOfClass:[QIOSApplicationDelegate class]]) - [uiApplication.delegate.window.rootViewController.view addSubview:m_view]; - } - - setWindowState(window->windowState()); + if ([[UIApplication sharedApplication].delegate isKindOfClass:[QIOSApplicationDelegate class]]) + [[UIApplication sharedApplication].delegate.window.rootViewController.view addSubview:m_view]; } QIOSWindow::~QIOSWindow() diff --git a/src/plugins/platforms/ios/qtmain.mm b/src/plugins/platforms/ios/qtmain.mm new file mode 100644 index 0000000000..9b4ce9918e --- /dev/null +++ b/src/plugins/platforms/ios/qtmain.mm @@ -0,0 +1,98 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qiosapplicationdelegate.h" + +int main(int argc, char *argv[]) +{ + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([QIOSMainWrapperApplicationDelegate class])); + } +} + +extern int qt_main(int argc, char *argv[]); + +@implementation QIOSMainWrapperApplicationDelegate + +- (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions +{ + // We may have a window already from a NIB or storyboard + if (!self.window) { + // If not, we create one ourselves + self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; + UIViewController *controller = [[UIViewController alloc] init]; + self.window.rootViewController = controller; + controller.view = [[UIView alloc] init]; + + // Aid debugging during development + self.window.backgroundColor = [UIColor cyanColor]; + self.window.rootViewController.view.backgroundColor = [UIColor magentaColor]; + + [self.window makeKeyAndVisible]; + } + + // We schedule the main-redirection for the next eventloop pass so that we + // can return from this function and let UIApplicationMain finish its job. + [NSTimer scheduledTimerWithTimeInterval:.01f target:self + selector:@selector(runUserMain) userInfo:nil repeats:NO]; + + if ([QIOSApplicationDelegate instancesRespondToSelector:_cmd]) + return [super application:application willFinishLaunchingWithOptions:launchOptions]; + else + return YES; +} + +- (void)runUserMain +{ + NSArray *arguments = [[NSProcessInfo processInfo] arguments]; + int argc = arguments.count; + char **argv = new char*[argc]; + for (int i = 0; i < argc; ++i) { + NSString *arg = [arguments objectAtIndex:i]; + argv[i] = reinterpret_cast(malloc([arg lengthOfBytesUsingEncoding:[NSString defaultCStringEncoding]])); + strcpy(argv[i], [arg cStringUsingEncoding:[NSString defaultCStringEncoding]]); + } + + qt_main(argc, argv); + delete[] argv; +} + +@end diff --git a/src/plugins/platforms/ios/qtmain.pro b/src/plugins/platforms/ios/qtmain.pro new file mode 100644 index 0000000000..7835c88eac --- /dev/null +++ b/src/plugins/platforms/ios/qtmain.pro @@ -0,0 +1,8 @@ +TARGET = qiosmain + +load(qt_plugin) + +OBJECTIVE_SOURCES = qtmain.mm + +target.path += $$[QT_INSTALL_PLUGINS]/platforms +INSTALLS += target -- cgit v1.2.3 From d8b3465dd3482040f0de077f87545415a1a2a5b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Wed, 14 Nov 2012 14:54:13 +0100 Subject: iOS: Don't use IOKit in QTestLib, it's a private framework on iOS Change-Id: I271a480b79c7768942911a28c84d6bb5a8d840d3 Reviewed-by: Richard Moe Gustavsen --- src/testlib/qtestcase.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp index f9f21c6a8f..ef8ffa570b 100644 --- a/src/testlib/qtestcase.cpp +++ b/src/testlib/qtestcase.cpp @@ -82,7 +82,7 @@ #include #endif -#ifdef Q_OS_MAC +#if defined(Q_OS_MAC) && !defined(Q_OS_IOS) #include #endif @@ -2078,7 +2078,7 @@ int QTest::qExec(QObject *testObject, int argc, char **argv) int callgrindChildExitCode = 0; #endif -#ifdef Q_OS_MAC +#if defined(Q_OS_MAC) && !defined(Q_OS_IOS) bool macNeedsActivate = qApp && (qstrcmp(qApp->metaObject()->className(), "QApplication") == 0); IOPMAssertionID powerID; #endif @@ -2093,7 +2093,7 @@ int QTest::qExec(QObject *testObject, int argc, char **argv) SetErrorMode(SetErrorMode(0) | SEM_NOGPFAULTERRORBOX); #endif -#ifdef Q_OS_MAC +#if defined(Q_OS_MAC) && !defined(Q_OS_IOS) if (macNeedsActivate) { CFStringRef reasonForActivity= CFSTR("No Display Sleep"); IOReturn ok = IOPMAssertionCreateWithName(kIOPMAssertionTypeNoDisplaySleep, kIOPMAssertionLevelOn, reasonForActivity, &powerID); @@ -2146,7 +2146,7 @@ int QTest::qExec(QObject *testObject, int argc, char **argv) } QTestLog::stopLogging(); -#ifdef Q_OS_MAC +#if defined(Q_OS_MAC) && !defined(Q_OS_IOS) if (macNeedsActivate) { IOPMAssertionRelease(powerID); } @@ -2163,7 +2163,7 @@ int QTest::qExec(QObject *testObject, int argc, char **argv) QSignalDumper::endDump(); -#ifdef Q_OS_MAC +#if defined(Q_OS_MAC) && !defined(Q_OS_IOS) if (macNeedsActivate) { IOPMAssertionRelease(powerID); } -- cgit v1.2.3 From f124e098ced89c3014d8bbc08a20db658d1cc7c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Wed, 14 Nov 2012 14:58:11 +0100 Subject: iOS: Set PLUGIN_TYPE = platforms before loading(qt_plugins) This takes care of setting INSTALLS for us, so we can skip that. Change-Id: I351cb9ec08b632fd9867d85e2c5fa59d8e5acc9d Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/plugin.pro | 4 +--- src/plugins/platforms/ios/qtmain.pro | 4 +--- 2 files changed, 2 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/plugins/platforms/ios/plugin.pro b/src/plugins/platforms/ios/plugin.pro index 8a2f63442d..222d8c8445 100644 --- a/src/plugins/platforms/ios/plugin.pro +++ b/src/plugins/platforms/ios/plugin.pro @@ -1,5 +1,6 @@ TARGET = qios +PLUGIN_TYPE = platforms load(qt_plugin) QT += core-private gui-private platformsupport-private @@ -25,6 +26,3 @@ HEADERS = \ qioscontext.h #HEADERS = qiossoftwareinputhandler.h - -target.path += $$[QT_INSTALL_PLUGINS]/platforms -INSTALLS += target diff --git a/src/plugins/platforms/ios/qtmain.pro b/src/plugins/platforms/ios/qtmain.pro index 7835c88eac..49ada385bb 100644 --- a/src/plugins/platforms/ios/qtmain.pro +++ b/src/plugins/platforms/ios/qtmain.pro @@ -1,8 +1,6 @@ TARGET = qiosmain +PLUGIN_TYPE = platforms load(qt_plugin) OBJECTIVE_SOURCES = qtmain.mm - -target.path += $$[QT_INSTALL_PLUGINS]/platforms -INSTALLS += target -- cgit v1.2.3 From 9d2e623451d4a4d695bc41e750a3218608c2546c Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Mon, 12 Nov 2012 15:20:06 +0100 Subject: iOS: insert Digia license headers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove Nokia. Change-Id: Iec7095ef4e3099453b6103814e826039b377ecce Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/plugin.mm | 48 ++++++++++----------- src/plugins/platforms/ios/qiosintegration.h | 48 ++++++++++----------- src/plugins/platforms/ios/qiosintegration.mm | 48 ++++++++++----------- src/plugins/platforms/ios/qiosscreen.h | 48 ++++++++++----------- src/plugins/platforms/ios/qiosscreen.mm | 48 ++++++++++----------- .../platforms/ios/qiossoftwareinputhandler.h | 50 +++++++++++----------- 6 files changed, 144 insertions(+), 146 deletions(-) (limited to 'src') diff --git a/src/plugins/platforms/ios/plugin.mm b/src/plugins/platforms/ios/plugin.mm index 3701ac7e28..a93b6037ad 100644 --- a/src/plugins/platforms/ios/plugin.mm +++ b/src/plugins/platforms/ios/plugin.mm @@ -1,38 +1,38 @@ /**************************************************************************** ** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal ** ** This file is part of the plugins of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** ** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. ** ** ** $QT_END_LICENSE$ diff --git a/src/plugins/platforms/ios/qiosintegration.h b/src/plugins/platforms/ios/qiosintegration.h index 11c17aced9..d5f79857f7 100644 --- a/src/plugins/platforms/ios/qiosintegration.h +++ b/src/plugins/platforms/ios/qiosintegration.h @@ -1,38 +1,38 @@ /**************************************************************************** ** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal ** ** This file is part of the plugins of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** ** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. ** ** ** $QT_END_LICENSE$ diff --git a/src/plugins/platforms/ios/qiosintegration.mm b/src/plugins/platforms/ios/qiosintegration.mm index fed278bffe..a417021cbd 100644 --- a/src/plugins/platforms/ios/qiosintegration.mm +++ b/src/plugins/platforms/ios/qiosintegration.mm @@ -1,38 +1,38 @@ /**************************************************************************** ** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal ** ** This file is part of the plugins of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** ** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. ** ** ** $QT_END_LICENSE$ diff --git a/src/plugins/platforms/ios/qiosscreen.h b/src/plugins/platforms/ios/qiosscreen.h index 8d67b1ecdf..f17f1c1d70 100644 --- a/src/plugins/platforms/ios/qiosscreen.h +++ b/src/plugins/platforms/ios/qiosscreen.h @@ -1,38 +1,38 @@ /**************************************************************************** ** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal ** ** This file is part of the plugins of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** ** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. ** ** ** $QT_END_LICENSE$ diff --git a/src/plugins/platforms/ios/qiosscreen.mm b/src/plugins/platforms/ios/qiosscreen.mm index effd19070a..efeacb8cb6 100644 --- a/src/plugins/platforms/ios/qiosscreen.mm +++ b/src/plugins/platforms/ios/qiosscreen.mm @@ -1,38 +1,38 @@ /**************************************************************************** ** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal ** ** This file is part of the plugins of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** ** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. ** ** ** $QT_END_LICENSE$ diff --git a/src/plugins/platforms/ios/qiossoftwareinputhandler.h b/src/plugins/platforms/ios/qiossoftwareinputhandler.h index 99e8fac61b..5dad6b8d86 100644 --- a/src/plugins/platforms/ios/qiossoftwareinputhandler.h +++ b/src/plugins/platforms/ios/qiossoftwareinputhandler.h @@ -1,40 +1,38 @@ - - /**************************************************************************** ** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal ** ** This file is part of the plugins of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** ** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. ** ** ** $QT_END_LICENSE$ -- cgit v1.2.3 From b3eccb0c15a3d4c9bee236c82c9a155c8752b66c Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Tue, 13 Nov 2012 17:15:19 +0100 Subject: iOS: add QIOSOrientationListener MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit QIOSScreen will use this to listen for orientation changes from UIDevice. Change-Id: I5a30f3808f8b9b885303608ce2fc1316c962898b Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/plugin.pro | 2 + .../platforms/ios/qiosorientationlistener.h | 65 +++++++++++++ .../platforms/ios/qiosorientationlistener.mm | 108 +++++++++++++++++++++ 3 files changed, 175 insertions(+) create mode 100644 src/plugins/platforms/ios/qiosorientationlistener.h create mode 100644 src/plugins/platforms/ios/qiosorientationlistener.mm (limited to 'src') diff --git a/src/plugins/platforms/ios/plugin.pro b/src/plugins/platforms/ios/plugin.pro index 222d8c8445..ab49115ed3 100644 --- a/src/plugins/platforms/ios/plugin.pro +++ b/src/plugins/platforms/ios/plugin.pro @@ -14,6 +14,7 @@ OBJECTIVE_SOURCES = \ qioseventdispatcher.mm \ qiosbackingstore.mm \ qiosapplicationdelegate.mm \ + qiosorientationlistener.mm \ qioscontext.mm HEADERS = \ @@ -23,6 +24,7 @@ HEADERS = \ qioseventdispatcher.h \ qiosbackingstore.h \ qiosapplicationdelegate.h \ + qiosorientationlistener.h \ qioscontext.h #HEADERS = qiossoftwareinputhandler.h diff --git a/src/plugins/platforms/ios/qiosorientationlistener.h b/src/plugins/platforms/ios/qiosorientationlistener.h new file mode 100644 index 0000000000..c7b481a03a --- /dev/null +++ b/src/plugins/platforms/ios/qiosorientationlistener.h @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QIOSORIENTATIONLISTENER_H +#define QIOSORIENTATIONLISTENER_H + +#include +#include + +QT_BEGIN_NAMESPACE + +class QIOSScreen; +Qt::ScreenOrientation convertToQtOrientation(UIDeviceOrientation uiDeviceOrientation); + +QT_END_NAMESPACE + +@interface QIOSOrientationListener : NSObject { + @public + QIOSScreen *m_screen; + Qt::ScreenOrientation m_orientation; +} +- (id) initWithQIOSScreen:(QIOSScreen *)screen; + +@end + +#endif + diff --git a/src/plugins/platforms/ios/qiosorientationlistener.mm b/src/plugins/platforms/ios/qiosorientationlistener.mm new file mode 100644 index 0000000000..626e43129b --- /dev/null +++ b/src/plugins/platforms/ios/qiosorientationlistener.mm @@ -0,0 +1,108 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qiosorientationlistener.h" +#include "qiosscreen.h" +#include + +QT_BEGIN_NAMESPACE + +Qt::ScreenOrientation convertToQtOrientation(UIDeviceOrientation uiDeviceOrientation) +{ + Qt::ScreenOrientation qtOrientation; + switch (uiDeviceOrientation) { + case UIDeviceOrientationPortraitUpsideDown: + qtOrientation = Qt::InvertedPortraitOrientation; + break; + case UIDeviceOrientationLandscapeLeft: + qtOrientation = Qt::InvertedLandscapeOrientation; + break; + case UIDeviceOrientationLandscapeRight: + qtOrientation = Qt::LandscapeOrientation; + break; + case UIDeviceOrientationFaceUp: + case UIDeviceOrientationFaceDown: + qtOrientation = static_cast(-1); // not supported ATM. + break; + default: + qtOrientation = Qt::PortraitOrientation; + break; + } + return qtOrientation; +} + +QT_END_NAMESPACE + +@implementation QIOSOrientationListener + +- (id) initWithQIOSScreen:(QIOSScreen *)screen +{ + self = [super init]; + if (self) { + m_screen = screen; + m_orientation = convertToQtOrientation([UIDevice currentDevice].orientation); + [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications]; + [[NSNotificationCenter defaultCenter] + addObserver:self + selector:@selector(orientationChanged:) + name:@"UIDeviceOrientationDidChangeNotification" object:nil]; + } + return self; +} + +- (void) dealloc +{ + [[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications]; + [super dealloc]; +} + +- (void) orientationChanged:(NSNotification *)notification +{ + Q_UNUSED(notification); + Qt::ScreenOrientation qtOrientation = convertToQtOrientation([UIDevice currentDevice].orientation); + if (qtOrientation != -1) { + m_orientation = qtOrientation; + QWindowSystemInterface::handleScreenOrientationChange(m_screen->screen(), m_orientation); + } +} + +@end + -- cgit v1.2.3 From 92252bcb93b2e8ba8cefeadf8cc0330c8ff1c47b Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Thu, 15 Nov 2012 13:06:22 +0100 Subject: iOS: let QIOSScreen start/stop listening for device orientation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From the qpa docs, we only need to listen for device orientation if orientationUpdateMask is non-zero Change-Id: Id5e828cdff9a08794c8a029e11763cc037e1b959 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiosscreen.h | 7 +++++++ src/plugins/platforms/ios/qiosscreen.mm | 27 +++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) (limited to 'src') diff --git a/src/plugins/platforms/ios/qiosscreen.h b/src/plugins/platforms/ios/qiosscreen.h index f17f1c1d70..ed21e54f4a 100644 --- a/src/plugins/platforms/ios/qiosscreen.h +++ b/src/plugins/platforms/ios/qiosscreen.h @@ -45,6 +45,7 @@ #include #include +#include QT_BEGIN_NAMESPACE @@ -52,6 +53,7 @@ class QIOSScreen : public QPlatformScreen { public: QIOSScreen(unsigned int screenIndex); + ~QIOSScreen(); enum ScreenIndex { MainScreen = 0 }; @@ -61,6 +63,10 @@ public: QImage::Format format() const; QSizeF physicalSize() const; + Qt::ScreenOrientation nativeOrientation() const; + Qt::ScreenOrientation orientation() const; + void setOrientationUpdateMask(Qt::ScreenOrientations mask); + UIScreen *uiScreen() const; private: @@ -68,6 +74,7 @@ private: QRect m_geometry; int m_depth; QSizeF m_physicalSize; + QIOSOrientationListener *m_orientationListener; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qiosscreen.mm b/src/plugins/platforms/ios/qiosscreen.mm index efeacb8cb6..00deaa2fc0 100644 --- a/src/plugins/platforms/ios/qiosscreen.mm +++ b/src/plugins/platforms/ios/qiosscreen.mm @@ -41,6 +41,7 @@ #include "qiosscreen.h" #include "qioswindow.h" +#include #include @@ -68,6 +69,7 @@ static QString deviceModelIdentifier() QIOSScreen::QIOSScreen(unsigned int screenIndex) : QPlatformScreen() , m_uiScreen([[UIScreen screens] objectAtIndex:qMin(screenIndex, [[UIScreen screens] count] - 1)]) + , m_orientationListener(0) { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; @@ -97,6 +99,11 @@ QIOSScreen::QIOSScreen(unsigned int screenIndex) [pool release]; } +QIOSScreen::~QIOSScreen() +{ + [m_orientationListener release]; +} + QRect QIOSScreen::geometry() const { return m_geometry; @@ -123,6 +130,26 @@ QSizeF QIOSScreen::physicalSize() const return m_physicalSize; } +Qt::ScreenOrientation QIOSScreen::nativeOrientation() const +{ + return Qt::PortraitOrientation; +} + +Qt::ScreenOrientation QIOSScreen::orientation() const +{ + return m_orientationListener ? m_orientationListener->m_orientation : nativeOrientation(); +} + +void QIOSScreen::setOrientationUpdateMask(Qt::ScreenOrientations mask) +{ + if (m_orientationListener && mask == Qt::PrimaryOrientation) { + [m_orientationListener release]; + m_orientationListener = 0; + } else if (!m_orientationListener) { + m_orientationListener = [[QIOSOrientationListener alloc] initWithQIOSScreen:this]; + } +} + UIScreen *QIOSScreen::uiScreen() const { return m_uiScreen; -- cgit v1.2.3 From 72f66a8ee57ad3865d25e0157179d042a474cfff Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Thu, 15 Nov 2012 14:02:04 +0100 Subject: iOS: add function convertToUIOrientation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I6145121d49eb3f5bab3f2a1ba57c779ec0b01023 Reviewed-by: Tor Arne Vestbø --- .../platforms/ios/qiosorientationlistener.h | 1 + .../platforms/ios/qiosorientationlistener.mm | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+) (limited to 'src') diff --git a/src/plugins/platforms/ios/qiosorientationlistener.h b/src/plugins/platforms/ios/qiosorientationlistener.h index c7b481a03a..9d2e902ce1 100644 --- a/src/plugins/platforms/ios/qiosorientationlistener.h +++ b/src/plugins/platforms/ios/qiosorientationlistener.h @@ -49,6 +49,7 @@ QT_BEGIN_NAMESPACE class QIOSScreen; Qt::ScreenOrientation convertToQtOrientation(UIDeviceOrientation uiDeviceOrientation); +UIDeviceOrientation convertToUIOrientation(Qt::ScreenOrientation qtOrientation); QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qiosorientationlistener.mm b/src/plugins/platforms/ios/qiosorientationlistener.mm index 626e43129b..264b77f14f 100644 --- a/src/plugins/platforms/ios/qiosorientationlistener.mm +++ b/src/plugins/platforms/ios/qiosorientationlistener.mm @@ -69,6 +69,28 @@ Qt::ScreenOrientation convertToQtOrientation(UIDeviceOrientation uiDeviceOrienta return qtOrientation; } +UIDeviceOrientation convertToUIOrientation(Qt::ScreenOrientation qtOrientation) +{ + UIDeviceOrientation uiOrientation; + switch (qtOrientation) { + case Qt::LandscapeOrientation: + uiOrientation = UIDeviceOrientationLandscapeRight; + break; + case Qt::InvertedLandscapeOrientation: + uiOrientation = UIDeviceOrientationLandscapeLeft; + break; + case Qt::InvertedPortraitOrientation: + uiOrientation = UIDeviceOrientationPortraitUpsideDown; + break; + case Qt::PrimaryOrientation: + case Qt::PortraitOrientation: + default: + uiOrientation = UIDeviceOrientationPortrait; + break; + } + return uiOrientation; +} + QT_END_NAMESPACE @implementation QIOSOrientationListener -- cgit v1.2.3 From fa731cddd16aed426f7c73bf4807475f0b087d4c Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Fri, 16 Nov 2012 09:24:41 +0100 Subject: iOS: add QIOSViewController MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We need our own viewcontroller to better control which orientations iOS can enter, and also ito be able to stop auto-rotation. We stop auto-rotation to happend by default, since this is how Qt wants it (it is seen as the responsibility of the application). Change-Id: Id07a96e355396752fffd28984af528aeb0b7c3e3 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/plugin.pro | 2 + src/plugins/platforms/ios/qiosviewcontroller.h | 46 +++++++++++++++++++ src/plugins/platforms/ios/qiosviewcontroller.mm | 60 +++++++++++++++++++++++++ src/plugins/platforms/ios/qtmain.mm | 3 +- src/plugins/platforms/ios/qtmain.pro | 5 ++- 5 files changed, 114 insertions(+), 2 deletions(-) create mode 100644 src/plugins/platforms/ios/qiosviewcontroller.h create mode 100644 src/plugins/platforms/ios/qiosviewcontroller.mm (limited to 'src') diff --git a/src/plugins/platforms/ios/plugin.pro b/src/plugins/platforms/ios/plugin.pro index ab49115ed3..12c5c6db01 100644 --- a/src/plugins/platforms/ios/plugin.pro +++ b/src/plugins/platforms/ios/plugin.pro @@ -15,6 +15,7 @@ OBJECTIVE_SOURCES = \ qiosbackingstore.mm \ qiosapplicationdelegate.mm \ qiosorientationlistener.mm \ + qiosviewcontroller.mm \ qioscontext.mm HEADERS = \ @@ -25,6 +26,7 @@ HEADERS = \ qiosbackingstore.h \ qiosapplicationdelegate.h \ qiosorientationlistener.h \ + qiosviewcontroller.h \ qioscontext.h #HEADERS = qiossoftwareinputhandler.h diff --git a/src/plugins/platforms/ios/qiosviewcontroller.h b/src/plugins/platforms/ios/qiosviewcontroller.h new file mode 100644 index 0000000000..d5a61cb3f4 --- /dev/null +++ b/src/plugins/platforms/ios/qiosviewcontroller.h @@ -0,0 +1,46 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#import + +@interface QIOSViewController : UIViewController +@end + diff --git a/src/plugins/platforms/ios/qiosviewcontroller.mm b/src/plugins/platforms/ios/qiosviewcontroller.mm new file mode 100644 index 0000000000..5381b3a21e --- /dev/null +++ b/src/plugins/platforms/ios/qiosviewcontroller.mm @@ -0,0 +1,60 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#import "qiosviewcontroller.h" + +@implementation QIOSViewController + +- (BOOL)shouldAutorotate +{ + return NO; +} + +- (NSUInteger)supportedInterfaceOrientations +{ + // We need to tell iOS that we support all orientations in order to set + // status bar orientation when application content orientation changes. + // But we return 'NO' above when asked if we 'shouldAutorotate': + return UIInterfaceOrientationMaskAll; +} + +@end + diff --git a/src/plugins/platforms/ios/qtmain.mm b/src/plugins/platforms/ios/qtmain.mm index 9b4ce9918e..61756edc93 100644 --- a/src/plugins/platforms/ios/qtmain.mm +++ b/src/plugins/platforms/ios/qtmain.mm @@ -40,6 +40,7 @@ ****************************************************************************/ #include "qiosapplicationdelegate.h" +#include "qiosviewcontroller.h" int main(int argc, char *argv[]) { @@ -58,7 +59,7 @@ extern int qt_main(int argc, char *argv[]); if (!self.window) { // If not, we create one ourselves self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; - UIViewController *controller = [[UIViewController alloc] init]; + QIOSViewController *controller = [[QIOSViewController alloc] init]; self.window.rootViewController = controller; controller.view = [[UIView alloc] init]; diff --git a/src/plugins/platforms/ios/qtmain.pro b/src/plugins/platforms/ios/qtmain.pro index 49ada385bb..7c4c4ab398 100644 --- a/src/plugins/platforms/ios/qtmain.pro +++ b/src/plugins/platforms/ios/qtmain.pro @@ -3,4 +3,7 @@ TARGET = qiosmain PLUGIN_TYPE = platforms load(qt_plugin) -OBJECTIVE_SOURCES = qtmain.mm +OBJECTIVE_SOURCES = qtmain.mm \ + qiosviewcontroller.mm + +HEADERS = qiosviewcontroller.h -- cgit v1.2.3 From 575d28a6fd62c83c82de5dfc0c34013948c0c9bd Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Thu, 15 Nov 2012 13:28:59 +0100 Subject: iOS: handle content orientation feedback from application MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I2bfb4ee4840086dcd3ec85c2ee7e8769e76d2700 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qioswindow.h | 1 + src/plugins/platforms/ios/qioswindow.mm | 9 +++++++++ 2 files changed, 10 insertions(+) (limited to 'src') diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h index 4e1970d4d4..b20c1c4fc5 100644 --- a/src/plugins/platforms/ios/qioswindow.h +++ b/src/plugins/platforms/ios/qioswindow.h @@ -86,6 +86,7 @@ public: void updateGeometry(const QRect &rect); void setWindowState(Qt::WindowState state); + void handleContentOrientationChange(Qt::ScreenOrientation orientation); GLuint framebufferObject(const QIOSContext &context) const; diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 5701ac8aa2..e220312d15 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -43,6 +43,7 @@ #include "qioscontext.h" #include "qiosscreen.h" #include "qiosapplicationdelegate.h" +#include "qiosorientationlistener.h" #import @@ -248,6 +249,14 @@ void QIOSWindow::setWindowState(Qt::WindowState state) } } +void QIOSWindow::handleContentOrientationChange(Qt::ScreenOrientation orientation) +{ + // Keep the status bar in sync with content orientation. This will ensure + // that the task bar (and associated gestures) are aligned correctly: + UIDeviceOrientation uiOrientation = convertToUIOrientation(orientation); + [[UIApplication sharedApplication] setStatusBarOrientation:uiOrientation animated:NO]; +} + GLuint QIOSWindow::framebufferObject(const QIOSContext &context) const { static GLuint framebuffer = 0; -- cgit v1.2.3 From 55f0bce0945a2f2b28e2454fbc03b1efd61819e4 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Fri, 16 Nov 2012 11:14:34 +0100 Subject: iOS: implement requestWindowOrientation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The application is normally supposed to rotate the content on its own, but can call requestWindowOrientation to ask the window manager to do it instead. This way of integrating orientation with the OS is fragile, because: 1. In some cases, you cannot stop the OS from rotating at all (tablets). 2. It would be more safe to inform the window manager up-front which orientations it could rotate into, rather that relying on a function you call call to force this later on. 3. When the QML application starts, its a bit late to inform the platform plugin that it supports e.g landscape. If the OS is in landscape already, the plugin must still assume that the app operates in portrait (doing rotating on its own) until requestWindowOrientation is called. This might cause the app to first start up in portrait, just to rotate into landscape. On iOS, it seems like we can handle the first two cases. The third need some more investigation. We should anyway investigate if we need some adjustment to the Qt API. Change-Id: I50638b78d469ab70820a787de86a2f1981470786 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiosviewcontroller.h | 8 +++++++- src/plugins/platforms/ios/qiosviewcontroller.mm | 26 ++++++++++++++++++++++--- src/plugins/platforms/ios/qioswindow.h | 1 + src/plugins/platforms/ios/qioswindow.mm | 17 ++++++++++++++++ 4 files changed, 48 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/plugins/platforms/ios/qiosviewcontroller.h b/src/plugins/platforms/ios/qiosviewcontroller.h index d5a61cb3f4..780ec7adab 100644 --- a/src/plugins/platforms/ios/qiosviewcontroller.h +++ b/src/plugins/platforms/ios/qiosviewcontroller.h @@ -40,7 +40,13 @@ ****************************************************************************/ #import +#import -@interface QIOSViewController : UIViewController +@interface QIOSViewController : UIViewController { +@public + bool m_shouldAutorotate; +} + +-(bool)rotateToDeviceOrientation; @end diff --git a/src/plugins/platforms/ios/qiosviewcontroller.mm b/src/plugins/platforms/ios/qiosviewcontroller.mm index 5381b3a21e..8b1a085cc5 100644 --- a/src/plugins/platforms/ios/qiosviewcontroller.mm +++ b/src/plugins/platforms/ios/qiosviewcontroller.mm @@ -43,12 +43,32 @@ @implementation QIOSViewController -- (BOOL)shouldAutorotate +-(id)init { - return NO; + self = [super init]; + if (self) { + m_shouldAutorotate = NO; + } + return self; } -- (NSUInteger)supportedInterfaceOrientations +-(bool)rotateToDeviceOrientation +{ + if ([UIViewController respondsToSelector:@selector(attemptRotationToDeviceOrientation)]) { + m_shouldAutorotate = YES; + [UIViewController attemptRotationToDeviceOrientation]; + m_shouldAutorotate = NO; + return true; + } + return false; +} + +-(BOOL)shouldAutorotate +{ + return m_shouldAutorotate; +} + +-(NSUInteger)supportedInterfaceOrientations { // We need to tell iOS that we support all orientations in order to set // status bar orientation when application content orientation changes. diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h index b20c1c4fc5..e4c3a6a17c 100644 --- a/src/plugins/platforms/ios/qioswindow.h +++ b/src/plugins/platforms/ios/qioswindow.h @@ -87,6 +87,7 @@ public: void setWindowState(Qt::WindowState state); void handleContentOrientationChange(Qt::ScreenOrientation orientation); + Qt::ScreenOrientation requestWindowOrientation(Qt::ScreenOrientation orientation); GLuint framebufferObject(const QIOSContext &context) const; diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index e220312d15..c1f14f22ef 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -44,6 +44,7 @@ #include "qiosscreen.h" #include "qiosapplicationdelegate.h" #include "qiosorientationlistener.h" +#include "qiosviewcontroller.h" #import @@ -257,6 +258,22 @@ void QIOSWindow::handleContentOrientationChange(Qt::ScreenOrientation orientatio [[UIApplication sharedApplication] setStatusBarOrientation:uiOrientation animated:NO]; } +Qt::ScreenOrientation QIOSWindow::requestWindowOrientation(Qt::ScreenOrientation orientation) +{ + if (!m_view.window) + return Qt::PortraitOrientation; + UIViewController *viewController = m_view.window.rootViewController; + if (!viewController || [viewController isKindOfClass:[QIOSViewController class]] == false) { + return convertToQtOrientation(viewController.interfaceOrientation); + } else { + QIOSViewController *qiosViewController = static_cast(viewController); + if ([qiosViewController rotateToDeviceOrientation]) + return orientation; + else + return convertToQtOrientation(viewController.interfaceOrientation); + } +} + GLuint QIOSWindow::framebufferObject(const QIOSContext &context) const { static GLuint framebuffer = 0; -- cgit v1.2.3 From 7f7d75201271bc1b87a8607a78c04aeab1ad3513 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Mon, 19 Nov 2012 13:58:11 +0100 Subject: iOS: use 'self' rather than 'super' pointer in initWithQIOSWindow MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If we use super, our own initWithFrame override will never be called. Change-Id: I606beb653239cdfc46f41db4ec0791dfa5d4edea Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qioswindow.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index c1f14f22ef..4e10c19ecc 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -72,7 +72,7 @@ static QRect fromCGRect(const CGRect &rect) -(id)initWithQIOSWindow:(QIOSWindow *)window { - if (self = [super initWithFrame:toCGRect(window->geometry())]) + if (self = [self initWithFrame:toCGRect(window->geometry())]) m_qioswindow = window; return self; -- cgit v1.2.3 From ad4cf5068cd39b9ca16bdd9705d0a3ef61783d33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Fri, 16 Nov 2012 07:36:49 +0100 Subject: iOS: Don't recreate paint device on beginPaint() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This causes painting errors. Use one lazily-created device that is used for the lifetime of the backing store. Change-Id: Ib36b6f1d6c9f958304dc8403cf17e5d71136469a Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiosbackingstore.mm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/plugins/platforms/ios/qiosbackingstore.mm b/src/plugins/platforms/ios/qiosbackingstore.mm index 71f14fdd91..6cefc03377 100644 --- a/src/plugins/platforms/ios/qiosbackingstore.mm +++ b/src/plugins/platforms/ios/qiosbackingstore.mm @@ -60,6 +60,7 @@ QIOSBackingStore::QIOSBackingStore(QWindow *window) QIOSBackingStore::~QIOSBackingStore() { delete m_context; + delete m_device; } void QIOSBackingStore::beginPaint(const QRegion &) @@ -68,7 +69,8 @@ void QIOSBackingStore::beginPaint(const QRegion &) window()->setSurfaceType(QSurface::OpenGLSurface); m_context->makeCurrent(window()); - m_device = new QOpenGLPaintDevice(window()->size()); + if (!m_device) + m_device = new QOpenGLPaintDevice(window()->size()); } QPaintDevice *QIOSBackingStore::paintDevice() @@ -86,8 +88,6 @@ void QIOSBackingStore::flush(QWindow *window, const QRegion ®ion, const QPoin void QIOSBackingStore::endPaint() { - delete m_device; - // Calling makeDone() on the context here would be an option, // but is not needed, and would actually add some overhead. } -- cgit v1.2.3 From 5d878cae1d090b9c7d5730a85667e569e67c17d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 6 Dec 2012 14:13:40 +0100 Subject: iOS: Remove requestWindowOrientation from QIOSWindow The API is scheduled to be removed in qtbase in time for Qt 5.0. Change-Id: Ie34d6cb79fcd81b0ce02892529e3e7184ddfa096 Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qiosviewcontroller.h | 7 +------ src/plugins/platforms/ios/qiosviewcontroller.mm | 22 +--------------------- src/plugins/platforms/ios/qioswindow.h | 1 - src/plugins/platforms/ios/qioswindow.mm | 16 ---------------- 4 files changed, 2 insertions(+), 44 deletions(-) (limited to 'src') diff --git a/src/plugins/platforms/ios/qiosviewcontroller.h b/src/plugins/platforms/ios/qiosviewcontroller.h index 780ec7adab..605f0f5b4c 100644 --- a/src/plugins/platforms/ios/qiosviewcontroller.h +++ b/src/plugins/platforms/ios/qiosviewcontroller.h @@ -42,11 +42,6 @@ #import #import -@interface QIOSViewController : UIViewController { -@public - bool m_shouldAutorotate; -} - --(bool)rotateToDeviceOrientation; +@interface QIOSViewController : UIViewController @end diff --git a/src/plugins/platforms/ios/qiosviewcontroller.mm b/src/plugins/platforms/ios/qiosviewcontroller.mm index 8b1a085cc5..a807dc2132 100644 --- a/src/plugins/platforms/ios/qiosviewcontroller.mm +++ b/src/plugins/platforms/ios/qiosviewcontroller.mm @@ -43,29 +43,9 @@ @implementation QIOSViewController --(id)init -{ - self = [super init]; - if (self) { - m_shouldAutorotate = NO; - } - return self; -} - --(bool)rotateToDeviceOrientation -{ - if ([UIViewController respondsToSelector:@selector(attemptRotationToDeviceOrientation)]) { - m_shouldAutorotate = YES; - [UIViewController attemptRotationToDeviceOrientation]; - m_shouldAutorotate = NO; - return true; - } - return false; -} - -(BOOL)shouldAutorotate { - return m_shouldAutorotate; + return NO; } -(NSUInteger)supportedInterfaceOrientations diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h index e4c3a6a17c..b20c1c4fc5 100644 --- a/src/plugins/platforms/ios/qioswindow.h +++ b/src/plugins/platforms/ios/qioswindow.h @@ -87,7 +87,6 @@ public: void setWindowState(Qt::WindowState state); void handleContentOrientationChange(Qt::ScreenOrientation orientation); - Qt::ScreenOrientation requestWindowOrientation(Qt::ScreenOrientation orientation); GLuint framebufferObject(const QIOSContext &context) const; diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 4e10c19ecc..0b2b5fcfd7 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -258,22 +258,6 @@ void QIOSWindow::handleContentOrientationChange(Qt::ScreenOrientation orientatio [[UIApplication sharedApplication] setStatusBarOrientation:uiOrientation animated:NO]; } -Qt::ScreenOrientation QIOSWindow::requestWindowOrientation(Qt::ScreenOrientation orientation) -{ - if (!m_view.window) - return Qt::PortraitOrientation; - UIViewController *viewController = m_view.window.rootViewController; - if (!viewController || [viewController isKindOfClass:[QIOSViewController class]] == false) { - return convertToQtOrientation(viewController.interfaceOrientation); - } else { - QIOSViewController *qiosViewController = static_cast(viewController); - if ([qiosViewController rotateToDeviceOrientation]) - return orientation; - else - return convertToQtOrientation(viewController.interfaceOrientation); - } -} - GLuint QIOSWindow::framebufferObject(const QIOSContext &context) const { static GLuint framebuffer = 0; -- cgit v1.2.3 From 599c7a5ab91f44cb9ed5f12f65d58ff9d543c930 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 6 Dec 2012 15:50:20 +0100 Subject: iOS: Set initial window state on window creation When showing a QWindow the window state is set first, and then the window is made visible. The latter is the step that creates the platform window, so we need to pick up the already set window state in our constructor and respect that. Change-Id: I54fe6c4ebcd3c9504614d2d48bd21f0d76adf3b7 Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qioswindow.mm | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 0b2b5fcfd7..daeb86fb62 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -202,6 +202,8 @@ QIOSWindow::QIOSWindow(QWindow *window) { if ([[UIApplication sharedApplication].delegate isKindOfClass:[QIOSApplicationDelegate class]]) [[UIApplication sharedApplication].delegate.window.rootViewController.view addSubview:m_view]; + + setWindowState(window->windowState()); } QIOSWindow::~QIOSWindow() -- cgit v1.2.3 From 189503933a9e59da22d6415e588a44c87d67c2bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 6 Dec 2012 16:42:56 +0100 Subject: iOS: Enable the ShowIsFullScreen style-hint so that show() implies fullscreen MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We may need to qualify this setting for UC2, so that the user may still create windows as sub-controls of a regular iOS user interface, but for UC1 it makes sense. Change-Id: I1a7019f901fabed8b5b9cbb18a929913780e6595 Reviewed-by: Richard Moe Gustavsen Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/ios/qiosintegration.h | 2 ++ src/plugins/platforms/ios/qiosintegration.mm | 10 ++++++++++ 2 files changed, 12 insertions(+) (limited to 'src') diff --git a/src/plugins/platforms/ios/qiosintegration.h b/src/plugins/platforms/ios/qiosintegration.h index d5f79857f7..363d267716 100644 --- a/src/plugins/platforms/ios/qiosintegration.h +++ b/src/plugins/platforms/ios/qiosintegration.h @@ -60,6 +60,8 @@ public: QPlatformFontDatabase *fontDatabase() const; + QVariant styleHint(StyleHint hint) const; + QAbstractEventDispatcher *guiThreadEventDispatcher() const; QPlatformNativeInterface *nativeInterface() const; diff --git a/src/plugins/platforms/ios/qiosintegration.mm b/src/plugins/platforms/ios/qiosintegration.mm index a417021cbd..b37e803455 100644 --- a/src/plugins/platforms/ios/qiosintegration.mm +++ b/src/plugins/platforms/ios/qiosintegration.mm @@ -106,6 +106,16 @@ QPlatformFontDatabase * QIOSIntegration::fontDatabase() const return m_fontDatabase; } +QVariant QIOSIntegration::styleHint(StyleHint hint) const +{ + switch (hint) { + case ShowIsFullScreen: + return true; + default: + return QPlatformIntegration::styleHint(hint); + } +} + QPlatformNativeInterface *QIOSIntegration::nativeInterface() const { return const_cast(this); -- cgit v1.2.3 From 3a59fc4c97a3658b9712fa214778008bbf914cf9 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Fri, 7 Dec 2012 13:34:51 +0100 Subject: iOS: when in fullscreen, dont respond to geometry changes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When QWindow is told to be in fullscreen, we should not respond to geometry changes. Instead we should bookkeep the requested geometry and set it when/if the window enters Qt::WindowNoState later. Change-Id: Ieaf4756b2a966212c8e1738af9df175a58786a75 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qioswindow.h | 1 - src/plugins/platforms/ios/qioswindow.mm | 34 ++++++++++++++------------------- 2 files changed, 14 insertions(+), 21 deletions(-) (limited to 'src') diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h index b20c1c4fc5..df632e672e 100644 --- a/src/plugins/platforms/ios/qioswindow.h +++ b/src/plugins/platforms/ios/qioswindow.h @@ -83,7 +83,6 @@ public: ~QIOSWindow(); void setGeometry(const QRect &rect); - void updateGeometry(const QRect &rect); void setWindowState(Qt::WindowState state); void handleContentOrientationChange(Qt::ScreenOrientation orientation); diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index daeb86fb62..c91c0b2f35 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -109,13 +109,11 @@ static QRect fromCGRect(const CGRect &rect) // the position of our QWindow (and platform window) will only get updated // when the size is also changed. - if (CGAffineTransformIsIdentity(self.transform)) { - // Reflect the new size (and possibly also position) in the QWindow - m_qioswindow->updateGeometry(fromCGRect(self.frame)); - } else { - qWarning() << "QIOSPlatformWindow's UIView has transform set, ignoring geometry updates"; - } + if (!CGAffineTransformIsIdentity(self.transform)) + qWarning() << m_qioswindow->window() + << "is backed by a UIView that has a transform set. This is not supported."; + QWindowSystemInterface::handleGeometryChange(m_qioswindow->window(), fromCGRect(self.frame)); [super layoutSubviews]; } @@ -218,22 +216,17 @@ void QIOSWindow::setGeometry(const QRect &rect) return; } + // If the window is in fullscreen, just bookkeep the requested + // geometry in case the window goes into Qt::WindowNoState later: + QPlatformWindow::setGeometry(rect); + if (window()->windowState() & (Qt::WindowMaximized | Qt::WindowFullScreen)) + return; + // Since we don't support transformations on the UIView, we can set the frame // directly and let UIKit deal with translating that into bounds and center. + // Changing the size of the view will end up in a call to -[EAGLView layoutSubviews] + // which will update QWindowSystemInterface with the new size. m_view.frame = toCGRect(rect); - - updateGeometry(rect); -} - -void QIOSWindow::updateGeometry(const QRect &rect) -{ - // The baseclass implementation will store the geometry, and allows use to - // re-use the baseclass geometry() implementation, which just returns rect. - QPlatformWindow::setGeometry(rect); - - // We inform Qt about new geometry, which will trigger resize and - // expose events for the application. - QWindowSystemInterface::handleGeometryChange(window(), rect); } void QIOSWindow::setWindowState(Qt::WindowState state) @@ -245,9 +238,10 @@ void QIOSWindow::setWindowState(Qt::WindowState state) switch (state) { case Qt::WindowMaximized: case Qt::WindowFullScreen: - setGeometry(QRect(QPoint(0, 0), window()->screen()->availableSize())); + m_view.frame = toCGRect(QRect(QPoint(0, 0), window()->screen()->availableSize())); break; default: + m_view.frame = toCGRect(geometry()); break; } } -- cgit v1.2.3 From 2d4e96352a0f52351e0fa69273b064a66d460c04 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Fri, 7 Dec 2012 15:15:21 +0100 Subject: iOS: one 'transform' warning per window is sufficient MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The layoutSubviews function will be called when the geometry changes, and we will catch the transform issue there for both UC1 and UC2 Change-Id: I29578bbc5b3091c86fbe69c7095ff280a64be458 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qioswindow.mm | 5 ----- 1 file changed, 5 deletions(-) (limited to 'src') diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index c91c0b2f35..7f03e0d46a 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -211,11 +211,6 @@ QIOSWindow::~QIOSWindow() void QIOSWindow::setGeometry(const QRect &rect) { - if (!CGAffineTransformIsIdentity(m_view.transform)) { - qWarning() << "Setting the geometry of a QWindow with a transform set on the UIView is not supported"; - return; - } - // If the window is in fullscreen, just bookkeep the requested // geometry in case the window goes into Qt::WindowNoState later: QPlatformWindow::setGeometry(rect); -- cgit v1.2.3 From 0d9a50380c2d3ecc33f632f9f0e158c3a8cd2099 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Fri, 7 Dec 2012 15:28:13 +0100 Subject: iOS: when in fullscreen, autoresize the view when the device rotates MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Tell the view that backs QWindow to autoresize itself when the superview (view of the root view controller) changes size. This will typically happen when the device changes orientation. Change-Id: Ib7c4dff9112d57f60012d3f0837677e09088bcaf Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qioswindow.mm | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 7f03e0d46a..2b97695a10 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -234,9 +234,11 @@ void QIOSWindow::setWindowState(Qt::WindowState state) case Qt::WindowMaximized: case Qt::WindowFullScreen: m_view.frame = toCGRect(QRect(QPoint(0, 0), window()->screen()->availableSize())); + m_view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; break; default: m_view.frame = toCGRect(geometry()); + m_view.autoresizingMask = UIViewAutoresizingNone; break; } } -- cgit v1.2.3 From b1cfa62ff45cc4b5c035fc5dbe49461e9fe6052a Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Fri, 7 Dec 2012 16:22:48 +0100 Subject: iOS: let fullscreen geometry take orientation into account MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since UIScreen is orientation agnostic, we need to look at the view of the top level view controller instead to determine available geometry. Change-Id: I3789ab7972a9970e46fbc8af81f2b7199e5ca5d1 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qioswindow.mm | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 2b97695a10..266000d2de 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -232,10 +232,13 @@ void QIOSWindow::setWindowState(Qt::WindowState state) switch (state) { case Qt::WindowMaximized: - case Qt::WindowFullScreen: - m_view.frame = toCGRect(QRect(QPoint(0, 0), window()->screen()->availableSize())); + case Qt::WindowFullScreen: { + // Since UIScreen does not take orientation into account when + // reporting geometry, we need to look at the top view instead: + CGSize fullscreenSize = m_view.window.rootViewController.view.bounds.size; + m_view.frame = CGRectMake(0, 0, fullscreenSize.width, fullscreenSize.height); m_view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; - break; + break; } default: m_view.frame = toCGRect(geometry()); m_view.autoresizingMask = UIViewAutoresizingNone; -- cgit v1.2.3 From a1c9f565521f971adbb1e6aad6b82d194f1a1905 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Mon, 10 Dec 2012 10:18:59 +0100 Subject: iOS: update QPlatformWindow::geometry() when UIView changes size MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It turns out that QWindow::geometry needs to be updated manually by the platform plugin, and not indirectly trough QWindowSystemInterface::handleGeometryChange as first assumed. We now always report the _actual_ geometry of the UIView (which also takes the status bar into account) to QWindow, and remember the _requested_ geometry of the window to use whenever the state of the window changes. Change-Id: Iea940173d26fb6af701234379cae914215dae984 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qioswindow.h | 1 + src/plugins/platforms/ios/qioswindow.mm | 9 ++++++--- 2 files changed, 7 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h index df632e672e..2a762d2bdc 100644 --- a/src/plugins/platforms/ios/qioswindow.h +++ b/src/plugins/platforms/ios/qioswindow.h @@ -93,6 +93,7 @@ public: private: EAGLView *m_view; + QRect m_requestedGeometry; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 266000d2de..b209bbc159 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -113,7 +113,9 @@ static QRect fromCGRect(const CGRect &rect) qWarning() << m_qioswindow->window() << "is backed by a UIView that has a transform set. This is not supported."; - QWindowSystemInterface::handleGeometryChange(m_qioswindow->window(), fromCGRect(self.frame)); + QRect geometry = fromCGRect(self.frame); + m_qioswindow->QPlatformWindow::setGeometry(geometry); + QWindowSystemInterface::handleGeometryChange(m_qioswindow->window(), geometry); [super layoutSubviews]; } @@ -197,6 +199,7 @@ QT_BEGIN_NAMESPACE QIOSWindow::QIOSWindow(QWindow *window) : QPlatformWindow(window) , m_view([[EAGLView alloc] initWithQIOSWindow:this]) + , m_requestedGeometry(QPlatformWindow::geometry()) { if ([[UIApplication sharedApplication].delegate isKindOfClass:[QIOSApplicationDelegate class]]) [[UIApplication sharedApplication].delegate.window.rootViewController.view addSubview:m_view]; @@ -213,7 +216,7 @@ void QIOSWindow::setGeometry(const QRect &rect) { // If the window is in fullscreen, just bookkeep the requested // geometry in case the window goes into Qt::WindowNoState later: - QPlatformWindow::setGeometry(rect); + m_requestedGeometry = rect; if (window()->windowState() & (Qt::WindowMaximized | Qt::WindowFullScreen)) return; @@ -240,7 +243,7 @@ void QIOSWindow::setWindowState(Qt::WindowState state) m_view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; break; } default: - m_view.frame = toCGRect(geometry()); + m_view.frame = toCGRect(m_requestedGeometry); m_view.autoresizingMask = UIViewAutoresizingNone; break; } -- cgit v1.2.3 From 8dde67fcd33fc35fe95262bd7acb6f7b5143fead Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Mon, 10 Dec 2012 16:40:40 +0100 Subject: iOS: Create QIOSBackingStore paint device lazily in paintDevice() Instead of constructor. Change-Id: I98cddd3f39add3e6f787c858b4d629325cc0f852 Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qiosbackingstore.mm | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/plugins/platforms/ios/qiosbackingstore.mm b/src/plugins/platforms/ios/qiosbackingstore.mm index 6cefc03377..dfa41f0003 100644 --- a/src/plugins/platforms/ios/qiosbackingstore.mm +++ b/src/plugins/platforms/ios/qiosbackingstore.mm @@ -69,12 +69,13 @@ void QIOSBackingStore::beginPaint(const QRegion &) window()->setSurfaceType(QSurface::OpenGLSurface); m_context->makeCurrent(window()); - if (!m_device) - m_device = new QOpenGLPaintDevice(window()->size()); } QPaintDevice *QIOSBackingStore::paintDevice() { + if (!m_device) + m_device = new QOpenGLPaintDevice(window()->size()); + return m_device; } -- cgit v1.2.3 From d059866eb43a7415dd786a2bcba14f729d938675 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Mon, 10 Dec 2012 17:11:15 +0100 Subject: iOS: Keep QIOSBackingStore's paint device size in sync with the window Treating the paint-device as a thing wrapper around the OpenGL paint engine failed when the window was resized, as the paint engine would clip the drawing to the old size. We need to update the size in beginPaint. QBackingStore resize still behaves like before, and we emit a warning if the user tries to resize the backing-store to some other size than the window size, as that's not a supported use-case for our iOS backing store. Change-Id: I1a0eeb65fa9db8b5538dc69963d6fc84be6e63f1 Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qiosbackingstore.mm | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/plugins/platforms/ios/qiosbackingstore.mm b/src/plugins/platforms/ios/qiosbackingstore.mm index dfa41f0003..6bae08ce2b 100644 --- a/src/plugins/platforms/ios/qiosbackingstore.mm +++ b/src/plugins/platforms/ios/qiosbackingstore.mm @@ -69,12 +69,14 @@ void QIOSBackingStore::beginPaint(const QRegion &) window()->setSurfaceType(QSurface::OpenGLSurface); m_context->makeCurrent(window()); + + static_cast(paintDevice())->setSize(window()->size()); } QPaintDevice *QIOSBackingStore::paintDevice() { if (!m_device) - m_device = new QOpenGLPaintDevice(window()->size()); + m_device = new QOpenGLPaintDevice; return m_device; } @@ -95,12 +97,16 @@ void QIOSBackingStore::endPaint() void QIOSBackingStore::resize(const QSize &size, const QRegion &staticContents) { - Q_UNUSED(size); Q_UNUSED(staticContents); - // We don't need to resize the QOpenGLPaintDevice, as it's just a thin wrapper - // around the OpenGL paint-engine, and the real geometry is handled by the - // context and window. + // Resizing the backing store would in our case mean resizing the QWindow, + // as we cheat and use an QOpenGLPaintDevice that we target at the window. + // That's probably not what the user intended, so we ignore resizes of the + // backing store and always keep the paint device's size in sync with the + // window size in beginPaint(). + + if (size != window()->size()) + qWarning() << "QIOSBackingStore needs to have the same size as its window"; } QT_END_NAMESPACE -- cgit v1.2.3 From 21965187096f8bde7866b05459444793e1a6c1b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Mon, 10 Dec 2012 17:49:53 +0100 Subject: iOS: Update GL render buffers when the accociated window is resized We keep track of the with and height of the FBO's buffers, and update their storage if the window size has changed since last time. Change-Id: I97788b69e7067a5b5b9f28e8498cf1bc5d2cf6ea Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qioscontext.h | 2 + src/plugins/platforms/ios/qioscontext.mm | 16 +++---- src/plugins/platforms/ios/qioswindow.h | 9 ++++ src/plugins/platforms/ios/qioswindow.mm | 82 ++++++++++++++++++-------------- 4 files changed, 66 insertions(+), 43 deletions(-) (limited to 'src') diff --git a/src/plugins/platforms/ios/qioscontext.h b/src/plugins/platforms/ios/qioscontext.h index 102aaaa387..b45917832c 100644 --- a/src/plugins/platforms/ios/qioscontext.h +++ b/src/plugins/platforms/ios/qioscontext.h @@ -62,6 +62,8 @@ public: void doneCurrent(); GLuint defaultFramebufferObject(QPlatformSurface *) const; + GLuint defaultColorRenderbuffer(QPlatformSurface *) const; + QFunctionPointer getProcAddress(const QByteArray &procName); EAGLContext *nativeContext() const; diff --git a/src/plugins/platforms/ios/qioscontext.mm b/src/plugins/platforms/ios/qioscontext.mm index 8beb588b03..68db28212b 100644 --- a/src/plugins/platforms/ios/qioscontext.mm +++ b/src/plugins/platforms/ios/qioscontext.mm @@ -88,7 +88,8 @@ bool QIOSContext::makeCurrent(QPlatformSurface *surface) [EAGLContext setCurrentContext:m_eaglContext]; glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebufferObject(surface)); - return true; + // Ensures render buffers are set up and match the size of the window + return defaultColorRenderbuffer(surface) != 0; } void QIOSContext::doneCurrent() @@ -101,13 +102,7 @@ void QIOSContext::swapBuffers(QPlatformSurface *surface) Q_ASSERT(surface && surface->surface()->surfaceType() == QSurface::OpenGLSurface); [EAGLContext setCurrentContext:m_eaglContext]; - - GLint renderbuffer; - glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebufferObject(surface)); - glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, - GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &renderbuffer); - glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer); - + glBindRenderbuffer(GL_RENDERBUFFER, defaultColorRenderbuffer(surface)); [m_eaglContext presentRenderbuffer:GL_RENDERBUFFER]; } @@ -116,6 +111,11 @@ GLuint QIOSContext::defaultFramebufferObject(QPlatformSurface *surface) const return static_cast(surface)->framebufferObject(*const_cast(this)); } +GLuint QIOSContext::defaultColorRenderbuffer(QPlatformSurface *surface) const +{ + return static_cast(surface)->colorRenderbuffer(*const_cast(this)); +} + QFunctionPointer QIOSContext::getProcAddress(const QByteArray& functionName) { return reinterpret_cast(dlsym(RTLD_NEXT, functionName.constData())); diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h index 2a762d2bdc..4c55249046 100644 --- a/src/plugins/platforms/ios/qioswindow.h +++ b/src/plugins/platforms/ios/qioswindow.h @@ -88,12 +88,21 @@ public: void handleContentOrientationChange(Qt::ScreenOrientation orientation); GLuint framebufferObject(const QIOSContext &context) const; + GLuint colorRenderbuffer(const QIOSContext &context) const; EAGLView *nativeView() const { return m_view; } private: EAGLView *m_view; QRect m_requestedGeometry; + + mutable struct GLData { + GLuint framebufferObject; + GLuint colorRenderbuffer; + GLuint depthRenderbuffer; + GLint renderbufferWidth; + GLint renderbufferHeight; + } m_glData; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index b209bbc159..90734e58e8 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -116,6 +116,10 @@ static QRect fromCGRect(const CGRect &rect) QRect geometry = fromCGRect(self.frame); m_qioswindow->QPlatformWindow::setGeometry(geometry); QWindowSystemInterface::handleGeometryChange(m_qioswindow->window(), geometry); + + // If we have a new size here we need to resize the FBO's corresponding buffers, + // but we defer that to when the application calls makeCurrent. + [super layoutSubviews]; } @@ -200,6 +204,7 @@ QIOSWindow::QIOSWindow(QWindow *window) : QPlatformWindow(window) , m_view([[EAGLView alloc] initWithQIOSWindow:this]) , m_requestedGeometry(QPlatformWindow::geometry()) + , m_glData() { if ([[UIApplication sharedApplication].delegate isKindOfClass:[QIOSApplicationDelegate class]]) [[UIApplication sharedApplication].delegate.window.rootViewController.view addSubview:m_view]; @@ -209,6 +214,13 @@ QIOSWindow::QIOSWindow(QWindow *window) QIOSWindow::~QIOSWindow() { + if (m_glData.framebufferObject) + glDeleteFramebuffers(1, &m_glData.framebufferObject); + if (m_glData.colorRenderbuffer) + glDeleteRenderbuffers(1, &m_glData.colorRenderbuffer); + if (m_glData.depthRenderbuffer) + glDeleteRenderbuffers(1, &m_glData.depthRenderbuffer); + [m_view release]; } @@ -259,56 +271,56 @@ void QIOSWindow::handleContentOrientationChange(Qt::ScreenOrientation orientatio GLuint QIOSWindow::framebufferObject(const QIOSContext &context) const { - static GLuint framebuffer = 0; + if (!m_glData.framebufferObject) { + [EAGLContext setCurrentContext:context.nativeContext()]; - // FIXME: Cache context and recreate framebuffer if window - // is used with a different context then last time. + glGenFramebuffers(1, &m_glData.framebufferObject); + glBindFramebuffer(GL_FRAMEBUFFER, m_glData.framebufferObject); - if (!framebuffer) { - EAGLContext* eaglContext = context.nativeContext(); + glGenRenderbuffers(1, &m_glData.colorRenderbuffer); + glBindRenderbuffer(GL_RENDERBUFFER, m_glData.colorRenderbuffer); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_glData.colorRenderbuffer); - [EAGLContext setCurrentContext:eaglContext]; + QSurfaceFormat requestedFormat = context.format(); + if (requestedFormat.depthBufferSize() > 0 || requestedFormat.stencilBufferSize() > 0) { + glGenRenderbuffers(1, &m_glData.depthRenderbuffer); + glBindRenderbuffer(GL_RENDERBUFFER, m_glData.depthRenderbuffer); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_glData.depthRenderbuffer); - // Create the framebuffer and bind it - glGenFramebuffers(1, &framebuffer); - glBindFramebuffer(GL_FRAMEBUFFER, framebuffer); + if (requestedFormat.stencilBufferSize() > 0) + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_glData.depthRenderbuffer); + } + } - GLint width; - GLint height; + return m_glData.framebufferObject; +} - // Create a color renderbuffer, allocate storage for it, - // and attach it to the framebuffer’s color attachment point. - GLuint colorRenderbuffer; - glGenRenderbuffers(1, &colorRenderbuffer); - glBindRenderbuffer(GL_RENDERBUFFER, colorRenderbuffer); - [eaglContext renderbufferStorage:GL_RENDERBUFFER fromDrawable:static_cast(m_view.layer)]; - glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &width); - glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &height); - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRenderbuffer); +GLuint QIOSWindow::colorRenderbuffer(const QIOSContext &context) const +{ + if (!m_glData.colorRenderbuffer || + m_glData.renderbufferWidth != geometry().width() || m_glData.renderbufferHeight != geometry().height()) { - QSurfaceFormat requestedFormat = context.format(); - if (requestedFormat.depthBufferSize() > 0 || requestedFormat.stencilBufferSize() > 0) { - // Create a depth or depth/stencil renderbuffer, allocate storage for it, - // and attach it to the framebuffer’s depth attachment point. - GLuint depthRenderbuffer; - glGenRenderbuffers(1, &depthRenderbuffer); - glBindRenderbuffer(GL_RENDERBUFFER, depthRenderbuffer); + glBindRenderbuffer(GL_RENDERBUFFER, m_glData.colorRenderbuffer); + [context.nativeContext() renderbufferStorage:GL_RENDERBUFFER fromDrawable:static_cast(m_view.layer)]; + + glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &m_glData.renderbufferWidth); + glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &m_glData.renderbufferHeight); + + if (m_glData.depthRenderbuffer) { + glBindRenderbuffer(GL_RENDERBUFFER, m_glData.depthRenderbuffer); // FIXME: Support more fine grained control over depth/stencil buffer sizes - if (requestedFormat.stencilBufferSize() > 0) { - glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, width, height); - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, depthRenderbuffer); - } else { - glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, width, height); - } - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthRenderbuffer); + if (context.format().stencilBufferSize() > 0) + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, m_glData.renderbufferWidth, m_glData.renderbufferHeight); + else + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, m_glData.renderbufferWidth, m_glData.renderbufferHeight); } if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) NSLog(@"Failed to make complete framebuffer object %x", glCheckFramebufferStatus(GL_FRAMEBUFFER)); } - return framebuffer; + return m_glData.colorRenderbuffer; } QT_END_NAMESPACE -- cgit v1.2.3 From 31a76b978b3f1c08787e3f88987e3a396d5eec45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Mon, 10 Dec 2012 19:27:30 +0100 Subject: iOS: Enable auto-rotation if no orientation update-mask has been set This is an intermediate heuristic until we have a proper API in Qt to deal with auto-rotation and orientation locking. Change-Id: I433992fa1c18d1670987f79e405a4501b6e5d365 Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qiosviewcontroller.mm | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/plugins/platforms/ios/qiosviewcontroller.mm b/src/plugins/platforms/ios/qiosviewcontroller.mm index a807dc2132..3121597dba 100644 --- a/src/plugins/platforms/ios/qiosviewcontroller.mm +++ b/src/plugins/platforms/ios/qiosviewcontroller.mm @@ -41,18 +41,27 @@ #import "qiosviewcontroller.h" +#include +#include + @implementation QIOSViewController -(BOOL)shouldAutorotate { - return NO; + // For now we assume that if the application doesn't listen to orientation + // updates it means it would like to enable auto-rotation, and vice versa. + if (QGuiApplication *guiApp = qobject_cast(qApp)) + return !guiApp->primaryScreen()->orientationUpdateMask(); + else + return NO; + + // FIXME: Investigate a proper Qt API for auto-rotation and orientation locking } -(NSUInteger)supportedInterfaceOrientations { // We need to tell iOS that we support all orientations in order to set // status bar orientation when application content orientation changes. - // But we return 'NO' above when asked if we 'shouldAutorotate': return UIInterfaceOrientationMaskAll; } -- cgit v1.2.3 From 509697adc30f858ee3483c2b74e292c60b75ba9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Mon, 10 Dec 2012 20:00:27 +0100 Subject: iOS: Remove unnecessary const-trickery when passing QIOSContext to the window Change-Id: I56b3873342c1572ea6a651027e8f1a684cbe2a5a Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qioscontext.mm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/plugins/platforms/ios/qioscontext.mm b/src/plugins/platforms/ios/qioscontext.mm index 68db28212b..00629a84ab 100644 --- a/src/plugins/platforms/ios/qioscontext.mm +++ b/src/plugins/platforms/ios/qioscontext.mm @@ -108,12 +108,12 @@ void QIOSContext::swapBuffers(QPlatformSurface *surface) GLuint QIOSContext::defaultFramebufferObject(QPlatformSurface *surface) const { - return static_cast(surface)->framebufferObject(*const_cast(this)); + return static_cast(surface)->framebufferObject(*this); } GLuint QIOSContext::defaultColorRenderbuffer(QPlatformSurface *surface) const { - return static_cast(surface)->colorRenderbuffer(*const_cast(this)); + return static_cast(surface)->colorRenderbuffer(*this); } QFunctionPointer QIOSContext::getProcAddress(const QByteArray& functionName) -- cgit v1.2.3 From d07bd1b22f6da2fcf961618b59f10f59d0a95d16 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Tue, 11 Dec 2012 12:07:05 +0100 Subject: iOS: remove the view from the view hierarchy upon destruction MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We need to remove the view that backs QWindow when the window is destroyed. Otherwise the view will still be visible on screen, but now with a dangling QWindow pointer. This fixes a crash that happens when closing dialogs. Change-Id: I9053c83c6db80a39f4f71a63993cc7ae73fc4196 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qioswindow.mm | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 90734e58e8..871a046c71 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -221,6 +221,7 @@ QIOSWindow::~QIOSWindow() if (m_glData.depthRenderbuffer) glDeleteRenderbuffers(1, &m_glData.depthRenderbuffer); + [m_view removeFromSuperview]; [m_view release]; } -- cgit v1.2.3 From 60294e0aa381419b897317e3eec208d98ca8b4aa Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Tue, 11 Dec 2012 12:01:17 +0100 Subject: iOS: implement in QIOSWindow::setVisible MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When QWindow is told to show/hide, we need to show/hide the backing UIView as well, otherwise the window will still be visible on screen. Change-Id: I806fdd8bb4afacbbc1c9c7381ba0a31195ee04ac Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qioswindow.h | 1 + src/plugins/platforms/ios/qioswindow.mm | 6 ++++++ 2 files changed, 7 insertions(+) (limited to 'src') diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h index 4c55249046..3a05901ae7 100644 --- a/src/plugins/platforms/ios/qioswindow.h +++ b/src/plugins/platforms/ios/qioswindow.h @@ -86,6 +86,7 @@ public: void setWindowState(Qt::WindowState state); void handleContentOrientationChange(Qt::ScreenOrientation orientation); + void setVisible(bool visible); GLuint framebufferObject(const QIOSContext &context) const; GLuint colorRenderbuffer(const QIOSContext &context) const; diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 871a046c71..a2901efd1d 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -225,6 +225,12 @@ QIOSWindow::~QIOSWindow() [m_view release]; } +void QIOSWindow::setVisible(bool visible) +{ + QPlatformWindow::setVisible(visible); + [m_view setHidden:!visible]; +} + void QIOSWindow::setGeometry(const QRect &rect) { // If the window is in fullscreen, just bookkeep the requested -- cgit v1.2.3 From c558c5c1b82256fc8c8e9e6f947eda6164ea59e8 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Tue, 11 Dec 2012 15:12:40 +0100 Subject: iOS: add class QIOSInputContext (to handle keyboard) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This change will add an initial implementation of the QPlatformInputContext for dealing with the keyboard. Change-Id: I29c1cfbbebb8456977b8a1db0e966973cd2c24a5 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/plugin.pro | 6 +- src/plugins/platforms/ios/qiosinputcontext.h | 69 +++++++++++++ src/plugins/platforms/ios/qiosinputcontext.mm | 134 ++++++++++++++++++++++++++ src/plugins/platforms/ios/qiosintegration.h | 2 + src/plugins/platforms/ios/qiosintegration.mm | 7 ++ 5 files changed, 216 insertions(+), 2 deletions(-) create mode 100644 src/plugins/platforms/ios/qiosinputcontext.h create mode 100644 src/plugins/platforms/ios/qiosinputcontext.mm (limited to 'src') diff --git a/src/plugins/platforms/ios/plugin.pro b/src/plugins/platforms/ios/plugin.pro index 12c5c6db01..d4fe25ef08 100644 --- a/src/plugins/platforms/ios/plugin.pro +++ b/src/plugins/platforms/ios/plugin.pro @@ -16,7 +16,8 @@ OBJECTIVE_SOURCES = \ qiosapplicationdelegate.mm \ qiosorientationlistener.mm \ qiosviewcontroller.mm \ - qioscontext.mm + qioscontext.mm \ + qiosinputcontext.mm HEADERS = \ qiosintegration.h \ @@ -27,6 +28,7 @@ HEADERS = \ qiosapplicationdelegate.h \ qiosorientationlistener.h \ qiosviewcontroller.h \ - qioscontext.h + qioscontext.h \ + qiosinputcontext.h #HEADERS = qiossoftwareinputhandler.h diff --git a/src/plugins/platforms/ios/qiosinputcontext.h b/src/plugins/platforms/ios/qiosinputcontext.h new file mode 100644 index 0000000000..22782d183c --- /dev/null +++ b/src/plugins/platforms/ios/qiosinputcontext.h @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QIOSINPUTCONTEXT_H +#define QIOSINPUTCONTEXT_H + +#include + +#include + +QT_BEGIN_NAMESPACE + +@class QIOSKeyboardListener; + +class QIOSInputContext : public QPlatformInputContext +{ +public: + QIOSInputContext(); + ~QIOSInputContext(); + + void showInputPanel(); + void hideInputPanel(); + bool isInputPanelVisible() const; + +private: + QIOSKeyboardListener *m_keyboardListener; +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/plugins/platforms/ios/qiosinputcontext.mm b/src/plugins/platforms/ios/qiosinputcontext.mm new file mode 100644 index 0000000000..7937337e4a --- /dev/null +++ b/src/plugins/platforms/ios/qiosinputcontext.mm @@ -0,0 +1,134 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qiosinputcontext.h" +#include "qioswindow.h" +#include + +@interface QIOSKeyboardListener : NSObject { +@public + QIOSInputContext *m_context; + BOOL m_keyboardVisible; +} +@end + +@implementation QIOSKeyboardListener + +- (id)initWithQIOSInputContext:(QIOSInputContext *)context +{ + self = [super init]; + if (self) { + m_context = context; + m_keyboardVisible = NO; + // After the keyboard became undockable (iOS5), UIKeyboardWillShow/UIKeyboardWillHide + // no longer works for all cases. So listen to keyboard frame changes instead: + [[NSNotificationCenter defaultCenter] + addObserver:self + selector:@selector(keyboardDidChangeFrame:) + name:@"UIKeyboardDidChangeFrameNotification" object:nil]; + } + return self; +} + +- (void) dealloc +{ + [[NSNotificationCenter defaultCenter] + removeObserver:self + name:@"UIKeyboardDidChangeFrameNotification" object:nil]; + [super dealloc]; +} + +- (void) keyboardDidChangeFrame:(NSNotification *)notification +{ + CGRect frame; + [[[notification userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] getValue:&frame]; + BOOL visible = CGRectIntersectsRect(frame, [UIScreen mainScreen].bounds); + if (m_keyboardVisible != visible) { + m_keyboardVisible = visible; + m_context->emitInputPanelVisibleChanged(); + } +} + +@end + +QIOSInputContext::QIOSInputContext() + : QPlatformInputContext(), + m_keyboardListener([[QIOSKeyboardListener alloc] initWithQIOSInputContext:this]) +{ +} + +QIOSInputContext::~QIOSInputContext() +{ + [m_keyboardListener release]; +} + +void QIOSInputContext::showInputPanel() +{ + if (isInputPanelVisible()) + return; + + // Documentation tells that one should call (and recall, if necessary) becomeFirstResponder/resignFirstResponder + // to show/hide the keyboard. This is slightly inconvenient, since there exist no API to get the current first + // responder. Rather than searching for it from the top, we assume that the view backing the focus window in Qt + // is the best candidate as long as there exist no first responder from before (which the isInputPanelVisible + // test on top should catch). Note that Qt will forward keyevents to whichever QObject that needs it, regardless of + // which UIView the input actually came from. So in this respect, we're undermining iOS' responder chain. + if (QWindow *window = QGuiApplication::focusWindow()) { + QIOSWindow *qiosWindow = static_cast(window->handle()); + [qiosWindow->nativeView() becomeFirstResponder]; + } +} + +void QIOSInputContext::hideInputPanel() +{ + if (!isInputPanelVisible()) + return; + + if (QWindow *window = QGuiApplication::focusWindow()) { + QIOSWindow *qiosWindow = static_cast(window->handle()); + [qiosWindow->nativeView() resignFirstResponder]; + } +} + +bool QIOSInputContext::isInputPanelVisible() const +{ + return m_keyboardListener->m_keyboardVisible; +} diff --git a/src/plugins/platforms/ios/qiosintegration.h b/src/plugins/platforms/ios/qiosintegration.h index 363d267716..9e6dadc5a1 100644 --- a/src/plugins/platforms/ios/qiosintegration.h +++ b/src/plugins/platforms/ios/qiosintegration.h @@ -59,6 +59,7 @@ public: QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const; QPlatformFontDatabase *fontDatabase() const; + QPlatformInputContext *inputContext() const; QVariant styleHint(StyleHint hint) const; @@ -69,6 +70,7 @@ public: private: QPlatformFontDatabase *m_fontDatabase; + QPlatformInputContext *m_inputContext; QPlatformScreen *m_screen; }; diff --git a/src/plugins/platforms/ios/qiosintegration.mm b/src/plugins/platforms/ios/qiosintegration.mm index b37e803455..9d603da150 100644 --- a/src/plugins/platforms/ios/qiosintegration.mm +++ b/src/plugins/platforms/ios/qiosintegration.mm @@ -45,6 +45,7 @@ #include "qiosscreen.h" #include "qioseventdispatcher.h" #include "qioscontext.h" +#include "qiosinputcontext.h" #include @@ -54,6 +55,7 @@ QT_BEGIN_NAMESPACE QIOSIntegration::QIOSIntegration() : m_fontDatabase(new QCoreTextFontDatabase) + , m_inputContext(new QIOSInputContext) , m_screen(new QIOSScreen(QIOSScreen::MainScreen)) { if (![UIApplication sharedApplication]) { @@ -106,6 +108,11 @@ QPlatformFontDatabase * QIOSIntegration::fontDatabase() const return m_fontDatabase; } +QPlatformInputContext *QIOSIntegration::inputContext() const +{ + return m_inputContext; +} + QVariant QIOSIntegration::styleHint(StyleHint hint) const { switch (hint) { -- cgit v1.2.3 From 72c1ada86f8aed0109936542b66ab66981ec39ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Wed, 12 Dec 2012 15:23:21 +0100 Subject: iOS: Make fusion style the default style on iOS, not the windows style Change-Id: I81b6049ff666bf23ac58d60e10d7c3d8713a19ea Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/plugin.pro | 6 ++- src/plugins/platforms/ios/qiosintegration.h | 3 ++ src/plugins/platforms/ios/qiosintegration.mm | 14 ++++++ src/plugins/platforms/ios/qiostheme.h | 62 +++++++++++++++++++++++++ src/plugins/platforms/ios/qiostheme.mm | 69 ++++++++++++++++++++++++++++ 5 files changed, 152 insertions(+), 2 deletions(-) create mode 100644 src/plugins/platforms/ios/qiostheme.h create mode 100644 src/plugins/platforms/ios/qiostheme.mm (limited to 'src') diff --git a/src/plugins/platforms/ios/plugin.pro b/src/plugins/platforms/ios/plugin.pro index d4fe25ef08..1be24d920d 100644 --- a/src/plugins/platforms/ios/plugin.pro +++ b/src/plugins/platforms/ios/plugin.pro @@ -17,7 +17,8 @@ OBJECTIVE_SOURCES = \ qiosorientationlistener.mm \ qiosviewcontroller.mm \ qioscontext.mm \ - qiosinputcontext.mm + qiosinputcontext.mm \ + qiostheme.mm HEADERS = \ qiosintegration.h \ @@ -29,6 +30,7 @@ HEADERS = \ qiosorientationlistener.h \ qiosviewcontroller.h \ qioscontext.h \ - qiosinputcontext.h + qiosinputcontext.h \ + qiostheme.h #HEADERS = qiossoftwareinputhandler.h diff --git a/src/plugins/platforms/ios/qiosintegration.h b/src/plugins/platforms/ios/qiosintegration.h index 9e6dadc5a1..5ba97bff6e 100644 --- a/src/plugins/platforms/ios/qiosintegration.h +++ b/src/plugins/platforms/ios/qiosintegration.h @@ -63,6 +63,9 @@ public: QVariant styleHint(StyleHint hint) const; + QStringList themeNames() const; + QPlatformTheme *createPlatformTheme(const QString &name) const; + QAbstractEventDispatcher *guiThreadEventDispatcher() const; QPlatformNativeInterface *nativeInterface() const; diff --git a/src/plugins/platforms/ios/qiosintegration.mm b/src/plugins/platforms/ios/qiosintegration.mm index 9d603da150..8008c5c0b0 100644 --- a/src/plugins/platforms/ios/qiosintegration.mm +++ b/src/plugins/platforms/ios/qiosintegration.mm @@ -46,6 +46,7 @@ #include "qioseventdispatcher.h" #include "qioscontext.h" #include "qiosinputcontext.h" +#include "qiostheme.h" #include @@ -123,6 +124,19 @@ QVariant QIOSIntegration::styleHint(StyleHint hint) const } } +QStringList QIOSIntegration::themeNames() const +{ + return QStringList(QLatin1String(QIOSTheme::name)); +} + +QPlatformTheme *QIOSIntegration::createPlatformTheme(const QString &name) const +{ + if (name == QLatin1String(QIOSTheme::name)) + return new QIOSTheme; + + return QPlatformIntegration::createPlatformTheme(name); +} + QPlatformNativeInterface *QIOSIntegration::nativeInterface() const { return const_cast(this); diff --git a/src/plugins/platforms/ios/qiostheme.h b/src/plugins/platforms/ios/qiostheme.h new file mode 100644 index 0000000000..d21d8804fa --- /dev/null +++ b/src/plugins/platforms/ios/qiostheme.h @@ -0,0 +1,62 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QIOSTHEME_H +#define QIOSTHEME_H + +#include + +QT_BEGIN_NAMESPACE + +class QIOSTheme : public QPlatformTheme +{ +public: + QIOSTheme(); + ~QIOSTheme(); + + QVariant themeHint(ThemeHint hint) const; + + static const char *name; +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/plugins/platforms/ios/qiostheme.mm b/src/plugins/platforms/ios/qiostheme.mm new file mode 100644 index 0000000000..6e54b9cb3b --- /dev/null +++ b/src/plugins/platforms/ios/qiostheme.mm @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qiostheme.h" + +#include +#include + +QT_BEGIN_NAMESPACE + +const char *QIOSTheme::name = "ios"; + +QIOSTheme::QIOSTheme() +{ +} + +QIOSTheme::~QIOSTheme() +{ +} + +QVariant QIOSTheme::themeHint(ThemeHint hint) const +{ + switch (hint) { + case QPlatformTheme::StyleNames: + return QStringList(QStringLiteral("fusion")); + default: + return QPlatformTheme::themeHint(hint); + } +} + +QT_END_NAMESPACE -- cgit v1.2.3 From 70b21ec3c12c655354676778e087182f20aadbb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 13 Dec 2012 15:20:30 +0100 Subject: iOS: Make default system font Helvetica Without a platform theme implementatin we were relying on QCoreTextFontDatabase::defaultFont() to return the system font. This didn't work because it reported the system font that iOS reports, '.Helvetica Neue UI', which is a private font that does not get added to our font database. The result was that we picked the first font in the list of known fonts -- in this case 'Academy Engraved LET'. We now implement QIOSTheme::font(), which takes precedence over the font database's default font, and hard-code the system font to 'Helvetica', since Qt does not yet have the concept of private system fonts. Change-Id: I901cf9c2b662ea2795212376b84b8391be2efbbe Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qiostheme.h | 2 ++ src/plugins/platforms/ios/qiostheme.mm | 27 +++++++++++++++++++++++++++ 2 files changed, 29 insertions(+) (limited to 'src') diff --git a/src/plugins/platforms/ios/qiostheme.h b/src/plugins/platforms/ios/qiostheme.h index d21d8804fa..5ccbcac710 100644 --- a/src/plugins/platforms/ios/qiostheme.h +++ b/src/plugins/platforms/ios/qiostheme.h @@ -54,6 +54,8 @@ public: QVariant themeHint(ThemeHint hint) const; + const QFont *font(Font type = SystemFont) const; + static const char *name; }; diff --git a/src/plugins/platforms/ios/qiostheme.mm b/src/plugins/platforms/ios/qiostheme.mm index 6e54b9cb3b..f98781f8a7 100644 --- a/src/plugins/platforms/ios/qiostheme.mm +++ b/src/plugins/platforms/ios/qiostheme.mm @@ -44,6 +44,11 @@ #include #include +#include + +#include +#include + QT_BEGIN_NAMESPACE const char *QIOSTheme::name = "ios"; @@ -66,4 +71,26 @@ QVariant QIOSTheme::themeHint(ThemeHint hint) const } } +const QFont *QIOSTheme::font(Font type) const +{ + static QHash fonts; + if (fonts.isEmpty()) { + // The real system font on iOS is '.Helvetica Neue UI', as returned by both [UIFont systemFontOfSize] + // and CTFontCreateUIFontForLanguage(kCTFontSystemFontType, ...), but this font is not included when + // populating the available fonts in QCoreTextFontDatabase::populateFontDatabase(), since the font + // is internal to iOS and not supposed to be used by applications. We could potentially add this + // font to the font-database, but it would then show up when enumerating user fonts from Qt + // applications since we don't have a flag in Qt to mark a font as a private system font. + // For now we hard-code the font to Helvetica, which should be very close to the actual + // system font. + QLatin1String systemFontFamilyName("Helvetica"); + fonts.insert(QPlatformTheme::SystemFont, new QFont(systemFontFamilyName, [UIFont systemFontSize])); + fonts.insert(QPlatformTheme::SmallFont, new QFont(systemFontFamilyName, [UIFont smallSystemFontSize])); + fonts.insert(QPlatformTheme::LabelFont, new QFont(systemFontFamilyName, [UIFont labelFontSize])); + fonts.insert(QPlatformTheme::PushButtonFont, new QFont(systemFontFamilyName, [UIFont buttonFontSize])); + } + + return fonts.value(type, 0); +} + QT_END_NAMESPACE -- cgit v1.2.3 From d5d3f5ea8e6620e1ae06488a9e35a36550367726 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Tue, 26 Feb 2013 13:49:03 +0100 Subject: iOS: let QIOSScreen change geometry according to interface rotation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Qt expects the screen to change geometry when the "desktop" rotates. On iOS, we interpret this as when the root view controller changes orientation, since after all, this is the surface we place QWindows on top of. Change-Id: Ia00e68c8f9f0a65aefcc60518ee544fb260d4595 Reviewed-by: Tor Arne Vestbø Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qiosscreen.h | 3 +++ src/plugins/platforms/ios/qiosscreen.mm | 32 +++++++++++++++++++++---- src/plugins/platforms/ios/qiosviewcontroller.h | 1 - src/plugins/platforms/ios/qiosviewcontroller.mm | 12 ++++++++++ src/plugins/platforms/ios/qtmain.pro | 2 ++ 5 files changed, 45 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/plugins/platforms/ios/qiosscreen.h b/src/plugins/platforms/ios/qiosscreen.h index ed21e54f4a..e05a6cd6a1 100644 --- a/src/plugins/platforms/ios/qiosscreen.h +++ b/src/plugins/platforms/ios/qiosscreen.h @@ -69,9 +69,12 @@ public: UIScreen *uiScreen() const; + void setPrimaryOrientation(Qt::ScreenOrientation orientation); + private: UIScreen *m_uiScreen; QRect m_geometry; + QRect m_availableGeometry; int m_depth; QSizeF m_physicalSize; QIOSOrientationListener *m_orientationListener; diff --git a/src/plugins/platforms/ios/qiosscreen.mm b/src/plugins/platforms/ios/qiosscreen.mm index 00deaa2fc0..f4cade2e6d 100644 --- a/src/plugins/platforms/ios/qiosscreen.mm +++ b/src/plugins/platforms/ios/qiosscreen.mm @@ -88,11 +88,12 @@ QIOSScreen::QIOSScreen(unsigned int screenIndex) unscaledDpi = 132; }; - // UIScreen does not report different bounds for different orientations. We - // match this behavior by staying with a fixed QScreen geometry. CGRect bounds = [m_uiScreen bounds]; m_geometry = QRect(bounds.origin.x, bounds.origin.y, bounds.size.width, bounds.size.height); + CGRect frame = m_uiScreen.applicationFrame; + m_availableGeometry = QRect(frame.origin.x, frame.origin.y, frame.size.width, frame.size.height); + const qreal millimetersPerInch = 25.4; m_physicalSize = QSizeF(m_geometry.size()) / unscaledDpi * millimetersPerInch; @@ -111,8 +112,7 @@ QRect QIOSScreen::geometry() const QRect QIOSScreen::availableGeometry() const { - CGRect frame = m_uiScreen.applicationFrame; - return QRect(frame.origin.x, frame.origin.y, frame.size.width, frame.size.height); + return m_availableGeometry; } int QIOSScreen::depth() const @@ -150,6 +150,30 @@ void QIOSScreen::setOrientationUpdateMask(Qt::ScreenOrientations mask) } } +void QIOSScreen::setPrimaryOrientation(Qt::ScreenOrientation orientation) +{ + // Note that UIScreen never changes orientation, but QScreen should. To work around + // this, we let QIOSViewController call us whenever interface orientation changes, and + // use that as primary orientation. After all, the viewcontrollers geometry is what we + // place QWindows on top of. A problem with this approach is that QIOSViewController is + // not in use in a mixed environment, which results in no change to primary orientation. + // We see that as acceptable since Qt should most likely not interfere with orientation + // for that case anyway. + bool portrait = screen()->isPortrait(orientation); + if (portrait && m_geometry.width() < m_geometry.height()) + return; + + // Switching portrait/landscape means swapping width/height (and adjusting x/y): + CGRect frame = m_uiScreen.applicationFrame; + m_availableGeometry = portrait ? QRect(frame.origin.x, frame.origin.y, frame.size.width, frame.size.height) + : QRect(frame.origin.y, m_geometry.width() - frame.size.width - frame.origin.x, frame.size.height, frame.size.width); + m_geometry = QRect(0, 0, m_geometry.height(), m_geometry.width()); + m_physicalSize = QSizeF(m_physicalSize.height(), m_physicalSize.width()); + + QWindowSystemInterface::handleScreenGeometryChange(screen(), m_geometry); + QWindowSystemInterface::handleScreenAvailableGeometryChange(screen(), m_availableGeometry); +} + UIScreen *QIOSScreen::uiScreen() const { return m_uiScreen; diff --git a/src/plugins/platforms/ios/qiosviewcontroller.h b/src/plugins/platforms/ios/qiosviewcontroller.h index 605f0f5b4c..d5a61cb3f4 100644 --- a/src/plugins/platforms/ios/qiosviewcontroller.h +++ b/src/plugins/platforms/ios/qiosviewcontroller.h @@ -40,7 +40,6 @@ ****************************************************************************/ #import -#import @interface QIOSViewController : UIViewController @end diff --git a/src/plugins/platforms/ios/qiosviewcontroller.mm b/src/plugins/platforms/ios/qiosviewcontroller.mm index 3121597dba..fe9e02666f 100644 --- a/src/plugins/platforms/ios/qiosviewcontroller.mm +++ b/src/plugins/platforms/ios/qiosviewcontroller.mm @@ -43,6 +43,7 @@ #include #include +#include "qiosscreen.h" @implementation QIOSViewController @@ -65,5 +66,16 @@ return UIInterfaceOrientationMaskAll; } +- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation +{ + Q_UNUSED(fromInterfaceOrientation); + Qt::ScreenOrientation orientation = convertToQtOrientation(self.interfaceOrientation); + if (orientation == -1) + return; + + QIOSScreen *qiosScreen = static_cast(QGuiApplication::primaryScreen()->handle()); + qiosScreen->setPrimaryOrientation(orientation); +} + @end diff --git a/src/plugins/platforms/ios/qtmain.pro b/src/plugins/platforms/ios/qtmain.pro index 7c4c4ab398..5c290b6c00 100644 --- a/src/plugins/platforms/ios/qtmain.pro +++ b/src/plugins/platforms/ios/qtmain.pro @@ -3,6 +3,8 @@ TARGET = qiosmain PLUGIN_TYPE = platforms load(qt_plugin) +QT += gui-private + OBJECTIVE_SOURCES = qtmain.mm \ qiosviewcontroller.mm -- cgit v1.2.3 From 70774d021a4ddb6437646ab09bde0928e30c8a90 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Mon, 17 Dec 2012 10:59:45 +0100 Subject: iOS: refactor QIOSOrientationListener into QIOSScreen MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Clean up a bit. The orientation conversion functions belongs to QIOSScreen more than QIOSOrientationListener. And rename them in the same go to follow toQRect/fromQRect standard. The orientation listener itself is tightly coupled to QIOSScreen, and does not make much sense on its own, so move it into QIOSScreen to follow the same patteren already implemented for QIOSInputContext. Change-Id: I8b6b4d08a42349b4232749d59d46748297083536 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/plugin.pro | 2 - .../platforms/ios/qiosorientationlistener.h | 66 ----------- .../platforms/ios/qiosorientationlistener.mm | 130 --------------------- src/plugins/platforms/ios/qiosscreen.h | 6 +- src/plugins/platforms/ios/qiosscreen.mm | 90 +++++++++++++- src/plugins/platforms/ios/qiosviewcontroller.mm | 2 +- src/plugins/platforms/ios/qioswindow.mm | 3 +- 7 files changed, 96 insertions(+), 203 deletions(-) delete mode 100644 src/plugins/platforms/ios/qiosorientationlistener.h delete mode 100644 src/plugins/platforms/ios/qiosorientationlistener.mm (limited to 'src') diff --git a/src/plugins/platforms/ios/plugin.pro b/src/plugins/platforms/ios/plugin.pro index 1be24d920d..a51ac39e03 100644 --- a/src/plugins/platforms/ios/plugin.pro +++ b/src/plugins/platforms/ios/plugin.pro @@ -14,7 +14,6 @@ OBJECTIVE_SOURCES = \ qioseventdispatcher.mm \ qiosbackingstore.mm \ qiosapplicationdelegate.mm \ - qiosorientationlistener.mm \ qiosviewcontroller.mm \ qioscontext.mm \ qiosinputcontext.mm \ @@ -27,7 +26,6 @@ HEADERS = \ qioseventdispatcher.h \ qiosbackingstore.h \ qiosapplicationdelegate.h \ - qiosorientationlistener.h \ qiosviewcontroller.h \ qioscontext.h \ qiosinputcontext.h \ diff --git a/src/plugins/platforms/ios/qiosorientationlistener.h b/src/plugins/platforms/ios/qiosorientationlistener.h deleted file mode 100644 index 9d2e902ce1..0000000000 --- a/src/plugins/platforms/ios/qiosorientationlistener.h +++ /dev/null @@ -1,66 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QIOSORIENTATIONLISTENER_H -#define QIOSORIENTATIONLISTENER_H - -#include -#include - -QT_BEGIN_NAMESPACE - -class QIOSScreen; -Qt::ScreenOrientation convertToQtOrientation(UIDeviceOrientation uiDeviceOrientation); -UIDeviceOrientation convertToUIOrientation(Qt::ScreenOrientation qtOrientation); - -QT_END_NAMESPACE - -@interface QIOSOrientationListener : NSObject { - @public - QIOSScreen *m_screen; - Qt::ScreenOrientation m_orientation; -} -- (id) initWithQIOSScreen:(QIOSScreen *)screen; - -@end - -#endif - diff --git a/src/plugins/platforms/ios/qiosorientationlistener.mm b/src/plugins/platforms/ios/qiosorientationlistener.mm deleted file mode 100644 index 264b77f14f..0000000000 --- a/src/plugins/platforms/ios/qiosorientationlistener.mm +++ /dev/null @@ -1,130 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qiosorientationlistener.h" -#include "qiosscreen.h" -#include - -QT_BEGIN_NAMESPACE - -Qt::ScreenOrientation convertToQtOrientation(UIDeviceOrientation uiDeviceOrientation) -{ - Qt::ScreenOrientation qtOrientation; - switch (uiDeviceOrientation) { - case UIDeviceOrientationPortraitUpsideDown: - qtOrientation = Qt::InvertedPortraitOrientation; - break; - case UIDeviceOrientationLandscapeLeft: - qtOrientation = Qt::InvertedLandscapeOrientation; - break; - case UIDeviceOrientationLandscapeRight: - qtOrientation = Qt::LandscapeOrientation; - break; - case UIDeviceOrientationFaceUp: - case UIDeviceOrientationFaceDown: - qtOrientation = static_cast(-1); // not supported ATM. - break; - default: - qtOrientation = Qt::PortraitOrientation; - break; - } - return qtOrientation; -} - -UIDeviceOrientation convertToUIOrientation(Qt::ScreenOrientation qtOrientation) -{ - UIDeviceOrientation uiOrientation; - switch (qtOrientation) { - case Qt::LandscapeOrientation: - uiOrientation = UIDeviceOrientationLandscapeRight; - break; - case Qt::InvertedLandscapeOrientation: - uiOrientation = UIDeviceOrientationLandscapeLeft; - break; - case Qt::InvertedPortraitOrientation: - uiOrientation = UIDeviceOrientationPortraitUpsideDown; - break; - case Qt::PrimaryOrientation: - case Qt::PortraitOrientation: - default: - uiOrientation = UIDeviceOrientationPortrait; - break; - } - return uiOrientation; -} - -QT_END_NAMESPACE - -@implementation QIOSOrientationListener - -- (id) initWithQIOSScreen:(QIOSScreen *)screen -{ - self = [super init]; - if (self) { - m_screen = screen; - m_orientation = convertToQtOrientation([UIDevice currentDevice].orientation); - [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications]; - [[NSNotificationCenter defaultCenter] - addObserver:self - selector:@selector(orientationChanged:) - name:@"UIDeviceOrientationDidChangeNotification" object:nil]; - } - return self; -} - -- (void) dealloc -{ - [[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications]; - [super dealloc]; -} - -- (void) orientationChanged:(NSNotification *)notification -{ - Q_UNUSED(notification); - Qt::ScreenOrientation qtOrientation = convertToQtOrientation([UIDevice currentDevice].orientation); - if (qtOrientation != -1) { - m_orientation = qtOrientation; - QWindowSystemInterface::handleScreenOrientationChange(m_screen->screen(), m_orientation); - } -} - -@end - diff --git a/src/plugins/platforms/ios/qiosscreen.h b/src/plugins/platforms/ios/qiosscreen.h index e05a6cd6a1..17a5c3149a 100644 --- a/src/plugins/platforms/ios/qiosscreen.h +++ b/src/plugins/platforms/ios/qiosscreen.h @@ -45,10 +45,14 @@ #include #include -#include + +@class QIOSOrientationListener; QT_BEGIN_NAMESPACE +Qt::ScreenOrientation toQtScreenOrientation(UIDeviceOrientation uiDeviceOrientation); +UIDeviceOrientation fromQtScreenOrientation(Qt::ScreenOrientation qtOrientation); + class QIOSScreen : public QPlatformScreen { public: diff --git a/src/plugins/platforms/ios/qiosscreen.mm b/src/plugins/platforms/ios/qiosscreen.mm index f4cade2e6d..02d719eaf1 100644 --- a/src/plugins/platforms/ios/qiosscreen.mm +++ b/src/plugins/platforms/ios/qiosscreen.mm @@ -45,8 +45,96 @@ #include +@interface QIOSOrientationListener : NSObject { + @public + QIOSScreen *m_screen; +} +- (id) initWithQIOSScreen:(QIOSScreen *)screen; +@end + +@implementation QIOSOrientationListener + +- (id) initWithQIOSScreen:(QIOSScreen *)screen +{ + self = [super init]; + if (self) { + m_screen = screen; + [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications]; + [[NSNotificationCenter defaultCenter] + addObserver:self + selector:@selector(orientationChanged:) + name:@"UIDeviceOrientationDidChangeNotification" object:nil]; + } + return self; +} + +- (void) dealloc +{ + [[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications]; + [[NSNotificationCenter defaultCenter] + removeObserver:self + name:@"UIDeviceOrientationDidChangeNotification" object:nil]; + [super dealloc]; +} + +- (void) orientationChanged:(NSNotification *)notification +{ + Q_UNUSED(notification); + Qt::ScreenOrientation orientation = toQtScreenOrientation([UIDevice currentDevice].orientation); + if (orientation != -1) + QWindowSystemInterface::handleScreenOrientationChange(m_screen->screen(), orientation); +} + +@end + QT_BEGIN_NAMESPACE +Qt::ScreenOrientation toQtScreenOrientation(UIDeviceOrientation uiDeviceOrientation) +{ + Qt::ScreenOrientation qtOrientation; + switch (uiDeviceOrientation) { + case UIDeviceOrientationPortraitUpsideDown: + qtOrientation = Qt::InvertedPortraitOrientation; + break; + case UIDeviceOrientationLandscapeLeft: + qtOrientation = Qt::InvertedLandscapeOrientation; + break; + case UIDeviceOrientationLandscapeRight: + qtOrientation = Qt::LandscapeOrientation; + break; + case UIDeviceOrientationFaceUp: + case UIDeviceOrientationFaceDown: + qtOrientation = static_cast(-1); // not supported ATM. + break; + default: + qtOrientation = Qt::PortraitOrientation; + break; + } + return qtOrientation; +} + +UIDeviceOrientation fromQtScreenOrientation(Qt::ScreenOrientation qtOrientation) +{ + UIDeviceOrientation uiOrientation; + switch (qtOrientation) { + case Qt::LandscapeOrientation: + uiOrientation = UIDeviceOrientationLandscapeRight; + break; + case Qt::InvertedLandscapeOrientation: + uiOrientation = UIDeviceOrientationLandscapeLeft; + break; + case Qt::InvertedPortraitOrientation: + uiOrientation = UIDeviceOrientationPortraitUpsideDown; + break; + case Qt::PrimaryOrientation: + case Qt::PortraitOrientation: + default: + uiOrientation = UIDeviceOrientationPortrait; + break; + } + return uiOrientation; +} + /*! Returns the model identifier of the device. @@ -137,7 +225,7 @@ Qt::ScreenOrientation QIOSScreen::nativeOrientation() const Qt::ScreenOrientation QIOSScreen::orientation() const { - return m_orientationListener ? m_orientationListener->m_orientation : nativeOrientation(); + return toQtScreenOrientation([UIDevice currentDevice].orientation); } void QIOSScreen::setOrientationUpdateMask(Qt::ScreenOrientations mask) diff --git a/src/plugins/platforms/ios/qiosviewcontroller.mm b/src/plugins/platforms/ios/qiosviewcontroller.mm index fe9e02666f..8c280d11d9 100644 --- a/src/plugins/platforms/ios/qiosviewcontroller.mm +++ b/src/plugins/platforms/ios/qiosviewcontroller.mm @@ -69,7 +69,7 @@ - (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation { Q_UNUSED(fromInterfaceOrientation); - Qt::ScreenOrientation orientation = convertToQtOrientation(self.interfaceOrientation); + Qt::ScreenOrientation orientation = toQtScreenOrientation(self.interfaceOrientation); if (orientation == -1) return; diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index a2901efd1d..cc016da106 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -43,7 +43,6 @@ #include "qioscontext.h" #include "qiosscreen.h" #include "qiosapplicationdelegate.h" -#include "qiosorientationlistener.h" #include "qiosviewcontroller.h" #import @@ -272,7 +271,7 @@ void QIOSWindow::handleContentOrientationChange(Qt::ScreenOrientation orientatio { // Keep the status bar in sync with content orientation. This will ensure // that the task bar (and associated gestures) are aligned correctly: - UIDeviceOrientation uiOrientation = convertToUIOrientation(orientation); + UIDeviceOrientation uiOrientation = fromQtScreenOrientation(orientation); [[UIApplication sharedApplication] setStatusBarOrientation:uiOrientation animated:NO]; } -- cgit v1.2.3 From d665ba2a9454dbd2ed9f4384e04c31d232b0c5eb Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Mon, 17 Dec 2012 13:39:59 +0100 Subject: iOS: let QIOSScreen use correct orientation at startup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When QScreen is created, we need to check if the application is already in landscape. Change-Id: I653c622154a5c23ec93e89ec3e80fefb6b1f1bdd Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiosscreen.mm | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src') diff --git a/src/plugins/platforms/ios/qiosscreen.mm b/src/plugins/platforms/ios/qiosscreen.mm index 02d719eaf1..a2fd10bdd4 100644 --- a/src/plugins/platforms/ios/qiosscreen.mm +++ b/src/plugins/platforms/ios/qiosscreen.mm @@ -42,6 +42,7 @@ #include "qiosscreen.h" #include "qioswindow.h" #include +#include "qiosapplicationdelegate.h" #include @@ -185,6 +186,12 @@ QIOSScreen::QIOSScreen(unsigned int screenIndex) const qreal millimetersPerInch = 25.4; m_physicalSize = QSizeF(m_geometry.size()) / unscaledDpi * millimetersPerInch; + if ([[UIApplication sharedApplication].delegate isKindOfClass:[QIOSApplicationDelegate class]]) { + // When in a non-mixed environment, let QScreen follow the current interface orientation: + UIViewController *controller = [UIApplication sharedApplication].delegate.window.rootViewController; + setPrimaryOrientation(toQtScreenOrientation(controller.interfaceOrientation)); + } + [pool release]; } -- cgit v1.2.3 From a593de41edfac04f3e3c6dd5bb024254e7e6ff4e Mon Sep 17 00:00:00 2001 From: Morten Johan Sorvig Date: Fri, 14 Dec 2012 17:25:56 +0100 Subject: iOS: Retina display support. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Scale the OpenGL paint device size and physical dpi by the device pixel ratio. Change-Id: I8b576f23129aafc47371795151c548663e94ad52 Reviewed-by: Tor Arne Vestbø --- src/gui/opengl/qopenglpaintdevice.cpp | 14 ++++++++++++-- src/gui/opengl/qopenglpaintdevice.h | 1 + src/plugins/platforms/ios/qiosbackingstore.mm | 10 ++++++++-- src/plugins/platforms/ios/qioswindow.h | 2 ++ src/plugins/platforms/ios/qioswindow.mm | 21 ++++++++++++++++++--- 5 files changed, 41 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/gui/opengl/qopenglpaintdevice.cpp b/src/gui/opengl/qopenglpaintdevice.cpp index 0b3d9dc46d..d55d6a91bf 100644 --- a/src/gui/opengl/qopenglpaintdevice.cpp +++ b/src/gui/opengl/qopenglpaintdevice.cpp @@ -116,6 +116,7 @@ public: qreal dpmx; qreal dpmy; + qreal devicePixelRatio; bool flipped; @@ -178,6 +179,7 @@ QOpenGLPaintDevicePrivate::QOpenGLPaintDevicePrivate(const QSize &sz) , ctx(QOpenGLContext::currentContext()) , dpmx(qt_defaultDpiX() * 100. / 2.54) , dpmy(qt_defaultDpiY() * 100. / 2.54) + , devicePixelRatio(1.0) , flipped(false) , engine(0) { @@ -248,6 +250,14 @@ void QOpenGLPaintDevice::setSize(const QSize &size) d_ptr->size = size; } +/*! + Sets the device pixel ratio for the paint device to \a devicePixelRatio. +*/ +void QOpenGLPaintDevice::setDevicePixelRatio(qreal devicePixelRatio) +{ + d_ptr->devicePixelRatio = devicePixelRatio; +} + /*! \reimp */ @@ -272,9 +282,9 @@ int QOpenGLPaintDevice::metric(QPaintDevice::PaintDeviceMetric metric) const case PdmDpiY: return qRound(d_ptr->dpmy * 0.0254); case PdmPhysicalDpiX: - return qRound(d_ptr->dpmx * 0.0254); + return qRound(d_ptr->dpmx * 0.0254 * d_ptr->devicePixelRatio); case PdmPhysicalDpiY: - return qRound(d_ptr->dpmy * 0.0254); + return qRound(d_ptr->dpmy * 0.0254 * d_ptr->devicePixelRatio); default: qWarning("QOpenGLPaintDevice::metric() - metric %d not known", metric); return 0; diff --git a/src/gui/opengl/qopenglpaintdevice.h b/src/gui/opengl/qopenglpaintdevice.h index 731000f131..5868a5740a 100644 --- a/src/gui/opengl/qopenglpaintdevice.h +++ b/src/gui/opengl/qopenglpaintdevice.h @@ -68,6 +68,7 @@ public: QOpenGLContext *context() const; QSize size() const; void setSize(const QSize &size); + void setDevicePixelRatio(qreal devicePixelRatio); qreal dotsPerMeterX() const; qreal dotsPerMeterY() const; diff --git a/src/plugins/platforms/ios/qiosbackingstore.mm b/src/plugins/platforms/ios/qiosbackingstore.mm index 6bae08ce2b..5ee048cb2f 100644 --- a/src/plugins/platforms/ios/qiosbackingstore.mm +++ b/src/plugins/platforms/ios/qiosbackingstore.mm @@ -71,12 +71,18 @@ void QIOSBackingStore::beginPaint(const QRegion &) m_context->makeCurrent(window()); static_cast(paintDevice())->setSize(window()->size()); + QIOSWindow *iosWindow = static_cast(window()->handle()); + static_cast(paintDevice())->setSize(window()->size() * iosWindow->devicePixelRatio()); } QPaintDevice *QIOSBackingStore::paintDevice() { - if (!m_device) - m_device = new QOpenGLPaintDevice; + if (!m_device) { + QIOSWindow *iosWindow = static_cast(window()->handle()); + QOpenGLPaintDevice *openGLDevice = new QOpenGLPaintDevice(window()->size() * iosWindow->devicePixelRatio()); + openGLDevice->setDevicePixelRatio(iosWindow->devicePixelRatio()); + m_device = openGLDevice; + } return m_device; } diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h index 3a05901ae7..cb2854d60e 100644 --- a/src/plugins/platforms/ios/qioswindow.h +++ b/src/plugins/platforms/ios/qioswindow.h @@ -90,6 +90,7 @@ public: GLuint framebufferObject(const QIOSContext &context) const; GLuint colorRenderbuffer(const QIOSContext &context) const; + qreal devicePixelRatio() const; EAGLView *nativeView() const { return m_view; } @@ -104,6 +105,7 @@ private: GLint renderbufferWidth; GLint renderbufferHeight; } m_glData; + qreal m_devicePixelRatio; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index cc016da106..e3da694bac 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -126,8 +126,7 @@ static QRect fromCGRect(const CGRect &rect) { UITouch *touch = [touches anyObject]; CGPoint locationInView = [touch locationInView:self]; - CGFloat scaleFactor = [self contentScaleFactor]; - QPoint p(locationInView.x * scaleFactor, locationInView.y * scaleFactor); + QPoint p(locationInView.x , locationInView.y); // TODO handle global touch point? for status bar? QWindowSystemInterface::handleMouseEvent(m_qioswindow->window(), (ulong)(event.timestamp*1000), p, p, buttons); @@ -204,11 +203,21 @@ QIOSWindow::QIOSWindow(QWindow *window) , m_view([[EAGLView alloc] initWithQIOSWindow:this]) , m_requestedGeometry(QPlatformWindow::geometry()) , m_glData() + , m_devicePixelRatio(1.0) { if ([[UIApplication sharedApplication].delegate isKindOfClass:[QIOSApplicationDelegate class]]) [[UIApplication sharedApplication].delegate.window.rootViewController.view addSubview:m_view]; setWindowState(window->windowState()); + + // Retina support: get screen scale factor and set it in the content view. + // This will make framebufferObject() create a 2x frame buffer on retina + // displays. Also set m_devicePixelRatio which is used for scaling the + // paint device. + if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)] == YES) { + m_devicePixelRatio = [[UIScreen mainScreen] scale]; + [m_view setContentScaleFactor : m_devicePixelRatio]; + } } QIOSWindow::~QIOSWindow() @@ -304,7 +313,8 @@ GLuint QIOSWindow::framebufferObject(const QIOSContext &context) const GLuint QIOSWindow::colorRenderbuffer(const QIOSContext &context) const { if (!m_glData.colorRenderbuffer || - m_glData.renderbufferWidth != geometry().width() || m_glData.renderbufferHeight != geometry().height()) { + m_glData.renderbufferWidth != geometry().width() * m_devicePixelRatio || + m_glData.renderbufferHeight != geometry().height() *m_devicePixelRatio) { glBindRenderbuffer(GL_RENDERBUFFER, m_glData.colorRenderbuffer); [context.nativeContext() renderbufferStorage:GL_RENDERBUFFER fromDrawable:static_cast(m_view.layer)]; @@ -329,4 +339,9 @@ GLuint QIOSWindow::colorRenderbuffer(const QIOSContext &context) const return m_glData.colorRenderbuffer; } +qreal QIOSWindow::devicePixelRatio() const +{ + return m_devicePixelRatio; +} + QT_END_NAMESPACE -- cgit v1.2.3 From 54448b2f9fb7501e9d4a8e2c8b75acb9de8f7ae0 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Wed, 12 Dec 2012 11:16:13 +0100 Subject: iOS: remove warning from unused function in QIOSEventDispatcher MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From the documentation for QAbstractEventDispatcher::flush(), this function does only make sense for X11. Change-Id: I7f445b67b283f60c9a30ac00837beb44e8205d8b Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/ios/qioseventdispatcher.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/plugins/platforms/ios/qioseventdispatcher.mm b/src/plugins/platforms/ios/qioseventdispatcher.mm index 9d455370c0..f6f60387d4 100644 --- a/src/plugins/platforms/ios/qioseventdispatcher.mm +++ b/src/plugins/platforms/ios/qioseventdispatcher.mm @@ -313,7 +313,7 @@ void QIOSEventDispatcher::interrupt() void QIOSEventDispatcher::flush() { - qDebug() << __FUNCTION__ << "not implemented"; + // X11 only. } QT_END_NAMESPACE -- cgit v1.2.3 From 5abe9aa435c316b845f4cf5f6a930eefd449f4e1 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Tue, 18 Dec 2012 10:15:39 +0100 Subject: iOS: refactor general convenience functions into new file 'qiosglobal' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some functions are needed across several files and classes. Lets place them in a common file for all to use. Change-Id: I5f9b578f948d66d10e57a835b80b5c493e07fb4c Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/plugin.pro | 6 +- src/plugins/platforms/ios/qiosglobal.h | 59 ++++++++++++++ src/plugins/platforms/ios/qiosglobal.mm | 104 ++++++++++++++++++++++++ src/plugins/platforms/ios/qiosscreen.h | 3 - src/plugins/platforms/ios/qiosscreen.mm | 49 +---------- src/plugins/platforms/ios/qiosviewcontroller.mm | 1 + src/plugins/platforms/ios/qioswindow.mm | 11 +-- 7 files changed, 170 insertions(+), 63 deletions(-) create mode 100644 src/plugins/platforms/ios/qiosglobal.h create mode 100644 src/plugins/platforms/ios/qiosglobal.mm (limited to 'src') diff --git a/src/plugins/platforms/ios/plugin.pro b/src/plugins/platforms/ios/plugin.pro index a51ac39e03..591a0a67ed 100644 --- a/src/plugins/platforms/ios/plugin.pro +++ b/src/plugins/platforms/ios/plugin.pro @@ -17,7 +17,8 @@ OBJECTIVE_SOURCES = \ qiosviewcontroller.mm \ qioscontext.mm \ qiosinputcontext.mm \ - qiostheme.mm + qiostheme.mm \ + qiosglobal.mm HEADERS = \ qiosintegration.h \ @@ -29,6 +30,7 @@ HEADERS = \ qiosviewcontroller.h \ qioscontext.h \ qiosinputcontext.h \ - qiostheme.h + qiostheme.h \ + qiosglobal.h #HEADERS = qiossoftwareinputhandler.h diff --git a/src/plugins/platforms/ios/qiosglobal.h b/src/plugins/platforms/ios/qiosglobal.h new file mode 100644 index 0000000000..cf4c89cfad --- /dev/null +++ b/src/plugins/platforms/ios/qiosglobal.h @@ -0,0 +1,59 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QIOSGLOBAL_H +#define QIOSGLOBAL_H + +#import +#import +#import +#import "qiosscreen.h" + +QT_BEGIN_NAMESPACE + +CGRect toCGRect(const QRect &rect); +QRect fromCGRect(const CGRect &rect); +Qt::ScreenOrientation toQtScreenOrientation(UIDeviceOrientation uiDeviceOrientation); +UIDeviceOrientation fromQtScreenOrientation(Qt::ScreenOrientation qtOrientation); + +QT_END_NAMESPACE + +#endif // QIOSGLOBAL_H diff --git a/src/plugins/platforms/ios/qiosglobal.mm b/src/plugins/platforms/ios/qiosglobal.mm new file mode 100644 index 0000000000..30138acc1b --- /dev/null +++ b/src/plugins/platforms/ios/qiosglobal.mm @@ -0,0 +1,104 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qiosglobal.h" +#include + +QT_BEGIN_NAMESPACE + +CGRect toCGRect(const QRect &rect) +{ + return CGRectMake(rect.x(), rect.y(), rect.width(), rect.height()); +} + +QRect fromCGRect(const CGRect &rect) +{ + return QRect(rect.origin.x, rect.origin.y, rect.size.width, rect.size.height); +} + +Qt::ScreenOrientation toQtScreenOrientation(UIDeviceOrientation uiDeviceOrientation) +{ + Qt::ScreenOrientation qtOrientation; + switch (uiDeviceOrientation) { + case UIDeviceOrientationPortraitUpsideDown: + qtOrientation = Qt::InvertedPortraitOrientation; + break; + case UIDeviceOrientationLandscapeLeft: + qtOrientation = Qt::InvertedLandscapeOrientation; + break; + case UIDeviceOrientationLandscapeRight: + qtOrientation = Qt::LandscapeOrientation; + break; + case UIDeviceOrientationFaceUp: + case UIDeviceOrientationFaceDown: + qtOrientation = static_cast(-1); // not supported ATM. + break; + default: + qtOrientation = Qt::PortraitOrientation; + break; + } + return qtOrientation; +} + +UIDeviceOrientation fromQtScreenOrientation(Qt::ScreenOrientation qtOrientation) +{ + UIDeviceOrientation uiOrientation; + switch (qtOrientation) { + case Qt::LandscapeOrientation: + uiOrientation = UIDeviceOrientationLandscapeRight; + break; + case Qt::InvertedLandscapeOrientation: + uiOrientation = UIDeviceOrientationLandscapeLeft; + break; + case Qt::InvertedPortraitOrientation: + uiOrientation = UIDeviceOrientationPortraitUpsideDown; + break; + case Qt::PrimaryOrientation: + case Qt::PortraitOrientation: + default: + uiOrientation = UIDeviceOrientationPortrait; + break; + } + return uiOrientation; +} + +QT_END_NAMESPACE + diff --git a/src/plugins/platforms/ios/qiosscreen.h b/src/plugins/platforms/ios/qiosscreen.h index 17a5c3149a..762c60e6da 100644 --- a/src/plugins/platforms/ios/qiosscreen.h +++ b/src/plugins/platforms/ios/qiosscreen.h @@ -50,9 +50,6 @@ QT_BEGIN_NAMESPACE -Qt::ScreenOrientation toQtScreenOrientation(UIDeviceOrientation uiDeviceOrientation); -UIDeviceOrientation fromQtScreenOrientation(Qt::ScreenOrientation qtOrientation); - class QIOSScreen : public QPlatformScreen { public: diff --git a/src/plugins/platforms/ios/qiosscreen.mm b/src/plugins/platforms/ios/qiosscreen.mm index a2fd10bdd4..87ddc63f4a 100644 --- a/src/plugins/platforms/ios/qiosscreen.mm +++ b/src/plugins/platforms/ios/qiosscreen.mm @@ -39,6 +39,7 @@ ** ****************************************************************************/ +#include "qiosglobal.h" #include "qiosscreen.h" #include "qioswindow.h" #include @@ -88,54 +89,6 @@ @end -QT_BEGIN_NAMESPACE - -Qt::ScreenOrientation toQtScreenOrientation(UIDeviceOrientation uiDeviceOrientation) -{ - Qt::ScreenOrientation qtOrientation; - switch (uiDeviceOrientation) { - case UIDeviceOrientationPortraitUpsideDown: - qtOrientation = Qt::InvertedPortraitOrientation; - break; - case UIDeviceOrientationLandscapeLeft: - qtOrientation = Qt::InvertedLandscapeOrientation; - break; - case UIDeviceOrientationLandscapeRight: - qtOrientation = Qt::LandscapeOrientation; - break; - case UIDeviceOrientationFaceUp: - case UIDeviceOrientationFaceDown: - qtOrientation = static_cast(-1); // not supported ATM. - break; - default: - qtOrientation = Qt::PortraitOrientation; - break; - } - return qtOrientation; -} - -UIDeviceOrientation fromQtScreenOrientation(Qt::ScreenOrientation qtOrientation) -{ - UIDeviceOrientation uiOrientation; - switch (qtOrientation) { - case Qt::LandscapeOrientation: - uiOrientation = UIDeviceOrientationLandscapeRight; - break; - case Qt::InvertedLandscapeOrientation: - uiOrientation = UIDeviceOrientationLandscapeLeft; - break; - case Qt::InvertedPortraitOrientation: - uiOrientation = UIDeviceOrientationPortraitUpsideDown; - break; - case Qt::PrimaryOrientation: - case Qt::PortraitOrientation: - default: - uiOrientation = UIDeviceOrientationPortrait; - break; - } - return uiOrientation; -} - /*! Returns the model identifier of the device. diff --git a/src/plugins/platforms/ios/qiosviewcontroller.mm b/src/plugins/platforms/ios/qiosviewcontroller.mm index 8c280d11d9..6950288912 100644 --- a/src/plugins/platforms/ios/qiosviewcontroller.mm +++ b/src/plugins/platforms/ios/qiosviewcontroller.mm @@ -44,6 +44,7 @@ #include #include #include "qiosscreen.h" +#include "qiosglobal.h" @implementation QIOSViewController diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index e3da694bac..9b10ba4e1c 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -39,6 +39,7 @@ ** ****************************************************************************/ +#include "qiosglobal.h" #include "qioswindow.h" #include "qioscontext.h" #include "qiosscreen.h" @@ -52,16 +53,6 @@ #include -static CGRect toCGRect(const QRect &rect) -{ - return CGRectMake(rect.x(), rect.y(), rect.width(), rect.height()); -} - -static QRect fromCGRect(const CGRect &rect) -{ - return QRect(rect.origin.x, rect.origin.y, rect.size.width, rect.size.height); -} - @implementation EAGLView + (Class)layerClass -- cgit v1.2.3 From b960424195634c00673d499e4719ccb4f8704ad0 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Tue, 18 Dec 2012 12:50:50 +0100 Subject: iOS: add global function 'isQtApplication' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Several places in the code we need to check if the plugin is running as a cross-platform Qt application or inside a native app. So we refactor this function to qiosglobal so we can access it from everywhere. Change-Id: I78db0dcde71b7d281868ce304867c8f876caef2a Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiosglobal.h | 1 + src/plugins/platforms/ios/qiosglobal.mm | 13 +++++++++++++ src/plugins/platforms/ios/qiosscreen.mm | 2 +- src/plugins/platforms/ios/qioswindow.mm | 2 +- 4 files changed, 16 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/plugins/platforms/ios/qiosglobal.h b/src/plugins/platforms/ios/qiosglobal.h index cf4c89cfad..7a23a2a485 100644 --- a/src/plugins/platforms/ios/qiosglobal.h +++ b/src/plugins/platforms/ios/qiosglobal.h @@ -49,6 +49,7 @@ QT_BEGIN_NAMESPACE +bool isQtApplication(); CGRect toCGRect(const QRect &rect); QRect fromCGRect(const CGRect &rect); Qt::ScreenOrientation toQtScreenOrientation(UIDeviceOrientation uiDeviceOrientation); diff --git a/src/plugins/platforms/ios/qiosglobal.mm b/src/plugins/platforms/ios/qiosglobal.mm index 30138acc1b..a8a89a1637 100644 --- a/src/plugins/platforms/ios/qiosglobal.mm +++ b/src/plugins/platforms/ios/qiosglobal.mm @@ -40,10 +40,23 @@ ****************************************************************************/ #include "qiosglobal.h" +#include "qiosapplicationdelegate.h" #include QT_BEGIN_NAMESPACE +bool isQtApplication() +{ + // Returns true if the plugin is in full control of the whole application. This means + // that we control the application delegate and the top view controller, and can take + // actions that impacts all parts of the application. The opposite means that we are + // embedded inside a native iOS application, and should be more focused on playing along + // with native UIControls, and less inclined to change structures that lies outside the + // scope of our QWindows/UIViews. + static bool isQt = ([[UIApplication sharedApplication].delegate isKindOfClass:[QIOSApplicationDelegate class]]); + return isQt; +} + CGRect toCGRect(const QRect &rect) { return CGRectMake(rect.x(), rect.y(), rect.width(), rect.height()); diff --git a/src/plugins/platforms/ios/qiosscreen.mm b/src/plugins/platforms/ios/qiosscreen.mm index 87ddc63f4a..fdf2f31ea1 100644 --- a/src/plugins/platforms/ios/qiosscreen.mm +++ b/src/plugins/platforms/ios/qiosscreen.mm @@ -139,7 +139,7 @@ QIOSScreen::QIOSScreen(unsigned int screenIndex) const qreal millimetersPerInch = 25.4; m_physicalSize = QSizeF(m_geometry.size()) / unscaledDpi * millimetersPerInch; - if ([[UIApplication sharedApplication].delegate isKindOfClass:[QIOSApplicationDelegate class]]) { + if (isQtApplication()) { // When in a non-mixed environment, let QScreen follow the current interface orientation: UIViewController *controller = [UIApplication sharedApplication].delegate.window.rootViewController; setPrimaryOrientation(toQtScreenOrientation(controller.interfaceOrientation)); diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 9b10ba4e1c..af184e2e7b 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -196,7 +196,7 @@ QIOSWindow::QIOSWindow(QWindow *window) , m_glData() , m_devicePixelRatio(1.0) { - if ([[UIApplication sharedApplication].delegate isKindOfClass:[QIOSApplicationDelegate class]]) + if (isQtApplication()) [[UIApplication sharedApplication].delegate.window.rootViewController.view addSubview:m_view]; setWindowState(window->windowState()); -- cgit v1.2.3 From 31796ca8abb8878165c7099145b08abfdf8bf1e3 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Tue, 18 Dec 2012 09:50:28 +0100 Subject: iOS: report changes to keyboard rect back to Qt MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit QInputContext expects us to report whenever the input panel changes geometry. This patch implements this. Change-Id: I9162f0d48da6925274a7489c9bcb6adab9afae82 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiosglobal.h | 1 + src/plugins/platforms/ios/qiosglobal.mm | 9 +++++++++ src/plugins/platforms/ios/qiosinputcontext.h | 1 + src/plugins/platforms/ios/qiosinputcontext.mm | 15 +++++++++++++-- src/plugins/platforms/ios/qiosscreen.mm | 4 +--- 5 files changed, 25 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/plugins/platforms/ios/qiosglobal.h b/src/plugins/platforms/ios/qiosglobal.h index 7a23a2a485..849d9bce37 100644 --- a/src/plugins/platforms/ios/qiosglobal.h +++ b/src/plugins/platforms/ios/qiosglobal.h @@ -54,6 +54,7 @@ CGRect toCGRect(const QRect &rect); QRect fromCGRect(const CGRect &rect); Qt::ScreenOrientation toQtScreenOrientation(UIDeviceOrientation uiDeviceOrientation); UIDeviceOrientation fromQtScreenOrientation(Qt::ScreenOrientation qtOrientation); +QRect fromPortraitToPrimary(const QRect &rect); QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qiosglobal.mm b/src/plugins/platforms/ios/qiosglobal.mm index a8a89a1637..f9b4b14a19 100644 --- a/src/plugins/platforms/ios/qiosglobal.mm +++ b/src/plugins/platforms/ios/qiosglobal.mm @@ -113,5 +113,14 @@ UIDeviceOrientation fromQtScreenOrientation(Qt::ScreenOrientation qtOrientation) return uiOrientation; } +QRect fromPortraitToPrimary(const QRect &rect) +{ + // UIScreen is always in portrait. Use this function to convert CGRects + // aligned with UIScreen into whatever is the current orientation of QScreen. + QScreen *screen = QGuiApplication::primaryScreen(); + return screen->isPortrait(screen->primaryOrientation()) ? rect + : QRect(rect.y(), screen->geometry().width() - rect.width() - rect.x(), rect.height(), rect.width()); +} + QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qiosinputcontext.h b/src/plugins/platforms/ios/qiosinputcontext.h index 22782d183c..ceed5ffaf2 100644 --- a/src/plugins/platforms/ios/qiosinputcontext.h +++ b/src/plugins/platforms/ios/qiosinputcontext.h @@ -56,6 +56,7 @@ public: QIOSInputContext(); ~QIOSInputContext(); + QRectF keyboardRect() const; void showInputPanel(); void hideInputPanel(); bool isInputPanelVisible() const; diff --git a/src/plugins/platforms/ios/qiosinputcontext.mm b/src/plugins/platforms/ios/qiosinputcontext.mm index 7937337e4a..89d210cb54 100644 --- a/src/plugins/platforms/ios/qiosinputcontext.mm +++ b/src/plugins/platforms/ios/qiosinputcontext.mm @@ -39,6 +39,7 @@ ** ****************************************************************************/ +#include "qiosglobal.h" #include "qiosinputcontext.h" #include "qioswindow.h" #include @@ -47,6 +48,7 @@ @public QIOSInputContext *m_context; BOOL m_keyboardVisible; + QRectF m_keyboardRect; } @end @@ -80,6 +82,10 @@ { CGRect frame; [[[notification userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] getValue:&frame]; + + m_keyboardRect = fromPortraitToPrimary(fromCGRect(frame)); + m_context->emitKeyboardRectChanged(); + BOOL visible = CGRectIntersectsRect(frame, [UIScreen mainScreen].bounds); if (m_keyboardVisible != visible) { m_keyboardVisible = visible; @@ -90,8 +96,8 @@ @end QIOSInputContext::QIOSInputContext() - : QPlatformInputContext(), - m_keyboardListener([[QIOSKeyboardListener alloc] initWithQIOSInputContext:this]) + : QPlatformInputContext() + , m_keyboardListener([[QIOSKeyboardListener alloc] initWithQIOSInputContext:this]) { } @@ -100,6 +106,11 @@ QIOSInputContext::~QIOSInputContext() [m_keyboardListener release]; } +QRectF QIOSInputContext::keyboardRect() const +{ + return m_keyboardListener->m_keyboardRect; +} + void QIOSInputContext::showInputPanel() { if (isInputPanelVisible()) diff --git a/src/plugins/platforms/ios/qiosscreen.mm b/src/plugins/platforms/ios/qiosscreen.mm index fdf2f31ea1..a0403a0d69 100644 --- a/src/plugins/platforms/ios/qiosscreen.mm +++ b/src/plugins/platforms/ios/qiosscreen.mm @@ -212,11 +212,9 @@ void QIOSScreen::setPrimaryOrientation(Qt::ScreenOrientation orientation) return; // Switching portrait/landscape means swapping width/height (and adjusting x/y): - CGRect frame = m_uiScreen.applicationFrame; - m_availableGeometry = portrait ? QRect(frame.origin.x, frame.origin.y, frame.size.width, frame.size.height) - : QRect(frame.origin.y, m_geometry.width() - frame.size.width - frame.origin.x, frame.size.height, frame.size.width); m_geometry = QRect(0, 0, m_geometry.height(), m_geometry.width()); m_physicalSize = QSizeF(m_physicalSize.height(), m_physicalSize.width()); + m_availableGeometry = fromPortraitToPrimary(fromCGRect(m_uiScreen.applicationFrame)); QWindowSystemInterface::handleScreenGeometryChange(screen(), m_geometry); QWindowSystemInterface::handleScreenAvailableGeometryChange(screen(), m_availableGeometry); -- cgit v1.2.3 From 5b452a502214a927c54b7cc6e4fb81a7c2141267 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Tue, 18 Dec 2012 12:58:43 +0100 Subject: iOS: update primary orientation when the rotation starts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We need to update primary orientation when the rotation starts, and not when it ends, so that we are in sync with the resize that happens to the backingstore upon layoutSubviews. Change-Id: I466a2d135e6c15550c6207c9659871629d748b73 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiosviewcontroller.mm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/plugins/platforms/ios/qiosviewcontroller.mm b/src/plugins/platforms/ios/qiosviewcontroller.mm index 6950288912..a441258f4e 100644 --- a/src/plugins/platforms/ios/qiosviewcontroller.mm +++ b/src/plugins/platforms/ios/qiosviewcontroller.mm @@ -67,10 +67,10 @@ return UIInterfaceOrientationMaskAll; } -- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation +- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration { - Q_UNUSED(fromInterfaceOrientation); - Qt::ScreenOrientation orientation = toQtScreenOrientation(self.interfaceOrientation); + Q_UNUSED(duration); + Qt::ScreenOrientation orientation = toQtScreenOrientation(toInterfaceOrientation); if (orientation == -1) return; -- cgit v1.2.3 From cbdd73d25d4c4aa6436591b259dec10aa4f74b0d Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Tue, 18 Dec 2012 13:52:13 +0100 Subject: iOS: bugfix portraitToPrimary global function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit QScreen geometry and orientation is updated a bit after we change geometry in QPlatformScreen, which this time was enough to break availableGeometry. Since this function is for internal use, we let it be based on internal data. Change-Id: I7701b0a6043839c89c01e87242decb8a739d00f1 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiosglobal.mm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/plugins/platforms/ios/qiosglobal.mm b/src/plugins/platforms/ios/qiosglobal.mm index f9b4b14a19..69547fb2a1 100644 --- a/src/plugins/platforms/ios/qiosglobal.mm +++ b/src/plugins/platforms/ios/qiosglobal.mm @@ -117,9 +117,9 @@ QRect fromPortraitToPrimary(const QRect &rect) { // UIScreen is always in portrait. Use this function to convert CGRects // aligned with UIScreen into whatever is the current orientation of QScreen. - QScreen *screen = QGuiApplication::primaryScreen(); - return screen->isPortrait(screen->primaryOrientation()) ? rect - : QRect(rect.y(), screen->geometry().width() - rect.width() - rect.x(), rect.height(), rect.width()); + QRect geometry = QGuiApplication::primaryScreen()->handle()->geometry(); + return geometry.width() < geometry.height() ? rect + : QRect(rect.y(), geometry.width() - rect.width() - rect.x(), rect.height(), rect.width()); } QT_END_NAMESPACE -- cgit v1.2.3 From 2dea9fdc3a04ccc9759427c6450e88cb78003381 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Wed, 19 Dec 2012 09:15:27 +0100 Subject: iOS: add convenience function to get to the root QIOSViewController MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It seems that we need to access our view controller from many places, and the syntax to do so is tricky to remember. So lets just add it to our global functions, with the added bonus of a using a little cache. Note: many of these functions could be made inline, but since one concern of the plugin will be the end size of the app, I prefer to trade size for speed at this point. We can always change this later. Change-Id: I578ea9ae8218d23d635b7728a930763ca53c4eaa Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiosglobal.h | 4 ++++ src/plugins/platforms/ios/qiosglobal.mm | 8 ++++++++ src/plugins/platforms/ios/qiosscreen.mm | 4 ++-- src/plugins/platforms/ios/qioswindow.mm | 2 +- 4 files changed, 15 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/plugins/platforms/ios/qiosglobal.h b/src/plugins/platforms/ios/qiosglobal.h index 849d9bce37..86377e7c64 100644 --- a/src/plugins/platforms/ios/qiosglobal.h +++ b/src/plugins/platforms/ios/qiosglobal.h @@ -47,9 +47,13 @@ #import #import "qiosscreen.h" +@class QIOSViewController; + QT_BEGIN_NAMESPACE bool isQtApplication(); +QIOSViewController *rootViewController(); + CGRect toCGRect(const QRect &rect); QRect fromCGRect(const CGRect &rect); Qt::ScreenOrientation toQtScreenOrientation(UIDeviceOrientation uiDeviceOrientation); diff --git a/src/plugins/platforms/ios/qiosglobal.mm b/src/plugins/platforms/ios/qiosglobal.mm index 69547fb2a1..cf69d8fdef 100644 --- a/src/plugins/platforms/ios/qiosglobal.mm +++ b/src/plugins/platforms/ios/qiosglobal.mm @@ -41,6 +41,7 @@ #include "qiosglobal.h" #include "qiosapplicationdelegate.h" +#include "qiosviewcontroller.h" #include QT_BEGIN_NAMESPACE @@ -57,6 +58,13 @@ bool isQtApplication() return isQt; } +QIOSViewController *rootViewController() +{ + static QIOSViewController *c = isQtApplication() ? + static_cast([UIApplication sharedApplication].delegate.window.rootViewController) : nil; + return c; +} + CGRect toCGRect(const QRect &rect) { return CGRectMake(rect.x(), rect.y(), rect.width(), rect.height()); diff --git a/src/plugins/platforms/ios/qiosscreen.mm b/src/plugins/platforms/ios/qiosscreen.mm index a0403a0d69..5905f1630e 100644 --- a/src/plugins/platforms/ios/qiosscreen.mm +++ b/src/plugins/platforms/ios/qiosscreen.mm @@ -44,6 +44,7 @@ #include "qioswindow.h" #include #include "qiosapplicationdelegate.h" +#include "qiosviewcontroller.h" #include @@ -141,8 +142,7 @@ QIOSScreen::QIOSScreen(unsigned int screenIndex) if (isQtApplication()) { // When in a non-mixed environment, let QScreen follow the current interface orientation: - UIViewController *controller = [UIApplication sharedApplication].delegate.window.rootViewController; - setPrimaryOrientation(toQtScreenOrientation(controller.interfaceOrientation)); + setPrimaryOrientation(toQtScreenOrientation(rootViewController().interfaceOrientation)); } [pool release]; diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index af184e2e7b..71816f7d94 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -197,7 +197,7 @@ QIOSWindow::QIOSWindow(QWindow *window) , m_devicePixelRatio(1.0) { if (isQtApplication()) - [[UIApplication sharedApplication].delegate.window.rootViewController.view addSubview:m_view]; + [rootViewController().view addSubview:m_view]; setWindowState(window->windowState()); -- cgit v1.2.3 From bbb8db9bdb503f4f2c558e5f081c201c09d33d77 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Wed, 19 Dec 2012 10:46:22 +0100 Subject: iOS: make EAGLView private in QIOSWindow MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Not the biggest gain, but since all the members of EAGLView are declared private, we might as well move the whole interface into the source file. We can then make the members public without caring about interface readability. We will make use of this in a following patch. Change-Id: I144fb5748573ca6faf257d72597907b5c17b1e05 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qioswindow.h | 29 ++--------------------------- src/plugins/platforms/ios/qioswindow.mm | 24 +++++++++++++++++++++++- 2 files changed, 25 insertions(+), 28 deletions(-) (limited to 'src') diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h index cb2854d60e..d0df791cf0 100644 --- a/src/plugins/platforms/ios/qioswindow.h +++ b/src/plugins/platforms/ios/qioswindow.h @@ -49,31 +49,6 @@ class QIOSContext; class QIOSWindow; -@interface EAGLView : UIView -{ - UITextAutocapitalizationType autocapitalizationType; - UITextAutocorrectionType autocorrectionType; - BOOL enablesReturnKeyAutomatically; - UIKeyboardAppearance keyboardAppearance; - UIKeyboardType keyboardType; - UIReturnKeyType returnKeyType; - BOOL secureTextEntry; - QIOSWindow *m_qioswindow; -} - -- (id)initWithQIOSWindow:(QIOSWindow *)qioswindow; -- (void)sendMouseEventForTouches:(NSSet *)touches withEvent:(UIEvent *)event fakeButtons:(Qt::MouseButtons)buttons; - -@property(nonatomic) UITextAutocapitalizationType autocapitalizationType; -@property(nonatomic) UITextAutocorrectionType autocorrectionType; -@property(nonatomic) BOOL enablesReturnKeyAutomatically; -@property(nonatomic) UIKeyboardAppearance keyboardAppearance; -@property(nonatomic) UIKeyboardType keyboardType; -@property(nonatomic) UIReturnKeyType returnKeyType; -@property(nonatomic, getter=isSecureTextEntry) BOOL secureTextEntry; - -@end - QT_BEGIN_NAMESPACE class QIOSWindow : public QPlatformWindow @@ -92,10 +67,10 @@ public: GLuint colorRenderbuffer(const QIOSContext &context) const; qreal devicePixelRatio() const; - EAGLView *nativeView() const { return m_view; } + UIView *nativeView() const { return m_view; } private: - EAGLView *m_view; + UIView *m_view; QRect m_requestedGeometry; mutable struct GLData { diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 71816f7d94..220f30c485 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -53,6 +53,29 @@ #include +@interface EAGLView : UIView +{ +@public + UITextAutocapitalizationType autocapitalizationType; + UITextAutocorrectionType autocorrectionType; + BOOL enablesReturnKeyAutomatically; + UIKeyboardAppearance keyboardAppearance; + UIKeyboardType keyboardType; + UIReturnKeyType returnKeyType; + BOOL secureTextEntry; + QIOSWindow *m_qioswindow; +} + +@property(nonatomic) UITextAutocapitalizationType autocapitalizationType; +@property(nonatomic) UITextAutocorrectionType autocorrectionType; +@property(nonatomic) BOOL enablesReturnKeyAutomatically; +@property(nonatomic) UIKeyboardAppearance keyboardAppearance; +@property(nonatomic) UIKeyboardType keyboardType; +@property(nonatomic) UIReturnKeyType returnKeyType; +@property(nonatomic, getter=isSecureTextEntry) BOOL secureTextEntry; + +@end + @implementation EAGLView + (Class)layerClass @@ -186,7 +209,6 @@ @end - QT_BEGIN_NAMESPACE QIOSWindow::QIOSWindow(QWindow *window) -- cgit v1.2.3 From 646b1fd2b65f42327ff81b92ead96c634bec6468 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Wed, 19 Dec 2012 10:23:54 +0100 Subject: iOS: add UIView category to get the QWindow it represents MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adding a simple way to get the QWindow pointer from any UIView makes writing code where you only have UIView pointers a bit easier. Perhaps we should also investigate if it is worthwhile to make this category public to the application, to further enhance working in a mixed environment. Change-Id: Ic263003dc7683a8d976024cbbbc2558e8472a790 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qioswindow.h | 4 ++++ src/plugins/platforms/ios/qioswindow.mm | 11 +++++++++++ 2 files changed, 15 insertions(+) (limited to 'src') diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h index d0df791cf0..63099682f1 100644 --- a/src/plugins/platforms/ios/qioswindow.h +++ b/src/plugins/platforms/ios/qioswindow.h @@ -49,6 +49,10 @@ class QIOSContext; class QIOSWindow; +@interface UIView (QIOS) +@property(readonly) QWindow *qwindow; +@end + QT_BEGIN_NAMESPACE class QIOSWindow : public QPlatformWindow diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 220f30c485..d79c1de461 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -209,6 +209,17 @@ @end +@implementation UIView (QIOS) + +- (QWindow *)qwindow +{ + if ([self isKindOfClass:[EAGLView class]]) + return static_cast(self)->m_qioswindow->window(); + return nil; +} + +@end + QT_BEGIN_NAMESPACE QIOSWindow::QIOSWindow(QWindow *window) -- cgit v1.2.3 From 1ff571142d5c06e91a1698d635ab092bbcf393cf Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Wed, 19 Dec 2012 11:05:27 +0100 Subject: iOS: activate next window when active window hides MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since the OS does not handle window management for us, we need to handle this ourselves. So when a QWindow is closed or hidden, we transfer activation to the top-most visible window. This will fix application unresponsive after closing a dialog. Change-Id: I83f836ebafa71edca5ab5ae3a2bdba7cd1decbc1 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qioswindow.mm | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index d79c1de461..53da97e12d 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -260,7 +260,21 @@ QIOSWindow::~QIOSWindow() void QIOSWindow::setVisible(bool visible) { QPlatformWindow::setVisible(visible); - [m_view setHidden:!visible]; + m_view.hidden = !visible; + + if (isQtApplication() && !visible) { + // Activate top-most visible QWindow: + NSArray *subviews = rootViewController().view.subviews; + for (int i = int(subviews.count) - 1; i >= 0; --i) { + UIView *view = [subviews objectAtIndex:i]; + if (!view.hidden) { + if (QWindow *window = view.qwindow) { + QWindowSystemInterface::handleWindowActivated(window); + break; + } + } + } + } } void QIOSWindow::setGeometry(const QRect &rect) -- cgit v1.2.3 From 9acae5ce0bfe94bde2711986ccebadf12e9a8a7a Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Wed, 19 Dec 2012 11:19:37 +0100 Subject: iOS: clean-up header includes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Try to keep qiosglobal.h free from unnecessary includes, since its typically included from many different locations. Change-Id: I6638bcaef1189b3eee3dbd5f744c15f8f7858d71 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiosglobal.h | 4 +--- src/plugins/platforms/ios/qiosglobal.mm | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/plugins/platforms/ios/qiosglobal.h b/src/plugins/platforms/ios/qiosglobal.h index 86377e7c64..3fe426c901 100644 --- a/src/plugins/platforms/ios/qiosglobal.h +++ b/src/plugins/platforms/ios/qiosglobal.h @@ -43,9 +43,7 @@ #define QIOSGLOBAL_H #import -#import -#import -#import "qiosscreen.h" +#include @class QIOSViewController; diff --git a/src/plugins/platforms/ios/qiosglobal.mm b/src/plugins/platforms/ios/qiosglobal.mm index cf69d8fdef..712968d216 100644 --- a/src/plugins/platforms/ios/qiosglobal.mm +++ b/src/plugins/platforms/ios/qiosglobal.mm @@ -42,7 +42,7 @@ #include "qiosglobal.h" #include "qiosapplicationdelegate.h" #include "qiosviewcontroller.h" -#include +#include "qiosscreen.h" QT_BEGIN_NAMESPACE -- cgit v1.2.3 From 25ce3a021ba3007ec0d2f059c5ec7fa259bdae83 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Wed, 19 Dec 2012 12:06:10 +0100 Subject: iOS: make QWindow views hidden by default MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Qt will tell us when the window should be visible. Showing all windows by default makes e.g the desktop widget visible as well, which causes problems with activation of windows. Change-Id: Ibf2283bc5f009df7ff23126f4dd04ec898141720 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qioswindow.mm | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 53da97e12d..4b4871dd64 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -109,6 +109,9 @@ keyboardType = UIKeyboardTypeDefault; returnKeyType = UIReturnKeyDone; secureTextEntry = NO; + + if (isQtApplication()) + self.hidden = YES; } return self; -- cgit v1.2.3 From e30659aaf500a2186dfe67f29ce57bea5bf86b76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Fri, 21 Dec 2012 15:06:55 +0100 Subject: iOS: Fix style nitpicks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I670567f1793b5548393a3b315650bf34a0a3880e Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/ios/qioswindow.mm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 4b4871dd64..9c814ac924 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -243,7 +243,7 @@ QIOSWindow::QIOSWindow(QWindow *window) // paint device. if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)] == YES) { m_devicePixelRatio = [[UIScreen mainScreen] scale]; - [m_view setContentScaleFactor : m_devicePixelRatio]; + [m_view setContentScaleFactor: m_devicePixelRatio]; } } @@ -355,7 +355,7 @@ GLuint QIOSWindow::colorRenderbuffer(const QIOSContext &context) const { if (!m_glData.colorRenderbuffer || m_glData.renderbufferWidth != geometry().width() * m_devicePixelRatio || - m_glData.renderbufferHeight != geometry().height() *m_devicePixelRatio) { + m_glData.renderbufferHeight != geometry().height() * m_devicePixelRatio) { glBindRenderbuffer(GL_RENDERBUFFER, m_glData.colorRenderbuffer); [context.nativeContext() renderbufferStorage:GL_RENDERBUFFER fromDrawable:static_cast(m_view.layer)]; -- cgit v1.2.3 From b05c20b4f33b35c8b3428caf2ee59675d858d5ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Tue, 25 Dec 2012 21:44:13 +0100 Subject: iOS: Don't check for existing window in QIOSMainWrapperApplicationDelegate The delegate is only used when we control the application, so we know that there isn't any window yet. Change-Id: Ibd774cb4fd8ceaab6a181769d2792b569f490495 Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qtmain.mm | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/plugins/platforms/ios/qtmain.mm b/src/plugins/platforms/ios/qtmain.mm index 61756edc93..7cc96f54b1 100644 --- a/src/plugins/platforms/ios/qtmain.mm +++ b/src/plugins/platforms/ios/qtmain.mm @@ -55,20 +55,16 @@ extern int qt_main(int argc, char *argv[]); - (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions { - // We may have a window already from a NIB or storyboard - if (!self.window) { - // If not, we create one ourselves - self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; - QIOSViewController *controller = [[QIOSViewController alloc] init]; - self.window.rootViewController = controller; - controller.view = [[UIView alloc] init]; + self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; + QIOSViewController *controller = [[QIOSViewController alloc] init]; + self.window.rootViewController = controller; + controller.view = [[UIView alloc] init]; - // Aid debugging during development - self.window.backgroundColor = [UIColor cyanColor]; - self.window.rootViewController.view.backgroundColor = [UIColor magentaColor]; + // Aid debugging during development + self.window.backgroundColor = [UIColor cyanColor]; + self.window.rootViewController.view.backgroundColor = [UIColor magentaColor]; - [self.window makeKeyAndVisible]; - } + [self.window makeKeyAndVisible]; // We schedule the main-redirection for the next eventloop pass so that we // can return from this function and let UIApplicationMain finish its job. -- cgit v1.2.3 From 78fec3372ad819cc93b9cfb5bd3df2da6d792cbd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Tue, 25 Dec 2012 21:55:10 +0100 Subject: iOS: Auto-release the UIWindow and root view-controller They are retained properties. Change-Id: Id1808d93fe30950fc05e41375f00183e098bff0b Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qtmain.mm | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/plugins/platforms/ios/qtmain.mm b/src/plugins/platforms/ios/qtmain.mm index 7cc96f54b1..04151cd720 100644 --- a/src/plugins/platforms/ios/qtmain.mm +++ b/src/plugins/platforms/ios/qtmain.mm @@ -55,10 +55,9 @@ extern int qt_main(int argc, char *argv[]); - (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions { - self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; - QIOSViewController *controller = [[QIOSViewController alloc] init]; - self.window.rootViewController = controller; - controller.view = [[UIView alloc] init]; + self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease]; + self.window.rootViewController = [[[QIOSViewController alloc] init] autorelease]; + self.window.rootViewController.view = [[UIView alloc] init]; // Aid debugging during development self.window.backgroundColor = [UIColor cyanColor]; -- cgit v1.2.3 From 8a854ea804c500c2f0425784fd6a24b843016077 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Tue, 25 Dec 2012 22:27:27 +0100 Subject: iOS: Don't init our own base view for the root viewcontroller This is handled automatically by the default implementation. Change-Id: Ia9bd0143490e6f2507ede03f3654a2b0b00e3e3d Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qtmain.mm | 1 - 1 file changed, 1 deletion(-) (limited to 'src') diff --git a/src/plugins/platforms/ios/qtmain.mm b/src/plugins/platforms/ios/qtmain.mm index 04151cd720..00bb581535 100644 --- a/src/plugins/platforms/ios/qtmain.mm +++ b/src/plugins/platforms/ios/qtmain.mm @@ -57,7 +57,6 @@ extern int qt_main(int argc, char *argv[]); { self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease]; self.window.rootViewController = [[[QIOSViewController alloc] init] autorelease]; - self.window.rootViewController.view = [[UIView alloc] init]; // Aid debugging during development self.window.backgroundColor = [UIColor cyanColor]; -- cgit v1.2.3 From c77d3d78e448f519c1770c863bb0fccc6c9b7263 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Tue, 25 Dec 2012 22:31:43 +0100 Subject: iOS: Move debug background color setting and guard for release builds Change-Id: Ie9131c3dfe16045805b37bf8af9381f4f9929da6 Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qiosviewcontroller.mm | 8 ++++++++ src/plugins/platforms/ios/qtmain.mm | 4 ++-- 2 files changed, 10 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/plugins/platforms/ios/qiosviewcontroller.mm b/src/plugins/platforms/ios/qiosviewcontroller.mm index a441258f4e..c85058743c 100644 --- a/src/plugins/platforms/ios/qiosviewcontroller.mm +++ b/src/plugins/platforms/ios/qiosviewcontroller.mm @@ -48,6 +48,14 @@ @implementation QIOSViewController +- (void)viewDidLoad +{ +#ifdef QT_DEBUG + if (!self.nibName) + self.view.backgroundColor = [UIColor magentaColor]; +#endif +} + -(BOOL)shouldAutorotate { // For now we assume that if the application doesn't listen to orientation diff --git a/src/plugins/platforms/ios/qtmain.mm b/src/plugins/platforms/ios/qtmain.mm index 00bb581535..10c83f4b18 100644 --- a/src/plugins/platforms/ios/qtmain.mm +++ b/src/plugins/platforms/ios/qtmain.mm @@ -58,9 +58,9 @@ extern int qt_main(int argc, char *argv[]); self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease]; self.window.rootViewController = [[[QIOSViewController alloc] init] autorelease]; - // Aid debugging during development +#ifdef QT_DEBUG self.window.backgroundColor = [UIColor cyanColor]; - self.window.rootViewController.view.backgroundColor = [UIColor magentaColor]; +#endif [self.window makeKeyAndVisible]; -- cgit v1.2.3 From 157d690b8c190f341f1fa4cb6aff4c044456e99f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Tue, 25 Dec 2012 22:56:42 +0100 Subject: iOS: Don't build qiosviewcontroller.mm into qtmain plugin It's already built as part of the iOS platform plugin. Change-Id: I5a97e8723b566b9ef15aafce374be35f01e6cf08 Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qtmain.pro | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'src') diff --git a/src/plugins/platforms/ios/qtmain.pro b/src/plugins/platforms/ios/qtmain.pro index 5c290b6c00..cbcb272217 100644 --- a/src/plugins/platforms/ios/qtmain.pro +++ b/src/plugins/platforms/ios/qtmain.pro @@ -5,7 +5,4 @@ load(qt_plugin) QT += gui-private -OBJECTIVE_SOURCES = qtmain.mm \ - qiosviewcontroller.mm - -HEADERS = qiosviewcontroller.h +OBJECTIVE_SOURCES = qtmain.mm -- cgit v1.2.3 From 847ac6008ca02a9acb1f4bd2159c6e4cfa332961 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Tue, 25 Dec 2012 00:21:25 +0100 Subject: iOS: Move handling of FBOs to QIOSContext instead of QIOSWindow MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The lifetime of an FBO is tied to its context, so letting each window manage its own FBO failed when the window tried to delete the FBO at destruction time without the proper context being current, or even available anymore. We solve this by moving all handling of FBOs to the context itself, which is fine as we're exposing the necessary bits from the window to allocate storage based on its layer. Change-Id: I8c7c96cf63d6b667527c816f10ac2f4ff6a05e0c Reviewed-by: Tor Arne Vestbø Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qioscontext.h | 21 +++++-- src/plugins/platforms/ios/qioscontext.mm | 100 +++++++++++++++++++++++++++---- src/plugins/platforms/ios/qioswindow.h | 11 +--- src/plugins/platforms/ios/qioswindow.mm | 65 ++------------------ 4 files changed, 113 insertions(+), 84 deletions(-) (limited to 'src') diff --git a/src/plugins/platforms/ios/qioscontext.h b/src/plugins/platforms/ios/qioscontext.h index b45917832c..082ec4794c 100644 --- a/src/plugins/platforms/ios/qioscontext.h +++ b/src/plugins/platforms/ios/qioscontext.h @@ -48,8 +48,10 @@ QT_BEGIN_NAMESPACE -class QIOSContext : public QPlatformOpenGLContext +class QIOSContext : public QObject, public QPlatformOpenGLContext { + Q_OBJECT + public: QIOSContext(QOpenGLContext *context); ~QIOSContext(); @@ -62,15 +64,26 @@ public: void doneCurrent(); GLuint defaultFramebufferObject(QPlatformSurface *) const; - GLuint defaultColorRenderbuffer(QPlatformSurface *) const; - QFunctionPointer getProcAddress(const QByteArray &procName); - EAGLContext *nativeContext() const; +private Q_SLOTS: + void windowDestroyed(QObject *object); private: EAGLContext *m_eaglContext; QSurfaceFormat m_format; + + struct FramebufferObject { + GLuint handle; + GLuint colorRenderbuffer; + GLuint depthRenderbuffer; + GLint renderbufferWidth; + GLint renderbufferHeight; + }; + + static void deleteBuffers(const FramebufferObject &framebufferObject); + + mutable QHash m_framebufferObjects; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qioscontext.mm b/src/plugins/platforms/ios/qioscontext.mm index 00629a84ab..dc431b57dd 100644 --- a/src/plugins/platforms/ios/qioscontext.mm +++ b/src/plugins/platforms/ios/qioscontext.mm @@ -70,12 +70,25 @@ QIOSContext::QIOSContext(QOpenGLContext *context) QIOSContext::~QIOSContext() { - if ([EAGLContext currentContext] == m_eaglContext) - doneCurrent(); + [EAGLContext setCurrentContext:m_eaglContext]; + + foreach (const FramebufferObject &framebufferObject, m_framebufferObjects) + deleteBuffers(framebufferObject); + [EAGLContext setCurrentContext:nil]; [m_eaglContext release]; } +void QIOSContext::deleteBuffers(const FramebufferObject &framebufferObject) +{ + if (framebufferObject.handle) + glDeleteFramebuffers(1, &framebufferObject.handle); + if (framebufferObject.colorRenderbuffer) + glDeleteRenderbuffers(1, &framebufferObject.colorRenderbuffer); + if (framebufferObject.depthRenderbuffer) + glDeleteRenderbuffers(1, &framebufferObject.depthRenderbuffer); +} + QSurfaceFormat QIOSContext::format() const { return m_format; @@ -88,8 +101,7 @@ bool QIOSContext::makeCurrent(QPlatformSurface *surface) [EAGLContext setCurrentContext:m_eaglContext]; glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebufferObject(surface)); - // Ensures render buffers are set up and match the size of the window - return defaultColorRenderbuffer(surface) != 0; + return true; } void QIOSContext::doneCurrent() @@ -100,20 +112,86 @@ void QIOSContext::doneCurrent() void QIOSContext::swapBuffers(QPlatformSurface *surface) { Q_ASSERT(surface && surface->surface()->surfaceType() == QSurface::OpenGLSurface); + Q_ASSERT(surface->surface()->surfaceClass() == QSurface::Window); + QWindow *window = static_cast(surface->surface()); + Q_ASSERT(m_framebufferObjects.contains(window)); [EAGLContext setCurrentContext:m_eaglContext]; - glBindRenderbuffer(GL_RENDERBUFFER, defaultColorRenderbuffer(surface)); + glBindRenderbuffer(GL_RENDERBUFFER, m_framebufferObjects[window].colorRenderbuffer); [m_eaglContext presentRenderbuffer:GL_RENDERBUFFER]; } GLuint QIOSContext::defaultFramebufferObject(QPlatformSurface *surface) const { - return static_cast(surface)->framebufferObject(*this); + Q_ASSERT(surface && surface->surface()->surfaceClass() == QSurface::Window); + QWindow *window = static_cast(surface->surface()); + + FramebufferObject &framebufferObject = m_framebufferObjects[window]; + + // Set up an FBO for the window if it hasn't been created yet + if (!framebufferObject.handle) { + [EAGLContext setCurrentContext:m_eaglContext]; + + glGenFramebuffers(1, &framebufferObject.handle); + glBindFramebuffer(GL_FRAMEBUFFER, framebufferObject.handle); + + glGenRenderbuffers(1, &framebufferObject.colorRenderbuffer); + glBindRenderbuffer(GL_RENDERBUFFER, framebufferObject.colorRenderbuffer); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, + framebufferObject.colorRenderbuffer); + + if (m_format.depthBufferSize() > 0 || m_format.stencilBufferSize() > 0) { + glGenRenderbuffers(1, &framebufferObject.depthRenderbuffer); + glBindRenderbuffer(GL_RENDERBUFFER, framebufferObject.depthRenderbuffer); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, + framebufferObject.depthRenderbuffer); + + if (m_format.stencilBufferSize() > 0) + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, + framebufferObject.depthRenderbuffer); + } + + connect(window, SIGNAL(destroyed(QObject*)), this, SLOT(windowDestroyed(QObject*))); + } + + // Ensure that the FBO's buffers match the size of the window + QIOSWindow *platformWindow = static_cast(surface); + if (framebufferObject.renderbufferWidth != platformWindow->effectiveWidth() || + framebufferObject.renderbufferHeight != platformWindow->effectiveHeight()) { + + glBindRenderbuffer(GL_RENDERBUFFER, framebufferObject.colorRenderbuffer); + CAEAGLLayer *layer = static_cast(platformWindow->nativeView().layer); + [m_eaglContext renderbufferStorage:GL_RENDERBUFFER fromDrawable:layer]; + + glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &framebufferObject.renderbufferWidth); + glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &framebufferObject.renderbufferHeight); + + if (framebufferObject.depthRenderbuffer) { + glBindRenderbuffer(GL_RENDERBUFFER, framebufferObject.depthRenderbuffer); + + // FIXME: Support more fine grained control over depth/stencil buffer sizes + if (m_format.stencilBufferSize() > 0) + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, + framebufferObject.renderbufferWidth, framebufferObject.renderbufferHeight); + else + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, + framebufferObject.renderbufferWidth, framebufferObject.renderbufferHeight); + } + + if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) + NSLog(@"Failed to make complete framebuffer object %x", glCheckFramebufferStatus(GL_FRAMEBUFFER)); + } + + return framebufferObject.handle; } -GLuint QIOSContext::defaultColorRenderbuffer(QPlatformSurface *surface) const +void QIOSContext::windowDestroyed(QObject *object) { - return static_cast(surface)->colorRenderbuffer(*this); + QWindow *window = static_cast(object); + if (m_framebufferObjects.contains(window)) { + deleteBuffers(m_framebufferObjects[window]); + m_framebufferObjects.remove(window); + } } QFunctionPointer QIOSContext::getProcAddress(const QByteArray& functionName) @@ -121,7 +199,5 @@ QFunctionPointer QIOSContext::getProcAddress(const QByteArray& functionName) return reinterpret_cast(dlsym(RTLD_NEXT, functionName.constData())); } -EAGLContext *QIOSContext::nativeContext() const -{ - return m_eaglContext; -} +#include "moc_qioscontext.cpp" + diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h index 63099682f1..1f36c525ce 100644 --- a/src/plugins/platforms/ios/qioswindow.h +++ b/src/plugins/platforms/ios/qioswindow.h @@ -67,9 +67,9 @@ public: void handleContentOrientationChange(Qt::ScreenOrientation orientation); void setVisible(bool visible); - GLuint framebufferObject(const QIOSContext &context) const; - GLuint colorRenderbuffer(const QIOSContext &context) const; qreal devicePixelRatio() const; + int effectiveWidth() const; + int effectiveHeight() const; UIView *nativeView() const { return m_view; } @@ -77,13 +77,6 @@ private: UIView *m_view; QRect m_requestedGeometry; - mutable struct GLData { - GLuint framebufferObject; - GLuint colorRenderbuffer; - GLuint depthRenderbuffer; - GLint renderbufferWidth; - GLint renderbufferHeight; - } m_glData; qreal m_devicePixelRatio; }; diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 9c814ac924..88debb7c33 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -229,7 +229,6 @@ QIOSWindow::QIOSWindow(QWindow *window) : QPlatformWindow(window) , m_view([[EAGLView alloc] initWithQIOSWindow:this]) , m_requestedGeometry(QPlatformWindow::geometry()) - , m_glData() , m_devicePixelRatio(1.0) { if (isQtApplication()) @@ -249,13 +248,6 @@ QIOSWindow::QIOSWindow(QWindow *window) QIOSWindow::~QIOSWindow() { - if (m_glData.framebufferObject) - glDeleteFramebuffers(1, &m_glData.framebufferObject); - if (m_glData.colorRenderbuffer) - glDeleteRenderbuffers(1, &m_glData.colorRenderbuffer); - if (m_glData.depthRenderbuffer) - glDeleteRenderbuffers(1, &m_glData.depthRenderbuffer); - [m_view removeFromSuperview]; [m_view release]; } @@ -325,64 +317,19 @@ void QIOSWindow::handleContentOrientationChange(Qt::ScreenOrientation orientatio [[UIApplication sharedApplication] setStatusBarOrientation:uiOrientation animated:NO]; } -GLuint QIOSWindow::framebufferObject(const QIOSContext &context) const +qreal QIOSWindow::devicePixelRatio() const { - if (!m_glData.framebufferObject) { - [EAGLContext setCurrentContext:context.nativeContext()]; - - glGenFramebuffers(1, &m_glData.framebufferObject); - glBindFramebuffer(GL_FRAMEBUFFER, m_glData.framebufferObject); - - glGenRenderbuffers(1, &m_glData.colorRenderbuffer); - glBindRenderbuffer(GL_RENDERBUFFER, m_glData.colorRenderbuffer); - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_glData.colorRenderbuffer); - - QSurfaceFormat requestedFormat = context.format(); - if (requestedFormat.depthBufferSize() > 0 || requestedFormat.stencilBufferSize() > 0) { - glGenRenderbuffers(1, &m_glData.depthRenderbuffer); - glBindRenderbuffer(GL_RENDERBUFFER, m_glData.depthRenderbuffer); - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_glData.depthRenderbuffer); - - if (requestedFormat.stencilBufferSize() > 0) - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_glData.depthRenderbuffer); - } - } - - return m_glData.framebufferObject; + return m_devicePixelRatio; } -GLuint QIOSWindow::colorRenderbuffer(const QIOSContext &context) const +int QIOSWindow::effectiveWidth() const { - if (!m_glData.colorRenderbuffer || - m_glData.renderbufferWidth != geometry().width() * m_devicePixelRatio || - m_glData.renderbufferHeight != geometry().height() * m_devicePixelRatio) { - - glBindRenderbuffer(GL_RENDERBUFFER, m_glData.colorRenderbuffer); - [context.nativeContext() renderbufferStorage:GL_RENDERBUFFER fromDrawable:static_cast(m_view.layer)]; - - glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &m_glData.renderbufferWidth); - glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &m_glData.renderbufferHeight); - - if (m_glData.depthRenderbuffer) { - glBindRenderbuffer(GL_RENDERBUFFER, m_glData.depthRenderbuffer); - - // FIXME: Support more fine grained control over depth/stencil buffer sizes - if (context.format().stencilBufferSize() > 0) - glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, m_glData.renderbufferWidth, m_glData.renderbufferHeight); - else - glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, m_glData.renderbufferWidth, m_glData.renderbufferHeight); - } - - if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) - NSLog(@"Failed to make complete framebuffer object %x", glCheckFramebufferStatus(GL_FRAMEBUFFER)); - } - - return m_glData.colorRenderbuffer; + return geometry().width() * m_devicePixelRatio; } -qreal QIOSWindow::devicePixelRatio() const +int QIOSWindow::effectiveHeight() const { - return m_devicePixelRatio; + return geometry().height() * m_devicePixelRatio; } QT_END_NAMESPACE -- cgit v1.2.3 From 16e8eca3621b89730f13e07c258fb8a4ae68a1ce Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Wed, 2 Jan 2013 11:03:59 +0100 Subject: iOS: transfer focus to the window touched MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since our QWindows are UIViews rather than UIWindows, we need to implement window activation manually. This patch will ensure that the window touched by the user also gets keyboard focus. Change-Id: I9390c5c8e50a4b066cd1320a2a044e02f2a9f75d Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qioswindow.mm | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src') diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 88debb7c33..c7c27c08ce 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -151,6 +151,11 @@ - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { + // Transfer focus to the touched window: + QWindow *window = m_qioswindow->window(); + if (window != QGuiApplication::focusWindow()) + QWindowSystemInterface::handleWindowActivated(window); + [self sendMouseEventForTouches:touches withEvent:event fakeButtons:Qt::LeftButton]; } -- cgit v1.2.3 From 7150e8f51f44b6299728c5bdfb8cb5b54b8d1141 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Mon, 14 Jan 2013 15:41:33 +0100 Subject: iOS: Use 72 DPI for font size conversion This matches how UIKit behaves Change-Id: I13fd2578cac84e57b6be29c42ddee414b7ee9cb9 Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qiosscreen.h | 1 + src/plugins/platforms/ios/qiosscreen.mm | 5 +++++ 2 files changed, 6 insertions(+) (limited to 'src') diff --git a/src/plugins/platforms/ios/qiosscreen.h b/src/plugins/platforms/ios/qiosscreen.h index 762c60e6da..bbc3eb7432 100644 --- a/src/plugins/platforms/ios/qiosscreen.h +++ b/src/plugins/platforms/ios/qiosscreen.h @@ -63,6 +63,7 @@ public: int depth() const; QImage::Format format() const; QSizeF physicalSize() const; + QDpi logicalDpi() const; Qt::ScreenOrientation nativeOrientation() const; Qt::ScreenOrientation orientation() const; diff --git a/src/plugins/platforms/ios/qiosscreen.mm b/src/plugins/platforms/ios/qiosscreen.mm index 5905f1630e..f3585407ce 100644 --- a/src/plugins/platforms/ios/qiosscreen.mm +++ b/src/plugins/platforms/ios/qiosscreen.mm @@ -178,6 +178,11 @@ QSizeF QIOSScreen::physicalSize() const return m_physicalSize; } +QDpi QIOSScreen::logicalDpi() const +{ + return QDpi(72, 72); +} + Qt::ScreenOrientation QIOSScreen::nativeOrientation() const { return Qt::PortraitOrientation; -- cgit v1.2.3 From 355f064ec97cf61c7041a6d32f198a6bde800e6e Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Wed, 2 Jan 2013 12:53:43 +0100 Subject: iOS: implement QPlatformWindow::raise() and lower() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Probably not going to be the most used functions on iOS, but implemented to support old widget apps out of the box. The implementation stacks both staysOnTop and popup windows on the same level for simplicity, since iOS does not have a concept of z-ordering UIViews (UILayer has z-order, but layers belong in a different hierarchy, and cannot be used in this respect). Change-Id: Idd68e5ceea7d4eaeb3066486c47400930cebb1b0 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qioswindow.h | 5 +++++ src/plugins/platforms/ios/qioswindow.mm | 32 +++++++++++++++++++++++++++++++- 2 files changed, 36 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h index 1f36c525ce..e7b04c53eb 100644 --- a/src/plugins/platforms/ios/qioswindow.h +++ b/src/plugins/platforms/ios/qioswindow.h @@ -67,6 +67,9 @@ public: void handleContentOrientationChange(Qt::ScreenOrientation orientation); void setVisible(bool visible); + void raise() { raiseOrLower(true); } + void lower() { raiseOrLower(false); } + qreal devicePixelRatio() const; int effectiveWidth() const; int effectiveHeight() const; @@ -78,6 +81,8 @@ private: QRect m_requestedGeometry; qreal m_devicePixelRatio; + + void raiseOrLower(bool raise); }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index c7c27c08ce..5bb5048b0a 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -153,8 +153,10 @@ { // Transfer focus to the touched window: QWindow *window = m_qioswindow->window(); - if (window != QGuiApplication::focusWindow()) + if (window != QGuiApplication::focusWindow()) { + m_qioswindow->raise(); QWindowSystemInterface::handleWindowActivated(window); + } [self sendMouseEventForTouches:touches withEvent:event fakeButtons:Qt::LeftButton]; } @@ -314,6 +316,34 @@ void QIOSWindow::setWindowState(Qt::WindowState state) } } +void QIOSWindow::raiseOrLower(bool raise) +{ + // Re-insert m_view at the correct index among its sibling views (QWindows), and ensure + // that window flags (staysOnTop, popup) are respected. This function assumes that all + // sibling views are sorted correctly. Note: We sort popup and staysOnTop windows at + // the same level: + if (!isQtApplication()) + return; + + NSArray *subviews = m_view.superview.subviews; + if (subviews.count == 1) + return; + + const Qt::WindowFlags topFlag = (Qt::Popup | Qt::WindowStaysOnTopHint) & ~Qt::Dialog; + bool thisWindowIsTop = topFlag & window()->flags(); + + for (int i = int(subviews.count) - 1; i >= 0; --i) { + UIView *view = static_cast([subviews objectAtIndex:i]); + bool otherWindowIsTop = topFlag & view.qwindow->flags(); + if ((raise && (thisWindowIsTop || !otherWindowIsTop)) + || (!raise && (thisWindowIsTop && !otherWindowIsTop))) { + [m_view.superview insertSubview:m_view aboveSubview:view]; + return; + } + } + [m_view.superview insertSubview:m_view atIndex:0]; +} + void QIOSWindow::handleContentOrientationChange(Qt::ScreenOrientation orientation) { // Keep the status bar in sync with content orientation. This will ensure -- cgit v1.2.3 From e83bed82c1b58cde1f9a49ad4e4b86d8a13304f1 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Tue, 15 Jan 2013 13:22:01 +0100 Subject: iOS: raise windows that becomes visible MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When a QWindow becomes visible, it should move to front and be active. Change-Id: Icab12c6031c0cc8d791e4f8cc49b9c2d5c73100d Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qioswindow.mm | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 5bb5048b0a..488962ab66 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -264,7 +264,15 @@ void QIOSWindow::setVisible(bool visible) QPlatformWindow::setVisible(visible); m_view.hidden = !visible; - if (isQtApplication() && !visible) { + if (!isQtApplication()) + return; + + // Since iOS doesn't do window management the way a Qt application + // expects, we need to raise and activate windows ourselves: + if (visible) { + raise(); + QWindowSystemInterface::handleWindowActivated(window()); + } else { // Activate top-most visible QWindow: NSArray *subviews = rootViewController().view.subviews; for (int i = int(subviews.count) - 1; i >= 0; --i) { -- cgit v1.2.3 From 73e879660376a40fd21ded84020f2e527f22cd13 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Tue, 15 Jan 2013 14:30:20 +0100 Subject: iOS: implement QPlatformWindow::requestActivateWindow() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Dispite the name, 'requestActivateWindow' means raise and transfer focus to the window. Change-Id: Ib97321ed7ec8da90e924ff8155a95896c12160c9 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qioswindow.h | 1 + src/plugins/platforms/ios/qioswindow.mm | 20 +++++++++++++------- 2 files changed, 14 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h index e7b04c53eb..01c1978a56 100644 --- a/src/plugins/platforms/ios/qioswindow.h +++ b/src/plugins/platforms/ios/qioswindow.h @@ -69,6 +69,7 @@ public: void raise() { raiseOrLower(true); } void lower() { raiseOrLower(false); } + void requestActivateWindow(); qreal devicePixelRatio() const; int effectiveWidth() const; diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 488962ab66..59f82fb64e 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -153,10 +153,8 @@ { // Transfer focus to the touched window: QWindow *window = m_qioswindow->window(); - if (window != QGuiApplication::focusWindow()) { - m_qioswindow->raise(); - QWindowSystemInterface::handleWindowActivated(window); - } + if (window != QGuiApplication::focusWindow()) + m_qioswindow->requestActivateWindow(); [self sendMouseEventForTouches:touches withEvent:event fakeButtons:Qt::LeftButton]; } @@ -270,8 +268,7 @@ void QIOSWindow::setVisible(bool visible) // Since iOS doesn't do window management the way a Qt application // expects, we need to raise and activate windows ourselves: if (visible) { - raise(); - QWindowSystemInterface::handleWindowActivated(window()); + requestActivateWindow(); } else { // Activate top-most visible QWindow: NSArray *subviews = rootViewController().view.subviews; @@ -279,7 +276,7 @@ void QIOSWindow::setVisible(bool visible) UIView *view = [subviews objectAtIndex:i]; if (!view.hidden) { if (QWindow *window = view.qwindow) { - QWindowSystemInterface::handleWindowActivated(window); + static_cast(window->handle())->requestActivateWindow(); break; } } @@ -324,6 +321,15 @@ void QIOSWindow::setWindowState(Qt::WindowState state) } } +void QIOSWindow::requestActivateWindow() +{ + // Note that several windows can be active at the same time if they exist in the same + // hierarchy (transient children). But only one window can be QGuiApplication::focusWindow(). + // Dispite the name, 'requestActivateWindow' means raise and transfer focus to the window: + raise(); + QPlatformWindow::requestActivateWindow(); +} + void QIOSWindow::raiseOrLower(bool raise) { // Re-insert m_view at the correct index among its sibling views (QWindows), and ensure -- cgit v1.2.3 From 0a9a4e826fc0a3909481f40d77708a86be55a345 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Wed, 16 Jan 2013 10:42:31 +0100 Subject: iOS: let first responder follow the view of the focus window MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This to ensure that the keyboard does not close prematurly. This can happen if the user opens up the keyboard while typing inside one window, then switch window, continue typing while the other window gets deleted. Change-Id: I5cfb1673ccbe4d5aaa14167b7aa53451031089a1 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiosinputcontext.h | 3 +++ src/plugins/platforms/ios/qiosinputcontext.mm | 33 ++++++++++++--------------- src/plugins/platforms/ios/qioswindow.mm | 5 ++++ 3 files changed, 23 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/plugins/platforms/ios/qiosinputcontext.h b/src/plugins/platforms/ios/qiosinputcontext.h index ceed5ffaf2..176ad05733 100644 --- a/src/plugins/platforms/ios/qiosinputcontext.h +++ b/src/plugins/platforms/ios/qiosinputcontext.h @@ -61,8 +61,11 @@ public: void hideInputPanel(); bool isInputPanelVisible() const; + void focusViewChanged(UIView *view); + private: QIOSKeyboardListener *m_keyboardListener; + UIView *m_focusView; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qiosinputcontext.mm b/src/plugins/platforms/ios/qiosinputcontext.mm index 89d210cb54..c0ff3b2531 100644 --- a/src/plugins/platforms/ios/qiosinputcontext.mm +++ b/src/plugins/platforms/ios/qiosinputcontext.mm @@ -98,12 +98,14 @@ QIOSInputContext::QIOSInputContext() : QPlatformInputContext() , m_keyboardListener([[QIOSKeyboardListener alloc] initWithQIOSInputContext:this]) + , m_focusView(0) { } QIOSInputContext::~QIOSInputContext() { [m_keyboardListener release]; + [m_focusView release]; } QRectF QIOSInputContext::keyboardRect() const @@ -113,33 +115,28 @@ QRectF QIOSInputContext::keyboardRect() const void QIOSInputContext::showInputPanel() { - if (isInputPanelVisible()) - return; - // Documentation tells that one should call (and recall, if necessary) becomeFirstResponder/resignFirstResponder // to show/hide the keyboard. This is slightly inconvenient, since there exist no API to get the current first - // responder. Rather than searching for it from the top, we assume that the view backing the focus window in Qt - // is the best candidate as long as there exist no first responder from before (which the isInputPanelVisible - // test on top should catch). Note that Qt will forward keyevents to whichever QObject that needs it, regardless of - // which UIView the input actually came from. So in this respect, we're undermining iOS' responder chain. - if (QWindow *window = QGuiApplication::focusWindow()) { - QIOSWindow *qiosWindow = static_cast(window->handle()); - [qiosWindow->nativeView() becomeFirstResponder]; - } + // responder. Rather than searching for it from the top, we let the active QIOSWindow tell us which view to use. + // Note that Qt will forward keyevents to whichever QObject that needs it, regardless of which UIView the input + // actually came from. So in this respect, we're undermining iOS' responder chain. + [m_focusView becomeFirstResponder]; } void QIOSInputContext::hideInputPanel() { - if (!isInputPanelVisible()) - return; - - if (QWindow *window = QGuiApplication::focusWindow()) { - QIOSWindow *qiosWindow = static_cast(window->handle()); - [qiosWindow->nativeView() resignFirstResponder]; - } + [m_focusView resignFirstResponder]; } bool QIOSInputContext::isInputPanelVisible() const { return m_keyboardListener->m_keyboardVisible; } + +void QIOSInputContext::focusViewChanged(UIView *view) +{ + if ([m_focusView isFirstResponder]) + [view becomeFirstResponder]; + [m_focusView release]; + m_focusView = [view retain]; +} diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 59f82fb64e..c5d9cbe323 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -42,9 +42,12 @@ #include "qiosglobal.h" #include "qioswindow.h" #include "qioscontext.h" +#include "qiosinputcontext.h" #include "qiosscreen.h" #include "qiosapplicationdelegate.h" #include "qiosviewcontroller.h" +#include +#include #import @@ -327,6 +330,8 @@ void QIOSWindow::requestActivateWindow() // hierarchy (transient children). But only one window can be QGuiApplication::focusWindow(). // Dispite the name, 'requestActivateWindow' means raise and transfer focus to the window: raise(); + QPlatformInputContext *context = QGuiApplicationPrivate::platformIntegration()->inputContext(); + static_cast(context)->focusViewChanged(m_view); QPlatformWindow::requestActivateWindow(); } -- cgit v1.2.3 From f2c52d65608d238ad35ca91099a8751e0c37ef52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Tue, 22 Jan 2013 12:00:19 +0100 Subject: iOS: Implement touch events. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Track touch events during the standard [Began -> Moved -> Ended] event sequence based on the UITouch pointer which stays constant. Enable multiTouch on Qt's UIView. Mouse events should now be automatically created from (unhanded) touch events by QGuiApplication. Reviewed by: Ada Sørvig (fingerpaint app approved) Change-Id: I2aeb48c962c697d8b8337f8ceab062070c2a4240 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiosintegration.h | 3 + src/plugins/platforms/ios/qiosintegration.mm | 11 +++ src/plugins/platforms/ios/qioswindow.h | 9 +++ src/plugins/platforms/ios/qioswindow.mm | 106 ++++++++++++++++++++++++--- 4 files changed, 118 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/plugins/platforms/ios/qiosintegration.h b/src/plugins/platforms/ios/qiosintegration.h index 5ba97bff6e..054933ea44 100644 --- a/src/plugins/platforms/ios/qiosintegration.h +++ b/src/plugins/platforms/ios/qiosintegration.h @@ -44,6 +44,7 @@ #include #include +#include QT_BEGIN_NAMESPACE @@ -71,10 +72,12 @@ public: void *nativeResourceForWindow(const QByteArray &resource, QWindow *window); + QTouchDevice *touchDevice(); private: QPlatformFontDatabase *m_fontDatabase; QPlatformInputContext *m_inputContext; QPlatformScreen *m_screen; + QTouchDevice *m_touchDevice; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qiosintegration.mm b/src/plugins/platforms/ios/qiosintegration.mm index 8008c5c0b0..cbe2717c34 100644 --- a/src/plugins/platforms/ios/qiosintegration.mm +++ b/src/plugins/platforms/ios/qiosintegration.mm @@ -72,10 +72,16 @@ QIOSIntegration::QIOSIntegration() } screenAdded(m_screen); + + m_touchDevice = new QTouchDevice; + m_touchDevice->setType(QTouchDevice::TouchScreen); + m_touchDevice->setCapabilities(QTouchDevice::Position | QTouchDevice::NormalizedPosition); + QWindowSystemInterface::registerTouchDevice(m_touchDevice); } QIOSIntegration::~QIOSIntegration() { + delete m_touchDevice; } QPlatformWindow *QIOSIntegration::createPlatformWindow(QWindow *window) const @@ -157,4 +163,9 @@ void *QIOSIntegration::nativeResourceForWindow(const QByteArray &resource, QWind return 0; } +QTouchDevice *QIOSIntegration::touchDevice() +{ + return m_touchDevice; +} + QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h index 01c1978a56..b3a94a8d0e 100644 --- a/src/plugins/platforms/ios/qioswindow.h +++ b/src/plugins/platforms/ios/qioswindow.h @@ -43,6 +43,7 @@ #define QIOSWINDOW_H #include +#include #import @@ -77,8 +78,16 @@ public: UIView *nativeView() const { return m_view; } + QList &touchPoints() { return m_touchPoints; } + QHash &activeTouches() { return m_activeTouches; } + int &touchId() { return m_touchId; } + private: UIView *m_view; + QList m_touchPoints; + QHash m_activeTouches; + int m_touchId; + QRect m_requestedGeometry; qreal m_devicePixelRatio; diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index c5d9cbe323..91e75bc660 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -46,6 +46,7 @@ #include "qiosscreen.h" #include "qiosapplicationdelegate.h" #include "qiosviewcontroller.h" +#include "qiosintegration.h" #include #include @@ -115,6 +116,8 @@ if (isQtApplication()) self.hidden = YES; + + self.multipleTouchEnabled = YES; } return self; @@ -142,39 +145,119 @@ [super layoutSubviews]; } -- (void)sendMouseEventForTouches:(NSSet *)touches withEvent:(UIEvent *)event fakeButtons:(Qt::MouseButtons)buttons +/* + Touch handling: + + UIKit generates [Began -> Moved -> Ended] event sequences for + each touch point. The iOS plugin tracks each individual + touch and assigns it an id for use by Qt. The id counter is + incremented on each began and decrement as follows: + 1) by one when the most recent touch ends. + 2) to zero when all touches ends. + + The TouchPoint list is reused between events. +*/ +- (void)updateTouchList:(NSSet *)touches withState:(Qt::TouchPointState)state { - UITouch *touch = [touches anyObject]; - CGPoint locationInView = [touch locationInView:self]; - QPoint p(locationInView.x , locationInView.y); + QList &touchPoints = m_qioswindow->touchPoints(); + QHash &activeTouches = m_qioswindow->activeTouches(); + + // Mark all touch points as stationary + for (QList::iterator it = touchPoints.begin(); it != touchPoints.end(); ++it) + it->state = Qt::TouchPointStationary; + + // Update changed touch points with the new state + for (UITouch *touch in touches) { + const int touchId = activeTouches.value(touch); + QWindowSystemInterface::TouchPoint &touchPoint = touchPoints[touchId]; + touchPoint.state = state; + if (state == Qt::TouchPointPressed) + touchPoint.pressure = 1.0; + else if (state == Qt::TouchPointReleased) + touchPoint.pressure = 0.0; + + // Set position + CGPoint location = [touch locationInView:self]; + touchPoint.area = QRectF(location.x, location.y, 0, 0); + QSize viewSize = fromCGRect(self.frame).size(); + touchPoint.normalPosition = QPointF(location.x / viewSize.width(), location.y / viewSize.height()); + } +} - // TODO handle global touch point? for status bar? - QWindowSystemInterface::handleMouseEvent(m_qioswindow->window(), (ulong)(event.timestamp*1000), p, p, buttons); +- (void) sendTouchEventWithTimestamp:(ulong)timeStamp +{ + // Send touch event synchronously + QIOSIntegration *iosIntegration = static_cast(QGuiApplicationPrivate::platformIntegration()); + QWindowSystemInterface::handleTouchEvent(m_qioswindow->window(), timeStamp, + iosIntegration->touchDevice(), m_qioswindow->touchPoints()); + QWindowSystemInterface::flushWindowSystemEvents(); } - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { - // Transfer focus to the touched window: QWindow *window = m_qioswindow->window(); + + // Transfer focus to the touched window: if (window != QGuiApplication::focusWindow()) m_qioswindow->requestActivateWindow(); - [self sendMouseEventForTouches:touches withEvent:event fakeButtons:Qt::LeftButton]; + // Track Cocoa touch id to Qt touch id. The UITouch pointer is constant + // for the touch duration. + QHash &activeTouches = m_qioswindow->activeTouches(); + QList &touchPoints = m_qioswindow->touchPoints(); + for (UITouch *touch in touches) + activeTouches.insert(touch, m_qioswindow->touchId()++); + + // Create new touch points if needed. + int newTouchPointsNeeded = m_qioswindow->touchId() - touchPoints.count(); + for (int i = 0; i < newTouchPointsNeeded; ++i) { + QWindowSystemInterface::TouchPoint touchPoint; + touchPoint.id = touchPoints.count(); // id is the index in the touchPoints list. + touchPoints.append(touchPoint); + } + + [self updateTouchList:touches withState:Qt::TouchPointPressed]; + [self sendTouchEventWithTimestamp:ulong(event.timestamp * 1000)]; } - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { - [self sendMouseEventForTouches:touches withEvent:event fakeButtons:Qt::LeftButton]; + [self updateTouchList:touches withState:Qt::TouchPointMoved]; + [self sendTouchEventWithTimestamp:ulong(event.timestamp * 1000)]; } - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { - [self sendMouseEventForTouches:touches withEvent:event fakeButtons:Qt::NoButton]; + [self updateTouchList:touches withState:Qt::TouchPointReleased]; + [self sendTouchEventWithTimestamp:ulong(event.timestamp * 1000)]; + + // Remove ended touch points from the active set (event processing has completed at this point) + QHash &activeTouches = m_qioswindow->activeTouches(); + for (UITouch *touch in touches) { + int id = activeTouches.take(touch); + + // If this touch is the most recent touch we can reuse its id + if (id == m_qioswindow->touchId() - 1) + --m_qioswindow->touchId(); + } + + // Reset the touch id when there are no more active touches + if (activeTouches.isEmpty()) + m_qioswindow->touchId() = 0; } - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event { - [self sendMouseEventForTouches:touches withEvent:event fakeButtons:Qt::NoButton]; + Q_UNUSED(touches) // ### can a subset of the active touches be cancelled? + + // Clear current touch points + m_qioswindow->activeTouches().clear(); + m_qioswindow->touchId() = 0; + + // Send cancel touch event synchronously + QIOSIntegration *iosIntegration = static_cast(QGuiApplicationPrivate::platformIntegration()); + QWindowSystemInterface::handleTouchCancelEvent(m_qioswindow->window(), ulong(event.timestamp * 1000), iosIntegration->touchDevice()); + QWindowSystemInterface::flushWindowSystemEvents(); } @synthesize autocapitalizationType; @@ -236,6 +319,7 @@ QT_BEGIN_NAMESPACE QIOSWindow::QIOSWindow(QWindow *window) : QPlatformWindow(window) , m_view([[EAGLView alloc] initWithQIOSWindow:this]) + , m_touchId(0) , m_requestedGeometry(QPlatformWindow::geometry()) , m_devicePixelRatio(1.0) { -- cgit v1.2.3 From 38e6d5a91588bfe823ff6bcb19bd356965d328f7 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Fri, 25 Jan 2013 11:49:34 +0100 Subject: iOS: add QIOSWindow::windowLevel() to simplify window stacking MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When adding modal windows into the mix, raiseOrLower became even more messy to write. So do it the usual way instead, and add a windowLevel variable to each QIOSWindow that we can sort on. The code becomes more readable, and we can handle more window types correctly. Change-Id: I348352473a7d8cf9909c17c1b074b2fe3fab9819 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qioswindow.h | 3 ++- src/plugins/platforms/ios/qioswindow.mm | 42 +++++++++++++++++++++++++-------- 2 files changed, 34 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h index b3a94a8d0e..2d7c4c9103 100644 --- a/src/plugins/platforms/ios/qioswindow.h +++ b/src/plugins/platforms/ios/qioswindow.h @@ -89,10 +89,11 @@ private: int m_touchId; QRect m_requestedGeometry; - + int m_windowLevel; qreal m_devicePixelRatio; void raiseOrLower(bool raise); + void updateWindowLevel(); }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 91e75bc660..4aa6b8a24e 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -321,6 +321,7 @@ QIOSWindow::QIOSWindow(QWindow *window) , m_view([[EAGLView alloc] initWithQIOSWindow:this]) , m_touchId(0) , m_requestedGeometry(QPlatformWindow::geometry()) + , m_windowLevel(0) , m_devicePixelRatio(1.0) { if (isQtApplication()) @@ -355,6 +356,7 @@ void QIOSWindow::setVisible(bool visible) // Since iOS doesn't do window management the way a Qt application // expects, we need to raise and activate windows ourselves: if (visible) { + updateWindowLevel(); requestActivateWindow(); } else { // Activate top-most visible QWindow: @@ -421,10 +423,8 @@ void QIOSWindow::requestActivateWindow() void QIOSWindow::raiseOrLower(bool raise) { - // Re-insert m_view at the correct index among its sibling views (QWindows), and ensure - // that window flags (staysOnTop, popup) are respected. This function assumes that all - // sibling views are sorted correctly. Note: We sort popup and staysOnTop windows at - // the same level: + // Re-insert m_view at the correct index among its sibling views + // (QWindows) according to their current m_windowLevel: if (!isQtApplication()) return; @@ -432,14 +432,12 @@ void QIOSWindow::raiseOrLower(bool raise) if (subviews.count == 1) return; - const Qt::WindowFlags topFlag = (Qt::Popup | Qt::WindowStaysOnTopHint) & ~Qt::Dialog; - bool thisWindowIsTop = topFlag & window()->flags(); - for (int i = int(subviews.count) - 1; i >= 0; --i) { UIView *view = static_cast([subviews objectAtIndex:i]); - bool otherWindowIsTop = topFlag & view.qwindow->flags(); - if ((raise && (thisWindowIsTop || !otherWindowIsTop)) - || (!raise && (thisWindowIsTop && !otherWindowIsTop))) { + if (view.hidden || view == m_view) + continue; + int level = static_cast(view.qwindow->handle())->m_windowLevel; + if (m_windowLevel > level || (raise && m_windowLevel == level)) { [m_view.superview insertSubview:m_view aboveSubview:view]; return; } @@ -447,6 +445,30 @@ void QIOSWindow::raiseOrLower(bool raise) [m_view.superview insertSubview:m_view atIndex:0]; } +void QIOSWindow::updateWindowLevel() +{ + Qt::WindowType type = static_cast(int(window()->flags() & Qt::WindowType_Mask)); + + if (type == Qt::ToolTip) + m_windowLevel = 120; + else if (window()->flags() & Qt::WindowStaysOnTopHint) + m_windowLevel = 100; + else if (window()->isModal()) + m_windowLevel = 30; + else if (type & Qt::Popup & ~Qt::Window) + m_windowLevel = 20; + else if (type == Qt::Tool) + m_windowLevel = 10; + else + m_windowLevel = 0; + + // A window should be in at least the same m_windowLevel as its parent: + QWindow *transientParent = window()->transientParent(); + QIOSWindow *transientParentWindow = transientParent ? static_cast(transientParent->handle()) : 0; + if (transientParentWindow) + m_windowLevel = qMax(transientParentWindow->m_windowLevel, m_windowLevel); +} + void QIOSWindow::handleContentOrientationChange(Qt::ScreenOrientation orientation) { // Keep the status bar in sync with content orientation. This will ensure -- cgit v1.2.3 From 58415530aacc5ef92f0076f7dff04d4f5074c4da Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Fri, 25 Jan 2013 11:00:54 +0100 Subject: iOS: avoid activating modally blocked windows MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make sure that the user cannot activate a window that is modally shaddowed. Change-Id: Ib92be319d017460bbc1ef63ad7556cb4758dfa6c Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qioswindow.h | 1 + src/plugins/platforms/ios/qioswindow.mm | 19 ++++++++++++++++++- 2 files changed, 19 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h index 2d7c4c9103..31fd8d3185 100644 --- a/src/plugins/platforms/ios/qioswindow.h +++ b/src/plugins/platforms/ios/qioswindow.h @@ -94,6 +94,7 @@ private: void raiseOrLower(bool raise); void updateWindowLevel(); + bool blockedByModal(); }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 4aa6b8a24e..9bc2541715 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -345,6 +345,12 @@ QIOSWindow::~QIOSWindow() [m_view release]; } +bool QIOSWindow::blockedByModal() +{ + QWindow *modalWindow = QGuiApplication::modalWindow(); + return modalWindow && modalWindow != window(); +} + void QIOSWindow::setVisible(bool visible) { QPlatformWindow::setVisible(visible); @@ -355,8 +361,16 @@ void QIOSWindow::setVisible(bool visible) // Since iOS doesn't do window management the way a Qt application // expects, we need to raise and activate windows ourselves: - if (visible) { + if (visible) updateWindowLevel(); + + if (blockedByModal()) { + if (visible) + raise(); + return; + } + + if (visible) { requestActivateWindow(); } else { // Activate top-most visible QWindow: @@ -415,6 +429,9 @@ void QIOSWindow::requestActivateWindow() // Note that several windows can be active at the same time if they exist in the same // hierarchy (transient children). But only one window can be QGuiApplication::focusWindow(). // Dispite the name, 'requestActivateWindow' means raise and transfer focus to the window: + if (blockedByModal()) + return; + raise(); QPlatformInputContext *context = QGuiApplicationPrivate::platformIntegration()->inputContext(); static_cast(context)->focusViewChanged(m_view); -- cgit v1.2.3 From 60685407c208466c67830744808b8a902bd2377b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Wed, 30 Jan 2013 20:31:06 +0100 Subject: iOS: Enable retina resolution for styles MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The QStyle code uses the global qApp->devicePixelRatio(), which queries the screen, not the window. Implement QIOSScreen::devicePixelRatio(). Change-Id: I0091e5793f8d07ab7a46b6de443edd9457dcff85 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiosscreen.h | 1 + src/plugins/platforms/ios/qiosscreen.mm | 5 +++++ 2 files changed, 6 insertions(+) (limited to 'src') diff --git a/src/plugins/platforms/ios/qiosscreen.h b/src/plugins/platforms/ios/qiosscreen.h index bbc3eb7432..40c7a3ccf7 100644 --- a/src/plugins/platforms/ios/qiosscreen.h +++ b/src/plugins/platforms/ios/qiosscreen.h @@ -64,6 +64,7 @@ public: QImage::Format format() const; QSizeF physicalSize() const; QDpi logicalDpi() const; + qreal devicePixelRatio() const; Qt::ScreenOrientation nativeOrientation() const; Qt::ScreenOrientation orientation() const; diff --git a/src/plugins/platforms/ios/qiosscreen.mm b/src/plugins/platforms/ios/qiosscreen.mm index f3585407ce..5cee5a3362 100644 --- a/src/plugins/platforms/ios/qiosscreen.mm +++ b/src/plugins/platforms/ios/qiosscreen.mm @@ -183,6 +183,11 @@ QDpi QIOSScreen::logicalDpi() const return QDpi(72, 72); } +qreal QIOSScreen::devicePixelRatio() const +{ + return [m_uiScreen scale]; +} + Qt::ScreenOrientation QIOSScreen::nativeOrientation() const { return Qt::PortraitOrientation; -- cgit v1.2.3 From 4993d3ed6bff681889faec3711fffa2400b7a601 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Wed, 6 Feb 2013 11:34:14 +0100 Subject: iOS: implement QIOSWindow::winId() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I3dd7accae43bcf7d4d6dfd8b272ab65d67bd935c Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qioscontext.mm | 3 ++- src/plugins/platforms/ios/qiosintegration.mm | 2 +- src/plugins/platforms/ios/qioswindow.h | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/plugins/platforms/ios/qioscontext.mm b/src/plugins/platforms/ios/qioscontext.mm index dc431b57dd..d3966964e0 100644 --- a/src/plugins/platforms/ios/qioscontext.mm +++ b/src/plugins/platforms/ios/qioscontext.mm @@ -160,7 +160,8 @@ GLuint QIOSContext::defaultFramebufferObject(QPlatformSurface *surface) const framebufferObject.renderbufferHeight != platformWindow->effectiveHeight()) { glBindRenderbuffer(GL_RENDERBUFFER, framebufferObject.colorRenderbuffer); - CAEAGLLayer *layer = static_cast(platformWindow->nativeView().layer); + UIView *view = reinterpret_cast(platformWindow->winId()); + CAEAGLLayer *layer = static_cast(view.layer); [m_eaglContext renderbufferStorage:GL_RENDERBUFFER fromDrawable:layer]; glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &framebufferObject.renderbufferWidth); diff --git a/src/plugins/platforms/ios/qiosintegration.mm b/src/plugins/platforms/ios/qiosintegration.mm index cbe2717c34..c5fef243ce 100644 --- a/src/plugins/platforms/ios/qiosintegration.mm +++ b/src/plugins/platforms/ios/qiosintegration.mm @@ -158,7 +158,7 @@ void *QIOSIntegration::nativeResourceForWindow(const QByteArray &resource, QWind QIOSWindow *platformWindow = static_cast(window->handle()); if (lowerCaseResource == "uiview") - return platformWindow->nativeView(); + return reinterpret_cast(platformWindow->winId()); return 0; } diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h index 31fd8d3185..7a0224dab0 100644 --- a/src/plugins/platforms/ios/qioswindow.h +++ b/src/plugins/platforms/ios/qioswindow.h @@ -76,7 +76,7 @@ public: int effectiveWidth() const; int effectiveHeight() const; - UIView *nativeView() const { return m_view; } + WId winId() const { return WId(m_view); }; QList &touchPoints() { return m_touchPoints; } QHash &activeTouches() { return m_activeTouches; } -- cgit v1.2.3 From 029029fa97b8f11b2384040f12dc1ca6b31e03a6 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Mon, 4 Feb 2013 12:42:59 +0100 Subject: iOS: QIOSWindow::setParent() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I1a413d898d10b55a4d0653eae719f5bd909a01ec Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qioswindow.h | 1 + src/plugins/platforms/ios/qioswindow.mm | 14 +++++++++++--- 2 files changed, 12 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h index 7a0224dab0..cefb6f9388 100644 --- a/src/plugins/platforms/ios/qioswindow.h +++ b/src/plugins/platforms/ios/qioswindow.h @@ -65,6 +65,7 @@ public: void setGeometry(const QRect &rect); void setWindowState(Qt::WindowState state); + void setParent(const QPlatformWindow *window); void handleContentOrientationChange(Qt::ScreenOrientation orientation); void setVisible(bool visible); diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 9bc2541715..e95f392655 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -324,9 +324,7 @@ QIOSWindow::QIOSWindow(QWindow *window) , m_windowLevel(0) , m_devicePixelRatio(1.0) { - if (isQtApplication()) - [rootViewController().view addSubview:m_view]; - + setParent(parent()); setWindowState(window->windowState()); // Retina support: get screen scale factor and set it in the content view. @@ -424,6 +422,16 @@ void QIOSWindow::setWindowState(Qt::WindowState state) } } +void QIOSWindow::setParent(const QPlatformWindow *parentWindow) +{ + if (parentWindow) { + UIView *parentView = reinterpret_cast(parentWindow->winId()); + [parentView addSubview:m_view]; + } else if (isQtApplication()) { + [rootViewController().view addSubview:m_view]; + } +} + void QIOSWindow::requestActivateWindow() { // Note that several windows can be active at the same time if they exist in the same -- cgit v1.2.3 From 3eeb388b429242da8bfd9b9dc70660980f62090a Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Fri, 8 Feb 2013 13:36:24 +0100 Subject: iOS: Skip flushing child windows in QIOSBackingStore MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We skip flushing raster-based child windows, to avoid the extra cost of copying from the parent FBO into the child FBO. Since the child is already drawn inside the parent FBO, it will become visible when flushing the parent. The only case we end up not supporting is if the child window overlaps a sibling window that's draws using a separate QOpenGLContext. Change-Id: Ib10414f4494747e5fe67f84b06575fe16ffddf96 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiosbackingstore.mm | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src') diff --git a/src/plugins/platforms/ios/qiosbackingstore.mm b/src/plugins/platforms/ios/qiosbackingstore.mm index 5ee048cb2f..566ff3a672 100644 --- a/src/plugins/platforms/ios/qiosbackingstore.mm +++ b/src/plugins/platforms/ios/qiosbackingstore.mm @@ -92,6 +92,13 @@ void QIOSBackingStore::flush(QWindow *window, const QRegion ®ion, const QPoin Q_UNUSED(region); Q_UNUSED(offset); + if (window != this->window()) { + // We skip flushing raster-based child windows, to avoid the extra cost of copying from the + // parent FBO into the child FBO. Since the child is already drawn inside the parent FBO, it + // will become visible when flushing the parent. The only case we end up not supporting is if + // the child window overlaps a sibling window that's draws using a separate QOpenGLContext. + return; + } m_context->swapBuffers(window); } -- cgit v1.2.3 From 11d50be6dd8bbfe695408ccd011cbf63f1b4324a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Thu, 14 Feb 2013 13:09:08 +0100 Subject: iOS: Set touch point position in screen coords. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously the position was set in window coordinates, which would break for non-fullscreen windows. Change-Id: Iefa2f590c6d62b09fc3e7fe60a882c1acd33e029 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiosglobal.h | 2 ++ src/plugins/platforms/ios/qiosglobal.mm | 10 ++++++++++ src/plugins/platforms/ios/qioswindow.mm | 11 +++++++---- 3 files changed, 19 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/plugins/platforms/ios/qiosglobal.h b/src/plugins/platforms/ios/qiosglobal.h index 3fe426c901..cd265c0603 100644 --- a/src/plugins/platforms/ios/qiosglobal.h +++ b/src/plugins/platforms/ios/qiosglobal.h @@ -54,6 +54,8 @@ QIOSViewController *rootViewController(); CGRect toCGRect(const QRect &rect); QRect fromCGRect(const CGRect &rect); +CGPoint toCGPoint(const QPoint &point); +QPoint fromCGPoint(const CGPoint &point); Qt::ScreenOrientation toQtScreenOrientation(UIDeviceOrientation uiDeviceOrientation); UIDeviceOrientation fromQtScreenOrientation(Qt::ScreenOrientation qtOrientation); QRect fromPortraitToPrimary(const QRect &rect); diff --git a/src/plugins/platforms/ios/qiosglobal.mm b/src/plugins/platforms/ios/qiosglobal.mm index 712968d216..4657b73a10 100644 --- a/src/plugins/platforms/ios/qiosglobal.mm +++ b/src/plugins/platforms/ios/qiosglobal.mm @@ -75,6 +75,16 @@ QRect fromCGRect(const CGRect &rect) return QRect(rect.origin.x, rect.origin.y, rect.size.width, rect.size.height); } +CGPoint toCGPoint(const QPoint &point) +{ + return CGPointMake(point.x(), point.y()); +} + +QPoint fromCGPoint(const CGPoint &point) +{ + return QPoint(point.x, point.y); +} + Qt::ScreenOrientation toQtScreenOrientation(UIDeviceOrientation uiDeviceOrientation) { Qt::ScreenOrientation qtOrientation; diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index e95f392655..e4fb5e2e1c 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -177,10 +177,13 @@ touchPoint.pressure = 0.0; // Set position - CGPoint location = [touch locationInView:self]; - touchPoint.area = QRectF(location.x, location.y, 0, 0); - QSize viewSize = fromCGRect(self.frame).size(); - touchPoint.normalPosition = QPointF(location.x / viewSize.width(), location.y / viewSize.height()); + QRect viewGeometry = fromCGRect(self.frame); + QPoint touchViewLocation = fromCGPoint([touch locationInView:self]); + QPoint touchScreenLocation = touchViewLocation + viewGeometry.topLeft(); + touchPoint.area = QRectF(touchScreenLocation , QSize(0, 0)); + + CGSize fullscreenSize = self.window.rootViewController.view.bounds.size; + touchPoint.normalPosition = QPointF(touchScreenLocation.x() / fullscreenSize.width, touchScreenLocation.y() / fullscreenSize.height); } } -- cgit v1.2.3 From c75bc5b532479e8dbe6b7f07dcc5f9fcc915f5c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Thu, 14 Feb 2013 14:08:09 +0100 Subject: iOS: Don't crash on landscape mode startup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fromPortraitToPrimary is called from the QIOSScreen constructor. This is probably to early to call QGuiApplication functions. Change-Id: I882304fd641df13dc530491990245ba9ad495377 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiosglobal.h | 4 +++- src/plugins/platforms/ios/qiosglobal.mm | 4 ++-- src/plugins/platforms/ios/qiosinputcontext.mm | 2 +- src/plugins/platforms/ios/qiosscreen.mm | 2 +- 4 files changed, 7 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/plugins/platforms/ios/qiosglobal.h b/src/plugins/platforms/ios/qiosglobal.h index cd265c0603..3be9f8bb21 100644 --- a/src/plugins/platforms/ios/qiosglobal.h +++ b/src/plugins/platforms/ios/qiosglobal.h @@ -49,6 +49,8 @@ QT_BEGIN_NAMESPACE +class QPlatformScreen; + bool isQtApplication(); QIOSViewController *rootViewController(); @@ -58,7 +60,7 @@ CGPoint toCGPoint(const QPoint &point); QPoint fromCGPoint(const CGPoint &point); Qt::ScreenOrientation toQtScreenOrientation(UIDeviceOrientation uiDeviceOrientation); UIDeviceOrientation fromQtScreenOrientation(Qt::ScreenOrientation qtOrientation); -QRect fromPortraitToPrimary(const QRect &rect); +QRect fromPortraitToPrimary(const QRect &rect, QPlatformScreen *screen); QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qiosglobal.mm b/src/plugins/platforms/ios/qiosglobal.mm index 4657b73a10..5860078372 100644 --- a/src/plugins/platforms/ios/qiosglobal.mm +++ b/src/plugins/platforms/ios/qiosglobal.mm @@ -131,11 +131,11 @@ UIDeviceOrientation fromQtScreenOrientation(Qt::ScreenOrientation qtOrientation) return uiOrientation; } -QRect fromPortraitToPrimary(const QRect &rect) +QRect fromPortraitToPrimary(const QRect &rect, QPlatformScreen *screen) { // UIScreen is always in portrait. Use this function to convert CGRects // aligned with UIScreen into whatever is the current orientation of QScreen. - QRect geometry = QGuiApplication::primaryScreen()->handle()->geometry(); + QRect geometry = screen->geometry(); return geometry.width() < geometry.height() ? rect : QRect(rect.y(), geometry.width() - rect.width() - rect.x(), rect.height(), rect.width()); } diff --git a/src/plugins/platforms/ios/qiosinputcontext.mm b/src/plugins/platforms/ios/qiosinputcontext.mm index c0ff3b2531..1d3ab12de9 100644 --- a/src/plugins/platforms/ios/qiosinputcontext.mm +++ b/src/plugins/platforms/ios/qiosinputcontext.mm @@ -83,7 +83,7 @@ CGRect frame; [[[notification userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] getValue:&frame]; - m_keyboardRect = fromPortraitToPrimary(fromCGRect(frame)); + m_keyboardRect = fromPortraitToPrimary(fromCGRect(frame), QGuiApplication::primaryScreen()->handle()); m_context->emitKeyboardRectChanged(); BOOL visible = CGRectIntersectsRect(frame, [UIScreen mainScreen].bounds); diff --git a/src/plugins/platforms/ios/qiosscreen.mm b/src/plugins/platforms/ios/qiosscreen.mm index 5cee5a3362..3265ed8e37 100644 --- a/src/plugins/platforms/ios/qiosscreen.mm +++ b/src/plugins/platforms/ios/qiosscreen.mm @@ -224,7 +224,7 @@ void QIOSScreen::setPrimaryOrientation(Qt::ScreenOrientation orientation) // Switching portrait/landscape means swapping width/height (and adjusting x/y): m_geometry = QRect(0, 0, m_geometry.height(), m_geometry.width()); m_physicalSize = QSizeF(m_physicalSize.height(), m_physicalSize.width()); - m_availableGeometry = fromPortraitToPrimary(fromCGRect(m_uiScreen.applicationFrame)); + m_availableGeometry = fromPortraitToPrimary(fromCGRect(m_uiScreen.applicationFrame), this); QWindowSystemInterface::handleScreenGeometryChange(screen(), m_geometry); QWindowSystemInterface::handleScreenAvailableGeometryChange(screen(), m_availableGeometry); -- cgit v1.2.3 From fecc1554080aa58167b8cc7018b2ccd037d05cfe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Thu, 14 Feb 2013 19:45:48 +0100 Subject: iOS: Enable autorotate on startup. The qobject_cast to QGuiAppplication will always fail at startup since QGuiApplication is not ready yet. Return YES in that case. Allowed orientations can then be controlled by setting "Supported Interface Orientations" in Xcode or the Info.plist file. Change-Id: Ifd86bbcedabc716e63563bbb7cb0c1c6833fd6c7 Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qiosviewcontroller.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/plugins/platforms/ios/qiosviewcontroller.mm b/src/plugins/platforms/ios/qiosviewcontroller.mm index c85058743c..c52bfd7345 100644 --- a/src/plugins/platforms/ios/qiosviewcontroller.mm +++ b/src/plugins/platforms/ios/qiosviewcontroller.mm @@ -63,7 +63,7 @@ if (QGuiApplication *guiApp = qobject_cast(qApp)) return !guiApp->primaryScreen()->orientationUpdateMask(); else - return NO; + return YES; // Startup case: QGuiApplication is not ready yet. // FIXME: Investigate a proper Qt API for auto-rotation and orientation locking } -- cgit v1.2.3 From 0c1ae5f8660941fed55c468487635c9a74846f7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 21 Feb 2013 08:07:04 +0100 Subject: iOS: Add potentially undefined version defines to qsystemdetection.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Unless we're building on the 6.1 SDK some of the version defines will not be defined in Availability.h, so we define them ourselves so that Qt can still use them. Change-Id: Ibb45e9f8f4e888fc57e35286bf15d2fee2c1a217 Reviewed-by: Morten Johan Sørvig --- src/corelib/global/qsystemdetection.h | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'src') diff --git a/src/corelib/global/qsystemdetection.h b/src/corelib/global/qsystemdetection.h index 86c724ebb5..6062dc7b7b 100644 --- a/src/corelib/global/qsystemdetection.h +++ b/src/corelib/global/qsystemdetection.h @@ -208,6 +208,22 @@ # define MAC_OS_X_VERSION_10_8 1080 # endif # +# if !defined(__IPHONE_4_3) +# define __IPHONE_4_3 40300 +# endif +# if !defined(__IPHONE_5_0) +# define __IPHONE_5_0 50000 +# endif +# if !defined(__IPHONE_5_1) +# define __IPHONE_5_1 50100 +# endif +# if !defined(__IPHONE_6_0) +# define __IPHONE_6_0 60000 +# endif +# if !defined(__IPHONE_6_1) +# define __IPHONE_6_1 60100 +# endif +# # if (__MAC_OS_X_VERSION_MAX_ALLOWED > __MAC_10_8) # warning "This version of Mac OS X is unsupported" # endif -- cgit v1.2.3 From aa5528b050472d1d1097e2665fb346232cbfa7e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Fri, 15 Feb 2013 11:25:39 +0100 Subject: iOS: Implement socket notifiers. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Create the QCFSocketNotifier class in platform support which contains shared socket notifier support for the Cocoa and iOS plugins. Remove the old code from the Cocoa plugin. The Cocoa code had one QCocoaEventDispatcher-specific call: maybeCancelWaitForMoreEvents. Create a forwarding function that is passed to QCFSocketNotifier. Change-Id: Ibf9bd4745ba4f577a55f13d0cc00f5ae04447405 Reviewed-by: Tor Arne Vestbø Reviewed-by: Richard Moe Gustavsen --- .../cfsocketnotifier/cfsocketnotifier.pri | 4 + .../cfsocketnotifier/qcfsocketnotifier.cpp | 255 +++++++++++++++++++++ .../cfsocketnotifier/qcfsocketnotifier_p.h | 90 ++++++++ src/platformsupport/platformsupport.pro | 1 + .../platforms/cocoa/qcocoaeventdispatcher.h | 12 +- .../platforms/cocoa/qcocoaeventdispatcher.mm | 193 +--------------- src/plugins/platforms/ios/qioseventdispatcher.h | 3 + src/plugins/platforms/ios/qioseventdispatcher.mm | 10 +- 8 files changed, 374 insertions(+), 194 deletions(-) create mode 100644 src/platformsupport/cfsocketnotifier/cfsocketnotifier.pri create mode 100644 src/platformsupport/cfsocketnotifier/qcfsocketnotifier.cpp create mode 100644 src/platformsupport/cfsocketnotifier/qcfsocketnotifier_p.h (limited to 'src') diff --git a/src/platformsupport/cfsocketnotifier/cfsocketnotifier.pri b/src/platformsupport/cfsocketnotifier/cfsocketnotifier.pri new file mode 100644 index 0000000000..9a19d3c278 --- /dev/null +++ b/src/platformsupport/cfsocketnotifier/cfsocketnotifier.pri @@ -0,0 +1,4 @@ +mac { + HEADERS += $$PWD/qcfsocketnotifier_p.h + SOURCES += $$PWD/qcfsocketnotifier.cpp +} diff --git a/src/platformsupport/cfsocketnotifier/qcfsocketnotifier.cpp b/src/platformsupport/cfsocketnotifier/qcfsocketnotifier.cpp new file mode 100644 index 0000000000..5dcd6a4ffd --- /dev/null +++ b/src/platformsupport/cfsocketnotifier/qcfsocketnotifier.cpp @@ -0,0 +1,255 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qcfsocketnotifier_p.h" +#include +#include +#include + + +/************************************************************************** + Socket Notifiers + *************************************************************************/ +void qt_mac_socket_callback(CFSocketRef s, CFSocketCallBackType callbackType, CFDataRef, + const void *, void *info) +{ + + QCFSocketNotifier *cfSocketNotifier = static_cast(info); + int nativeSocket = CFSocketGetNative(s); + MacSocketInfo *socketInfo = cfSocketNotifier->macSockets.value(nativeSocket); + QEvent notifierEvent(QEvent::SockAct); + + // There is a race condition that happen where we disable the notifier and + // the kernel still has a notification to pass on. We then get this + // notification after we've successfully disabled the CFSocket, but our Qt + // notifier is now gone. The upshot is we have to check the notifier + // every time. + if (callbackType == kCFSocketReadCallBack) { + if (socketInfo->readNotifier) + QGuiApplication::sendEvent(socketInfo->readNotifier, ¬ifierEvent); + } else if (callbackType == kCFSocketWriteCallBack) { + if (socketInfo->writeNotifier) + QGuiApplication::sendEvent(socketInfo->writeNotifier, ¬ifierEvent); + } + + if (cfSocketNotifier->maybeCancelWaitForMoreEvents) + cfSocketNotifier->maybeCancelWaitForMoreEvents(cfSocketNotifier->eventDispatcher); +} + +/* + Adds a loop source for the given socket to the current run loop. +*/ +CFRunLoopSourceRef qt_mac_add_socket_to_runloop(const CFSocketRef socket) +{ + CFRunLoopSourceRef loopSource = CFSocketCreateRunLoopSource(kCFAllocatorDefault, socket, 0); + if (!loopSource) + return 0; + + CFRunLoopAddSource(CFRunLoopGetMain(), loopSource, kCFRunLoopCommonModes); + return loopSource; +} + +/* + Removes the loop source for the given socket from the current run loop. +*/ +void qt_mac_remove_socket_from_runloop(const CFSocketRef socket, CFRunLoopSourceRef runloop) +{ + Q_ASSERT(runloop); + CFRunLoopRemoveSource(CFRunLoopGetMain(), runloop, kCFRunLoopCommonModes); + CFSocketDisableCallBacks(socket, kCFSocketReadCallBack); + CFSocketDisableCallBacks(socket, kCFSocketWriteCallBack); + CFRunLoopSourceInvalidate(runloop); +} + +QCFSocketNotifier::QCFSocketNotifier() +:eventDispatcher(0) +{ + +} + +QCFSocketNotifier::~QCFSocketNotifier() +{ + +} + +void QCFSocketNotifier::setHostEventDispatcher(QAbstractEventDispatcher *hostEventDispacher) +{ + eventDispatcher = hostEventDispacher; +} + +void QCFSocketNotifier::setMaybeCancelWaitForMoreEventsCallback(MaybeCancelWaitForMoreEventsFn callBack) +{ + maybeCancelWaitForMoreEvents = callBack; +} + +void QCFSocketNotifier::registerSocketNotifier(QSocketNotifier *notifier) +{ + Q_ASSERT(notifier); + int nativeSocket = notifier->socket(); + int type = notifier->type(); +#ifndef QT_NO_DEBUG + if (nativeSocket < 0 || nativeSocket > FD_SETSIZE) { + qWarning("QSocketNotifier: Internal error"); + return; + } else if (notifier->thread() != eventDispatcher->thread() + || eventDispatcher->thread() != QThread::currentThread()) { + qWarning("QSocketNotifier: socket notifiers cannot be enabled from another thread"); + return; + } +#endif + + if (type == QSocketNotifier::Exception) { + qWarning("QSocketNotifier::Exception is not supported on iOS"); + return; + } + + // Check if we have a CFSocket for the native socket, create one if not. + MacSocketInfo *socketInfo = macSockets.value(nativeSocket); + if (!socketInfo) { + socketInfo = new MacSocketInfo(); + + // Create CFSocket, specify that we want both read and write callbacks (the callbacks + // are enabled/disabled later on). + const int callbackTypes = kCFSocketReadCallBack | kCFSocketWriteCallBack; + CFSocketContext context = {0, this, 0, 0, 0}; + socketInfo->socket = CFSocketCreateWithNative(kCFAllocatorDefault, nativeSocket, callbackTypes, qt_mac_socket_callback, &context); + if (CFSocketIsValid(socketInfo->socket) == false) { + qWarning("QEventDispatcherMac::registerSocketNotifier: Failed to create CFSocket"); + return; + } + + CFOptionFlags flags = CFSocketGetSocketFlags(socketInfo->socket); + flags |= kCFSocketAutomaticallyReenableWriteCallBack; //QSocketNotifier stays enabled after a write + flags &= ~kCFSocketCloseOnInvalidate; //QSocketNotifier doesn't close the socket upon destruction/invalidation + CFSocketSetSocketFlags(socketInfo->socket, flags); + + // Add CFSocket to runloop. + if (!(socketInfo->runloop = qt_mac_add_socket_to_runloop(socketInfo->socket))) { + qWarning("QEventDispatcherMac::registerSocketNotifier: Failed to add CFSocket to runloop"); + CFSocketInvalidate(socketInfo->socket); + CFRelease(socketInfo->socket); + return; + } + + // Disable both callback types by default. This must be done after + // we add the CFSocket to the runloop, or else these calls will have + // no effect. + CFSocketDisableCallBacks(socketInfo->socket, kCFSocketReadCallBack); + CFSocketDisableCallBacks(socketInfo->socket, kCFSocketWriteCallBack); + + macSockets.insert(nativeSocket, socketInfo); + } + + // Increment read/write counters and select enable callbacks if necessary. + if (type == QSocketNotifier::Read) { + Q_ASSERT(socketInfo->readNotifier == 0); + socketInfo->readNotifier = notifier; + CFSocketEnableCallBacks(socketInfo->socket, kCFSocketReadCallBack); + } else if (type == QSocketNotifier::Write) { + Q_ASSERT(socketInfo->writeNotifier == 0); + socketInfo->writeNotifier = notifier; + CFSocketEnableCallBacks(socketInfo->socket, kCFSocketWriteCallBack); + } +} + +void QCFSocketNotifier::unregisterSocketNotifier(QSocketNotifier *notifier) +{ + Q_ASSERT(notifier); + int nativeSocket = notifier->socket(); + int type = notifier->type(); +#ifndef QT_NO_DEBUG + if (nativeSocket < 0 || nativeSocket > FD_SETSIZE) { + qWarning("QSocketNotifier: Internal error"); + return; + } else if (notifier->thread() != eventDispatcher->thread() || eventDispatcher->thread() != QThread::currentThread()) { + qWarning("QSocketNotifier: socket notifiers cannot be disabled from another thread"); + return; + } +#endif + + if (type == QSocketNotifier::Exception) { + qWarning("QSocketNotifier::Exception is not supported on iOS"); + return; + } + MacSocketInfo *socketInfo = macSockets.value(nativeSocket); + if (!socketInfo) { + qWarning("QEventDispatcherMac::unregisterSocketNotifier: Tried to unregister a not registered notifier"); + return; + } + + // Decrement read/write counters and disable callbacks if necessary. + if (type == QSocketNotifier::Read) { + Q_ASSERT(notifier == socketInfo->readNotifier); + socketInfo->readNotifier = 0; + CFSocketDisableCallBacks(socketInfo->socket, kCFSocketReadCallBack); + } else if (type == QSocketNotifier::Write) { + Q_ASSERT(notifier == socketInfo->writeNotifier); + socketInfo->writeNotifier = 0; + CFSocketDisableCallBacks(socketInfo->socket, kCFSocketWriteCallBack); + } + + // Remove CFSocket from runloop if this was the last QSocketNotifier. + if (socketInfo->readNotifier == 0 && socketInfo->writeNotifier == 0) { + if (CFSocketIsValid(socketInfo->socket)) + qt_mac_remove_socket_from_runloop(socketInfo->socket, socketInfo->runloop); + CFRunLoopSourceInvalidate(socketInfo->runloop); + CFRelease(socketInfo->runloop); + CFSocketInvalidate(socketInfo->socket); + CFRelease(socketInfo->socket); + delete socketInfo; + macSockets.remove(nativeSocket); + } +} + +void QCFSocketNotifier::removeSocketNotifiers() +{ + // Remove CFSockets from the runloop. + for (MacSocketHash::ConstIterator it = macSockets.constBegin(); it != macSockets.constEnd(); ++it) { + MacSocketInfo *socketInfo = (*it); + if (CFSocketIsValid(socketInfo->socket)) { + qt_mac_remove_socket_from_runloop(socketInfo->socket, socketInfo->runloop); + CFRunLoopSourceInvalidate(socketInfo->runloop); + CFRelease(socketInfo->runloop); + CFSocketInvalidate(socketInfo->socket); + CFRelease(socketInfo->socket); + } + } +} diff --git a/src/platformsupport/cfsocketnotifier/qcfsocketnotifier_p.h b/src/platformsupport/cfsocketnotifier/qcfsocketnotifier_p.h new file mode 100644 index 0000000000..cd1eb8e4ca --- /dev/null +++ b/src/platformsupport/cfsocketnotifier/qcfsocketnotifier_p.h @@ -0,0 +1,90 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QCFSOCKETNOTIFIER_P_H +#define QCFSOCKETNOTIFIER_P_H + +#include +#include + +#include + +QT_BEGIN_NAMESPACE + +struct MacSocketInfo { + MacSocketInfo() : socket(0), runloop(0), readNotifier(0), writeNotifier(0) {} + CFSocketRef socket; + CFRunLoopSourceRef runloop; + QObject *readNotifier; + QObject *writeNotifier; +}; +typedef QHash MacSocketHash; + +typedef void (*MaybeCancelWaitForMoreEventsFn)(QAbstractEventDispatcher *hostEventDispacher); + +// The CoreFoundationSocketNotifier class implements socket notifiers support using +// CFSocket for event dispatchers running on top of the Core Foundation run loop system. +// (currently Mac and iOS) +// +// The principal functions are registerSocketNotifier() and unregisterSocketNotifier(). +// +// setHostEventDispatcher() should be called at startup. +// removeSocketNotifiers() should be called at shutdown. +// +class QCFSocketNotifier +{ +public: + QCFSocketNotifier(); + ~QCFSocketNotifier(); + void setHostEventDispatcher(QAbstractEventDispatcher *hostEventDispacher); + void setMaybeCancelWaitForMoreEventsCallback(MaybeCancelWaitForMoreEventsFn callBack); + void registerSocketNotifier(QSocketNotifier *notifier); + void unregisterSocketNotifier(QSocketNotifier *notifier); + void removeSocketNotifiers(); + + MacSocketHash macSockets; + QAbstractEventDispatcher *eventDispatcher; + MaybeCancelWaitForMoreEventsFn maybeCancelWaitForMoreEvents; +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/platformsupport/platformsupport.pro b/src/platformsupport/platformsupport.pro index 469c76ffae..8e0f396993 100644 --- a/src/platformsupport/platformsupport.pro +++ b/src/platformsupport/platformsupport.pro @@ -9,6 +9,7 @@ load(qt_module) DEFINES += QT_NO_CAST_FROM_ASCII PRECOMPILED_HEADER = ../corelib/global/qt_pch.h +include(cfsocketnotifier/cfsocketnotifier.pri) include(cglconvenience/cglconvenience.pri) include(dnd/dnd.pri) include(eglconvenience/eglconvenience.pri) diff --git a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h index f63ac0d205..93476ee1b4 100644 --- a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h +++ b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h @@ -93,6 +93,7 @@ #include #include #include +#include #include @@ -132,16 +133,9 @@ public: void wakeUp(); void interrupt(); void flush(); -}; -struct MacSocketInfo { - MacSocketInfo() : socket(0), runloop(0), readNotifier(0), writeNotifier(0) {} - CFSocketRef socket; - CFRunLoopSourceRef runloop; - QObject *readNotifier; - QObject *writeNotifier; + friend void qt_mac_maybeCancelWaitForMoreEventsForwarder(QAbstractEventDispatcher *eventDispatcher); }; -typedef QHash MacSocketHash; class QCocoaEventDispatcherPrivate : public QAbstractEventDispatcherPrivate { @@ -183,7 +177,7 @@ public: void maybeCancelWaitForMoreEvents(); void ensureNSAppInitialized(); - MacSocketHash macSockets; + QCFSocketNotifier cfSocketNotifier; QList queuedUserInputEvents; // NSEvent * CFRunLoopSourceRef postedEventsSource; CFRunLoopObserverRef waitingObserver; diff --git a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm index 987600c6b4..ed4f8cd1fb 100644 --- a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm +++ b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm @@ -270,58 +270,6 @@ QCocoaEventDispatcher::registeredTimers(QObject *object) const return d->timerInfoList.registeredTimers(object); } -/************************************************************************** - Socket Notifiers - *************************************************************************/ -void qt_mac_socket_callback(CFSocketRef s, CFSocketCallBackType callbackType, CFDataRef, - const void *, void *info) { - QCocoaEventDispatcherPrivate *const eventDispatcher - = static_cast(info); - int nativeSocket = CFSocketGetNative(s); - MacSocketInfo *socketInfo = eventDispatcher->macSockets.value(nativeSocket); - QEvent notifierEvent(QEvent::SockAct); - - // There is a race condition that happen where we disable the notifier and - // the kernel still has a notification to pass on. We then get this - // notification after we've successfully disabled the CFSocket, but our Qt - // notifier is now gone. The upshot is we have to check the notifier - // everytime. - if (callbackType == kCFSocketReadCallBack) { - if (socketInfo->readNotifier) - QGuiApplication::sendEvent(socketInfo->readNotifier, ¬ifierEvent); - } else if (callbackType == kCFSocketWriteCallBack) { - if (socketInfo->writeNotifier) - QGuiApplication::sendEvent(socketInfo->writeNotifier, ¬ifierEvent); - } - - eventDispatcher->maybeCancelWaitForMoreEvents(); -} - -/* - Adds a loop source for the given socket to the current run loop. -*/ -CFRunLoopSourceRef qt_mac_add_socket_to_runloop(const CFSocketRef socket) -{ - CFRunLoopSourceRef loopSource = CFSocketCreateRunLoopSource(kCFAllocatorDefault, socket, 0); - if (!loopSource) - return 0; - - CFRunLoopAddSource(mainRunLoop(), loopSource, kCFRunLoopCommonModes); - return loopSource; -} - -/* - Removes the loop source for the given socket from the current run loop. -*/ -void qt_mac_remove_socket_from_runloop(const CFSocketRef socket, CFRunLoopSourceRef runloop) -{ - Q_ASSERT(runloop); - CFRunLoopRemoveSource(mainRunLoop(), runloop, kCFRunLoopCommonModes); - CFSocketDisableCallBacks(socket, kCFSocketReadCallBack); - CFSocketDisableCallBacks(socket, kCFSocketWriteCallBack); - CFRunLoopSourceInvalidate(runloop); -} - /* Register a QSocketNotifier with the mac event system by creating a CFSocket with with a read/write callback. @@ -331,130 +279,14 @@ void qt_mac_remove_socket_from_runloop(const CFSocketRef socket, CFRunLoopSource */ void QCocoaEventDispatcher::registerSocketNotifier(QSocketNotifier *notifier) { - Q_ASSERT(notifier); - int nativeSocket = notifier->socket(); - int type = notifier->type(); -#ifndef QT_NO_DEBUG - if (nativeSocket < 0 || nativeSocket > FD_SETSIZE) { - qWarning("QSocketNotifier: Internal error"); - return; - } else if (notifier->thread() != thread() - || thread() != QThread::currentThread()) { - qWarning("QSocketNotifier: socket notifiers cannot be enabled from another thread"); - return; - } -#endif - Q_D(QCocoaEventDispatcher); - - if (type == QSocketNotifier::Exception) { - qWarning("QSocketNotifier::Exception is not supported on Mac OS X"); - return; - } - - // Check if we have a CFSocket for the native socket, create one if not. - MacSocketInfo *socketInfo = d->macSockets.value(nativeSocket); - if (!socketInfo) { - socketInfo = new MacSocketInfo(); - - // Create CFSocket, specify that we want both read and write callbacks (the callbacks - // are enabled/disabled later on). - const int callbackTypes = kCFSocketReadCallBack | kCFSocketWriteCallBack; - CFSocketContext context = {0, d, 0, 0, 0}; - socketInfo->socket = CFSocketCreateWithNative(kCFAllocatorDefault, nativeSocket, callbackTypes, qt_mac_socket_callback, &context); - if (CFSocketIsValid(socketInfo->socket) == false) { - qWarning("QEventDispatcherMac::registerSocketNotifier: Failed to create CFSocket"); - return; - } - - CFOptionFlags flags = CFSocketGetSocketFlags(socketInfo->socket); - flags |= kCFSocketAutomaticallyReenableWriteCallBack; //QSocketNotifier stays enabled after a write - flags &= ~kCFSocketCloseOnInvalidate; //QSocketNotifier doesn't close the socket upon destruction/invalidation - CFSocketSetSocketFlags(socketInfo->socket, flags); - - // Add CFSocket to runloop. - if(!(socketInfo->runloop = qt_mac_add_socket_to_runloop(socketInfo->socket))) { - qWarning("QEventDispatcherMac::registerSocketNotifier: Failed to add CFSocket to runloop"); - CFSocketInvalidate(socketInfo->socket); - CFRelease(socketInfo->socket); - return; - } - - // Disable both callback types by default. This must be done after - // we add the CFSocket to the runloop, or else these calls will have - // no effect. - CFSocketDisableCallBacks(socketInfo->socket, kCFSocketReadCallBack); - CFSocketDisableCallBacks(socketInfo->socket, kCFSocketWriteCallBack); - - d->macSockets.insert(nativeSocket, socketInfo); - } - - // Increment read/write counters and select enable callbacks if necessary. - if (type == QSocketNotifier::Read) { - Q_ASSERT(socketInfo->readNotifier == 0); - socketInfo->readNotifier = notifier; - CFSocketEnableCallBacks(socketInfo->socket, kCFSocketReadCallBack); - } else if (type == QSocketNotifier::Write) { - Q_ASSERT(socketInfo->writeNotifier == 0); - socketInfo->writeNotifier = notifier; - CFSocketEnableCallBacks(socketInfo->socket, kCFSocketWriteCallBack); - } + d->cfSocketNotifier.registerSocketNotifier(notifier); } -/* - Unregister QSocketNotifer. The CFSocket correspoding to this notifier is - removed from the runloop of this is the last notifier that users - that CFSocket. -*/ void QCocoaEventDispatcher::unregisterSocketNotifier(QSocketNotifier *notifier) { - Q_ASSERT(notifier); - int nativeSocket = notifier->socket(); - int type = notifier->type(); -#ifndef QT_NO_DEBUG - if (nativeSocket < 0 || nativeSocket > FD_SETSIZE) { - qWarning("QSocketNotifier: Internal error"); - return; - } else if (notifier->thread() != thread() || thread() != QThread::currentThread()) { - qWarning("QSocketNotifier: socket notifiers cannot be disabled from another thread"); - return; - } -#endif - Q_D(QCocoaEventDispatcher); - - if (type == QSocketNotifier::Exception) { - qWarning("QSocketNotifier::Exception is not supported on Mac OS X"); - return; - } - MacSocketInfo *socketInfo = d->macSockets.value(nativeSocket); - if (!socketInfo) { - qWarning("QEventDispatcherMac::unregisterSocketNotifier: Tried to unregister a not registered notifier"); - return; - } - - // Decrement read/write counters and disable callbacks if necessary. - if (type == QSocketNotifier::Read) { - Q_ASSERT(notifier == socketInfo->readNotifier); - socketInfo->readNotifier = 0; - CFSocketDisableCallBacks(socketInfo->socket, kCFSocketReadCallBack); - } else if (type == QSocketNotifier::Write) { - Q_ASSERT(notifier == socketInfo->writeNotifier); - socketInfo->writeNotifier = 0; - CFSocketDisableCallBacks(socketInfo->socket, kCFSocketWriteCallBack); - } - - // Remove CFSocket from runloop if this was the last QSocketNotifier. - if (socketInfo->readNotifier == 0 && socketInfo->writeNotifier == 0) { - if (CFSocketIsValid(socketInfo->socket)) - qt_mac_remove_socket_from_runloop(socketInfo->socket, socketInfo->runloop); - CFRunLoopSourceInvalidate(socketInfo->runloop); - CFRelease(socketInfo->runloop); - CFSocketInvalidate(socketInfo->socket); - CFRelease(socketInfo->socket); - delete socketInfo; - d->macSockets.remove(nativeSocket); - } + d->cfSocketNotifier.unregisterSocketNotifier(notifier); } bool QCocoaEventDispatcher::hasPendingEvents() @@ -940,11 +772,19 @@ QCocoaEventDispatcherPrivate::QCocoaEventDispatcherPrivate() { } +void qt_mac_maybeCancelWaitForMoreEventsForwarder(QAbstractEventDispatcher *eventDispatcher) +{ + static_cast(eventDispatcher)->d_func()->maybeCancelWaitForMoreEvents(); +} + QCocoaEventDispatcher::QCocoaEventDispatcher(QObject *parent) : QAbstractEventDispatcher(*new QCocoaEventDispatcherPrivate, parent) { Q_D(QCocoaEventDispatcher); + d->cfSocketNotifier.setHostEventDispatcher(this); + d->cfSocketNotifier.setMaybeCancelWaitForMoreEventsCallback(qt_mac_maybeCancelWaitForMoreEventsForwarder); + // keep our sources running when modal loops are running CFRunLoopAddCommonMode(mainRunLoop(), (CFStringRef) NSModalPanelRunLoopMode); @@ -1127,17 +967,8 @@ QCocoaEventDispatcher::~QCocoaEventDispatcher() [nsevent release]; } - // Remove CFSockets from the runloop. - for (MacSocketHash::ConstIterator it = d->macSockets.constBegin(); it != d->macSockets.constEnd(); ++it) { - MacSocketInfo *socketInfo = (*it); - if (CFSocketIsValid(socketInfo->socket)) { - qt_mac_remove_socket_from_runloop(socketInfo->socket, socketInfo->runloop); - CFRunLoopSourceInvalidate(socketInfo->runloop); - CFRelease(socketInfo->runloop); - CFSocketInvalidate(socketInfo->socket); - CFRelease(socketInfo->socket); - } - } + d->cfSocketNotifier.removeSocketNotifiers(); + CFRunLoopRemoveSource(mainRunLoop(), d->postedEventsSource, kCFRunLoopCommonModes); CFRelease(d->postedEventsSource); diff --git a/src/plugins/platforms/ios/qioseventdispatcher.h b/src/plugins/platforms/ios/qioseventdispatcher.h index 88d5127855..53a75618ce 100644 --- a/src/plugins/platforms/ios/qioseventdispatcher.h +++ b/src/plugins/platforms/ios/qioseventdispatcher.h @@ -78,6 +78,7 @@ #include #include +#include #include QT_BEGIN_NAMESPACE @@ -116,6 +117,8 @@ private: QTimerInfoList m_timerInfoList; CFRunLoopTimerRef m_runLoopTimerRef; + QCFSocketNotifier m_cfSocketNotifier; + void processPostedEvents(); void maybeStartCFRunLoopTimer(); void maybeStopCFRunLoopTimer(); diff --git a/src/plugins/platforms/ios/qioseventdispatcher.mm b/src/plugins/platforms/ios/qioseventdispatcher.mm index f6f60387d4..e9bf039047 100644 --- a/src/plugins/platforms/ios/qioseventdispatcher.mm +++ b/src/plugins/platforms/ios/qioseventdispatcher.mm @@ -155,6 +155,8 @@ QIOSEventDispatcher::QIOSEventDispatcher(QObject *parent) , m_interrupted(false) , m_runLoopTimerRef(0) { + m_cfSocketNotifier.setHostEventDispatcher(this); + CFRunLoopRef mainRunLoop = CFRunLoopGetMain(); CFRunLoopSourceContext context; bzero(&context, sizeof(CFRunLoopSourceContext)); @@ -184,6 +186,8 @@ QIOSEventDispatcher::~QIOSEventDispatcher() maybeStopCFRunLoopTimer(); CFRunLoopRemoveSource(CFRunLoopGetMain(), m_blockingTimerRunLoopSource, kCFRunLoopCommonModes); CFRelease(m_blockingTimerRunLoopSource); + + m_cfSocketNotifier.removeSocketNotifiers(); } bool QIOSEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags) @@ -215,14 +219,12 @@ bool QIOSEventDispatcher::hasPendingEvents() void QIOSEventDispatcher::registerSocketNotifier(QSocketNotifier *notifier) { - qDebug() << __FUNCTION__ << "not implemented"; - Q_UNUSED(notifier); + m_cfSocketNotifier.registerSocketNotifier(notifier); } void QIOSEventDispatcher::unregisterSocketNotifier(QSocketNotifier *notifier) { - qDebug() << __FUNCTION__ << "not implemented"; - Q_UNUSED(notifier); + m_cfSocketNotifier.unregisterSocketNotifier(notifier); } void QIOSEventDispatcher::registerTimer(int timerId, int interval, Qt::TimerType timerType, QObject *obj) -- cgit v1.2.3 From 76e4b6d2f24f7f88250db34fb03838a30fc43eec Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Thu, 21 Feb 2013 14:41:12 +0100 Subject: iOS: Add QIOSIntegration::hasCapability function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add the missing override, and report that we support OpenGL (and multiple windows). Change-Id: If95138cab9099b547d12d3dfed008bd63b6d2acf Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiosintegration.h | 2 ++ src/plugins/platforms/ios/qiosintegration.mm | 12 ++++++++++++ 2 files changed, 14 insertions(+) (limited to 'src') diff --git a/src/plugins/platforms/ios/qiosintegration.h b/src/plugins/platforms/ios/qiosintegration.h index 054933ea44..329a0a3d9b 100644 --- a/src/plugins/platforms/ios/qiosintegration.h +++ b/src/plugins/platforms/ios/qiosintegration.h @@ -54,6 +54,8 @@ public: QIOSIntegration(); ~QIOSIntegration(); + bool hasCapability(Capability cap) const; + QPlatformWindow *createPlatformWindow(QWindow *window) const; QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const; diff --git a/src/plugins/platforms/ios/qiosintegration.mm b/src/plugins/platforms/ios/qiosintegration.mm index c5fef243ce..adb33da344 100644 --- a/src/plugins/platforms/ios/qiosintegration.mm +++ b/src/plugins/platforms/ios/qiosintegration.mm @@ -84,6 +84,18 @@ QIOSIntegration::~QIOSIntegration() delete m_touchDevice; } +bool QIOSIntegration::hasCapability(Capability cap) const +{ + switch (cap) { + case OpenGL: + return true; + case MultipleWindows: + return true; + default: + return QPlatformIntegration::hasCapability(cap); + } +} + QPlatformWindow *QIOSIntegration::createPlatformWindow(QWindow *window) const { qDebug() << __FUNCTION__ << "Creating platform window"; -- cgit v1.2.3 From 75a7dc7a574e0c949214feecc711e385f38060e9 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Thu, 21 Feb 2013 14:59:30 +0100 Subject: iOS: Remove debug output noise MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This debug information is not needed anymore, and only causes noise when trying to debug other stuff. Change-Id: I076826e251b84a3883e63aa7669f6e1bb55a0d1f Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiosintegration.mm | 3 --- 1 file changed, 3 deletions(-) (limited to 'src') diff --git a/src/plugins/platforms/ios/qiosintegration.mm b/src/plugins/platforms/ios/qiosintegration.mm index adb33da344..c7541c3e38 100644 --- a/src/plugins/platforms/ios/qiosintegration.mm +++ b/src/plugins/platforms/ios/qiosintegration.mm @@ -98,14 +98,12 @@ bool QIOSIntegration::hasCapability(Capability cap) const QPlatformWindow *QIOSIntegration::createPlatformWindow(QWindow *window) const { - qDebug() << __FUNCTION__ << "Creating platform window"; return new QIOSWindow(window); } // Used when the QWindow's surface type is set by the client to QSurface::RasterSurface QPlatformBackingStore *QIOSIntegration::createPlatformBackingStore(QWindow *window) const { - qDebug() << __FUNCTION__ << "Creating platform backingstore"; return new QIOSBackingStore(window); } @@ -113,7 +111,6 @@ QPlatformBackingStore *QIOSIntegration::createPlatformBackingStore(QWindow *wind QPlatformOpenGLContext *QIOSIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const { Q_UNUSED(context); - qDebug() << __FUNCTION__ << "Creating platform opengl context"; return new QIOSContext(context); } -- cgit v1.2.3 From 9b05f675e311d1962f0670193cf4df75a07f4999 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Thu, 21 Feb 2013 13:44:01 +0100 Subject: QFusionStyle: Fix crash on iOS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit First of all, the ifdef section was meant for osx, and not ios. Second, a platform theme does not necessarily need to override the palette function, which will return 0 by default. Change-Id: I5a28f4ee1020c9253d0803c9d962c6a058e5358c Reviewed-by: Tor Arne Vestbø Reviewed-by: J-P Nurmi Reviewed-by: Jens Bache-Wiig --- src/widgets/styles/qfusionstyle_p_p.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/widgets/styles/qfusionstyle_p_p.h b/src/widgets/styles/qfusionstyle_p_p.h index d3f2ff5f40..58595fe889 100644 --- a/src/widgets/styles/qfusionstyle_p_p.h +++ b/src/widgets/styles/qfusionstyle_p_p.h @@ -88,9 +88,9 @@ public: // On mac we want a standard blue color used when the system palette is used bool isMacSystemPalette(const QPalette &pal) const { Q_UNUSED(pal); -#ifdef Q_OS_MAC +#if defined(Q_OS_MAC) && !defined(Q_OS_IOS) const QPalette *themePalette = QGuiApplicationPrivate::platformTheme()->palette(); - if (themePalette->color(QPalette::Normal, QPalette::Highlight) == + if (themePalette && themePalette->color(QPalette::Normal, QPalette::Highlight) == pal.color(QPalette::Normal, QPalette::Highlight) && themePalette->color(QPalette::Normal, QPalette::HighlightedText) == pal.color(QPalette::Normal, QPalette::HighlightedText)) -- cgit v1.2.3