summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/ios/qiostextresponder.mm
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@theqtcompany.com>2015-12-18 08:37:31 +0100
committerLiang Qi <liang.qi@theqtcompany.com>2015-12-18 08:37:31 +0100
commitbeb65dcd79f8c354dab7bb4a8d08157bd9d69329 (patch)
tree4632a0ff0df8462f8913f347042cf8378de03268 /src/plugins/platforms/ios/qiostextresponder.mm
parent3fc1002489d5861d4f7cc2e1e8800881d6593c9d (diff)
parente3288f246b44ba2b6d90b90eb99ab61f496d8d57 (diff)
Merge remote-tracking branch 'origin/5.6' into dev
Conflicts: src/gui/painting/painting.pri src/plugins/platforms/xcb/qxcbconnection.cpp tests/auto/corelib/thread/qthreadstorage/qthreadstorage.pro tests/auto/corelib/tools/qlocale/test/test.pro tests/auto/gui/kernel/qwindow/tst_qwindow.cpp tools/configure/environment.cpp Change-Id: I9c40f458b89b2c206de2d2c24e90b5f679c93495
Diffstat (limited to 'src/plugins/platforms/ios/qiostextresponder.mm')
-rw-r--r--src/plugins/platforms/ios/qiostextresponder.mm61
1 files changed, 58 insertions, 3 deletions
diff --git a/src/plugins/platforms/ios/qiostextresponder.mm b/src/plugins/platforms/ios/qiostextresponder.mm
index 9ca5e22b90..320b1cac61 100644
--- a/src/plugins/platforms/ios/qiostextresponder.mm
+++ b/src/plugins/platforms/ios/qiostextresponder.mm
@@ -318,7 +318,11 @@
// 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]) {
+ if (![UIResponder currentFirstResponder]) {
+ // No first responder set anymore, sync this with Qt by clearing the
+ // focus object.
+ m_inputContext->clearCurrentFocusObject();
+ } else if ([UIResponder currentFirstResponder] == [self nextResponder]) {
// We have resigned the keyboard, and transferred first responder back to the parent view
Q_ASSERT(!FirstResponderCandidate::currentCandidate());
if ([self currentImeState:Qt::ImEnabled].toBool()) {
@@ -364,6 +368,32 @@
[self sendKeyPressRelease:key modifiers:modifiers];
}
+- (BOOL)canPerformAction:(SEL)action withSender:(id)sender
+{
+ bool isEditAction = (action == @selector(cut:)
+ || action == @selector(copy:)
+ || action == @selector(paste:)
+ || action == @selector(delete:)
+ || action == @selector(toggleBoldface:)
+ || action == @selector(toggleItalics:)
+ || action == @selector(toggleUnderline:)
+ || action == @selector(undo)
+ || action == @selector(redo));
+
+ bool isSelectAction = (action == @selector(select:)
+ || action == @selector(selectAll:)
+ || action == @selector(paste:)
+ || action == @selector(undo)
+ || action == @selector(redo));
+
+ const bool unknownAction = !isEditAction && !isSelectAction;
+ const bool hasSelection = ![self selectedTextRange].empty;
+
+ if (unknownAction)
+ return [super canPerformAction:action withSender:sender];
+ return (hasSelection && isEditAction) || (!hasSelection && isSelectAction);
+}
+
- (void)cut:(id)sender
{
Q_UNUSED(sender);
@@ -382,6 +412,13 @@
[self sendShortcut:QKeySequence::Paste];
}
+- (void)select:(id)sender
+{
+ Q_UNUSED(sender);
+ [self sendShortcut:QKeySequence::MoveToPreviousWord];
+ [self sendShortcut:QKeySequence::SelectNextWord];
+}
+
- (void)selectAll:(id)sender
{
Q_UNUSED(sender);
@@ -580,7 +617,8 @@
- (UITextPosition *)endOfDocument
{
- int endPosition = [self currentImeState:Qt::ImSurroundingText].toString().length();
+ QString surroundingText = [self currentImeState:Qt::ImSurroundingText].toString();
+ int endPosition = surroundingText.length() + m_markedText.length();
return [QUITextPosition positionWithIndex:endPosition];
}
@@ -611,9 +649,18 @@
- (NSString *)textInRange:(UITextRange *)range
{
+ QString text = [self currentImeState:Qt::ImSurroundingText].toString();
+ if (!m_markedText.isEmpty()) {
+ // [UITextInput textInRange] is sparsely documented, but it turns out that unconfirmed
+ // marked text should be seen as a part of the text document. This is different from
+ // ImSurroundingText, which excludes it.
+ int cursorPos = [self currentImeState:Qt::ImCursorPosition].toInt();
+ text = text.left(cursorPos) + m_markedText + text.mid(cursorPos);
+ }
+
int s = static_cast<QUITextPosition *>([range start]).index;
int e = static_cast<QUITextPosition *>([range end]).index;
- return [self currentImeState:Qt::ImSurroundingText].toString().mid(s, e - s).toNSString();
+ return text.mid(s, e - s).toNSString();
}
- (void)setMarkedText:(NSString *)markedText selectedRange:(NSRange)selectedRange
@@ -882,6 +929,14 @@
if ([text isEqualToString:@"\n"]) {
[self sendKeyPressRelease:Qt::Key_Return modifiers:Qt::NoModifier];
+ // An onEnter handler of a TextInput might move to the next input by calling
+ // nextInput.forceActiveFocus() which changes the focusObject.
+ // In that case we don't want to hide the VKB.
+ if (focusObject != QGuiApplication::focusObject()) {
+ qImDebug() << "focusObject already changed, not resigning first responder.";
+ return;
+ }
+
if (self.returnKeyType == UIReturnKeyDone || self.returnKeyType == UIReturnKeyGo
|| self.returnKeyType == UIReturnKeySend || self.returnKeyType == UIReturnKeySearch)
[self resignFirstResponder];