Fixed the restoration of geometry when user closed maximized window

This commit is contained in:
Eism
2021-12-21 15:32:43 +02:00
committed by Sergio Martins
parent 29b1a434c4
commit 336f1146d3
7 changed files with 84 additions and 29 deletions

View File

@@ -30,6 +30,7 @@
#include "private/LayoutWidget_p.h"
#include "private/Logging_p.h"
#include "private/Position_p.h"
#include "private/Utils_p.h"
#include <qmath.h>
#include <QDebug>
@@ -339,10 +340,17 @@ void LayoutSaver::Private::deserializeWindowGeometry(const T &saved, QWidgetOrQu
// Not simply calling QWidget::setGeometry() here.
// For QtQuick we need to modify the QWindow's geometry.
QRect geometry = saved.geometry;
if (!isNormalWindowState(saved.windowState)) {
// The window will be maximized. We first set its geometry to normal
// Later it's maximized and will remember this value
geometry = saved.normalGeometry;
}
if (topLevel->isWindow()) {
topLevel->setGeometry(saved.geometry);
topLevel->setGeometry(geometry);
} else {
KDDockWidgets::Private::setTopLevelGeometry(saved.geometry, topLevel);
KDDockWidgets::Private::setTopLevelGeometry(geometry, topLevel);
}
topLevel->setVisible(saved.isVisible);
@@ -848,6 +856,7 @@ QVariantMap LayoutSaver::MainWindow::toVariantMap() const
map.insert(QStringLiteral("multiSplitterLayout"), multiSplitterLayout.toVariantMap());
map.insert(QStringLiteral("uniqueName"), uniqueName);
map.insert(QStringLiteral("geometry"), Layouting::rectToMap(geometry));
map.insert(QStringLiteral("normalGeometry"), Layouting::rectToMap(normalGeometry));
map.insert(QStringLiteral("screenIndex"), screenIndex);
map.insert(QStringLiteral("screenSize"), Layouting::sizeToMap(screenSize));
map.insert(QStringLiteral("isVisible"), isVisible);
@@ -869,6 +878,7 @@ void LayoutSaver::MainWindow::fromVariantMap(const QVariantMap &map)
multiSplitterLayout.fromVariantMap(map.value(QStringLiteral("multiSplitterLayout")).toMap());
uniqueName = map.value(QStringLiteral("uniqueName")).toString();
geometry = Layouting::mapToRect(map.value(QStringLiteral("geometry")).toMap());
normalGeometry = Layouting::mapToRect(map.value(QStringLiteral("normalGeometry")).toMap());
screenIndex = map.value(QStringLiteral("screenIndex")).toInt();
screenSize = Layouting::mapToSize(map.value(QStringLiteral("screenSize")).toMap());
isVisible = map.value(QStringLiteral("isVisible")).toBool();

View File

@@ -739,6 +739,7 @@ LayoutSaver::MainWindow MainWindowBase::serialize() const
m.options = options();
m.geometry = windowGeometry();
m.normalGeometry = normalGeometry();
m.isVisible = isVisible();
m.uniqueName = uniqueName();
m.screenIndex = screenNumberForWidget(this);

View File

@@ -459,12 +459,6 @@ bool FloatingWindow::deserialize(const LayoutSaver::FloatingWindow &fw)
if (dropArea()->deserialize(fw.multiSplitterLayout)) {
updateTitleBarVisibility();
if (fw.normalGeometry.isValid() && !isNormalWindowState(fw.windowState)) {
// Restore QWidgetPrivate's normalGeometry (no public API in QWidget)
setNormalGeometry(fw.normalGeometry);
}
// And show it:
if (fw.windowState & Qt::WindowMaximized) {
showMaximized();
} else if (fw.windowState & Qt::WindowMinimized) {

View File

@@ -284,6 +284,7 @@ public:
QString uniqueName;
QStringList affinities;
QRect geometry;
QRect normalGeometry;
int screenIndex;
QSize screenSize; // for relative-size restoring
bool isVisible;

View File

@@ -138,6 +138,8 @@ QWidgetAdapter::QWidgetAdapter(QQuickItem *parent, Qt::WindowFlags flags)
}
});
qApp->installEventFilter(this);
setSize(QSize(800, 800));
}
@@ -178,6 +180,55 @@ void QWidgetAdapter::onMouseRelease()
void QWidgetAdapter::onCloseEvent(QCloseEvent *)
{
}
void QWidgetAdapter::onResizeEvent(QResizeEvent *event)
{
QWindow* window = windowHandle();
if (!window) {
return;
}
if (isNormalWindowState(m_oldWindowState)) {
QRect geo = normalGeometry();
auto curState = window->windowState();
if (isNormalWindowState(curState)) {
geo.setSize(event->size());
} else {
geo.setSize(event->oldSize());
}
setNormalGeometry(geo);
}
}
void QWidgetAdapter::onMoveEvent(QMoveEvent *event)
{
QWindow* window = windowHandle();
if (!window) {
return;
}
if (isNormalWindowState(m_oldWindowState)) {
QRect geo = normalGeometry();
auto windowCurrentState = window->windowState();
if (isNormalWindowState(windowCurrentState)) {
geo.moveTopLeft(event->pos());
} else {
geo.moveTopLeft(event->oldPos());
}
setNormalGeometry(geo);
}
}
void QWidgetAdapter::onWindowStateChangeEvent(QWindowStateChangeEvent *)
{
QWindow* window = windowHandle();
if (!window) {
return;
}
m_oldWindowState = window->windowState();
}
void QWidgetAdapter::itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &data)
{
@@ -300,23 +351,12 @@ QRect QWidgetAdapter::geometry() const
QRect QWidgetAdapter::normalGeometry() const
{
// TODO: There's no such concept in QWindow, do we need to workaround for QtQuick ?
return QWidgetAdapter::geometry();
return m_normalGeometry;
}
void QWidgetAdapter::setNormalGeometry(QRect geo)
{
if (!isTopLevel())
return;
if (QWindow *w = windowHandle()) {
if (isNormalWindowState(w->windowStates())) {
w->setGeometry(geo);
} else {
// Nothing better at this point, as QWindow doesn't have this concept
qDebug() << Q_FUNC_INFO << "TODO";
}
}
m_normalGeometry = geo;
}
QRect QWidgetAdapter::rect() const
@@ -749,6 +789,14 @@ bool QWidgetAdapter::eventFilter(QObject *watched, QEvent *ev)
break;
}
}
if (ev->type() == QEvent::Resize) {
onResizeEvent(static_cast<QResizeEvent *>(ev));
} else if (ev->type() == QEvent::Move) {
onMoveEvent(static_cast<QMoveEvent *>(ev));
} else if (ev->type() == QEvent::WindowStateChange) {
onWindowStateChangeEvent(static_cast<QWindowStateChangeEvent *>(ev));
}
}
return QQuickItem::eventFilter(watched, ev);

