vcl/inc/qt5/Qt5Frame.hxx | 7 +++++++ vcl/inc/qt5/Qt5Widget.hxx | 1 + vcl/qt5/Qt5Frame.cxx | 10 ++++++---- vcl/qt5/Qt5Widget.cxx | 24 +++++++++++++++++------- 4 files changed, 31 insertions(+), 11 deletions(-)
New commits: commit 9dcf5816c90e9819861332f11e014ef7b78e2fe7 Author: Jan-Marek Glogowski <glo...@fbihome.de> AuthorDate: Fri Jul 30 05:25:37 2021 +0200 Commit: Jan-Marek Glogowski <glo...@fbihome.de> CommitDate: Fri Jul 30 20:24:39 2021 +0200 tdf#143580 Qt5 don't use Qt::Popup for FLOAT wins Main problem is, that Qt::Popup grabs the focus and therefore generates a focus-out event for the combobox, which then closes the just shown popup window. The grab happens inside QWidget private code and there is no way around it. But instead of "faking" Qt::Tooltip, this uses Qt::Widget with additional flags. Regression from commit 7e6fee830116823b9cd8e46d6962df4ea2bc1ea6 ("Qt5 fix Qt::Popup window handling"). Change-Id: Ia1f8e33d98f7ec36cf1ebc350886121dfaadd658 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/119691 Tested-by: Jenkins Reviewed-by: Jan-Marek Glogowski <glo...@fbihome.de> diff --git a/vcl/inc/qt5/Qt5Frame.hxx b/vcl/inc/qt5/Qt5Frame.hxx index ed82c2a7a8fb..01b93ad3b825 100644 --- a/vcl/inc/qt5/Qt5Frame.hxx +++ b/vcl/inc/qt5/Qt5Frame.hxx @@ -210,6 +210,7 @@ public: inline bool CallCallback(SalEvent nEvent, const void* pEvent) const; void setInputLanguage(LanguageType); + inline bool isPopup() const; }; inline bool Qt5Frame::CallCallback(SalEvent nEvent, const void* pEvent) const @@ -218,4 +219,10 @@ inline bool Qt5Frame::CallCallback(SalEvent nEvent, const void* pEvent) const return SalFrame::CallCallback(nEvent, pEvent); } +inline bool Qt5Frame::isPopup() const +{ + return ((m_nStyle & SalFrameStyleFlags::FLOAT) + && !(m_nStyle & SalFrameStyleFlags::OWNERDRAWDECORATION)); +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/inc/qt5/Qt5Widget.hxx b/vcl/inc/qt5/Qt5Widget.hxx index 7bf7ead6ae9a..60db1a306efd 100644 --- a/vcl/inc/qt5/Qt5Widget.hxx +++ b/vcl/inc/qt5/Qt5Widget.hxx @@ -75,6 +75,7 @@ class Qt5Widget : public QWidget void inputMethodEvent(QInputMethodEvent*) override; QVariant inputMethodQuery(Qt::InputMethodQuery) const override; + static void closePopup(); public: Qt5Widget(Qt5Frame& rFrame, Qt::WindowFlags f = Qt::WindowFlags()); diff --git a/vcl/qt5/Qt5Frame.cxx b/vcl/qt5/Qt5Frame.cxx index 02032d149d29..a4c78d1b71a7 100644 --- a/vcl/qt5/Qt5Frame.cxx +++ b/vcl/qt5/Qt5Frame.cxx @@ -146,9 +146,11 @@ Qt5Frame::Qt5Frame(Qt5Frame* pParent, SalFrameStyleFlags nStyle, bool bUseCairo) aWinFlags |= Qt::Tool | Qt::FramelessWindowHint; else if (nStyle & SalFrameStyleFlags::TOOLTIP) aWinFlags |= Qt::ToolTip; - else if ((nStyle & SalFrameStyleFlags::FLOAT) - && !(nStyle & SalFrameStyleFlags::OWNERDRAWDECORATION)) - aWinFlags |= Qt::Popup; + // Can't use Qt::Popup, because it grabs the input focus and generates + // a focus-out event, reaking the compbo box. This used to map to + // Qt::ToolTip, which doesn't feel that correct... + else if (isPopup()) + aWinFlags = Qt::Widget | Qt::FramelessWindowHint | Qt::BypassWindowManagerHint; else if (nStyle & SalFrameStyleFlags::TOOLWINDOW) aWinFlags |= Qt::Tool; // top level windows can't be transient in Qt, so make them dialogs, if they have a parent. At least @@ -426,7 +428,7 @@ void Qt5Frame::Show(bool bVisible, bool bNoActivate) pSalInst->RunInMainThread([this, bVisible, bNoActivate]() { asChild()->setVisible(bVisible); asChild()->raise(); - if (!bNoActivate) + if (!bNoActivate && !isPopup()) { asChild()->activateWindow(); asChild()->setFocus(); diff --git a/vcl/qt5/Qt5Widget.cxx b/vcl/qt5/Qt5Widget.cxx index ebb11cef51ff..864701340ad3 100644 --- a/vcl/qt5/Qt5Widget.cxx +++ b/vcl/qt5/Qt5Widget.cxx @@ -46,6 +46,7 @@ #include <cairo.h> #include <vcl/commandevent.hxx> #include <vcl/event.hxx> +#include <vcl/toolkit/floatwin.hxx> #include <window.h> #include <tools/diagnose_ex.h> @@ -179,11 +180,10 @@ void Qt5Widget::handleMouseButtonEvent(const Qt5Frame& rFrame, const QMouseEvent void Qt5Widget::mousePressEvent(QMouseEvent* pEvent) { - if ((windowFlags() & Qt::Popup) - && !geometry().translated(geometry().topLeft() * -1).contains(pEvent->pos())) - close(); - else - handleMousePressEvent(m_rFrame, pEvent); + handleMousePressEvent(m_rFrame, pEvent); + if (m_rFrame.isPopup() + || !geometry().translated(geometry().topLeft() * -1).contains(pEvent->pos())) + closePopup(); } void Qt5Widget::mouseReleaseEvent(QMouseEvent* pEvent) @@ -593,10 +593,21 @@ void Qt5Widget::keyReleaseEvent(QKeyEvent* pEvent) void Qt5Widget::focusInEvent(QFocusEvent*) { m_rFrame.CallCallback(SalEvent::GetFocus, nullptr); } +void Qt5Widget::closePopup() +{ + VclPtr<FloatingWindow> pFirstFloat = ImplGetSVData()->mpWinData->mpFirstFloat; + if (pFirstFloat && !(pFirstFloat->GetPopupModeFlags() & FloatWinPopupFlags::NoAppFocusClose)) + { + SolarMutexGuard aGuard; + pFirstFloat->EndPopupMode(FloatWinPopupEndFlags::Cancel | FloatWinPopupEndFlags::CloseAll); + } +} + void Qt5Widget::focusOutEvent(QFocusEvent*) { endExtTextInput(); m_rFrame.CallCallback(SalEvent::LoseFocus, nullptr); + closePopup(); } Qt5Widget::Qt5Widget(Qt5Frame& rFrame, Qt::WindowFlags f) @@ -608,8 +619,7 @@ Qt5Widget::Qt5Widget(Qt5Frame& rFrame, Qt::WindowFlags f) { create(); setMouseTracking(true); - if (!(f & Qt::Popup)) - setFocusPolicy(Qt::StrongFocus); + setFocusPolicy(Qt::StrongFocus); } static ExtTextInputAttr lcl_MapUndrelineStyle(QTextCharFormat::UnderlineStyle us)