macOS: Always place input panels at NSPopUpMenuWindowLevel or above

Implementing NSTextInputClient.windowLevel to return the level of the
current input client window is not sufficient, as there may be other
windows visible with a higher window level than that.

For example, QCompleter's completion is shown using a Qt::Popup
window, which has a NSPopUpMenuWindowLevel.

Ideally we'd hide the QCompleter's completion when the IM is
in the process of compositing, but as a first step, and as
safeguard for other similar scenarios, we now return a minimum
window level of NSPopUpMenuWindowLevel for our text input
client.

Fixes: QTBUG-102831
Pick-to: 6.5 6.2
Change-Id: Id74a6350595bd136027a9af470f6700ee90f52a7
Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>
(cherry picked from commit cc4834c0b975300e9405fa001f917199dd41139c)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
Tor Arne Vestbø 2023-11-07 20:01:19 -08:00 committed by Qt Cherry-pick Bot
parent e5b46f3ea7
commit 33584b7572

View File

@ -518,8 +518,17 @@
// including being set via QWindow::setFlags() or directly on the
// NSWindow, or because we're embedded into a native view hierarchy.
// Return the actual window level to account for this.
return m_platformWindow ? m_platformWindow->nativeWindow().level
: NSNormalWindowLevel;
auto level = m_platformWindow ? m_platformWindow->nativeWindow().level
: NSNormalWindowLevel;
// The logic above only covers our own window though. In some cases,
// such as when a completer is active, the text input has a lower
// window level than another window that's also visible, and we don't
// want the input panel to be sandwiched between these two windows.
// Account for this by explicitly using NSPopUpMenuWindowLevel as
// the minimum window level, which corresponds to the highest level
// one can get via QWindow::setFlags(), except for Qt::ToolTip.
return qMax(level, NSPopUpMenuWindowLevel);
}
// ------------- Helper functions -------------