View File

@@ -251,6 +251,9 @@ protected:
virtual void onMouseMove(QPoint globalPos);
virtual void onMouseRelease();
virtual void onCloseEvent(QCloseEvent *);
virtual void onResizeEvent(QResizeEvent *);
virtual void onMoveEvent(QMoveEvent *);
virtual void onWindowStateChangeEvent(QWindowStateChangeEvent *);
void itemChange(QQuickItem::ItemChange, const QQuickItem::ItemChangeData &) override;
private:
@@ -265,6 +268,8 @@ private:
bool m_isWrapper = false;
bool m_inSetParent = false;
MouseEventRedirector *m_mouseEventRedirector = nullptr;
QRect m_normalGeometry;
Qt::WindowStates m_oldWindowState = Qt::WindowState::WindowNoState;
};
inline qreal logicalDpiFactor(const QQuickItem *item)

View File

@@ -133,15 +133,11 @@ QWidget *KDDockWidgets::Private::widgetForWindow(QWindow *window)
void QWidgetAdapter::setNormalGeometry(QRect geo)
{
if (isNormalWindowState(windowState())) {
setGeometry(geo);
QWidgetPrivate *priv = QWidgetPrivate::get(this);
if (priv->extra && priv->extra->topextra) {
priv->topData()->normalGeometry = geo;
} else {
QWidgetPrivate *priv = QWidgetPrivate::get(this);
if (priv->extra && priv->extra->topextra) {
priv->topData()->normalGeometry = geo;
} else {
qWarning() << Q_FUNC_INFO << "Failing to set normal geometry";
}
qWarning() << Q_FUNC_INFO << "Failing to set normal geometry";
}
}