From 1186d2b78c76b3b9f7733e59a599245c060078d4 Mon Sep 17 00:00:00 2001 From: Uwe Kindler Date: Fri, 28 Apr 2023 11:12:22 +0200 Subject: [PATCH] Fixed #509 - Implemented support for restoring maximized state of floating widgets on Windows --- src/DockManager.cpp | 36 ++++++++++++++++++++++- src/DockManager.h | 17 +++++++++-- src/FloatingDockContainer.cpp | 54 +++++++++++++++++++++-------------- src/FloatingDockContainer.h | 2 -- 4 files changed, 83 insertions(+), 26 deletions(-) diff --git a/src/DockManager.cpp b/src/DockManager.cpp index 5c7dd4d..9ccaec3 100644 --- a/src/DockManager.cpp +++ b/src/DockManager.cpp @@ -47,6 +47,7 @@ #include #include #include +#include #include "FloatingDockContainer.h" #include "DockOverlay.h" @@ -116,6 +117,7 @@ struct DockManagerPrivate QVector UninitializedFloatingWidgets; CDockFocusController* FocusController = nullptr; CDockWidget* CentralWidget = nullptr; + bool IsLeavingMinimized = false; /** * Private data constructor @@ -510,9 +512,10 @@ CDockManager::CDockManager(QWidget *parent) : d->FocusController = new CDockFocusController(this); } -#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS) + window()->installEventFilter(this); +#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS) connect(qApp, &QApplication::focusWindowChanged, [](QWindow* focusWindow) { // bring modal dialogs to foreground to ensure that they are in front of any @@ -629,8 +632,39 @@ bool CDockManager::eventFilter(QObject *obj, QEvent *e) } return Super::eventFilter(obj, e); } +#else +//============================================================================ +bool CDockManager::eventFilter(QObject *obj, QEvent *e) +{ + if (e->type() == QEvent::WindowStateChange) + { + QWindowStateChangeEvent* ev = static_cast(e); + if (ev->oldState().testFlag(Qt::WindowMinimized)) + { + d->IsLeavingMinimized = true; + QMetaObject::invokeMethod(this, "endLeavingMinimizedState", Qt::QueuedConnection); + } + } + return Super::eventFilter(obj, e); +} #endif + +//============================================================================ +void CDockManager::endLeavingMinimizedState() +{ + d->IsLeavingMinimized = false; + this->activateWindow(); +} + + +//============================================================================ +bool CDockManager::isLeavingMinimizedState() const +{ + return d->IsLeavingMinimized; +} + + //============================================================================ void CDockManager::registerFloatingWidget(CFloatingDockContainer* FloatingWidget) { diff --git a/src/DockManager.h b/src/DockManager.h index bdb8c72..e0f9d44 100644 --- a/src/DockManager.h +++ b/src/DockManager.h @@ -88,6 +88,12 @@ private: friend class CAutoHideDockContainer; friend CAutoHideSideBar; +public Q_SLOTS: + /** + * Ends the isRestoringFromMinimizedState + */ + void endLeavingMinimizedState(); + protected: /** @@ -539,6 +545,15 @@ public: */ bool isRestoringState() const; + /** + * This function returns true, if the DockManager window is restoring from + * minimized state. + * The DockManager is in this state starting from the QWindowStateChangeEvent + * that signals the state change from minimized to normal until + * endLeavingMinimizedState() function is called. + */ + bool isLeavingMinimizedState() const; + /** * The distance the user needs to move the mouse with the left button * hold down before a dock widget start floating @@ -560,9 +575,7 @@ public: widget->setFocus(Qt::OtherFocusReason); } -#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS) bool eventFilter(QObject *obj, QEvent *e) override; -#endif /** * Returns the dock widget that has focus style in the ui or a nullptr if diff --git a/src/FloatingDockContainer.cpp b/src/FloatingDockContainer.cpp index 9d19d3b..0a2cdc7 100644 --- a/src/FloatingDockContainer.cpp +++ b/src/FloatingDockContainer.cpp @@ -763,18 +763,43 @@ CDockContainerWidget* CFloatingDockContainer::dockContainer() const void CFloatingDockContainer::changeEvent(QEvent *event) { Super::changeEvent(event); - if ((event->type() == QEvent::ActivationChange) && isActiveWindow()) + switch (event->type()) { - ADS_PRINT("FloatingWidget::changeEvent QEvent::ActivationChange "); - d->zOrderIndex = ++zOrderCounter; + case QEvent::ActivationChange: + if (isActiveWindow()) + { + ADS_PRINT("FloatingWidget::changeEvent QEvent::ActivationChange "); + d->zOrderIndex = ++zOrderCounter; #if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS) - if (d->DraggingState == DraggingFloatingWidget) - { - d->titleMouseReleaseEvent(); - d->DraggingState = DraggingInactive; - } + if (d->DraggingState == DraggingFloatingWidget) + { + d->titleMouseReleaseEvent(); + d->DraggingState = DraggingInactive; + } #endif + } + break; + + case QEvent::WindowStateChange: + // If the DockManager window is restored from minimized on Windows + // then the FloatingWidgets are not properly restored to maximized but + // to normal state. + // We simply check here, if the FloatingWidget was maximized before + // and if the DockManager is just leaving the minimized state. In this + // case, we restore the maximized state of this floating widget + if (d->DockManager->isLeavingMinimizedState()) + { + QWindowStateChangeEvent* ev = static_cast(event); + if (ev->oldState().testFlag(Qt::WindowMaximized)) + { + this->showMaximized(); + } + } + break; + + default: + break; // do nothing } } @@ -1337,19 +1362,6 @@ bool CFloatingDockContainer::hasNativeTitleBar() } #endif - -//============================================================================ -bool CFloatingDockContainer::event(QEvent *e) -{ - qDebug() << "CFloatingDockContainer::event: " << e; - if (e->type() == QEvent::WindowStateChange) - { - QWindowStateChangeEvent* ev = static_cast(e); - qDebug() << "WindowStateChange " << ev->oldState() << " -> " << windowState(); - qDebug() << "isActiveWindow " << isActiveWindow(); - } - return Super::event(e); -} } // namespace ads //--------------------------------------------------------------------------- diff --git a/src/FloatingDockContainer.h b/src/FloatingDockContainer.h index c358c9c..333915f 100644 --- a/src/FloatingDockContainer.h +++ b/src/FloatingDockContainer.h @@ -298,8 +298,6 @@ public: */ bool hasNativeTitleBar(); #endif - - virtual bool event(QEvent *e) override; }; // class FloatingDockContainer } // namespace ads