From 2b361aceb315b401dea7ef3eb6ddbcffa8005abc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Tue, 7 Nov 2023 20:01:19 -0800 Subject: [PATCH] macOS: Always place input panels at NSPopUpMenuWindowLevel or above MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Change-Id: Id74a6350595bd136027a9af470f6700ee90f52a7 Reviewed-by: Timur Pocheptsov (cherry picked from commit cc4834c0b975300e9405fa001f917199dd41139c) Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/cocoa/qnsview_complextext.mm | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/cocoa/qnsview_complextext.mm b/src/plugins/platforms/cocoa/qnsview_complextext.mm index a93527381b1..5063e997324 100644 --- a/src/plugins/platforms/cocoa/qnsview_complextext.mm +++ b/src/plugins/platforms/cocoa/qnsview_complextext.mm @@ -542,8 +542,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 -------------