File indexing completed on 2024-04-28 16:55:02

0001 /*
0002     SPDX-FileCopyrightText: 2019 David Edmundson <davidedmundson@kde.org>
0003     SPDX-FileCopyrightText: 2019 Tranter Madi <trmdi@yandex.com>
0004 
0005     SPDX-License-Identifier: LGPL-2.0-or-later
0006 */
0007 
0008 #include "strutmanager.h"
0009 #include "screenpool.h"
0010 #include "shellcorona.h"
0011 
0012 #include <QDBusConnection>
0013 #include <QDBusConnectionInterface>
0014 #include <QDBusMetaType>
0015 #include <QDBusServiceWatcher>
0016 
0017 StrutManager::StrutManager(ShellCorona *plasmashellCorona)
0018     : QObject(plasmashellCorona)
0019     , m_plasmashellCorona(plasmashellCorona)
0020     , m_serviceWatcher(new QDBusServiceWatcher(this))
0021 {
0022     qDBusRegisterMetaType<QList<QRect>>();
0023 
0024     QDBusConnection dbus = QDBusConnection::sessionBus();
0025     dbus.registerObject("/StrutManager", this, QDBusConnection::ExportAllSlots);
0026     m_serviceWatcher->setConnection(dbus);
0027 
0028     connect(m_serviceWatcher, &QDBusServiceWatcher::serviceUnregistered, [=](const QString &service) {
0029         m_availableScreenRects.remove(service);
0030         m_availableScreenRegions.remove(service);
0031         m_serviceWatcher->removeWatchedService(service);
0032 
0033         Q_EMIT m_plasmashellCorona->availableScreenRectChanged();
0034     });
0035 }
0036 
0037 QRect StrutManager::availableScreenRect(int id) const
0038 {
0039     QRect r = m_plasmashellCorona->_availableScreenRect(id);
0040     QHash<int, QRect> service;
0041     foreach (service, m_availableScreenRects) {
0042         if (!service.value(id).isNull()) {
0043             r &= service[id];
0044         }
0045     }
0046     return r;
0047 }
0048 
0049 QRect StrutManager::availableScreenRect(const QString &screenName) const
0050 {
0051     return availableScreenRect(m_plasmashellCorona->screenPool()->idForName(screenName));
0052 }
0053 
0054 QRegion StrutManager::availableScreenRegion(int id) const
0055 {
0056     QRegion r = m_plasmashellCorona->_availableScreenRegion(id);
0057     QHash<int, QRegion> service;
0058     foreach (service, m_availableScreenRegions) {
0059         if (!service.value(id).isNull()) {
0060             r &= service[id];
0061         }
0062     }
0063     return r;
0064 }
0065 
0066 void StrutManager::setAvailableScreenRect(const QString &service, const QString &screenName, const QRect &rect)
0067 {
0068     int id = m_plasmashellCorona->screenPool()->idForName(screenName);
0069     if (id == -1 || m_availableScreenRects.value(service).value(id) == rect || !addWatchedService(service)) {
0070         return;
0071     }
0072     m_availableScreenRects[service][id] = rect;
0073     Q_EMIT m_plasmashellCorona->availableScreenRectChanged();
0074 }
0075 
0076 void StrutManager::setAvailableScreenRegion(const QString &service, const QString &screenName, const QList<QRect> &rects)
0077 {
0078     int id = m_plasmashellCorona->screenPool()->idForName(screenName);
0079     QRegion region;
0080     for (const QRect &rect : rects) {
0081         region += rect;
0082     }
0083 
0084     if (id == -1 || m_availableScreenRegions.value(service).value(id) == region || !addWatchedService(service)) {
0085         return;
0086     }
0087     m_availableScreenRegions[service][id] = region;
0088     Q_EMIT m_plasmashellCorona->availableScreenRegionChanged();
0089 }
0090 
0091 bool StrutManager::addWatchedService(const QString &service)
0092 {
0093     if (!m_serviceWatcher->watchedServices().contains(service)) {
0094         if (!QDBusConnection::sessionBus().interface()->isServiceRegistered(service)) {
0095             return false;
0096         }
0097         m_serviceWatcher->addWatchedService(service);
0098     }
0099     return true;
0100 }