summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/ios/qiostextresponder.mm
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/platforms/ios/qiostextresponder.mm')
-rw-r--r--src/plugins/platforms/ios/qiostextresponder.mm80
1 files changed, 60 insertions, 20 deletions
diff --git a/src/plugins/platforms/ios/qiostextresponder.mm b/src/plugins/platforms/ios/qiostextresponder.mm
index 54362cde7a..2fcc7258f7 100644
--- a/src/plugins/platforms/ios/qiostextresponder.mm
+++ b/src/plugins/platforms/ios/qiostextresponder.mm
@@ -173,9 +173,13 @@
m_inSendEventToFocusObject = NO;
m_inputContext = inputContext;
+ QVariantMap platformData = [self imValue:Qt::ImPlatformData].toMap();
Qt::InputMethodHints hints = Qt::InputMethodHints([self imValue:Qt::ImHints].toUInt());
- self.returnKeyType = (hints & Qt::ImhMultiLine) ? UIReturnKeyDefault : UIReturnKeyDone;
+ self.returnKeyType = platformData.value(kImePlatformDataReturnKeyType).isValid() ?
+ UIReturnKeyType(platformData.value(kImePlatformDataReturnKeyType).toInt()) :
+ (hints & Qt::ImhMultiLine) ? UIReturnKeyDefault : UIReturnKeyDone;
+
self.secureTextEntry = BOOL(hints & Qt::ImhHiddenText);
self.autocorrectionType = (hints & Qt::ImhNoPredictiveText) ?
UITextAutocorrectionTypeNo : UITextAutocorrectionTypeDefault;
@@ -202,7 +206,6 @@
else
self.keyboardType = UIKeyboardTypeDefault;
- QVariantMap platformData = [self imValue:Qt::ImPlatformData].toMap();
if (UIView *inputView = static_cast<UIView *>(platformData.value(kImePlatformDataInputView).value<void *>()))
self.inputView = [[[WrapperView alloc] initWithView:inputView] autorelease];
if (UIView *accessoryView = static_cast<UIView *>(platformData.value(kImePlatformDataInputAccessoryView).value<void *>()))
@@ -218,30 +221,68 @@
[super dealloc];
}
-- (BOOL)isFirstResponder
+- (BOOL)canBecomeFirstResponder
{
return YES;
}
-- (UIResponder*)nextResponder
+- (BOOL)becomeFirstResponder
{
- return qApp->focusWindow() ?
- reinterpret_cast<QUIView *>(qApp->focusWindow()->handle()->winId()) : 0;
+ FirstResponderCandidate firstResponderCandidate(self);
+
+ qImDebug() << "self:" << self << "first:" << [UIResponder currentFirstResponder];
+
+ if (![super becomeFirstResponder]) {
+ qImDebug() << self << "was not allowed to become first responder";
+ return NO;
+ }
+
+ qImDebug() << self << "became first responder";
+
+ return YES;
}
-/*!
- iOS uses [UIResponder(Internal) _requiresKeyboardWhenFirstResponder] to check if the
- current responder should bring up the keyboard, which in turn checks if the responder
- supports the UIKeyInput protocol. By dynamically reporting our protocol conformance
- we can control the keyboard visibility depending on whether or not we have a focus
- object with IME enabled.
-*/
-- (BOOL)conformsToProtocol:(Protocol *)protocol
+- (BOOL)resignFirstResponder
{
- if (protocol == @protocol(UIKeyInput))
- return m_inputContext->inputMethodAccepted();
+ qImDebug() << "self:" << self << "first:" << [UIResponder currentFirstResponder];
- return [super conformsToProtocol:protocol];
+ // Don't allow activation events of the window that we're doing text on behalf on
+ // to steal responder.
+ if (FirstResponderCandidate::currentCandidate() == [self nextResponder]) {
+ qImDebug() << "not allowing parent window to steal responder";
+ return NO;
+ }
+
+ if (![super resignFirstResponder])
+ return NO;
+
+ qImDebug() << self << "resigned first responder";
+
+ // Dismissing the keyboard will trigger resignFirstResponder, but so will
+ // a regular responder transfer to another window. In the former case, iOS
+ // will set the new first-responder to our next-responder, and in the latter
+ // case we'll have an active responder candidate.
+ if ([UIResponder currentFirstResponder] == [self nextResponder]) {
+ // We have resigned the keyboard, and transferred back to the parent view, so unset focus object
+ Q_ASSERT(!FirstResponderCandidate::currentCandidate());
+ qImDebug() << "keyboard was closed, clearing focus object";
+ m_inputContext->clearCurrentFocusObject();
+ } else {
+ // We've lost responder status because another Qt window was made active,
+ // another QIOSTextResponder was made first-responder, another UIView was
+ // made first-responder, or the first-responder was cleared globally. In
+ // either of these cases we don't have to do anything.
+ qImDebug() << "lost first responder, but not clearing focus object";
+ }
+
+ return YES;
+}
+
+
+- (UIResponder*)nextResponder
+{
+ return qApp->focusWindow() ?
+ reinterpret_cast<QUIView *>(qApp->focusWindow()->handle()->winId()) : 0;
}
// -------------------------------------------------------------------------
@@ -575,9 +616,8 @@
[self sendEventToFocusObject:press];
[self sendEventToFocusObject:release];
- Qt::InputMethodHints imeHints = static_cast<Qt::InputMethodHints>([self imValue:Qt::ImHints].toUInt());
- if (!(imeHints & Qt::ImhMultiLine))
- m_inputContext->hideVirtualKeyboard();
+ if (self.returnKeyType == UIReturnKeyDone)
+ [self resignFirstResponder];
return;
}