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 <QApplication>
#include <QWindow>
#include <QWindowStateChangeEvent>
#include "FloatingDockContainer.h"
#include "DockOverlay.h"
@ -116,6 +117,7 @@ struct DockManagerPrivate
QVector<CFloatingDockContainer*> 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<QWindowStateChangeEvent*>(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)
{

View File

@ -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

View File

@ -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<QWindowStateChangeEvent*>(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<QWindowStateChangeEvent*>(e);
qDebug() << "WindowStateChange " << ev->oldState() << " -> " << windowState();
qDebug() << "isActiveWindow " << isActiveWindow();
}
return Super::event(e);
}
} // namespace ads
//---------------------------------------------------------------------------

View File

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