summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/ios
diff options
context:
space:
mode:
authorFrederik Gladhorn <frederik.gladhorn@digia.com>2014-07-01 10:03:53 +0200
committerFrederik Gladhorn <frederik.gladhorn@digia.com>2014-07-01 16:25:19 +0200
commita09a8d509a69ed16d8afbe15296b8332cacd6c66 (patch)
tree28645b437fd0390d903f753a44ba79626eecb8ac /src/plugins/platforms/ios
parent4b28152da64f7f23a1bbb810d8cdb7626a5f0b8e (diff)
parent83f06da1c6bffff61af78cbe75a0691d53742b53 (diff)
Merge remote-tracking branch 'origin/5.3' into dev
Conflicts: mkspecs/qnx-x86-qcc/qplatformdefs.h src/corelib/global/qglobal.h src/network/socket/qnativesocketengine_winrt.cpp src/plugins/platforms/android/androidjniaccessibility.cpp src/plugins/platforms/windows/qwindowswindow.cpp Manually adjusted: mkspecs/qnx-armle-v7-qcc/qplatformdefs.h to include 9ce697f2d54be6d94381c72af28dda79cbc027d4 Thanks goes to Sergio for the qnx mkspecs adjustments. Change-Id: I53b1fd6bc5bc884e5ee2c2b84975f58171a1cb8e
Diffstat (limited to 'src/plugins/platforms/ios')
-rw-r--r--src/plugins/platforms/ios/qiosinputcontext.mm10
-rw-r--r--src/plugins/platforms/ios/quiview.h1
-rw-r--r--src/plugins/platforms/ios/quiview_textinput.mm89
3 files changed, 61 insertions, 39 deletions
diff --git a/src/plugins/platforms/ios/qiosinputcontext.mm b/src/plugins/platforms/ios/qiosinputcontext.mm
index 8be3846e06..d109d53168 100644
--- a/src/plugins/platforms/ios/qiosinputcontext.mm
+++ b/src/plugins/platforms/ios/qiosinputcontext.mm
@@ -54,7 +54,6 @@
QIOSInputContext *m_context;
BOOL m_keyboardVisible;
BOOL m_keyboardVisibleAndDocked;
- BOOL m_ignoreKeyboardChanges;
BOOL m_touchPressWhileKeyboardVisible;
BOOL m_keyboardHiddenByGesture;
QRectF m_keyboardRect;
@@ -74,7 +73,6 @@
m_context = context;
m_keyboardVisible = NO;
m_keyboardVisibleAndDocked = NO;
- m_ignoreKeyboardChanges = NO;
m_touchPressWhileKeyboardVisible = NO;
m_keyboardHiddenByGesture = NO;
m_duration = 0;
@@ -160,7 +158,7 @@
- (void) keyboardWillShow:(NSNotification *)notification
{
- if (m_ignoreKeyboardChanges)
+ if ([QUIView inUpdateKeyboardLayout])
return;
// Note that UIKeyboardWillShowNotification is only sendt when the keyboard is docked.
m_keyboardVisibleAndDocked = YES;
@@ -175,7 +173,7 @@
- (void) keyboardWillHide:(NSNotification *)notification
{
- if (m_ignoreKeyboardChanges)
+ if ([QUIView inUpdateKeyboardLayout])
return;
// Note that UIKeyboardWillHideNotification is also sendt when the keyboard is undocked.
m_keyboardVisibleAndDocked = NO;
@@ -407,11 +405,7 @@ void QIOSInputContext::update(Qt::InputMethodQueries query)
void QIOSInputContext::reset()
{
- // Since the call to reset will cause a 'keyboardWillHide'
- // notification to be sendt, we block keyboard nofifications to avoid artifacts:
- m_keyboardListener->m_ignoreKeyboardChanges = true;
[m_focusView reset];
- m_keyboardListener->m_ignoreKeyboardChanges = false;
}
void QIOSInputContext::commit()
diff --git a/src/plugins/platforms/ios/quiview.h b/src/plugins/platforms/ios/quiview.h
index 91c4fc9dde..7c65037004 100644
--- a/src/plugins/platforms/ios/quiview.h
+++ b/src/plugins/platforms/ios/quiview.h
@@ -77,4 +77,5 @@
- (void)updateInputMethodWithQuery:(Qt::InputMethodQueries)query;
- (void)reset;
- (void)commit;
++ (bool)inUpdateKeyboardLayout;
@end
diff --git a/src/plugins/platforms/ios/quiview_textinput.mm b/src/plugins/platforms/ios/quiview_textinput.mm
index 03006b3f99..e65ac1cc46 100644
--- a/src/plugins/platforms/ios/quiview_textinput.mm
+++ b/src/plugins/platforms/ios/quiview_textinput.mm
@@ -45,9 +45,12 @@ class StaticVariables
{
public:
QInputMethodQueryEvent inputMethodQueryEvent;
+ bool inUpdateKeyboardLayout;
QTextCharFormat markedTextFormat;
- StaticVariables() : inputMethodQueryEvent(Qt::ImQueryInput)
+ StaticVariables()
+ : inputMethodQueryEvent(Qt::ImQueryInput)
+ , inUpdateKeyboardLayout(false)
{
// There seems to be no way to query how the preedit text
// should be drawn. So we need to hard-code the color.
@@ -152,6 +155,47 @@ Q_GLOBAL_STATIC(StaticVariables, staticVariables);
return [super resignFirstResponder];
}
++ (bool)inUpdateKeyboardLayout
+{
+ return staticVariables()->inUpdateKeyboardLayout;
+}
+
+- (void)updateKeyboardLayout
+{
+ if (![self isFirstResponder])
+ return;
+
+ // There seems to be no API to inform that the keyboard layout needs to update.
+ // As a work-around, we quickly resign first responder just to reassign it again.
+ QScopedValueRollback<bool> rollback(staticVariables()->inUpdateKeyboardLayout);
+ staticVariables()->inUpdateKeyboardLayout = true;
+ [super resignFirstResponder];
+ [self updateTextInputTraits];
+ [super becomeFirstResponder];
+}
+
+- (void)updateUITextInputDelegate:(NSNumber *)intQuery
+{
+ // As documented, we should not report textWillChange/textDidChange unless the text
+ // was changed externally. That will cause spell checking etc to fail. But we don't
+ // really know if the text/selection was changed by UITextInput or Qt/app when getting
+ // update calls from Qt. We therefore use a less ideal approach where we always assume
+ // that UITextView caused the change if we're currently processing an event sendt from it.
+ if (m_inSendEventToFocusObject)
+ return;
+
+ Qt::InputMethodQueries query = Qt::InputMethodQueries([intQuery intValue]);
+ if (query & (Qt::ImCursorPosition | Qt::ImAnchorPosition)) {
+ [self.inputDelegate selectionWillChange:id<UITextInput>(self)];
+ [self.inputDelegate selectionDidChange:id<UITextInput>(self)];
+ }
+
+ if (query & Qt::ImSurroundingText) {
+ [self.inputDelegate textWillChange:id<UITextInput>(self)];
+ [self.inputDelegate textDidChange:id<UITextInput>(self)];
+ }
+}
+
- (void)updateInputMethodWithQuery:(Qt::InputMethodQueries)query
{
Q_UNUSED(query);
@@ -160,26 +204,13 @@ Q_GLOBAL_STATIC(StaticVariables, staticVariables);
if (!focusObject)
return;
- if (!m_inSendEventToFocusObject) {
- if (query & (Qt::ImCursorPosition | Qt::ImAnchorPosition))
- [self.inputDelegate selectionWillChange:id<UITextInput>(self)];
- if (query & Qt::ImSurroundingText)
- [self.inputDelegate textWillChange:id<UITextInput>(self)];
- }
-
// Note that we ignore \a query, and instead update using Qt::ImQueryInput. This enables us to just
// store the event without copying out the result from the event each time. Besides, we seem to be
// called with Qt::ImQueryInput when only changing selection, and always if typing text. So there would
// not be any performance gain by only updating \a query.
staticVariables()->inputMethodQueryEvent = QInputMethodQueryEvent(Qt::ImQueryInput);
QCoreApplication::sendEvent(focusObject, &staticVariables()->inputMethodQueryEvent);
-
- if (!m_inSendEventToFocusObject) {
- if (query & (Qt::ImCursorPosition | Qt::ImAnchorPosition))
- [self.inputDelegate selectionDidChange:id<UITextInput>(self)];
- if (query & Qt::ImSurroundingText)
- [self.inputDelegate textDidChange:id<UITextInput>(self)];
- }
+ [self updateUITextInputDelegate:[NSNumber numberWithInt:int(query)]];
}
- (void)sendEventToFocusObject:(QEvent &)e
@@ -189,35 +220,31 @@ Q_GLOBAL_STATIC(StaticVariables, staticVariables);
return;
// While sending the event, we will receive back updateInputMethodWithQuery calls.
- // To not confuse iOS, we cannot not call textWillChange/textDidChange at that
- // point since it will cause spell checking etc to fail. So we use a guard.
+ // Note that it would be more correct to post the event instead, but UITextInput expects
+ // callbacks to take effect immediately (it will query us for information after a callback).
+ QScopedValueRollback<BOOL> rollback(m_inSendEventToFocusObject);
m_inSendEventToFocusObject = YES;
QCoreApplication::sendEvent(focusObject, &e);
- m_inSendEventToFocusObject = NO;
}
- (void)reset
{
- [self.inputDelegate textWillChange:id<UITextInput>(self)];
[self setMarkedText:@"" selectedRange:NSMakeRange(0, 0)];
[self updateInputMethodWithQuery:Qt::ImQueryInput];
-
- if ([self isFirstResponder]) {
- // There seem to be no way to inform that the keyboard needs to update (since
- // text input traits might have changed). As a work-around, we quickly resign
- // first responder status just to reassign it again:
- [super resignFirstResponder];
- [self updateTextInputTraits];
- [super becomeFirstResponder];
- }
- [self.inputDelegate textDidChange:id<UITextInput>(self)];
+ // Guard agains recursive callbacks by posting calls to UITextInput
+ [self performSelectorOnMainThread:@selector(updateKeyboardLayout) withObject:nil waitUntilDone:NO];
+ [self performSelectorOnMainThread:@selector(updateUITextInputDelegate:)
+ withObject:[NSNumber numberWithInt:int(Qt::ImQueryInput)]
+ waitUntilDone:NO];
}
- (void)commit
{
- [self.inputDelegate textWillChange:id<UITextInput>(self)];
[self unmarkText];
- [self.inputDelegate textDidChange:id<UITextInput>(self)];
+ // Guard agains recursive callbacks by posting calls to UITextInput
+ [self performSelectorOnMainThread:@selector(updateUITextInputDelegate:)
+ withObject:[NSNumber numberWithInt:int(Qt::ImSurroundingText)]
+ waitUntilDone:NO];
}
- (QVariant)imValue:(Qt::InputMethodQuery)query