Fix locator popup on Windows

When the locator popup gets focus on Windows, we need to handle the
escape key explicitly and also need to make sure that it isn't
considered as a "base window" when requesting locator again.

On other platforms the locator popup never gets focus, so the issue
doesn't appear.

Fixes: QTCREATORBUG-22119
Change-Id: I1e1a74332c174bc20f961ebe0709c591f82f2829
Reviewed-by: David Schulz <david.schulz@qt.io>
Reviewed-by: André Hartmann <aha_1980@gmx.de>
This commit is contained in:
Eike Ziller
2021-11-17 14:32:05 +01:00
parent 1b57bee32b
commit db1d3f3c94
2 changed files with 27 additions and 4 deletions

View File

@@ -54,6 +54,9 @@ static LocatorWidget *locatorWidget()
{
static QPointer<LocatorPopup> popup;
QWidget *window = ICore::dialogParent()->window();
// if that is a popup, try to find a better one
if (window->windowFlags() & Qt::Popup && window->parentWidget())
window = window->parentWidget()->window();
if (auto *widget = Aggregation::query<LocatorWidget>(window)) {
if (popup)
popup->close();

View File

@@ -360,21 +360,40 @@ void LocatorPopup::updateWindow()
bool LocatorPopup::event(QEvent *event)
{
if (event->type() == QEvent::ParentChange)
if (event->type() == QEvent::ParentChange) {
updateWindow();
else if (event->type() == QEvent::Show)
} else if (event->type() == QEvent::Show) {
// make sure the popup has correct position before it becomes visible
doUpdateGeometry();
else if (event->type() == QEvent::LayoutRequest)
} else if (event->type() == QEvent::LayoutRequest) {
// completion list resizes after first items are shown --> LayoutRequest
QMetaObject::invokeMethod(this, &LocatorPopup::doUpdateGeometry, Qt::QueuedConnection);
} else if (event->type() == QEvent::ShortcutOverride) {
// if we (the popup) has focus, we need to handle escape manually (Windows)
auto ke = static_cast<QKeyEvent *>(event);
if (ke->modifiers() == Qt::NoModifier && ke->key() == Qt::Key_Escape)
event->accept();
} else if (event->type() == QEvent::KeyPress) {
// if we (the popup) has focus, we need to handle escape manually (Windows)
auto ke = static_cast<QKeyEvent *>(event);
if (ke->modifiers() == Qt::NoModifier && ke->key() == Qt::Key_Escape)
hide();
}
return QWidget::event(event);
}
bool LocatorPopup::eventFilter(QObject *watched, QEvent *event)
{
if (watched == m_window && event->type() == QEvent::Resize)
if (watched == m_tree && event->type() == QEvent::FocusOut) {
// if the tree had focus and another application is brought to foreground,
// we need to hide the popup because it otherwise stays on top of
// everything else (even other applications) (Windows)
auto fe = static_cast<QFocusEvent *>(event);
if (fe->reason() == Qt::ActiveWindowFocusReason && !QApplication::activeWindow())
hide();
} else if (watched == m_window && event->type() == QEvent::Resize) {
doUpdateGeometry();
}
return QWidget::eventFilter(watched, event);
}
@@ -412,6 +431,7 @@ LocatorPopup::LocatorPopup(LocatorWidget *locatorWidget, QWidget *parent)
m_tree->setFrameStyle(QFrame::NoFrame); // tool tip already includes a frame
m_tree->setModel(locatorWidget->model());
m_tree->setTextElideMode(Qt::ElideMiddle);
m_tree->installEventFilter(this);
auto layout = new QVBoxLayout;
layout->setSizeConstraint(QLayout::SetMinimumSize);