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"