File indexing completed on 2024-05-12 15:34:14

0001 /*
0002     SPDX-FileCopyrightText: 2022 Volker Krause <vkrause@kde.org>
0003     SPDX-License-Identifier: LGPL-2.0-or-later
0004 */
0005 
0006 #include "kwindowstatesaver.h"
0007 #include "ksharedconfig.h"
0008 #include "kwindowconfig.h"
0009 
0010 #include <QWindow>
0011 
0012 class KWindowStateSaverPrivate
0013 {
0014 public:
0015     QWindow *window = nullptr;
0016     KConfigGroup configGroup;
0017     std::function<QWindow *()> windowHandleCallback;
0018     int timerId = 0;
0019 
0020     void init(KWindowStateSaver *q);
0021     void initWidget(QObject *widget, KWindowStateSaver *q);
0022 };
0023 
0024 void KWindowStateSaverPrivate::init(KWindowStateSaver *q)
0025 {
0026     if (!window) {
0027         return;
0028     }
0029 
0030     KWindowConfig::restoreWindowSize(window, configGroup);
0031     KWindowConfig::restoreWindowPosition(window, configGroup);
0032 
0033     const auto deferredSave = [q, this]() {
0034         if (!timerId) {
0035             timerId = q->startTimer(250);
0036         }
0037     };
0038     QObject::connect(window, &QWindow::widthChanged, q, deferredSave);
0039     QObject::connect(window, &QWindow::heightChanged, q, deferredSave);
0040     QObject::connect(window, &QWindow::xChanged, q, deferredSave);
0041     QObject::connect(window, &QWindow::yChanged, q, deferredSave);
0042 }
0043 
0044 void KWindowStateSaverPrivate::initWidget(QObject *widget, KWindowStateSaver *q)
0045 {
0046     if (!window && windowHandleCallback) {
0047         window = windowHandleCallback();
0048     }
0049     if (window) {
0050         init(q);
0051     } else {
0052         widget->installEventFilter(q);
0053     }
0054 }
0055 
0056 KWindowStateSaver::KWindowStateSaver(QWindow *window, const KConfigGroup &configGroup)
0057     : QObject(window)
0058     , d(new KWindowStateSaverPrivate)
0059 {
0060     Q_ASSERT(window);
0061     d->window = window;
0062     d->configGroup = configGroup;
0063     d->init(this);
0064 }
0065 
0066 KWindowStateSaver::KWindowStateSaver(QWindow *window, const QString &configGroupName)
0067     : QObject(window)
0068     , d(new KWindowStateSaverPrivate)
0069 {
0070     Q_ASSERT(window);
0071     d->window = window;
0072     d->configGroup = KConfigGroup(KSharedConfig::openStateConfig(), configGroupName);
0073     d->init(this);
0074 }
0075 
0076 KWindowStateSaver::KWindowStateSaver(QWindow *window, const char *configGroupName)
0077     : QObject(window)
0078     , d(new KWindowStateSaverPrivate)
0079 {
0080     Q_ASSERT(window);
0081     d->window = window;
0082     d->configGroup = KConfigGroup(KSharedConfig::openStateConfig(), configGroupName);
0083     d->init(this);
0084 }
0085 
0086 KWindowStateSaver::~KWindowStateSaver()
0087 {
0088     delete d;
0089 }
0090 
0091 void KWindowStateSaver::timerEvent(QTimerEvent *event)
0092 {
0093     killTimer(event->timerId());
0094     KWindowConfig::saveWindowPosition(d->window, d->configGroup);
0095     KWindowConfig::saveWindowSize(d->window, d->configGroup);
0096     d->timerId = 0;
0097 }
0098 
0099 bool KWindowStateSaver::eventFilter(QObject *watched, QEvent *event)
0100 {
0101     // QEvent::PlatformSurface would give us a valid window, but if there are
0102     // intial resizings (explicitly or via layout constraints) those would then
0103     // already overwrite our restored values. So wait until all that is done
0104     // and only restore afterwards.
0105     if (event->type() == QEvent::ShowToParent && !d->window) {
0106         watched->removeEventFilter(this);
0107         d->window = d->windowHandleCallback();
0108         d->init(this);
0109     }
0110 
0111     return QObject::eventFilter(watched, event);
0112 }
0113 
0114 void KWindowStateSaver::initWidget(QObject *widget, const std::function<QWindow *()> &windowHandleCallback, const KConfigGroup &configGroup)
0115 {
0116     d = new KWindowStateSaverPrivate;
0117     d->windowHandleCallback = windowHandleCallback;
0118     d->configGroup = configGroup;
0119     d->initWidget(widget, this);
0120 }
0121 
0122 void KWindowStateSaver::initWidget(QObject *widget, const std::function<QWindow *()> &windowHandleCallback, const QString &configGroupName)
0123 {
0124     d = new KWindowStateSaverPrivate;
0125     d->windowHandleCallback = windowHandleCallback;
0126     d->configGroup = KConfigGroup(KSharedConfig::openStateConfig(), configGroupName);
0127     d->initWidget(widget, this);
0128 }
0129 
0130 void KWindowStateSaver::initWidget(QObject *widget, const std::function<QWindow *()> &windowHandleCallback, const char *configGroupName)
0131 {
0132     d = new KWindowStateSaverPrivate;
0133     d->windowHandleCallback = windowHandleCallback;
0134     d->configGroup = KConfigGroup(KSharedConfig::openStateConfig(), configGroupName);
0135     d->initWidget(widget, this);
0136 }
0137 
0138 #include "moc_kwindowstatesaver.cpp"