From b24da5449bc0520b8c6eb9a943f934d95fd49cfa Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Thu, 6 May 2021 17:00:22 +0200 Subject: [PATCH] macOS: in password lineedits, pass dead keys to the input method MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Otherwise the IM cannot correctly compose the input, making it impossible to enter e.g. ü or ~ on certain keyboard layouts. Note that the native macOS NSSecureTextField does not allow that either, which is however a very bad user experience. With this change, the modifier characters like ¨ diacritics will be visible when entering them in either NoEcho or Password line edits. The follow-up commit will remove those as well. Fixes: QTBUG-84664 Change-Id: Ib4c5ab85634c17c407623f82b46c4849c72d9e69 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/cocoa/qnsview.mm | 2 ++ src/plugins/platforms/cocoa/qnsview_keys.mm | 6 +++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index 471fa368c33..8e4efc6fb64 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -125,6 +125,7 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSViewMouseMoveHelper); Qt::MouseButtons m_frameStrutButtons; QString m_composingText; QPointer m_composingFocusObject; + bool m_lastKeyDead; bool m_sendKeyEvent; bool m_dontOverrideCtrlLMB; bool m_sendUpAsRightButton; @@ -142,6 +143,7 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSViewMouseMoveHelper); { if ((self = [super initWithFrame:NSZeroRect])) { m_platformWindow = platformWindow; + m_lastKeyDead = false; m_sendKeyEvent = false; m_inputSource = nil; m_resendKeyEvent = false; diff --git a/src/plugins/platforms/cocoa/qnsview_keys.mm b/src/plugins/platforms/cocoa/qnsview_keys.mm index 23b8254d630..d58155237e0 100644 --- a/src/plugins/platforms/cocoa/qnsview_keys.mm +++ b/src/plugins/platforms/cocoa/qnsview_keys.mm @@ -111,11 +111,15 @@ if (QCoreApplication::sendEvent(fo, &queryEvent)) { bool imEnabled = queryEvent.value(Qt::ImEnabled).toBool(); Qt::InputMethodHints hints = static_cast(queryEvent.value(Qt::ImHints).toUInt()); - if (imEnabled && !(hints & Qt::ImhDigitsOnly || hints & Qt::ImhFormattedNumbersOnly || hints & Qt::ImhHiddenText)) { + // make sure we send dead keys and the next key to the input method for composition + const bool ignoreHidden = (hints & Qt::ImhHiddenText) && !text.isEmpty() && !m_lastKeyDead; + if (imEnabled && !(hints & Qt::ImhDigitsOnly || hints & Qt::ImhFormattedNumbersOnly || ignoreHidden)) { // pass the key event to the input method. note that m_sendKeyEvent may be set to false during this call m_currentlyInterpretedKeyEvent = nsevent; [self interpretKeyEvents:@[nsevent]]; m_currentlyInterpretedKeyEvent = 0; + // if the last key we sent was dead, then pass the next key to the IM as well to complete composition + m_lastKeyDead = text.isEmpty(); } } }