summaryrefslogtreecommitdiff
path: root/vcl/qt5
diff options
context:
space:
mode:
authorJan-Marek Glogowski <glogow@fbihome.de>2021-10-31 02:33:46 +0200
committerJan-Marek Glogowski <glogow@fbihome.de>2021-10-31 21:04:33 +0100
commitb00a68a8e19370e106cd76258a3c1825f43613ee (patch)
tree7dc47d21ca3f2401c6b29bde91492053f222b4e8 /vcl/qt5
parente4abf879f4a24258bcc560eb58ca78b147768d46 (diff)
tdf#145363 Qt reparent modal dialogs on show
Simply said, one can't have two modal dialogs open at the same parent in Qt. All modal windows must open as a stack, each parented to the previous one. This is kind of logical. Unexpectedly Qt totally breaks, if you open two modal dialogs on the same window. This happens, because the existing paragraph style dialog and the "sub" "list style" dialog are both children of their Writer window. I'm not sure the additionally introduced QWidget-based parent handling is strictly needed. It seems Ok. So for every visibility and modality change, we reparent the Qt widget, either on top of the modal stack or restore the original LO-based parent. The LO hierachy is never changed! Change-Id: Id209c9aa67774440089dc50a6648ac293950087a Reviewed-on: https://gerrit.libreoffice.org/c/core/+/124500 Tested-by: Jenkins Reviewed-by: Jan-Marek Glogowski <glogow@fbihome.de>
Diffstat (limited to 'vcl/qt5')
-rw-r--r--vcl/qt5/QtFrame.cxx80
-rw-r--r--vcl/qt5/QtWidget.cxx6
2 files changed, 76 insertions, 10 deletions
diff --git a/vcl/qt5/QtFrame.cxx b/vcl/qt5/QtFrame.cxx
index 73bdad874552..1ae4016d589d 100644
--- a/vcl/qt5/QtFrame.cxx
+++ b/vcl/qt5/QtFrame.cxx
@@ -417,24 +417,71 @@ void QtFrame::DrawMenuBar() { /* not needed */}
void QtFrame::SetExtendedFrameStyle(SalExtStyle /*nExtStyle*/) { /* not needed */}
+void QtFrame::modalReparent(bool bVisible)
+{
+#ifndef NDEBUG
+ auto* pSalInst(static_cast<QtInstance*>(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() : nullptr,
+ m_pQWidget->windowFlags());
+ return;
+ }
+
+ if (!QGuiApplication::modalWindow())
+ return;
+
+ QtInstance* pInst = static_cast<QtInstance*>(GetSalData()->m_pInstance);
+ for (auto* pFrame : pInst->getFrames())
+ {
+ QWidget* pQWidget = static_cast<QtFrame*>(pFrame)->asChild();
+ if (pQWidget->windowHandle() == QGuiApplication::modalWindow())
+ {
+ m_pQWidget->setParent(pQWidget, m_pQWidget->windowFlags());
+ break;
+ }
+ }
+}
+
void QtFrame::Show(bool bVisible, bool bNoActivate)
{
assert(m_pQWidget);
if (bVisible == asChild()->isVisible())
return;
+ auto* pSalInst(static_cast<QtInstance*>(GetSalData()->m_pInstance));
+ assert(pSalInst);
+
+ if (!bVisible) // hide
+ {
+ pSalInst->RunInMainThread([this]() {
+ asChild()->hide();
+ if (m_pQWidget->isModal())
+ modalReparent(false);
+ });
+ return;
+ }
+
+ // show
SetDefaultSize();
SetDefaultPos();
- auto* pSalInst(static_cast<QtInstance*>(GetSalData()->m_pInstance));
- assert(pSalInst);
- pSalInst->RunInMainThread([this, bVisible, bNoActivate]() {
- asChild()->setVisible(bVisible);
- asChild()->raise();
+ pSalInst->RunInMainThread([this, bNoActivate]() {
+ QWidget* const pChild = asChild();
+ if (m_pQWidget->isModal())
+ modalReparent(true);
+ pChild->show();
+ pChild->raise();
if (!bNoActivate && !isPopup())
{
- asChild()->activateWindow();
- asChild()->setFocus();
+ pChild->activateWindow();
+ pChild->setFocus();
}
});
}
@@ -610,7 +657,7 @@ SalFrame* QtFrame::GetParent() const { return m_pParent; }
void QtFrame::SetModal(bool bModal)
{
- if (!isWindow())
+ if (!isWindow() || asChild()->isModal() == bModal)
return;
auto* pSalInst(static_cast<QtInstance*>(GetSalData()->m_pInstance));
@@ -622,12 +669,20 @@ void QtFrame::SetModal(bool bModal)
// modality change is only effective if the window is hidden
if (bWasVisible)
+ {
pChild->hide();
+ if (!bModal)
+ modalReparent(false);
+ }
pChild->setWindowModality(bModal ? Qt::WindowModal : Qt::NonModal);
if (bWasVisible)
+ {
+ if (bModal)
+ modalReparent(true);
pChild->show();
+ }
});
}
@@ -1180,7 +1235,14 @@ void QtFrame::SimulateKeyPress(sal_uInt16 nKeyCode)
SAL_WARN("vcl.qt", "missing simulate keypress " << nKeyCode);
}
-void QtFrame::SetParent(SalFrame* pNewParent) { m_pParent = static_cast<QtFrame*>(pNewParent); }
+void QtFrame::SetParent(SalFrame* pNewParent)
+{
+ if (m_pParent == pNewParent)
+ return;
+ m_pParent = static_cast<QtFrame*>(pNewParent);
+ if (!m_pTopLevel)
+ m_pQWidget->setParent(m_pParent->asChild(), m_pQWidget->windowFlags());
+}
void QtFrame::SetPluginParent(SystemParentData* /*pNewParent*/)
{
diff --git a/vcl/qt5/QtWidget.cxx b/vcl/qt5/QtWidget.cxx
index 44952f9318b0..85bcd814b03a 100644
--- a/vcl/qt5/QtWidget.cxx
+++ b/vcl/qt5/QtWidget.cxx
@@ -23,6 +23,7 @@
#include <QtFrame.hxx>
#include <QtGraphics.hxx>
#include <QtInstance.hxx>
+#include <QtMainWindow.hxx>
#include <QtSvpGraphics.hxx>
#include <QtTransferable.hxx>
#include <QtTools.hxx>
@@ -616,7 +617,10 @@ void QtWidget::focusOutEvent(QFocusEvent*)
}
QtWidget::QtWidget(QtFrame& rFrame, Qt::WindowFlags f)
- : QWidget(Q_NULLPTR, f)
+ : QWidget(!rFrame.GetTopLevelWindow() && rFrame.GetParent()
+ ? static_cast<QtFrame*>(rFrame.GetParent())->asChild()
+ : Q_NULLPTR,
+ f)
, m_rFrame(rFrame)
, m_bNonEmptyIMPreeditSeen(false)
, m_nDeltaX(0)