File indexing completed on 2024-04-28 05:36: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, [this](const QString &service) {
0029         m_availableScreenRects.remove(service);
0030         m_availableScreenRegions.remove(service);
0031         m_serviceWatcher->removeWatchedService(service);
0032 
0033         for (int i = 0; i < m_plasmashellCorona->numScreens(); ++i) {
0034             Q_EMIT m_plasmashellCorona->availableScreenRectChanged(i);
0035         }
0036     });
0037 }
0038 
0039 QRect StrutManager::availableScreenRect(int id) const
0040 {
0041     QRect r = m_plasmashellCorona->_availableScreenRect(id);
0042     QHash<int, QRect> service;
0043     foreach (service, m_availableScreenRects) {
0044         if (!service.value(id).isNull()) {
0045             r &= service[id];
0046         }
0047     }
0048     return r;
0049 }
0050 
0051 QRect StrutManager::availableScreenRect(const QString &screenName) const
0052 {
0053     return availableScreenRect(m_plasmashellCorona->screenPool()->idForName(screenName));
0054 }
0055 
0056 QRegion StrutManager::availableScreenRegion(int id) const
0057 {
0058     QRegion r = m_plasmashellCorona->_availableScreenRegion(id);
0059     QHash<int, QRegion> service;
0060     foreach (service, m_availableScreenRegions) {
0061         if (!service.value(id).isNull()) {
0062             r &= service[id];
0063         }
0064     }
0065     return r;
0066 }
0067 
0068 void StrutManager::setAvailableScreenRect(const QString &service, const QString &screenName, const QRect &rect)
0069 {
0070     int id = m_plasmashellCorona->screenPool()->idForName(screenName);
0071     if (id == -1 || m_availableScreenRects.value(service).value(id) == rect || !addWatchedService(service)) {
0072         return;
0073     }
0074     m_availableScreenRects[service][id] = rect;
0075     Q_EMIT m_plasmashellCorona->availableScreenRectChanged(id);
0076 }
0077 
0078 void StrutManager::setAvailableScreenRegion(const QString &service, const QString &screenName, const QList<QRect> &rects)
0079 {
0080     int id = m_plasmashellCorona->screenPool()->idForName(screenName);
0081     QRegion region;
0082     for (const QRect &rect : rects) {
0083         region += rect;
0084     }
0085 
0086     if (id == -1 || m_availableScreenRegions.value(service).value(id) == region || !addWatchedService(service)) {
0087         return;
0088     }
0089     m_availableScreenRegions[service][id] = region;
0090     Q_EMIT m_plasmashellCorona->availableScreenRegionChanged(id);
0091 }
0092 
0093 bool StrutManager::addWatchedService(const QString &service)
0094 {
0095     if (!m_serviceWatcher->watchedServices().contains(service)) {
0096         if (!QDBusConnection::sessionBus().interface()->isServiceRegistered(service)) {
0097             return false;
0098         }
0099         m_serviceWatcher->addWatchedService(service);
0100     }
0101     return true;
0102 }