File indexing completed on 2024-05-05 05:38:39

0001 /*
0002     SPDX-FileCopyrightText: 2017 David Edmundson <davidedmundson@kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0005 */
0006 
0007 #include "xwindowsystemeventbatcher.h"
0008 
0009 #include <QDebug>
0010 #include <QTimerEvent>
0011 
0012 #include <KX11Extras>
0013 
0014 #define BATCH_TIME 10
0015 
0016 static const NET::Properties s_cachableProperties = NET::WMName | NET::WMVisibleName;
0017 static const NET::Properties2 s_cachableProperties2 = NET::WM2UserTime;
0018 
0019 XWindowSystemEventBatcher::XWindowSystemEventBatcher(QObject *parent)
0020     : QObject(parent)
0021 {
0022     connect(KX11Extras::self(), &KX11Extras::windowAdded, this, &XWindowSystemEventBatcher::windowAdded);
0023 
0024     // remove our cache entries when we lose a window, otherwise we might fire change signals after a window is destroyed which wouldn't make sense
0025     connect(KX11Extras::self(), &KX11Extras::windowRemoved, this, [this](WId wid) {
0026         m_cache.remove(wid);
0027         Q_EMIT windowRemoved(wid);
0028     });
0029 
0030     QObject::connect(KX11Extras::self(), &KX11Extras::windowChanged, this, [this](WId window, NET::Properties properties, NET::Properties2 properties2) {
0031         // if properties contained only cachable flags
0032         if ((properties | s_cachableProperties) == s_cachableProperties && (properties2 | s_cachableProperties2) == s_cachableProperties2) {
0033             m_cache[window].properties |= properties;
0034             m_cache[window].properties2 |= properties2;
0035             if (!m_timerId) {
0036                 m_timerId = startTimer(BATCH_TIME);
0037             }
0038         } else {
0039             // submit all caches along with any real updates
0040             auto it = m_cache.constFind(window);
0041             if (it != m_cache.constEnd()) {
0042                 properties |= it->properties;
0043                 properties2 |= it->properties2;
0044                 m_cache.erase(it);
0045             }
0046             Q_EMIT windowChanged(window, properties, properties2);
0047         }
0048     });
0049 }
0050 
0051 void XWindowSystemEventBatcher::timerEvent(QTimerEvent *event)
0052 {
0053     if (event->timerId() != m_timerId) {
0054         return;
0055     }
0056     for (auto it = m_cache.constBegin(); it != m_cache.constEnd(); it++) {
0057         Q_EMIT windowChanged(it.key(), it.value().properties, it.value().properties2);
0058     };
0059     m_cache.clear();
0060     killTimer(m_timerId);
0061     m_timerId = 0;
0062 }