summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan-Marek Glogowski <glogow@fbihome.de>2021-07-30 05:25:37 +0200
committerJan-Marek Glogowski <glogow@fbihome.de>2021-07-30 20:24:39 +0200
commit9dcf5816c90e9819861332f11e014ef7b78e2fe7 (patch)
tree8799fb5085d64cea10236fdd00476eef6ce1596a
parent0c0444c44107f1a18f23dd0833d462d8dbf56569 (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.hxx7
-rw-r--r--vcl/inc/qt5/Qt5Widget.hxx1
-rw-r--r--vcl/qt5/Qt5Frame.cxx10
-rw-r--r--vcl/qt5/Qt5Widget.cxx24
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)