summaryrefslogtreecommitdiffstats
path: root/src/plugins
diff options
context:
space:
mode:
authorTor Arne Vestbø <tor.arne.vestbo@digia.com>2014-11-25 15:43:52 +0100
committerTor Arne Vestbø <tor.arne.vestbo@digia.com>2014-12-02 10:56:54 +0100
commit44e9e7fe199f197fe1e639e5fbcf858f4775d31b (patch)
tree07477f5629352867f0a68031a803afa793f244a2 /src/plugins
parentc59c8ddf1f98938441925e01d9931c3c1eb3f5cc (diff)
iOS: Simplify view management in QIOSKeyboardListener
We don't need to keep track of the view-controller or add ourselves as a gesture recognizer inside QIOSKeyboardListener. In fact, leaving the call to removeGestureRecognizer in [QIOSKeyboardListener dealloc] will result in QIOSKeyboardListener never being released, as the view that we add the recognizer to will keep a strong reference to the recognizer, so dealloc is never called unless the view is also released, which is unlikely to happen. We now fully control the lifetime of the recognizer. Change-Id: I6755e8cdfcc8f1062314db51aa54a2b7ecd1b967 Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@theqtcompany.com>
Diffstat (limited to 'src/plugins')
-rw-r--r--src/plugins/platforms/ios/qiosinputcontext.h2
-rw-r--r--src/plugins/platforms/ios/qiosinputcontext.mm71
-rw-r--r--src/plugins/platforms/ios/qiosscreen.h1
-rw-r--r--src/plugins/platforms/ios/qiosscreen.mm5
4 files changed, 48 insertions, 31 deletions
diff --git a/src/plugins/platforms/ios/qiosinputcontext.h b/src/plugins/platforms/ios/qiosinputcontext.h
index 174c44751c..eb6b04a2ac 100644
--- a/src/plugins/platforms/ios/qiosinputcontext.h
+++ b/src/plugins/platforms/ios/qiosinputcontext.h
@@ -91,6 +91,8 @@ public:
static QIOSInputContext *instance();
private:
+ UIView* scrollableRootView();
+
union {
QIOSKeyboardListener *m_keyboardHideGesture;
id <KeyboardState> m_keyboardState;
diff --git a/src/plugins/platforms/ios/qiosinputcontext.mm b/src/plugins/platforms/ios/qiosinputcontext.mm
index 72437fea6e..49eff2b88a 100644
--- a/src/plugins/platforms/ios/qiosinputcontext.mm
+++ b/src/plugins/platforms/ios/qiosinputcontext.mm
@@ -45,6 +45,7 @@
#include "qiosglobal.h"
#include "qiosintegration.h"
+#include "qiosscreen.h"
#include "qiostextresponder.h"
#include "qiosviewcontroller.h"
#include "qioswindow.h"
@@ -76,8 +77,6 @@ static QUIView *focusView()
// -------------------------------------------------------------------------
@interface QIOSKeyboardListener : UIGestureRecognizer <KeyboardState, UIGestureRecognizerDelegate> {
- @public
- UIViewController *m_viewController;
@private
QIOSInputContext *m_context;
}
@@ -97,26 +96,13 @@ static QUIView *focusView()
{
if (self = [super initWithTarget:self action:@selector(gestureStateChanged:)]) {
m_context = context;
- m_viewController = 0;
-
- if (isQtApplication()) {
- // Get the root view controller that is on the same screen as the keyboard:
- for (UIWindow *uiWindow in [[UIApplication sharedApplication] windows]) {
- if (uiWindow.screen == [UIScreen mainScreen]) {
- m_viewController = [uiWindow.rootViewController retain];
- break;
- }
- }
- Q_ASSERT(m_viewController);
-
- // Attach 'hide keyboard' gesture to the window, but keep it disabled when the
- // keyboard is not visible.
- self.enabled = NO;
- self.cancelsTouchesInView = NO;
- self.delaysTouchesEnded = NO;
- [m_viewController.view.window addGestureRecognizer:self];
- }
+ // UIGestureRecognizer
+ self.enabled = NO;
+ self.cancelsTouchesInView = NO;
+ self.delaysTouchesEnded = NO;
+
+ /// KeyboardState
self.keyboardVisible = NO;
self.keyboardVisibleAndDocked = NO;
self.animationDuration = 0;
@@ -141,9 +127,6 @@ static QUIView *focusView()
- (void)dealloc
{
- [m_viewController.view.window removeGestureRecognizer:self];
- [m_viewController release];
-
[[NSNotificationCenter defaultCenter]
removeObserver:self
name:@"UIKeyboardWillShowNotification" object:nil];
@@ -247,7 +230,7 @@ static QUIView *focusView()
if (self.state != UIGestureRecognizerStatePossible)
return;
- CGPoint touchPoint = [[touches anyObject] locationInView:m_viewController.view.window];
+ CGPoint touchPoint = [[touches anyObject] locationInView:self.view];
if (CGRectContainsPoint(self.keyboardEndRect, touchPoint))
self.state = UIGestureRecognizerStateBegan;
}
@@ -349,14 +332,21 @@ QIOSInputContext::QIOSInputContext()
, m_keyboardHideGesture([[QIOSKeyboardListener alloc] initWithQIOSInputContext:this])
, m_textResponder(0)
{
- if (isQtApplication())
+ if (isQtApplication()) {
+ QIOSScreen *iosScreen = static_cast<QIOSScreen*>(QGuiApplication::primaryScreen()->handle());
+ [iosScreen->uiWindow() addGestureRecognizer:m_keyboardHideGesture];
+
connect(qGuiApp->inputMethod(), &QInputMethod::cursorRectangleChanged, this, &QIOSInputContext::cursorRectangleChanged);
+ }
+
connect(qGuiApp, &QGuiApplication::focusWindowChanged, this, &QIOSInputContext::focusWindowChanged);
}
QIOSInputContext::~QIOSInputContext()
{
+ [m_keyboardHideGesture.view removeGestureRecognizer:m_keyboardHideGesture];
[m_keyboardHideGesture release];
+
[m_textResponder release];
}
@@ -398,6 +388,8 @@ QRectF QIOSInputContext::keyboardRect() const
return m_keyboardState.keyboardRect;
}
+// -------------------------------------------------------------------------
+
void QIOSInputContext::cursorRectangleChanged()
{
if (!m_keyboardState.keyboardVisibleAndDocked || !qApp->focusObject())
@@ -415,6 +407,18 @@ void QIOSInputContext::cursorRectangleChanged()
prevCursor = cursor;
}
+UIView *QIOSInputContext::scrollableRootView()
+{
+ if (!m_keyboardHideGesture.view)
+ return 0;
+
+ UIWindow *window = static_cast<UIWindow*>(m_keyboardHideGesture.view);
+ if (![window.rootViewController isKindOfClass:[QIOSViewController class]])
+ return 0;
+
+ return window.rootViewController.view;
+}
+
void QIOSInputContext::scrollToCursor()
{
if (!isQtApplication())
@@ -427,24 +431,29 @@ void QIOSInputContext::scrollToCursor()
return;
}
- UIView *view = m_keyboardHideGesture->m_viewController.view;
- if (view.window != focusView().window)
+ UIView *rootView = scrollableRootView();
+ if (!rootView)
+ return;
+
+ if (rootView.window != focusView().window)
return;
const int margin = 20;
QRectF translatedCursorPos = qApp->inputMethod()->cursorRectangle();
translatedCursorPos.translate(focusView().qwindow->geometry().topLeft());
- qreal keyboardY = [view convertRect:m_keyboardState.keyboardEndRect fromView:nil].origin.y;
+ qreal keyboardY = [rootView convertRect:m_keyboardState.keyboardEndRect fromView:nil].origin.y;
int statusBarY = qGuiApp->primaryScreen()->availableGeometry().y();
scroll((translatedCursorPos.bottomLeft().y() < keyboardY - margin) ? 0
- : qMin(view.bounds.size.height - keyboardY, translatedCursorPos.y() - statusBarY - margin));
+ : qMin(rootView.bounds.size.height - keyboardY, translatedCursorPos.y() - statusBarY - margin));
}
void QIOSInputContext::scroll(int y)
{
- UIView *rootView = m_keyboardHideGesture->m_viewController.view;
+ UIView *rootView = scrollableRootView();
+ if (!rootView)
+ return;
CATransform3D translationTransform = CATransform3DMakeTranslation(0.0, -y, 0.0);
if (CATransform3DEqualToTransform(translationTransform, rootView.layer.sublayerTransform))
diff --git a/src/plugins/platforms/ios/qiosscreen.h b/src/plugins/platforms/ios/qiosscreen.h
index 7987ef82d5..7aa62b9190 100644
--- a/src/plugins/platforms/ios/qiosscreen.h
+++ b/src/plugins/platforms/ios/qiosscreen.h
@@ -63,6 +63,7 @@ public:
void setOrientationUpdateMask(Qt::ScreenOrientations mask);
UIScreen *uiScreen() const;
+ UIWindow *uiWindow() const;
void updateProperties();
diff --git a/src/plugins/platforms/ios/qiosscreen.mm b/src/plugins/platforms/ios/qiosscreen.mm
index e70b369b79..4af2a4965f 100644
--- a/src/plugins/platforms/ios/qiosscreen.mm
+++ b/src/plugins/platforms/ios/qiosscreen.mm
@@ -321,6 +321,11 @@ UIScreen *QIOSScreen::uiScreen() const
return m_uiScreen;
}
+UIWindow *QIOSScreen::uiWindow() const
+{
+ return m_uiWindow;
+}
+
#include "moc_qiosscreen.cpp"
QT_END_NAMESPACE