File indexing completed on 2024-05-12 03:54:29

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()
0077 {
0078     delete d;
0079 }
0080 
0081 void KWindowStateSaver::timerEvent(QTimerEvent *event)
0082 {
0083     killTimer(event->timerId());
0084     KWindowConfig::saveWindowPosition(d->window, d->configGroup);
0085     KWindowConfig::saveWindowSize(d->window, d->configGroup);
0086     d->timerId = 0;
0087 }
0088 
0089 bool KWindowStateSaver::eventFilter(QObject *watched, QEvent *event)
0090 {
0091     // QEvent::PlatformSurface would give us a valid window, but if there are
0092     // intial resizings (explicitly or via layout constraints) those would then
0093     // already overwrite our restored values. So wait until all that is done
0094     // and only restore afterwards.
0095     if (event->type() == QEvent::ShowToParent && !d->window) {
0096         watched->removeEventFilter(this);
0097         d->window = d->windowHandleCallback();
0098         d->init(this);
0099     }
0100 
0101     return QObject::eventFilter(watched, event);
0102 }
0103 
0104 void KWindowStateSaver::initWidget(QObject *widget, const std::function<QWindow *()> &windowHandleCallback, const KConfigGroup &configGroup)
0105 {
0106     d = new KWindowStateSaverPrivate;
0107     d->windowHandleCallback = windowHandleCallback;
0108     d->configGroup = configGroup;
0109     d->initWidget(widget, this);
0110 }
0111 
0112 void KWindowStateSaver::initWidget(QObject *widget, const std::function<QWindow *()> &windowHandleCallback, const QString &configGroupName)
0113 {
0114     d = new KWindowStateSaverPrivate;
0115     d->windowHandleCallback = windowHandleCallback;
0116     d->configGroup = KConfigGroup(KSharedConfig::openStateConfig(), configGroupName);
0117     d->initWidget(widget, this);
0118 }
0119 
0120 #include "moc_kwindowstatesaver.cpp"