[Libreoffice-commits] core.git: Branch 'libreoffice-7-3' - vcl/inc vcl/qt5

2022-05-25 Thread Jan-Marek Glogowski (via logerrit)
 vcl/inc/qt5/QtObject.hxx |   25 ++
 vcl/qt5/QtObject.cxx |   65 ++-
 2 files changed, 57 insertions(+), 33 deletions(-)

New commits:
commit 70e497f786dad6bda3aa593c07c778b06381c0e4
Author: Jan-Marek Glogowski 
AuthorDate: Tue May 24 11:34:59 2022 +0200
Commit: Michael Weghorn 
CommitDate: Wed May 25 16:25:34 2022 +0200

tdf#148864 Qt switch QtObjectWindow to QWidget

... and therefore rename it to QtObjectWidget

Replacement of the QWidget with QWindow originally happened in
commit 56b19f9a814ae5a39ed760ee542d715493cd0bf3 ("tdf#121247,
tdf#121266 KDE5: Add basic support for OpenGL"), but that
unfortunately has a very sparce commit message with no reason
for this change. Then the code was further complicated in commit
25edbded9946801effd117b9c46de0f8b4bc5632 ("tdf#125517 Qt5
implement a minimal Qt5ObjectWindow") and a few follow up fixes
to restore input and focus handling.

But appearingly all this QWindow handling isn't necessary and just
returning to a QWidget based class fixes the problems with the
video overlay (AKA QWidget::winId()) and video playback for good.

The OpenGL Impress transition (Fade) mentioned in the original
tdf#121266 bug still works.

This also adds the previously missing SolarMutexGuard to all the
overridden QtObjectWidget functions, which call the SalObject's
Callback function. I accidently triggered a DBG_TESTSOLARMUTEX
crashing Impress while debugging this.

Change-Id: Ia22cabfd4f3585dc7fa3f9f18a913c5bd1987dd8
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/134864
Reviewed-by: Michael Weghorn 
Tested-by: Jenkins
(cherry picked from commit 4366e0605214260e55a937173b0c2e02225dc843)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/134903
Reviewed-by: Ilmari Lauhakangas 

diff --git a/vcl/inc/qt5/QtObject.hxx b/vcl/inc/qt5/QtObject.hxx
index 328946e4388e..bc5a8e584b8f 100644
--- a/vcl/inc/qt5/QtObject.hxx
+++ b/vcl/inc/qt5/QtObject.hxx
@@ -24,10 +24,11 @@
 
 #include 
 #include 
-#include 
+#include 
 
 class QtFrame;
-class QWidget;
+class QtObjectWidget;
+class QWindow;
 
 class QtObject final : public QObject, public SalObject
 {
@@ -35,17 +36,18 @@ class QtObject final : public QObject, public SalObject
 
 SystemEnvData m_aSystemData;
 QtFrame* m_pParent;
-QWidget* m_pQWidget; // main widget, container
-QWindow* m_pQWindow; // contained window, used for opengl rendering
+QtObjectWidget* m_pQWidget;
 QRegion m_pRegion;
+bool m_bForwardKey;
 
 public:
 QtObject(QtFrame* pParent, bool bShow);
 ~QtObject() override;
 
 QtFrame* frame() const { return m_pParent; }
-QWidget* widget() const { return m_pQWidget; }
-QWindow* windowHandle() const { return m_pQWindow; }
+inline QWidget* widget() const;
+QWindow* windowHandle() const;
+bool forwardKey() const { return m_bForwardKey; }
 
 virtual void ResetClipRegion() override;
 virtual void BeginSetClipRegion(sal_uInt32 nRects) override;
@@ -60,22 +62,25 @@ public:
 virtual void SetForwardKey(bool bEnable) override;
 
 virtual const SystemEnvData* GetSystemData() const override { return 
_aSystemData; }
+
+virtual void Reparent(SalFrame* pFrame) override;
 };
 
-class QtObjectWindow final : public QWindow
+class QtObjectWidget final : public QWidget
 {
 QtObject& m_rParent;
 
-bool event(QEvent*) override;
 void focusInEvent(QFocusEvent*) override;
 void focusOutEvent(QFocusEvent*) override;
 void mousePressEvent(QMouseEvent*) override;
 void mouseReleaseEvent(QMouseEvent*) override;
-// keyPressEvent(QKeyEvent*) is handled via event(QEvent*); see comment in 
QtWidget::event
+void keyPressEvent(QKeyEvent*) override;
 void keyReleaseEvent(QKeyEvent*) override;
 
 public:
-explicit QtObjectWindow(QtObject& rParent);
+explicit QtObjectWidget(QtObject& rParent);
 };
 
+QWidget* QtObject::widget() const { return m_pQWidget; }
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/qt5/QtObject.cxx b/vcl/qt5/QtObject.cxx
index 569586a0dc98..fbdc8e9b625e 100644
--- a/vcl/qt5/QtObject.cxx
+++ b/vcl/qt5/QtObject.cxx
@@ -24,20 +24,18 @@
 #include 
 
 #include 
+#include 
+#include 
 
 QtObject::QtObject(QtFrame* pParent, bool bShow)
 : m_pParent(pParent)
 , m_pQWidget(nullptr)
-, m_pQWindow(nullptr)
+, m_bForwardKey(false)
 {
 if (!m_pParent || !pParent->GetQWidget())
 return;
 
-m_pQWindow = new QtObjectWindow(*this);
-m_pQWidget = QWidget::createWindowContainer(m_pQWindow, 
pParent->GetQWidget());
-m_pQWidget->setAttribute(Qt::WA_NoSystemBackground);
-connect(m_pQWidget, ::destroyed, this, [this]() { m_pQWidget = 
nullptr; });
-
+m_pQWidget = new QtObjectWidget(*this);
 if (bShow)
 m_pQWidget->show();
 
@@ -53,6 +51,11 @@ QtObject::~QtObject()
 

[Libreoffice-commits] core.git: Branch 'libreoffice-7-3' - vcl/inc vcl/qt5

2022-04-21 Thread Jan-Marek Glogowski (via logerrit)
 vcl/inc/qt5/QtInstance.hxx |6 ++
 vcl/inc/qt5/QtWidget.hxx   |1 +
 vcl/qt5/QtInstance.cxx |7 +++
 vcl/qt5/QtWidget.cxx   |   20 
 4 files changed, 30 insertions(+), 4 deletions(-)

New commits:
commit 06c51d61e4a16057f945effe85b1ff9457f8cffb
Author: Jan-Marek Glogowski 
AuthorDate: Thu Apr 21 10:56:42 2022 +0200
Commit: Jan-Marek Glogowski 
CommitDate: Thu Apr 21 18:57:05 2022 +0200

tdf#148699 Qt track the active / shown popup

I have no idea, if there can be multiple active popups in LO in
some way. There can be multiple FloatingWindow and gtk does count
them in m_nFloats... There is a whole lot going on in gtk3 related
to isFloatGrabWindow(), with "funny" comments like:

// FIXME: find out who the hell steals the focus from our frame

So this goes with some "optimistic" approach: there is just one
active popup, so we can track it in QtInstance. It WFM...

Change-Id: I9778587696e1ad9e641dba4f102e2e921266eee6
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/133249
Tested-by: Jenkins
Reviewed-by: Michael Weghorn 
(cherry picked from commit 347622a98f512dae709f938a85498dcdcf9f225a)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/133260
Reviewed-by: Jan-Marek Glogowski 

diff --git a/vcl/inc/qt5/QtInstance.hxx b/vcl/inc/qt5/QtInstance.hxx
index 9a9853a7a2ce..fd111bb22abe 100644
--- a/vcl/inc/qt5/QtInstance.hxx
+++ b/vcl/inc/qt5/QtInstance.hxx
@@ -35,6 +35,7 @@
 
 #include "QtFilePicker.hxx"
 
+class QtFrame;
 class QtTimer;
 
 class QApplication;
@@ -67,6 +68,8 @@ class VCLPLUG_QT_PUBLIC QtInstance : public QObject,
 Timer m_aUpdateStyleTimer;
 bool m_bUpdateFonts;
 
+QtFrame* m_pActivePopup;
+
 DECL_DLLPRIVATE_LINK(updateStyleHdl, Timer*, void);
 void AfterAppInit() override;
 
@@ -172,6 +175,9 @@ public:
 void UpdateStyle(bool bFontsChanged);
 
 void* CreateGStreamerSink(const SystemChildWindow*) override;
+
+QtFrame* activePopup() const { return m_pActivePopup; }
+void setActivePopup(QtFrame*);
 };
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/inc/qt5/QtWidget.hxx b/vcl/inc/qt5/QtWidget.hxx
index 4a40589b16ba..8f7f6cc319e1 100644
--- a/vcl/inc/qt5/QtWidget.hxx
+++ b/vcl/inc/qt5/QtWidget.hxx
@@ -73,6 +73,7 @@ class QtWidget : public QWidget
 virtual void paintEvent(QPaintEvent*) override;
 virtual void resizeEvent(QResizeEvent*) override;
 virtual void showEvent(QShowEvent*) override;
+virtual void hideEvent(QHideEvent*) override;
 virtual void wheelEvent(QWheelEvent*) override;
 virtual void closeEvent(QCloseEvent*) override;
 virtual void changeEvent(QEvent*) override;
diff --git a/vcl/qt5/QtInstance.cxx b/vcl/qt5/QtInstance.cxx
index d252109e122a..247001443020 100644
--- a/vcl/qt5/QtInstance.cxx
+++ b/vcl/qt5/QtInstance.cxx
@@ -223,6 +223,7 @@ QtInstance::QtInstance(std::unique_ptr& 
pQApp, bool bUseCairo)
 , m_pQApplication(std::move(pQApp))
 , m_aUpdateStyleTimer("vcl::qt5 m_aUpdateStyleTimer")
 , m_bUpdateFonts(false)
+, m_pActivePopup(nullptr)
 {
 ImplSVData* pSVData = ImplGetSVData();
 const OUString sToolkit = "qt" + OUString::number(QT_VERSION_MAJOR);
@@ -722,6 +723,12 @@ std::unique_ptr 
QtInstance::CreateQApplication(int& nArgc, char**
 return pQApp;
 }
 
+void QtInstance::setActivePopup(QtFrame* pFrame)
+{
+assert(!pFrame || pFrame->isPopup());
+m_pActivePopup = pFrame;
+}
+
 extern "C" {
 VCLPLUG_QT_PUBLIC SalInstance* create_SalInstance()
 {
diff --git a/vcl/qt5/QtWidget.cxx b/vcl/qt5/QtWidget.cxx
index 5f07974600e8..8c545fd13377 100644
--- a/vcl/qt5/QtWidget.cxx
+++ b/vcl/qt5/QtWidget.cxx
@@ -317,9 +317,21 @@ void QtWidget::showEvent(QShowEvent*)
 // sequence from QtFrame::SetModal, if the frame was already set visible,
 // resulting in a hidden / unmapped window
 SalPaintEvent aPaintEvt(0, 0, aSize.width(), aSize.height());
+if (m_rFrame.isPopup())
+{
+auto* pQtInst(static_cast(GetSalData()->m_pInstance));
+pQtInst->setActivePopup(_rFrame);
+}
 m_rFrame.CallCallback(SalEvent::Paint, );
 }
 
+void QtWidget::hideEvent(QHideEvent*)
+{
+auto* pQtInst(static_cast(GetSalData()->m_pInstance));
+if (m_rFrame.isPopup() && pQtInst->activePopup() == _rFrame)
+pQtInst->setActivePopup(nullptr);
+}
+
 void QtWidget::closeEvent(QCloseEvent* /*pEvent*/)
 {
 m_rFrame.CallCallback(SalEvent::Close, nullptr);
@@ -627,11 +639,11 @@ bool QtWidget::handleEvent(QtFrame& rFrame, QWidget& 
rWidget, QEvent* pEvent)
 }
 else if (pEvent->type() == QEvent::ToolTip)
 {
-// Qt's POV on focus is wrong for our fake popup windows, so check 
LO's state.
+// Qt's POV on the active popup is wrong due to our fake popup, so 
check LO's state.
 // Otherwise Qt will continue handling ToolTip events from the 
"parent" window.
-const vcl::Window* pFocusWin = 

[Libreoffice-commits] core.git: Branch 'libreoffice-7-3' - vcl/inc vcl/qt5

2022-04-21 Thread Jan-Marek Glogowski (via logerrit)
 vcl/inc/qt5/QtWidget.hxx |7 +++
 vcl/qt5/QtWidget.cxx |   35 +++
 2 files changed, 42 insertions(+)

New commits:
commit 00f9671624e676f34c9039d7b0b0ebba6034f05c
Author: Jan-Marek Glogowski 
AuthorDate: Tue Apr 19 16:03:56 2022 +0200
Commit: Michael Weghorn 
CommitDate: Thu Apr 21 11:31:13 2022 +0200

tdf#140463 Qt handle mouse enter+leave events

Currently just implemented for the QtWidget, but still as a static
function, so it may be used for QtObject at some point too.

But there is no (mouse) enter or leave event function in QWindow,
so no way to handle these there. And since we can't modify the
returned QWidget from QWidget::createWindowContainer, the only way
would be to expand the static QtWidget::handleEvent used by
QtObjectWindow::event ... if it's actually needed at some point.

Includes squashed commit 5d56255c22c79b72c1cedb48cfe0a200f89bdc66
("qt6: Fix build (QtWidget::enterEvent)").

Change-Id: If9009e5dfca508acd1e702df1a17eb8ad7c29690
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/133190
Tested-by: Jenkins
Reviewed-by: Jan-Marek Glogowski 
(cherry picked from commit dc886bc6de2c0061a840bea2426663c3be2ecd26)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/133149
Reviewed-by: Michael Weghorn 

diff --git a/vcl/inc/qt5/QtWidget.hxx b/vcl/inc/qt5/QtWidget.hxx
index 878c8b1229ce..4a40589b16ba 100644
--- a/vcl/inc/qt5/QtWidget.hxx
+++ b/vcl/inc/qt5/QtWidget.hxx
@@ -51,6 +51,7 @@ class QtWidget : public QWidget
 static void commitText(QtFrame&, const QString& aText);
 static bool handleKeyEvent(QtFrame&, const QWidget&, QKeyEvent*, const 
ButtonKeyState);
 static void handleMouseButtonEvent(const QtFrame&, const QMouseEvent*, 
const ButtonKeyState);
+static void handleMouseEnterLeaveEvents(const QtFrame&, QEvent*);
 static void fillSalAbstractMouseEvent(const QtFrame& rFrame, const 
QInputEvent* pQEvent,
   const QPoint& rPos, Qt::MouseButtons 
eButtons, int nWidth,
   SalAbstractMouseEvent& aSalEvent);
@@ -75,6 +76,12 @@ class QtWidget : public QWidget
 virtual void wheelEvent(QWheelEvent*) override;
 virtual void closeEvent(QCloseEvent*) override;
 virtual void changeEvent(QEvent*) override;
+virtual void leaveEvent(QEvent*) override;
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+virtual void enterEvent(QEnterEvent*) override;
+#else
+virtual void enterEvent(QEvent*) override;
+#endif
 
 void inputMethodEvent(QInputMethodEvent*) override;
 QVariant inputMethodQuery(Qt::InputMethodQuery) const override;
diff --git a/vcl/qt5/QtWidget.cxx b/vcl/qt5/QtWidget.cxx
index 017249b05434..5f07974600e8 100644
--- a/vcl/qt5/QtWidget.cxx
+++ b/vcl/qt5/QtWidget.cxx
@@ -208,6 +208,41 @@ void QtWidget::mouseMoveEvent(QMouseEvent* pEvent)
 pEvent->accept();
 }
 
+void QtWidget::handleMouseEnterLeaveEvents(const QtFrame& rFrame, QEvent* 
pQEvent)
+{
+const qreal fRatio = rFrame.devicePixelRatioF();
+const QWidget* pWidget = rFrame.GetQWidget();
+const Point aPos = toPoint(pWidget->mapFromGlobal(QCursor::pos()) * 
fRatio);
+
+SalMouseEvent aEvent;
+aEvent.mnX
+= QGuiApplication::isLeftToRight() ? aPos.X() : round(pWidget->width() 
* fRatio) - aPos.X();
+aEvent.mnY = aPos.Y();
+aEvent.mnTime = 0;
+aEvent.mnButton = 0;
+aEvent.mnCode = GetKeyModCode(QGuiApplication::keyboardModifiers())
+| GetMouseModCode(QGuiApplication::mouseButtons());
+
+SalEvent nEventType;
+if (pQEvent->type() == QEvent::Enter)
+nEventType = SalEvent::MouseMove;
+else
+nEventType = SalEvent::MouseLeave;
+rFrame.CallCallback(nEventType, );
+pQEvent->accept();
+}
+
+void QtWidget::leaveEvent(QEvent* pEvent) { 
handleMouseEnterLeaveEvents(m_rFrame, pEvent); }
+
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+void QtWidget::enterEvent(QEnterEvent* pEvent)
+#else
+void QtWidget::enterEvent(QEvent* pEvent)
+#endif
+{
+handleMouseEnterLeaveEvents(m_rFrame, pEvent);
+}
+
 void QtWidget::wheelEvent(QWheelEvent* pEvent)
 {
 SalWheelMouseEvent aEvent;


[Libreoffice-commits] core.git: Branch 'libreoffice-7-3' - vcl/inc vcl/qt5

2022-04-13 Thread Jan-Marek Glogowski (via logerrit)
 vcl/inc/qt5/QtFrame.hxx  |3 +++
 vcl/inc/qt5/QtWidget.hxx |2 +-
 vcl/qt5/QtFrame.cxx  |8 +++-
 vcl/qt5/QtWidget.cxx |   19 ++-
 4 files changed, 29 insertions(+), 3 deletions(-)

New commits:
commit 7fc871299080427587307932c505d3ae93d6a357
Author: Jan-Marek Glogowski 
AuthorDate: Tue Apr 12 00:29:56 2022 +0200
Commit: Jan-Marek Glogowski 
CommitDate: Wed Apr 13 22:31:30 2022 +0200

tdf#148115 Qt handle tooltips via event loop

Instead of calling QToolTip::showText directly from LO, this
defers showing the tooltip to the QEvent processing, which takes
the tooltip timeouts into account. So tooltips are shown with
a slight delay, therefore they happen less fast on mouse move,
reducing / avoiding artifacts of fast changing windows.

This unfortunately comes with yet an other hack in the area of
our fake popup windows...

New handling is based on the code of the Qt Tool Tips example.

Change-Id: I42634ad36dd12171c30f52f07a02a88d3c48a718
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/132841
Reviewed-by: Michael Weghorn 
Tested-by: Jenkins
(cherry picked from commit af6dd54d53eee0d0de1164bff0a77c6b433b3935)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/132864
Reviewed-by: Jan-Marek Glogowski 

diff --git a/vcl/inc/qt5/QtFrame.hxx b/vcl/inc/qt5/QtFrame.hxx
index 5ffaacf3ad94..23a4fd9887f1 100644
--- a/vcl/inc/qt5/QtFrame.hxx
+++ b/vcl/inc/qt5/QtFrame.hxx
@@ -111,6 +111,9 @@ class VCLPLUG_QT_PUBLIC QtFrame : public QObject, public 
SalFrame
 
 LanguageType m_nInputLanguage;
 
+OUString m_aTooltipText;
+QRect m_aTooltipArea;
+
 void SetDefaultPos();
 Size CalcDefaultSize();
 void SetDefaultSize();
diff --git a/vcl/inc/qt5/QtWidget.hxx b/vcl/inc/qt5/QtWidget.hxx
index 575cef11014f..878c8b1229ce 100644
--- a/vcl/inc/qt5/QtWidget.hxx
+++ b/vcl/inc/qt5/QtWidget.hxx
@@ -87,7 +87,7 @@ public:
 void endExtTextInput();
 void fakeResize();
 
-static bool handleEvent(QtFrame&, const QWidget&, QEvent*);
+static bool handleEvent(QtFrame&, QWidget&, QEvent*);
 // key events might be propagated further down => call base on false
 static inline bool handleKeyReleaseEvent(QtFrame&, const QWidget&, 
QKeyEvent*);
 // mouse events are always accepted
diff --git a/vcl/qt5/QtFrame.cxx b/vcl/qt5/QtFrame.cxx
index c78417b3070a..f6f4b6c2611d 100644
--- a/vcl/qt5/QtFrame.cxx
+++ b/vcl/qt5/QtFrame.cxx
@@ -175,7 +175,12 @@ QtFrame::QtFrame(QtFrame* pParent, SalFrameStyleFlags 
nStyle, bool bUseCairo)
 m_pTopLevel->setFocusProxy(m_pQWidget);
 }
 else
+{
 m_pQWidget = new QtWidget(*this, aWinFlags);
+// from Qt's POV the popup window doesn't have the input focus, so we 
must force tooltips...
+if (isPopup())
+m_pQWidget->setAttribute(Qt::WA_AlwaysShowToolTips);
+}
 
 QWindow* pChildWindow = windowHandle();
 connect(pChildWindow, ::screenChanged, this, 
::screenChanged);
@@ -855,7 +860,8 @@ bool QtFrame::ShowTooltip(const OUString& rText, const 
tools::Rectangle& rHelpAr
 QRect aHelpArea(toQRect(rHelpArea));
 if (QGuiApplication::isRightToLeft())
 aHelpArea.moveLeft(maGeometry.nWidth - aHelpArea.width() - 
aHelpArea.left() - 1);
-QToolTip::showText(QCursor::pos(), toQString(rText), m_pQWidget, 
aHelpArea);
+m_aTooltipText = rText;
+m_aTooltipArea = aHelpArea;
 return true;
 }
 
diff --git a/vcl/qt5/QtWidget.cxx b/vcl/qt5/QtWidget.cxx
index 1fe2ce9a7159..017249b05434 100644
--- a/vcl/qt5/QtWidget.cxx
+++ b/vcl/qt5/QtWidget.cxx
@@ -42,6 +42,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 #include 
@@ -562,7 +563,7 @@ bool QtWidget::handleKeyEvent(QtFrame& rFrame, const 
QWidget& rWidget, QKeyEvent
 return bStopProcessingKey;
 }
 
-bool QtWidget::handleEvent(QtFrame& rFrame, const QWidget& rWidget, QEvent* 
pEvent)
+bool QtWidget::handleEvent(QtFrame& rFrame, QWidget& rWidget, QEvent* pEvent)
 {
 if (pEvent->type() == QEvent::ShortcutOverride)
 {
@@ -589,6 +590,22 @@ bool QtWidget::handleEvent(QtFrame& rFrame, const QWidget& 
rWidget, QEvent* pEve
ButtonKeyState::Pressed))
 return true;
 }
+else if (pEvent->type() == QEvent::ToolTip)
+{
+// Qt's POV on focus is wrong for our fake popup windows, so check 
LO's state.
+// Otherwise Qt will continue handling ToolTip events from the 
"parent" window.
+const vcl::Window* pFocusWin = Application::GetFocusWindow();
+if (!rFrame.m_aTooltipText.isEmpty() && pFocusWin
+&& pFocusWin->GetFrameWindow() == rFrame.GetWindow())
+QToolTip::showText(QCursor::pos(), 
toQString(rFrame.m_aTooltipText), ,
+   rFrame.m_aTooltipArea);
+else
+{
+QToolTip::hideText();
+pEvent->ignore();
+}
+return true;
+}
 

[Libreoffice-commits] core.git: Branch 'libreoffice-7-3' - vcl/inc vcl/qt5

2022-04-12 Thread Jan-Marek Glogowski (via logerrit)
 vcl/inc/qt5/QtMenu.hxx |1 -
 vcl/qt5/QtMenu.cxx |8 +---
 2 files changed, 5 insertions(+), 4 deletions(-)

New commits:
commit 664ea7545a62e1329eb1761caea25b7f31cafa7a
Author: Jan-Marek Glogowski 
AuthorDate: Wed Apr 6 16:42:24 2022 +0200
Commit: Jan-Marek Glogowski 
CommitDate: Tue Apr 12 20:18:41 2022 +0200

tdf#148491 Qt reconnect the QMenuBar close button

When the QMenuBar of a QMainWindow is replaced, an existing
corner widget is preserved / transferred, but its connections
are still severed; a bit unexpected...

The documentation for QMenuBar::setCornerWidget is not really
clear what is happening, but the code has this nice comment:
"// Reparent corner widgets before we delete the old menu".
At least there is no need to explicitly delete the button.

Still we must reconnect an existing button on each SetFrame.

Regression from commit 9c4ef8ce3183e27ca174475cf4a8d15cc0368f60
("tdf#145954 Qt unshare QMenubar usage").

This includes commit 4a537cf77affc4f1f2e2e5be9ff0b1ff11724509
("Qt drop unused QtMenu::mpCloseButton").

Change-Id: I13c31734e665b78231a08cd76ca6305122e08879
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/132836
Tested-by: Jenkins
Reviewed-by: Michael Weghorn 
(cherry picked from commit f751417b77e6573a0c639778e76ec943449f4573)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/132894
Reviewed-by: Jan-Marek Glogowski 

diff --git a/vcl/inc/qt5/QtMenu.hxx b/vcl/inc/qt5/QtMenu.hxx
index f39be7e8d506..11f3f00c5aa6 100644
--- a/vcl/inc/qt5/QtMenu.hxx
+++ b/vcl/inc/qt5/QtMenu.hxx
@@ -49,7 +49,6 @@ private:
 std::unique_ptr mpOwnedQMenu;
 // pointer to QMenu owned by the corresponding QtMenuItem or self (-> 
mpOwnedQMenu)
 QMenu* mpQMenu;
-QPushButton* mpCloseButton;
 
 void DoFullMenuUpdate(Menu* pMenuBar);
 static void NativeItemText(OUString& rItemText);
diff --git a/vcl/qt5/QtMenu.cxx b/vcl/qt5/QtMenu.cxx
index 44873ce3384d..9400f5e129bf 100644
--- a/vcl/qt5/QtMenu.cxx
+++ b/vcl/qt5/QtMenu.cxx
@@ -40,7 +40,6 @@ QtMenu::QtMenu(bool bMenuBar)
 , mbMenuBar(bMenuBar)
 , mpQMenuBar(nullptr)
 , mpQMenu(nullptr)
-, mpCloseButton(nullptr)
 {
 }
 
@@ -431,7 +430,9 @@ void QtMenu::SetFrame(const SalFrame* pFrame)
 mpQMenuBar = new QMenuBar();
 pMainWindow->setMenuBar(mpQMenuBar);
 
-mpCloseButton = nullptr;
+QPushButton* pButton = 
static_cast(mpQMenuBar->cornerWidget(Qt::TopRightCorner));
+if (pButton)
+connect(pButton, ::clicked, this, 
::slotCloseDocument);
 mpQMenu = nullptr;
 
 DoFullMenuUpdate(mpVCLMenu);
@@ -650,6 +651,8 @@ void QtMenu::ShowCloseButton(bool bShow)
 return;
 
 QPushButton* pButton = 
static_cast(mpQMenuBar->cornerWidget(Qt::TopRightCorner));
+if (!pButton && !bShow)
+return;
 if (!pButton)
 {
 QIcon aIcon;
@@ -665,7 +668,6 @@ void QtMenu::ShowCloseButton(bool bShow)
 pButton->setToolTip(toQString(VclResId(SV_HELPTEXT_CLOSEDOCUMENT)));
 mpQMenuBar->setCornerWidget(pButton, Qt::TopRightCorner);
 connect(pButton, ::clicked, this, 
::slotCloseDocument);
-mpCloseButton = pButton;
 }
 
 if (bShow)


[Libreoffice-commits] core.git: Branch 'libreoffice-7-3' - vcl/inc vcl/qt5

2022-04-08 Thread Jan-Marek Glogowski (via logerrit)
 vcl/inc/qt5/QtFrame.hxx  |6 +-
 vcl/inc/qt5/QtWidget.hxx |1 +
 vcl/qt5/QtFrame.cxx  |   21 ++---
 vcl/qt5/QtWidget.cxx |6 ++
 4 files changed, 26 insertions(+), 8 deletions(-)

New commits:
commit 76de12a19bd90c0ed0d7a6a85502d3dccdbeba4e
Author: Jan-Marek Glogowski 
AuthorDate: Thu Apr 7 01:07:43 2022 +0200
Commit: Jan-Marek Glogowski 
CommitDate: Fri Apr 8 19:48:56 2022 +0200

tdf#141578 Qt handle QtFrame screen changes

LO doesn't provide any way to notify screen changes / scaling
factors of a window and in fact doesn't really handle scaling
factors in VCL. The QWidget doesn't receive a resize event,
because it's size doesn't change, just the scaling factor.
So we trigger a faked resize on QWindow::screenChanged signal.

Change-Id: I6928c4c62d1c0995c70fea0088cff17849bcd1d4
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/132650
Reviewed-by: Michael Weghorn 
Tested-by: Jenkins
(cherry picked from commit 881cfbf77567194f5016a961d1c3db869734d68b)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/132740
Reviewed-by: Jan-Marek Glogowski 

diff --git a/vcl/inc/qt5/QtFrame.hxx b/vcl/inc/qt5/QtFrame.hxx
index 59ec093a2ed6..5ffaacf3ad94 100644
--- a/vcl/inc/qt5/QtFrame.hxx
+++ b/vcl/inc/qt5/QtFrame.hxx
@@ -25,6 +25,7 @@
 #include 
 
 #include "QtTools.hxx"
+#include "QtWidget.hxx"
 
 #include 
 #include 
@@ -70,7 +71,7 @@ class VCLPLUG_QT_PUBLIC QtFrame : public QObject, public 
SalFrame
 
 friend class QtWidget;
 
-QWidget* m_pQWidget;
+QtWidget* m_pQWidget;
 QtMainWindow* m_pTopLevel;
 
 const bool m_bUseCairo;
@@ -134,6 +135,9 @@ class VCLPLUG_QT_PUBLIC QtFrame : public QObject, public 
SalFrame
 
 void fixICCCMwindowGroup();
 
+private Q_SLOTS:
+void screenChanged(QScreen*);
+
 public:
 QtFrame(QtFrame* pParent, SalFrameStyleFlags nSalFrameStyle, bool 
bUseCairo);
 virtual ~QtFrame() override;
diff --git a/vcl/inc/qt5/QtWidget.hxx b/vcl/inc/qt5/QtWidget.hxx
index e2a22d3c9f18..575cef11014f 100644
--- a/vcl/inc/qt5/QtWidget.hxx
+++ b/vcl/inc/qt5/QtWidget.hxx
@@ -85,6 +85,7 @@ public:
 
 QtFrame& frame() const { return m_rFrame; }
 void endExtTextInput();
+void fakeResize();
 
 static bool handleEvent(QtFrame&, const QWidget&, QEvent*);
 // key events might be propagated further down => call base on false
diff --git a/vcl/qt5/QtFrame.cxx b/vcl/qt5/QtFrame.cxx
index bcd95494dabd..c78417b3070a 100644
--- a/vcl/qt5/QtFrame.cxx
+++ b/vcl/qt5/QtFrame.cxx
@@ -30,7 +30,6 @@
 #include 
 #include 
 #include 
-#include 
 
 #include 
 #include 
@@ -178,10 +177,12 @@ QtFrame::QtFrame(QtFrame* pParent, SalFrameStyleFlags 
nStyle, bool bUseCairo)
 else
 m_pQWidget = new QtWidget(*this, aWinFlags);
 
+QWindow* pChildWindow = windowHandle();
+connect(pChildWindow, ::screenChanged, this, 
::screenChanged);
+
 if (pParent && !(pParent->m_nStyle & SalFrameStyleFlags::PLUG))
 {
-QWindow* pParentWindow = 
pParent->GetQWidget()->window()->windowHandle();
-QWindow* pChildWindow = asChild()->window()->windowHandle();
+QWindow* pParentWindow = pParent->windowHandle();
 if (pParentWindow && pChildWindow && (pParentWindow != pChildWindow))
 pChildWindow->setTransientParent(pParentWindow);
 }
@@ -193,6 +194,8 @@ QtFrame::QtFrame(QtFrame* pParent, SalFrameStyleFlags 
nStyle, bool bUseCairo)
 fixICCCMwindowGroup();
 }
 
+void QtFrame::screenChanged(QScreen*) { m_pQWidget->fakeResize(); }
+
 void QtFrame::FillSystemEnvData(SystemEnvData& rData, sal_IntPtr pWindow, 
QWidget* pWidget)
 {
 if (QGuiApplication::platformName() == "wayland")
@@ -343,7 +346,12 @@ bool QtFrame::PostEvent(std::unique_ptr pData)
 return true;
 }
 
-QWidget* QtFrame::asChild() const { return m_pTopLevel ? m_pTopLevel : 
m_pQWidget; }
+QWidget* QtFrame::asChild() const
+{
+if (m_pTopLevel)
+return m_pTopLevel;
+return m_pQWidget;
+}
 
 qreal QtFrame::devicePixelRatioF() const { return 
asChild()->devicePixelRatioF(); }
 
@@ -864,9 +872,8 @@ void QtFrame::SetInputContext(SalInputContext* pContext)
 
 void QtFrame::EndExtTextInput(EndExtTextInputFlags /*nFlags*/)
 {
-QtWidget* pQtWidget = static_cast(m_pQWidget);
-if (pQtWidget)
-pQtWidget->endExtTextInput();
+if (m_pQWidget)
+m_pQWidget->endExtTextInput();
 }
 
 OUString QtFrame::GetKeyName(sal_uInt16 nKeyCode)
diff --git a/vcl/qt5/QtWidget.cxx b/vcl/qt5/QtWidget.cxx
index ab8bf2dc0017..1fe2ce9a7159 100644
--- a/vcl/qt5/QtWidget.cxx
+++ b/vcl/qt5/QtWidget.cxx
@@ -135,6 +135,12 @@ void QtWidget::resizeEvent(QResizeEvent* pEvent)
 m_rFrame.CallCallback(SalEvent::Resize, nullptr);
 }
 
+void QtWidget::fakeResize()
+{
+QResizeEvent aEvent(size(), QSize());
+resizeEvent();
+}
+
 void QtWidget::fillSalAbstractMouseEvent(const QtFrame& rFrame, const 
QInputEvent* pQEvent,
  

[Libreoffice-commits] core.git: Branch 'libreoffice-7-3' - vcl/inc vcl/qt5

2022-04-08 Thread Jan-Marek Glogowski (via logerrit)
 vcl/inc/qt5/QtWidget.hxx |3 +++
 vcl/qt5/QtFrame.cxx  |5 +++--
 vcl/qt5/QtWidget.cxx |   18 +-
 3 files changed, 19 insertions(+), 7 deletions(-)

New commits:
commit a174fe91987160c0d57099d0aaf49dcc8e036f5b
Author: Jan-Marek Glogowski 
AuthorDate: Wed Apr 6 18:59:10 2022 +0200
Commit: Jan-Marek Glogowski 
CommitDate: Fri Apr 8 08:19:42 2022 +0200

tdf#143135 Qt break recursive IM QueryCursorRect

To reproduce the Impress crash, you need an IM, e.g. fcitx / ibus.
This is triggered by having an active input, like double-clicking
one of a presentations text fields, then leaving the window and
switching back to it.

This results in a stack exhaustion in a few seconds. The backtrace
is basically:

QWidget::setFocus
QtFrame::ToTop
sd::Window::GrabFocus
ImplHandleExtTextInputPos
QtWidget::inputMethodQuery
QInputMethod::cursorRectangle
QWidget::setFocus
QApplication::setActiveWindow
QtInstance::DoYield
main

I scratched my head over the longer backtrace for while, but there
seems to be no good way to prevent this from LO's POV. The only
alternative from the Qt VCL plugin is QtFrame::ToTop. That code
is less ugly (no mutable or cached result), but QtWidget::
inputMethodQuery is earlier in the backtrace.

Change-Id: Ief3a8e44bca295cc676e75050d52d70a1da98a88
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/132643
Tested-by: Jenkins
Reviewed-by: Michael Weghorn 
Reviewed-by: Jan-Marek Glogowski 
(cherry picked from commit e81385277c091dabb1f6542a94229d7dcc77289b)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/132612

diff --git a/vcl/inc/qt5/QtWidget.hxx b/vcl/inc/qt5/QtWidget.hxx
index 801cd290ff88..e2a22d3c9f18 100644
--- a/vcl/inc/qt5/QtWidget.hxx
+++ b/vcl/inc/qt5/QtWidget.hxx
@@ -19,6 +19,7 @@
 
 #pragma once
 
+#include 
 #include 
 #include 
 
@@ -36,6 +37,8 @@ class QtWidget : public QWidget
 
 QtFrame& m_rFrame;
 bool m_bNonEmptyIMPreeditSeen;
+mutable bool m_bInInputMethodQueryCursorRectangle;
+mutable QRect m_aImCursorRectangle;
 int m_nDeltaX;
 int m_nDeltaY;
 
diff --git a/vcl/qt5/QtFrame.cxx b/vcl/qt5/QtFrame.cxx
index ad9c03d0bfa1..bcd95494dabd 100644
--- a/vcl/qt5/QtFrame.cxx
+++ b/vcl/qt5/QtFrame.cxx
@@ -795,8 +795,9 @@ void QtFrame::ToTop(SalFrameToTop nFlags)
 pWidget->activateWindow();
 else if ((nFlags & SalFrameToTop::GrabFocus) || (nFlags & 
SalFrameToTop::GrabFocusOnly))
 {
-pWidget->activateWindow();
-pWidget->setFocus();
+if (!(nFlags & SalFrameToTop::GrabFocusOnly))
+pWidget->activateWindow();
+pWidget->setFocus(Qt::OtherFocusReason);
 }
 }
 
diff --git a/vcl/qt5/QtWidget.cxx b/vcl/qt5/QtWidget.cxx
index 86431a3488b1..ab8bf2dc0017 100644
--- a/vcl/qt5/QtWidget.cxx
+++ b/vcl/qt5/QtWidget.cxx
@@ -623,6 +623,7 @@ QtWidget::QtWidget(QtFrame& rFrame, Qt::WindowFlags f)
 : QWidget(Q_NULLPTR, f)
 , m_rFrame(rFrame)
 , m_bNonEmptyIMPreeditSeen(false)
+, m_bInInputMethodQueryCursorRectangle(false)
 , m_nDeltaX(0)
 , m_nDeltaY(0)
 {
@@ -796,11 +797,18 @@ QVariant QtWidget::inputMethodQuery(Qt::InputMethodQuery 
property) const
 }
 case Qt::ImCursorRectangle:
 {
-const qreal fRatio = m_rFrame.devicePixelRatioF();
-SalExtTextInputPosEvent aPosEvent;
-m_rFrame.CallCallback(SalEvent::ExtTextInputPos, );
-return QVariant(QRect(aPosEvent.mnX / fRatio, aPosEvent.mnY / 
fRatio,
-  aPosEvent.mnWidth / fRatio, 
aPosEvent.mnHeight / fRatio));
+if (!m_bInInputMethodQueryCursorRectangle)
+{
+m_bInInputMethodQueryCursorRectangle = true;
+SalExtTextInputPosEvent aPosEvent;
+m_rFrame.CallCallback(SalEvent::ExtTextInputPos, );
+const qreal fRatio = m_rFrame.devicePixelRatioF();
+m_aImCursorRectangle.setRect(aPosEvent.mnX / fRatio, 
aPosEvent.mnY / fRatio,
+ aPosEvent.mnWidth / fRatio,
+ aPosEvent.mnHeight / fRatio);
+m_bInInputMethodQueryCursorRectangle = false;
+}
+return QVariant(m_aImCursorRectangle);
 }
 case Qt::ImAnchorPosition:
 {


[Libreoffice-commits] core.git: Branch 'libreoffice-7-3' - vcl/inc vcl/qt5

2022-04-06 Thread Michael Weghorn (via logerrit)
 vcl/inc/qt5/QtTransferable.hxx |2 +-
 vcl/qt5/QtTransferable.cxx |   25 +
 2 files changed, 18 insertions(+), 9 deletions(-)

New commits:
commit b60e4b4ba11c726cbbc45f0747d8fc4d3da0ed74
Author: Michael Weghorn 
AuthorDate: Wed Apr 6 13:51:59 2022 +0200
Commit: Michael Weghorn 
CommitDate: Thu Apr 7 07:21:58 2022 +0200

tdf#147285 qt: Prefer "text/plain;charset=utf-8" over "text/plain"

If there were no data for MIME type "text/plain;charset=utf-16"
in the clipboard, but "text/plain" was provided, it was previously
assumed that this would be encoded in the locale's encoding, and
corresponding conversion using that encoding happened to provide
"text/plain;charset=utf-16" ourselves.

"text/plain;charset=utf-8" data was simply ignored, but using
it (if present) and preferring it over "text/plain"
is more reliable (and e.g. avoids incorrect paste of Chinese
characters from Firefox into Impress when using the qt5/qt6/kf5
VCL plugins on Wayland), so use it if present.

Rename the "m_bConvertFromLocale" member to better fit
the new meaning.

(An alternative solution to adding our own handling for
"text/plain;charset=utf-8" and making assumptions for the
encoding of "text/plain" data would be to let Qt handle
this and just call `QMimeData::text()` for the
`m_bProvideUTF16FromOtherEncoding=true` case
in `QtTransferable::getTransferData`.
Since qtbase commit 589a01ff6b1eacf81e74a5fc4801572135214f43
("QMimeData: Prefer UTF-8 when multiple charsets are available",
contained in Qt >= 5.13), that one handles MIME type
"text/plain;charset=utf-8" in addition to "text/plain".)

[1] 
https://code.qt.io/cgit/qt/qtbase.git/commit/?id=589a01ff6b1eacf81e74a5fc4801572135214f43

Change-Id: I89f33216bf6be02a347d245b2359273af2eb530a
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/132631
Reviewed-by: Jan-Marek Glogowski 
Tested-by: Jenkins
(cherry picked from commit 5b3227fac58dcbd588e2389e205679cd77842bac)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/132607
Reviewed-by: Adolfo Jayme Barrientos 

diff --git a/vcl/inc/qt5/QtTransferable.hxx b/vcl/inc/qt5/QtTransferable.hxx
index f2997089c037..5f1533dd5968 100644
--- a/vcl/inc/qt5/QtTransferable.hxx
+++ b/vcl/inc/qt5/QtTransferable.hxx
@@ -35,7 +35,7 @@ class QtTransferable : public 
cppu::WeakImplHelper m_aMimeTypeSeq;
 
 public:
diff --git a/vcl/qt5/QtTransferable.cxx b/vcl/qt5/QtTransferable.cxx
index a2483b4b5f3a..1ab07dbb6224 100644
--- a/vcl/qt5/QtTransferable.cxx
+++ b/vcl/qt5/QtTransferable.cxx
@@ -42,7 +42,7 @@ static bool lcl_textMimeInfo(const OUString& rMimeString, 
bool& bHaveNoCharset,
 
 QtTransferable::QtTransferable(const QMimeData* pMimeData)
 : m_pMimeData(pMimeData)
-, m_bConvertFromLocale(false)
+, m_bProvideUTF16FromOtherEncoding(false)
 {
 assert(pMimeData);
 }
@@ -62,7 +62,7 @@ css::uno::Sequence SAL_CALL 
QtTransferable::getTr
 QStringList aFormatList(m_pMimeData->formats());
 // we might add the UTF-16 mime text variant later
 const int nMimeTypeSeqSize = aFormatList.size() + 1;
-bool bHaveNoCharset = false, bHaveUTF16 = false;
+bool bHaveNoCharset = false, bHaveUTF16 = false, bHaveUTF8 = false;
 css::uno::Sequence 
aMimeTypeSeq(nMimeTypeSeqSize);
 auto pMimeTypeSeq = aMimeTypeSeq.getArray();
 
@@ -85,6 +85,7 @@ css::uno::Sequence SAL_CALL 
QtTransferable::getTr
 {
 bHaveNoCharset |= bIsNoCharset;
 bHaveUTF16 |= bIsUTF16;
+bHaveUTF8 |= bIsUTF8;
 if (bIsUTF16)
 aFlavor.DataType = cppu::UnoType::get();
 else
@@ -99,8 +100,8 @@ css::uno::Sequence SAL_CALL 
QtTransferable::getTr
 nMimeTypeCount++;
 }
 
-m_bConvertFromLocale = bHaveNoCharset && !bHaveUTF16;
-if (m_bConvertFromLocale)
+m_bProvideUTF16FromOtherEncoding = (bHaveNoCharset || bHaveUTF8) && 
!bHaveUTF16;
+if (m_bProvideUTF16FromOtherEncoding)
 {
 aFlavor.MimeType = "text/plain;charset=utf-16";
 aFlavor.DataType = cppu::UnoType::get();
@@ -133,11 +134,19 @@ css::uno::Any SAL_CALL 
QtTransferable::getTransferData(const css::datatransfer::
 if (rFlavor.MimeType == "text/plain;charset=utf-16")
 {
 OUString aString;
-if (m_bConvertFromLocale)
+if (m_bProvideUTF16FromOtherEncoding)
 {
-QByteArray 
aByteData(m_pMimeData->data(QStringLiteral("text/plain")));
-aString = OUString(reinterpret_cast(aByteData.data()), aByteData.size(),
-   osl_getThreadTextEncoding());
+if (m_pMimeData->hasFormat("text/plain;charset=utf-8"))
+{
+QByteArray 
aByteData(m_pMimeData->data(QStringLiteral("text/plain;charset=utf-8")));
+aString = OUString::fromUtf8(reinterpret_cast(aByteData.data()));
+}
+ 

[Libreoffice-commits] core.git: Branch 'libreoffice-7-3' - vcl/inc vcl/qt5

2022-04-06 Thread Jan-Marek Glogowski (via logerrit)
 vcl/inc/qt5/QtMenu.hxx |2 +-
 vcl/qt5/QtMenu.cxx |   38 --
 2 files changed, 21 insertions(+), 19 deletions(-)

New commits:
commit 45d7a65f3d3dadcd71807a290fc11ff546aa5ba7
Author: Jan-Marek Glogowski 
AuthorDate: Tue Apr 5 16:49:38 2022 +0200
Commit: Jan-Marek Glogowski 
CommitDate: Wed Apr 6 15:16:47 2022 +0200

tdf#145954 Qt unshare QMenubar usage

The Qt code was sharing the menu bar from the top level frame, but
LO expects independent menu bars per SetFrame calls. So instead of
showing the new bar and then hiding the old one, this was always
show and hiding the same menu bar, resulting in a hidden menu bar.

As a result of unsharing, LO now must check that its menu bar
pointer is still valid for usage. The QMainWindows takes ownership
when a QMenuBar is assigned and destroy old ones.

Change-Id: I2c6b12199a1e17a5d9f88686a4b27b1413beda47
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/132581
Tested-by: Jenkins
Reviewed-by: Jan-Marek Glogowski 
(cherry picked from commit 9c4ef8ce3183e27ca174475cf4a8d15cc0368f60)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/132604
Reviewed-by: Michael Weghorn 

diff --git a/vcl/inc/qt5/QtMenu.hxx b/vcl/inc/qt5/QtMenu.hxx
index 55275ae6e099..f39be7e8d506 100644
--- a/vcl/inc/qt5/QtMenu.hxx
+++ b/vcl/inc/qt5/QtMenu.hxx
@@ -50,7 +50,6 @@ private:
 // pointer to QMenu owned by the corresponding QtMenuItem or self (-> 
mpOwnedQMenu)
 QMenu* mpQMenu;
 QPushButton* mpCloseButton;
-QMetaObject::Connection maCloseButtonConnection;
 
 void DoFullMenuUpdate(Menu* pMenuBar);
 static void NativeItemText(OUString& rItemText);
@@ -60,6 +59,7 @@ private:
 void ReinitializeActionGroup(unsigned nPos);
 void ResetAllActionGroups();
 void UpdateActionGroupItem(const QtMenuItem* pSalMenuItem);
+bool validateQMenuBar();
 
 public:
 QtMenu(bool bMenuBar);
diff --git a/vcl/qt5/QtMenu.cxx b/vcl/qt5/QtMenu.cxx
index c6224b137665..44873ce3384d 100644
--- a/vcl/qt5/QtMenu.cxx
+++ b/vcl/qt5/QtMenu.cxx
@@ -59,7 +59,7 @@ void QtMenu::InsertMenuItem(QtMenuItem* pSalMenuItem, 
unsigned nPos)
 if (mbMenuBar)
 {
 // top-level menu
-if (mpQMenuBar)
+if (validateQMenuBar())
 {
 QMenu* pQMenu = new QMenu(toQString(aText), nullptr);
 pSalMenuItem->mpMenu.reset(pQMenu);
@@ -428,20 +428,10 @@ void QtMenu::SetFrame(const SalFrame* pFrame)
 if (!pMainWindow)
 return;
 
-mpQMenuBar = pMainWindow->menuBar();
-if (mpQMenuBar)
-{
-mpQMenuBar->clear();
-QPushButton* pButton
-= 
static_cast(mpQMenuBar->cornerWidget(Qt::TopRightCorner));
-if (pButton && ((mpCloseButton != pButton) || 
!maCloseButtonConnection))
-{
-maCloseButtonConnection
-= connect(pButton, ::clicked, this, 
::slotCloseDocument);
-mpCloseButton = pButton;
-}
-}
+mpQMenuBar = new QMenuBar();
+pMainWindow->setMenuBar(mpQMenuBar);
 
+mpCloseButton = nullptr;
 mpQMenu = nullptr;
 
 DoFullMenuUpdate(mpVCLMenu);
@@ -565,9 +555,22 @@ QtMenu* QtMenu::GetTopLevel()
 return pMenu;
 }
 
+bool QtMenu::validateQMenuBar()
+{
+if (!mpQMenuBar)
+return false;
+assert(mpFrame);
+QtMainWindow* pMainWindow = mpFrame->GetTopLevelWindow();
+assert(pMainWindow);
+const bool bValid = mpQMenuBar == pMainWindow->menuBar();
+if (!bValid)
+mpQMenuBar = nullptr;
+return bValid;
+}
+
 void QtMenu::ShowMenuBar(bool bVisible)
 {
-if (mpQMenuBar)
+if (validateQMenuBar())
 mpQMenuBar->setVisible(bVisible);
 }
 
@@ -643,7 +646,7 @@ void QtMenu::slotCloseDocument()
 
 void QtMenu::ShowCloseButton(bool bShow)
 {
-if (!mpQMenuBar)
+if (!validateQMenuBar())
 return;
 
 QPushButton* pButton = 
static_cast(mpQMenuBar->cornerWidget(Qt::TopRightCorner));
@@ -661,8 +664,7 @@ void QtMenu::ShowCloseButton(bool bShow)
 pButton->setFocusPolicy(Qt::NoFocus);
 pButton->setToolTip(toQString(VclResId(SV_HELPTEXT_CLOSEDOCUMENT)));
 mpQMenuBar->setCornerWidget(pButton, Qt::TopRightCorner);
-maCloseButtonConnection
-= connect(pButton, ::clicked, this, 
::slotCloseDocument);
+connect(pButton, ::clicked, this, 
::slotCloseDocument);
 mpCloseButton = pButton;
 }
 


[Libreoffice-commits] core.git: Branch 'libreoffice-7-3' - vcl/inc vcl/qt5

2022-04-06 Thread Jan-Marek Glogowski (via logerrit)
 vcl/inc/qt5/QtFrame.hxx |1 
 vcl/qt5/QtFrame.cxx |   73 +++-
 vcl/qt5/QtWidget.cxx|8 +
 3 files changed, 15 insertions(+), 67 deletions(-)

New commits:
commit c309ddb6d9cd61f3024ffeee33fce1a0e173d9cc
Author: Jan-Marek Glogowski 
AuthorDate: Mon Apr 4 18:02:28 2022 +0200
Commit: Michael Weghorn 
CommitDate: Wed Apr 6 14:49:52 2022 +0200

tdf#144585 Qt fix Wayland LO fake popups

So Michael Weghorn was somehow reminded of an abandoned
commit from me ("Qt5 rework parent handling") archived in
https://gerrit.libreoffice.org/c/core/+/73463.

The bug introducing the new QWidget parenting, tdf#145363, was
resolved in a better way by explicitly setting parents for the
modal dialogs, so LO doesn't break Qt anymore. The actual problem
is, that an additional modal dialog needs to be stacked to the
previous modal dialog; no "parallel" modal dialogs are allowed,
which my original fix tried to enforce by reparenting.

Then there is the problem with Qt::Popup's focus grabbing on show,
which breaks LO's editable ComboBox. So LO's popup / FLOAT windows
are mapped to Qt::ToolTip, which are automatically advertised as
tooltips via accessibility. For X11 / xcb, Qt:Window with the
Qt::BypassWindowManagerHint works well enough as an alternative,
but WASM and Wayland don't seem to implement it correctly, so this
just handles popups as Qt::ToolTip on all platforms.

This reverts commit b00a68a8e19370e106cd76258a3c1825f43613ee
("tdf#145363 Qt reparent modal dialogs on show").
In addition the popup widgets are switched back to Qt::ToolTip.

Change-Id: If726771b4e9cc3f639f21cf502b3ec5985873643
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/132526
Reviewed-by: Jan-Marek Glogowski 
Reviewed-by: Michael Weghorn 
Tested-by: Jenkins
(cherry picked from commit fbf739198aa7f02975d531521c6525073783c7f1)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/132625

diff --git a/vcl/inc/qt5/QtFrame.hxx b/vcl/inc/qt5/QtFrame.hxx
index dbf54079313d..59ec093a2ed6 100644
--- a/vcl/inc/qt5/QtFrame.hxx
+++ b/vcl/inc/qt5/QtFrame.hxx
@@ -133,7 +133,6 @@ class VCLPLUG_QT_PUBLIC QtFrame : public QObject, public 
SalFrame
 int menuBarOffset() const;
 
 void fixICCCMwindowGroup();
-void modalReparent(bool bVisible);
 
 public:
 QtFrame(QtFrame* pParent, SalFrameStyleFlags nSalFrameStyle, bool 
bUseCairo);
diff --git a/vcl/qt5/QtFrame.cxx b/vcl/qt5/QtFrame.cxx
index 10b7e46909c5..ad9c03d0bfa1 100644
--- a/vcl/qt5/QtFrame.cxx
+++ b/vcl/qt5/QtFrame.cxx
@@ -149,11 +149,14 @@ QtFrame::QtFrame(QtFrame* pParent, SalFrameStyleFlags 
nStyle, bool bUseCairo)
 aWinFlags = Qt::Tool | Qt::FramelessWindowHint;
 else if (nStyle & SalFrameStyleFlags::TOOLTIP)
 aWinFlags = Qt::ToolTip;
-// Can't use Qt::Popup, because it grabs the input focus and generates
-// a focus-out event, reaching the combo box. This used to map to
-// Qt::ToolTip, which doesn't feel that correct...
+// Can't use Qt::Popup, because it grabs the input focus and generates 
a focus-out event,
+// instantly auto-closing the LO's editable ComboBox popup.
+// On X11, the alternative Qt::Window | Qt::FramelessWindowHint | 
Qt::BypassWindowManagerHint
+// seems to work well enough, but at least on Wayland and WASM, this 
results in problems.
+// So while using Qt::ToolTip, the popups are wrongly advertised via 
accessibility, at least
+// the GUI seems to work on all platforms... what a mess.
 else if (isPopup())
-aWinFlags = Qt::Window | Qt::FramelessWindowHint | 
Qt::BypassWindowManagerHint;
+aWinFlags = Qt::ToolTip | Qt::FramelessWindowHint;
 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
@@ -168,7 +171,7 @@ QtFrame::QtFrame(QtFrame* pParent, SalFrameStyleFlags 
nStyle, bool bUseCairo)
 if (aWinFlags == Qt::Window)
 {
 m_pTopLevel = new QtMainWindow(*this, aWinFlags);
-m_pQWidget = new QtWidget(*this, aWinFlags);
+m_pQWidget = new QtWidget(*this);
 m_pTopLevel->setCentralWidget(m_pQWidget);
 m_pTopLevel->setFocusProxy(m_pQWidget);
 }
@@ -417,38 +420,6 @@ void QtFrame::DrawMenuBar() { /* not needed */}
 
 void QtFrame::SetExtendedFrameStyle(SalExtStyle /*nExtStyle*/) { /* not needed 
*/}
 
-void QtFrame::modalReparent(bool bVisible)
-{
-#ifndef NDEBUG
-auto* pSalInst(static_cast(GetSalData()->m_pInstance));
-assert(pSalInst);
-assert(pSalInst->IsMainThread());
-assert(!asChild()->isVisible());
-assert(asChild()->isModal());
-#endif
-
-if (!bVisible)
-{
-m_pQWidget->setParent(m_pParent ? m_pParent->asChild() : 

[Libreoffice-commits] core.git: Branch 'libreoffice-7-3' - vcl/inc vcl/qt5

2022-01-16 Thread Jan-Marek Glogowski (via logerrit)
 vcl/inc/qt5/QtInstance.hxx |8 
 vcl/qt5/QtInstance.cxx |   36 
 2 files changed, 44 insertions(+)

New commits:
commit e49d774fd2bb5ddf35a47368f36980d5e0d32ad3
Author: Jan-Marek Glogowski 
AuthorDate: Sun Jan 16 10:14:47 2022 +0100
Commit: Caolán McNamara 
CommitDate: Sun Jan 16 18:22:44 2022 +0100

Qt notify LO of many QScreen related events

LO just has a single display event, SalEvent::DisplayChanged, Qt
has a multitude. So this will generate multiple LO notifications.
I don't see any reasonable way to prevent that. Doesn't seem a
problem here.

Change-Id: I2f11e53765869a4ca292a1d337347e4e7470e3c2
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/128474
Tested-by: Jenkins
Reviewed-by: Jan-Marek Glogowski 
(cherry picked from commit ced4cde59eb51e4364daf69520a184b55c2c54db)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/128434
Tested-by: Caolán McNamara 
Reviewed-by: Caolán McNamara 

diff --git a/vcl/inc/qt5/QtInstance.hxx b/vcl/inc/qt5/QtInstance.hxx
index 009b9ae8c312..9a9853a7a2ce 100644
--- a/vcl/inc/qt5/QtInstance.hxx
+++ b/vcl/inc/qt5/QtInstance.hxx
@@ -75,6 +75,12 @@ private Q_SLOTS:
 static void deleteObjectLater(QObject* pObject);
 static void localeChanged();
 
+void orientationChanged(Qt::ScreenOrientation);
+void primaryScreenChanged(QScreen*);
+void screenAdded(QScreen*);
+void screenRemoved(QScreen*);
+void virtualGeometryChanged(const QRect&);
+
 Q_SIGNALS:
 bool ImplYieldSignal(bool bWait, bool bHandleAllCurrentEvents);
 void deleteObjectLaterSignal(QObject* pObject);
@@ -86,6 +92,8 @@ protected:
 bool useCairo() const { return m_bUseCairo; }
 // encodes cairo usage and Qt platform name into the ToolkitName
 OUString constructToolkitID(std::u16string_view sTKname);
+void connectQScreenSignals(const QScreen*);
+void notifyDisplayChanged();
 
 public:
 explicit QtInstance(std::unique_ptr& pQApp, bool bUseCairo = 
false);
diff --git a/vcl/qt5/QtInstance.cxx b/vcl/qt5/QtInstance.cxx
index 29a7d0e4ddf7..d252109e122a 100644
--- a/vcl/qt5/QtInstance.cxx
+++ b/vcl/qt5/QtInstance.cxx
@@ -40,6 +40,7 @@
 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -248,6 +249,12 @@ QtInstance::QtInstance(std::unique_ptr& 
pQApp, bool bUseCairo)
 connect(QGuiApplication::inputMethod(), ::localeChanged, this,
 ::localeChanged);
 
+for (const QScreen* pCurScreen : QApplication::screens())
+connectQScreenSignals(pCurScreen);
+connect(qApp, ::primaryScreenChanged, this, 
::primaryScreenChanged);
+connect(qApp, ::screenAdded, this, 
::screenAdded);
+connect(qApp, ::screenRemoved, this, 
::screenRemoved);
+
 #ifndef EMSCRIPTEN
 m_bSupportsOpenGL = true;
 #endif
@@ -602,6 +609,35 @@ void* QtInstance::CreateGStreamerSink(const 
SystemChildWindow* pWindow)
 #endif
 }
 
+void QtInstance::connectQScreenSignals(const QScreen* pScreen)
+{
+connect(pScreen, ::orientationChanged, this, 
::orientationChanged);
+connect(pScreen, ::virtualGeometryChanged, this, 
::virtualGeometryChanged);
+}
+
+void QtInstance::notifyDisplayChanged()
+{
+SolarMutexGuard aGuard;
+SalFrame* pAnyFrame = anyFrame();
+if (pAnyFrame)
+pAnyFrame->CallCallback(SalEvent::DisplayChanged, nullptr);
+}
+
+void QtInstance::orientationChanged(Qt::ScreenOrientation) { 
notifyDisplayChanged(); }
+
+void QtInstance::primaryScreenChanged(QScreen*) { notifyDisplayChanged(); }
+
+void QtInstance::screenAdded(QScreen* pScreen)
+{
+connectQScreenSignals(pScreen);
+if (QApplication::screens().size() == 1)
+notifyDisplayChanged();
+}
+
+void QtInstance::screenRemoved(QScreen*) { notifyDisplayChanged(); }
+
+void QtInstance::virtualGeometryChanged(const QRect&) { 
notifyDisplayChanged(); }
+
 void QtInstance::AllocFakeCmdlineArgs(std::unique_ptr& rFakeArgv,
   std::unique_ptr& rFakeArgc,
   std::vector& 
rFakeArgvFreeable)


[Libreoffice-commits] core.git: Branch 'libreoffice-7-3' - vcl/inc vcl/qt5

2021-12-21 Thread Jan-Marek Glogowski (via logerrit)
 vcl/inc/qt5/QtFrame.hxx |1 +
 vcl/qt5/QtFrame.cxx |   20 ++--
 2 files changed, 15 insertions(+), 6 deletions(-)

New commits:
commit 4d30c63bd0652c75cda9c57ef21c4cfe65df184f
Author: Jan-Marek Glogowski 
AuthorDate: Mon Dec 20 13:32:52 2021 +0100
Commit: Adolfo Jayme Barrientos 
CommitDate: Wed Dec 22 05:01:00 2021 +0100

tdf#131467 Qt set default position on first resize

Setting the position in Show() is too late, because LO will try
to set the mouse pointer to the default button, if configured.
That obviously needs the window position.
And also take the menubar offset into account.

Change-Id: Ia280539c082ff6f675966869fb6643a41a17d696
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/127154
Tested-by: Jenkins
Reviewed-by: Jan-Marek Glogowski 
(cherry picked from commit ca28826a087245686d7fca3ffc8ca1f03307924d)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/127185
Reviewed-by: Adolfo Jayme Barrientos 

diff --git a/vcl/inc/qt5/QtFrame.hxx b/vcl/inc/qt5/QtFrame.hxx
index c3c9cdb9f309..dbf54079313d 100644
--- a/vcl/inc/qt5/QtFrame.hxx
+++ b/vcl/inc/qt5/QtFrame.hxx
@@ -130,6 +130,7 @@ class VCLPLUG_QT_PUBLIC QtFrame : public QObject, public 
SalFrame
 bool isMinimized() const;
 bool isMaximized() const;
 void SetWindowStateImpl(Qt::WindowStates eState);
+int menuBarOffset() const;
 
 void fixICCCMwindowGroup();
 void modalReparent(bool bVisible);
diff --git a/vcl/qt5/QtFrame.cxx b/vcl/qt5/QtFrame.cxx
index 5772e7e87251..7b24103908e9 100644
--- a/vcl/qt5/QtFrame.cxx
+++ b/vcl/qt5/QtFrame.cxx
@@ -470,7 +470,6 @@ void QtFrame::Show(bool bVisible, bool bNoActivate)
 
 // show
 SetDefaultSize();
-SetDefaultPos();
 
 pSalInst->RunInMainThread([this, bNoActivate]() {
 QWidget* const pChild = asChild();
@@ -504,6 +503,14 @@ void QtFrame::SetMaxClientSize(tools::Long nWidth, 
tools::Long nHeight)
 }
 }
 
+int QtFrame::menuBarOffset() const
+{
+QtMainWindow* pTopLevel = m_pParent->GetTopLevelWindow();
+if (pTopLevel && pTopLevel->menuBar() && pTopLevel->menuBar()->isVisible())
+return round(pTopLevel->menuBar()->geometry().height() * 
devicePixelRatioF());
+return 0;
+}
+
 void QtFrame::SetDefaultPos()
 {
 if (!m_bDefaultPos)
@@ -516,6 +523,7 @@ void QtFrame::SetDefaultPos()
 QWidget* const pParentWin = m_pParent->asChild()->window();
 QWidget* const pChildWin = asChild()->window();
 QPoint aPos = (pParentWin->rect().center() - 
pChildWin->rect().center()) * fRatio;
+aPos.ry() -= menuBarOffset();
 SetPosSize(aPos.x(), aPos.y(), 0, 0, SAL_FRAME_POSSIZE_X | 
SAL_FRAME_POSSIZE_Y);
 assert(!m_bDefaultPos);
 }
@@ -604,7 +612,11 @@ void QtFrame::SetPosSize(tools::Long nX, tools::Long nY, 
tools::Long nWidth, too
 }
 
 if (!(nFlags & (SAL_FRAME_POSSIZE_X | SAL_FRAME_POSSIZE_Y)))
+{
+if (nFlags & (SAL_FRAME_POSSIZE_WIDTH | SAL_FRAME_POSSIZE_HEIGHT))
+SetDefaultPos();
 return;
+}
 
 if (m_pParent)
 {
@@ -613,11 +625,7 @@ void QtFrame::SetPosSize(tools::Long nX, tools::Long nY, 
tools::Long nWidth, too
 nX = aParentGeometry.nX + aParentGeometry.nWidth - nX - 
maGeometry.nWidth - 1;
 else
 nX += aParentGeometry.nX;
-nY += aParentGeometry.nY;
-
-QtMainWindow* pTopLevel = m_pParent->GetTopLevelWindow();
-if (pTopLevel && pTopLevel->menuBar() && 
pTopLevel->menuBar()->isVisible())
-nY += round(pTopLevel->menuBar()->geometry().height() * 
devicePixelRatioF());
+nY += aParentGeometry.nY + menuBarOffset();
 }
 
 if (!(nFlags & SAL_FRAME_POSSIZE_X))