From 119ea0f2dbaa4cdea6929e542c59f99b2dfd0ef9 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Mon, 2 Dec 2013 22:34:26 +0100 Subject: iOS: fix application hangs when opening keyboard MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit QIOSInputContext controls QUIViews first responder status based on whether or not the keyboard should be open. But since QGuiApplication updates focusObject before focusWindow (when e.g a popup closes), we sometimes ended up activating the old window upon a call to becomeFirstResponder. This in turn led the application to hang because of recursive dependencies in qioscontext when the focus window changed. So the solution for now is to avoid activating the window when the view becomes first responder. This should be fine since we now activate the window from QIOSWindow::requestActivateWindow (ref: 6272a816d1) Task-number: QTBUG-35340 Change-Id: I3068c14fec18d84d4b0b348a043c4c054e366c75 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qioswindow.mm | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'src/plugins/platforms/ios') diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 0dd810bdf6..43f36e32e0 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -330,13 +330,9 @@ - (BOOL)becomeFirstResponder { - // On iOS, a QWindow should only have input focus when the input panel is - // open. This is to stop cursors and focus rects from being drawn when the - // user cannot type. And since the keyboard will open when a view becomes - // the first responder, it's now a good time to inform QPA that the QWindow - // this view backs became active: + // Note: QIOSInputContext controls our first responder status based on + // whether or not the keyboard should be open or closed. [self updateTextInputTraits]; - QWindowSystemInterface::handleWindowActivated(m_qioswindow->window()); return [super becomeFirstResponder]; } -- cgit v1.2.3 From 32f71db1bdcf93c8a03a9ef11ff4044479afa369 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Tue, 3 Dec 2013 13:55:20 +0100 Subject: iOS: fix crash when application quits MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit An application will sometimes crash if the keyboard is told to hide while the application is about to quit. This patch will ensure that we set m_qioswindow (and [UIView qwindow]) to 0 when the window is destroyed. We also check this pointer before telling QUIView to resign first responder when closing the keyboard. The latter will fix the crash. Task-number: QTBUG-35356 Change-Id: I934088beb7e877c5b33d96225cb215a8ffd4dbb2 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qioswindow.mm | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'src/plugins/platforms/ios') diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 43f36e32e0..7b217e0bdc 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -341,7 +341,8 @@ // Resigning first responed status means that the virtual keyboard was closed, or // some other view became first responder. In either case we clear the focus object to // avoid blinking cursors in line edits etc: - static_cast(QObjectPrivate::get(m_qioswindow->window()))->clearFocusObject(); + if (m_qioswindow) + static_cast(QObjectPrivate::get(m_qioswindow->window()))->clearFocusObject(); return [super resignFirstResponder]; } @@ -423,8 +424,10 @@ - (QWindow *)qwindow { - if ([self isKindOfClass:[QUIView class]]) - return static_cast(self)->m_qioswindow->window(); + if ([self isKindOfClass:[QUIView class]]) { + if (QIOSWindow *w = static_cast(self)->m_qioswindow) + return w->window(); + } return nil; } @@ -461,6 +464,7 @@ QIOSWindow::~QIOSWindow() // cancellation of all touch events. [m_view touchesCancelled:0 withEvent:0]; + m_view->m_qioswindow = 0; [m_view removeFromSuperview]; [m_view release]; } -- cgit v1.2.3 From bd9cf0b7b96ea5836d18259b073870f8b145b46d Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Mon, 2 Dec 2013 22:32:13 +0100 Subject: iOS: fix crash when focusWindow changes while keyboard is open MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It turns out we cannot rely on QGuiApplication::focusWindow() to be non-zero at all times (e.g when pop-ups are closing etc). So instead use m_focusView.qwindow which points to a valid QWindow. This window is the same as QGuiApplication::focusWindow most of the time, except when a focus window closes. For those cases we get a new call to scrollRootView immediately after with m_focusView updated to reflect the new focusWindow. Task-number: QTBUG-35339 Change-Id: Icb3a8d3140af1f1904495a9289c8c26ab79e70f6 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiosinputcontext.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/plugins/platforms/ios') diff --git a/src/plugins/platforms/ios/qiosinputcontext.mm b/src/plugins/platforms/ios/qiosinputcontext.mm index 0e43429015..ea6a0bd4a6 100644 --- a/src/plugins/platforms/ios/qiosinputcontext.mm +++ b/src/plugins/platforms/ios/qiosinputcontext.mm @@ -270,7 +270,7 @@ void QIOSInputContext::scrollRootView() && m_keyboardListener->m_keyboardVisibleAndDocked && m_focusView.window == view.window) { QRectF cursorRect = qGuiApp->inputMethod()->cursorRectangle(); - cursorRect.translate(qGuiApp->focusWindow()->geometry().topLeft()); + cursorRect.translate(m_focusView.qwindow->geometry().topLeft()); qreal keyboardY = m_keyboardListener->m_keyboardEndRect.y(); int statusBarY = qGuiApp->primaryScreen()->availableGeometry().y(); const int margin = 20; -- cgit v1.2.3 From 520eee8570c8ddf4014d896ae3f121c315274000 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Tue, 3 Dec 2013 15:37:49 +0100 Subject: iOS: Disable drag and drop completely instead of enabling simple d'n'd The drag and drop event filters do not play nicely with touch events or virtual keyboards. Task-number: QTBUG-35348 Change-Id: Id4d079ae72882f48750d394f13e10700d60e4532 Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qiosintegration.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/plugins/platforms/ios') diff --git a/src/plugins/platforms/ios/qiosintegration.h b/src/plugins/platforms/ios/qiosintegration.h index c655d8d3bf..fdecf70725 100644 --- a/src/plugins/platforms/ios/qiosintegration.h +++ b/src/plugins/platforms/ios/qiosintegration.h @@ -74,6 +74,8 @@ public: QStringList themeNames() const; QPlatformTheme *createPlatformTheme(const QString &name) const; + QPlatformDrag *drag() const Q_DECL_OVERRIDE { return 0; } + QAbstractEventDispatcher *createEventDispatcher() const; QPlatformNativeInterface *nativeInterface() const; -- cgit v1.2.3 From b05b940185450af70791befd47b2dd47eb0acfd5 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Wed, 4 Dec 2013 13:24:21 +0100 Subject: iOS: fix assert when using QOffscreenSurface MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Qt defaults to creating a QWindow as offscreen surface if QPlatformIntegration::createPlatformOffscreenSurface returns 0. Using an offscreen surface is often done in a background thread, which is problematic, since then a QIOSWindow will also be created in a background thread. According to Apple docs, working with a UIView from other threads than the main thread should not be done. In our case, we instead hit an assert in QApplication that checks for the same. As a quick fix for Qt 5.2, we remove the offending call that causes the assert, since we anyway will call the same function lazily when becoming first responder. Task-number: QTBUG-35378 Change-Id: Id35462f99783a9748c688b163f6497de9bfff73e Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qioswindow.mm | 2 -- 1 file changed, 2 deletions(-) (limited to 'src/plugins/platforms/ios') diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 7b217e0bdc..5374bc530d 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -108,8 +108,6 @@ [NSNumber numberWithBool:YES], kEAGLDrawablePropertyRetainedBacking, kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat, nil]; - [self updateTextInputTraits]; - if (isQtApplication()) self.hidden = YES; -- cgit v1.2.3 From 996d78d4c94a0116eecec160caf605ea3629f36c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 28 Nov 2013 13:09:44 +0100 Subject: iOS: Handle statusbar changes to child windows MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Going through the platform window failed when the parent wasn't created yet. We can still get the window state of an yet-to-be-created top level window. Change-Id: Iaa61ddc50df037ac0bd2fd0884884c2bfce1dd9a Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiosviewcontroller.mm | 6 +++--- src/plugins/platforms/ios/qioswindow.h | 2 +- src/plugins/platforms/ios/qioswindow.mm | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) (limited to 'src/plugins/platforms/ios') diff --git a/src/plugins/platforms/ios/qiosviewcontroller.mm b/src/plugins/platforms/ios/qiosviewcontroller.mm index 2e7e44d32c..9a9fba5a8e 100644 --- a/src/plugins/platforms/ios/qiosviewcontroller.mm +++ b/src/plugins/platforms/ios/qiosviewcontroller.mm @@ -102,11 +102,11 @@ - (BOOL)prefersStatusBarHidden { QWindow *focusWindow = QGuiApplication::focusWindow(); - if (!focusWindow) + if (!focusWindow || !focusWindow->handle()) return [UIApplication sharedApplication].statusBarHidden; - QIOSWindow *topLevel = static_cast(focusWindow->handle())->topLevelWindow(); - return topLevel->window()->windowState() == Qt::WindowFullScreen; + QWindow *topLevel = static_cast(focusWindow->handle())->topLevelWindow(); + return topLevel->windowState() == Qt::WindowFullScreen; } @end diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h index a5e122bda1..01a82866dc 100644 --- a/src/plugins/platforms/ios/qioswindow.h +++ b/src/plugins/platforms/ios/qioswindow.h @@ -85,7 +85,7 @@ public: WId winId() const { return WId(m_view); }; - QIOSWindow *topLevelWindow() const; + QWindow *topLevelWindow() const; private: void applyGeometry(const QRect &rect); diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 5374bc530d..d62d5420b7 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -622,7 +622,7 @@ void QIOSWindow::setParent(const QPlatformWindow *parentWindow) } } -QIOSWindow *QIOSWindow::topLevelWindow() const +QWindow *QIOSWindow::topLevelWindow() const { QWindow *window = this->window(); while (window) { @@ -636,7 +636,7 @@ QIOSWindow *QIOSWindow::topLevelWindow() const window = parent; } - return static_cast(window->handle()); + return window; } void QIOSWindow::requestActivateWindow() -- cgit v1.2.3 From 2e132854460e11a1ade516f61477723202d56a93 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Tue, 26 Nov 2013 11:13:56 +0100 Subject: iOS: don't show statusbar if hidden from Info.plist MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently there is no way to always hide the statusbar on iOS other than showing a window in fullscreen. This patch will check if the statusbar is (initially) hidden from the Info.plist, and respect that in the application. SubAttack is an example of an app that (because of styling issues with MainWindow margins) manually sets the geometry larger than fullsreen, and calls showNormal(). In that case we still want the statusbar to be hidden. Change-Id: Ia365d14971978360d0b39621ff0f8f82f74b57e2 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiosviewcontroller.mm | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/plugins/platforms/ios') diff --git a/src/plugins/platforms/ios/qiosviewcontroller.mm b/src/plugins/platforms/ios/qiosviewcontroller.mm index 9a9fba5a8e..0a6a00b753 100644 --- a/src/plugins/platforms/ios/qiosviewcontroller.mm +++ b/src/plugins/platforms/ios/qiosviewcontroller.mm @@ -101,6 +101,9 @@ - (BOOL)prefersStatusBarHidden { + static bool hiddenFromPlist = infoPlistValue(@"UIStatusBarHidden", false); + if (hiddenFromPlist) + return YES; QWindow *focusWindow = QGuiApplication::focusWindow(); if (!focusWindow || !focusWindow->handle()) return [UIApplication sharedApplication].statusBarHidden; -- cgit v1.2.3 From 6c5febd20331b58f0e55f137af6200d701b03b0e Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Tue, 26 Nov 2013 10:38:21 +0100 Subject: iOS: move infoPlistValue to qiosglobal MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: If237f08683290105413dc47923e23a496765bb22 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qioseventdispatcher.mm | 7 ------- src/plugins/platforms/ios/qiosglobal.h | 1 + src/plugins/platforms/ios/qiosglobal.mm | 7 +++++++ 3 files changed, 8 insertions(+), 7 deletions(-) (limited to 'src/plugins/platforms/ios') diff --git a/src/plugins/platforms/ios/qioseventdispatcher.mm b/src/plugins/platforms/ios/qioseventdispatcher.mm index 51eb10d385..f93c6cc3a7 100644 --- a/src/plugins/platforms/ios/qioseventdispatcher.mm +++ b/src/plugins/platforms/ios/qioseventdispatcher.mm @@ -206,13 +206,6 @@ namespace bool debugStackUsage = false; } -static int infoPlistValue(NSString* key, int defaultValue) -{ - static NSBundle *bundle = [NSBundle mainBundle]; - NSNumber* value = [bundle objectForInfoDictionaryKey:key]; - return value ? [value intValue] : defaultValue; -} - extern "C" int __attribute__((weak)) main(int argc, char *argv[]) { @autoreleasepool { diff --git a/src/plugins/platforms/ios/qiosglobal.h b/src/plugins/platforms/ios/qiosglobal.h index 1c76d29389..17184dc21d 100644 --- a/src/plugins/platforms/ios/qiosglobal.h +++ b/src/plugins/platforms/ios/qiosglobal.h @@ -61,6 +61,7 @@ QPointF fromCGPoint(const CGPoint &point); Qt::ScreenOrientation toQtScreenOrientation(UIDeviceOrientation uiDeviceOrientation); UIDeviceOrientation fromQtScreenOrientation(Qt::ScreenOrientation qtOrientation); QRect fromPortraitToPrimary(const QRect &rect, QPlatformScreen *screen); +int infoPlistValue(NSString* key, int defaultValue); QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qiosglobal.mm b/src/plugins/platforms/ios/qiosglobal.mm index d749b8f514..8dd690f301 100644 --- a/src/plugins/platforms/ios/qiosglobal.mm +++ b/src/plugins/platforms/ios/qiosglobal.mm @@ -134,5 +134,12 @@ QRect fromPortraitToPrimary(const QRect &rect, QPlatformScreen *screen) : QRect(rect.y(), geometry.height() - rect.width() - rect.x(), rect.height(), rect.width()); } +int infoPlistValue(NSString* key, int defaultValue) +{ + static NSBundle *bundle = [NSBundle mainBundle]; + NSNumber* value = [bundle objectForInfoDictionaryKey:key]; + return value ? [value intValue] : defaultValue; +} + QT_END_NAMESPACE -- cgit v1.2.3 From 37f99502f9006c5681686e4a43bc80c2b1d0b089 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Mon, 9 Dec 2013 15:09:29 +0100 Subject: iOS: Fix failing assert in QUIView displayLayer() In layoutSubviews we take the root viewcontroller position into account when determening the new QWindow geometry, but we were missing this logic in displayLayer, and would assert if the in-call statusbar was visible. Since we don't really need the position of the window in displayLayer, we change the assert to only check the size of the exposed area, which is independent of the position of the root viewcontroller. Change-Id: I774b8d9b075518e729f488a789b3a9e584c3f4d3 Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qioswindow.mm | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src/plugins/platforms/ios') diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 1acd9ee354..7a0ff055ec 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -204,11 +204,12 @@ - (void)displayLayer:(CALayer *)layer { - QRect geometry = fromCGRect(layer.frame).toRect(); - Q_ASSERT(m_qioswindow->geometry() == geometry); + QSize bounds = fromCGRect(layer.bounds).toRect().size(); + + Q_ASSERT(m_qioswindow->geometry().size() == bounds); Q_ASSERT(self.hidden == !m_qioswindow->window()->isVisible()); - QRegion region = self.hidden ? QRegion() : QRect(QPoint(), geometry.size()); + QRegion region = self.hidden ? QRegion() : QRect(QPoint(), bounds); QWindowSystemInterface::handleExposeEvent(m_qioswindow->window(), region); QWindowSystemInterface::flushWindowSystemEvents(); } -- cgit v1.2.3