diff options
author | Jan-Marek Glogowski <glogow@fbihome.de> | 2021-07-30 05:25:37 +0200 |
---|---|---|
committer | Jan-Marek Glogowski <glogow@fbihome.de> | 2021-07-30 20:24:39 +0200 |
commit | 9dcf5816c90e9819861332f11e014ef7b78e2fe7 (patch) | |
tree | 8799fb5085d64cea10236fdd00476eef6ce1596a | |
parent | 0c0444c44107f1a18f23dd0833d462d8dbf56569 (diff) |
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 <glogow@fbihome.de>
-rw-r--r-- | vcl/inc/qt5/Qt5Frame.hxx | 7 | ||||
-rw-r--r-- | vcl/inc/qt5/Qt5Widget.hxx | 1 | ||||
-rw-r--r-- | vcl/qt5/Qt5Frame.cxx | 10 | ||||
-rw-r--r-- | vcl/qt5/Qt5Widget.cxx | 24 |
4 files changed, 31 insertions, 11 deletions
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) |