Fixed #509 - Implemented support for restoring maximized state of floating widgets on Windows

This commit is contained in:
Uwe Kindler 2023-04-28 11:12:22 +02:00
parent 44115d4bd9
commit 1186d2b78c
4 changed files with 83 additions and 26 deletions

View File

@ -47,6 +47,7 @@
#include <QMenu> #include <QMenu>
#include <QApplication> #include <QApplication>
#include <QWindow> #include <QWindow>
#include <QWindowStateChangeEvent>
#include "FloatingDockContainer.h" #include "FloatingDockContainer.h"
#include "DockOverlay.h" #include "DockOverlay.h"
@ -116,6 +117,7 @@ struct DockManagerPrivate
QVector<CFloatingDockContainer*> UninitializedFloatingWidgets; QVector<CFloatingDockContainer*> UninitializedFloatingWidgets;
CDockFocusController* FocusController = nullptr; CDockFocusController* FocusController = nullptr;
CDockWidget* CentralWidget = nullptr; CDockWidget* CentralWidget = nullptr;
bool IsLeavingMinimized = false;
/** /**
* Private data constructor * Private data constructor
@ -510,9 +512,10 @@ CDockManager::CDockManager(QWidget *parent) :
d->FocusController = new CDockFocusController(this); d->FocusController = new CDockFocusController(this);
} }
#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)
window()->installEventFilter(this); window()->installEventFilter(this);
#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)
connect(qApp, &QApplication::focusWindowChanged, [](QWindow* focusWindow) connect(qApp, &QApplication::focusWindowChanged, [](QWindow* focusWindow)
{ {
// bring modal dialogs to foreground to ensure that they are in front of any // 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); return Super::eventFilter(obj, e);
} }
#else
//============================================================================
bool CDockManager::eventFilter(QObject *obj, QEvent *e)
{
if (e->type() == QEvent::WindowStateChange)
{
QWindowStateChangeEvent* ev = static_cast<QWindowStateChangeEvent*>(e);
if (ev->oldState().testFlag(Qt::WindowMinimized))
{
d->IsLeavingMinimized = true;
QMetaObject::invokeMethod(this, "endLeavingMinimizedState", Qt::QueuedConnection);
}
}
return Super::eventFilter(obj, e);
}
#endif #endif
//============================================================================
void CDockManager::endLeavingMinimizedState()
{
d->IsLeavingMinimized = false;
this->activateWindow();
}
//============================================================================
bool CDockManager::isLeavingMinimizedState() const
{
return d->IsLeavingMinimized;
}
//============================================================================ //============================================================================
void CDockManager::registerFloatingWidget(CFloatingDockContainer* FloatingWidget) void CDockManager::registerFloatingWidget(CFloatingDockContainer* FloatingWidget)
{ {

View File

@ -88,6 +88,12 @@ private:
friend class CAutoHideDockContainer; friend class CAutoHideDockContainer;
friend CAutoHideSideBar; friend CAutoHideSideBar;
public Q_SLOTS:
/**
* Ends the isRestoringFromMinimizedState
*/
void endLeavingMinimizedState();
protected: protected:
/** /**
@ -539,6 +545,15 @@ public:
*/ */
bool isRestoringState() const; 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 * The distance the user needs to move the mouse with the left button
* hold down before a dock widget start floating * hold down before a dock widget start floating
@ -560,9 +575,7 @@ public:
widget->setFocus(Qt::OtherFocusReason); widget->setFocus(Qt::OtherFocusReason);
} }
#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)
bool eventFilter(QObject *obj, QEvent *e) override; bool eventFilter(QObject *obj, QEvent *e) override;
#endif
/** /**
* Returns the dock widget that has focus style in the ui or a nullptr if * Returns the dock widget that has focus style in the ui or a nullptr if

View File

@ -763,18 +763,43 @@ CDockContainerWidget* CFloatingDockContainer::dockContainer() const
void CFloatingDockContainer::changeEvent(QEvent *event) void CFloatingDockContainer::changeEvent(QEvent *event)
{ {
Super::changeEvent(event); Super::changeEvent(event);
if ((event->type() == QEvent::ActivationChange) && isActiveWindow()) switch (event->type())
{ {
ADS_PRINT("FloatingWidget::changeEvent QEvent::ActivationChange "); case QEvent::ActivationChange:
d->zOrderIndex = ++zOrderCounter; if (isActiveWindow())
{
ADS_PRINT("FloatingWidget::changeEvent QEvent::ActivationChange ");
d->zOrderIndex = ++zOrderCounter;
#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS) #if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)
if (d->DraggingState == DraggingFloatingWidget) if (d->DraggingState == DraggingFloatingWidget)
{ {
d->titleMouseReleaseEvent(); d->titleMouseReleaseEvent();
d->DraggingState = DraggingInactive; d->DraggingState = DraggingInactive;
} }
#endif #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<QWindowStateChangeEvent*>(event);
if (ev->oldState().testFlag(Qt::WindowMaximized))
{
this->showMaximized();
}
}
break;
default:
break; // do nothing
} }
} }
@ -1337,19 +1362,6 @@ bool CFloatingDockContainer::hasNativeTitleBar()
} }
#endif #endif
//============================================================================
bool CFloatingDockContainer::event(QEvent *e)
{
qDebug() << "CFloatingDockContainer::event: " << e;
if (e->type() == QEvent::WindowStateChange)
{
QWindowStateChangeEvent* ev = static_cast<QWindowStateChangeEvent*>(e);
qDebug() << "WindowStateChange " << ev->oldState() << " -> " << windowState();
qDebug() << "isActiveWindow " << isActiveWindow();
}
return Super::event(e);
}
} // namespace ads } // namespace ads
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------

View File

@ -298,8 +298,6 @@ public:
*/ */
bool hasNativeTitleBar(); bool hasNativeTitleBar();
#endif #endif
virtual bool event(QEvent *e) override;
}; // class FloatingDockContainer }; // class FloatingDockContainer
} }
// namespace ads // namespace ads