iOS: update keyboard layout upon focus transfer
When iOS transfers focus from one view to another, it asks the new view for its UIKeyInput properties before deciding how the keyboard should be configured. For Qt, the same QUIView is used for the whole QWindow which means that UIKit will not change the keyboard configuration just because we change the focus object in Qt, since the UIView does not change. There seems to be no way to tell UIKit that the keyboard needs to change becuse the UIKeyInput properties has changed. To work around this, we briefly resign first responder status, and grabs it again, for the same QUIView. Change-Id: I2d15cc0c928deb023e7da58ad4669b7099dce2cf Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@digia.com>
This commit is contained in:
parent
bdf0670c02
commit
484d6ce776
@ -71,6 +71,7 @@ private:
|
||||
UIView<UIKeyInput> *m_focusView;
|
||||
QTransform m_inputItemTransform;
|
||||
bool m_hasPendingHideRequest;
|
||||
bool m_inSetFocusObject;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -170,6 +170,7 @@ QIOSInputContext::QIOSInputContext()
|
||||
, m_keyboardListener([[QIOSKeyboardListener alloc] initWithQIOSInputContext:this])
|
||||
, m_focusView(0)
|
||||
, m_hasPendingHideRequest(false)
|
||||
, m_inSetFocusObject(false)
|
||||
{
|
||||
if (isQtApplication())
|
||||
connect(qGuiApp->inputMethod(), &QInputMethod::cursorRectangleChanged, this, &QIOSInputContext::scrollRootView);
|
||||
@ -218,7 +219,22 @@ bool QIOSInputContext::isInputPanelVisible() const
|
||||
void QIOSInputContext::setFocusObject(QObject *)
|
||||
{
|
||||
m_inputItemTransform = qApp->inputMethod()->inputItemTransform();
|
||||
scrollRootView();
|
||||
|
||||
if (!m_focusView || !m_focusView.isFirstResponder)
|
||||
return;
|
||||
|
||||
// Since m_focusView is the first responder, it means that the keyboard is open and we
|
||||
// should update keyboard layout. But there seem to be no way to tell it to reread the
|
||||
// UITextInputTraits from m_focusView. To work around that, we quickly resign first
|
||||
// responder status just to reassign it again. To not remove the focusObject in the same
|
||||
// go, we need to call the super implementation of resignFirstResponder. Since the call
|
||||
// will cause a 'keyboardWillHide' notification to be sendt, we also block scrollRootView
|
||||
// to avoid artifacts:
|
||||
m_inSetFocusObject = true;
|
||||
SEL sel = @selector(resignFirstResponder);
|
||||
[[m_focusView superclass] instanceMethodForSelector:sel](m_focusView, sel);
|
||||
m_inSetFocusObject = false;
|
||||
[m_focusView becomeFirstResponder];
|
||||
}
|
||||
|
||||
void QIOSInputContext::focusWindowChanged(QWindow *focusWindow)
|
||||
@ -238,7 +254,7 @@ void QIOSInputContext::scrollRootView()
|
||||
// - the first responder is a QUIView, and not some other foreign UIView.
|
||||
// - the keyboard is docked. Otherwise the user can move the keyboard instead.
|
||||
// - the inputItem has not been moved/scrolled
|
||||
if (!isQtApplication() || !m_focusView)
|
||||
if (!isQtApplication() || !m_focusView || m_inSetFocusObject)
|
||||
return;
|
||||
|
||||
if (m_inputItemTransform != qApp->inputMethod()->inputItemTransform()) {
|
||||
|
Loading…
Reference in New Issue
Block a user