Commit e8e36086 authored by Tranter Madi's avatar Tranter Madi 🌧
Browse files

Allow to set the available screen rect/region from outside through dbus

Summary:
I'm trying to implement the idea of @davidedmundson from this https://phabricator.kde.org/T10172 with my limited knowledge of C++/Qt/KDE/programming. This is the start of a new class so it could lack many things but it's usable.

- It allows clients to set the available screen rect/region from outside through dbus.
- The final available screen rect/region would be the intersection of all set values.
- When a client dies, its values would be removed automatically.

Test Plan:
+ qdbus-qt5 org.kde.plasmashell /StrutManager test org.kde.lattedock LVDS-1 0 24 1366 768
+ After killing latte-dock, the values are got only from plasmashellCorona.

{F7820969}

Reviewers: #plasma, mvourlakos, davidedmundson, mart, apol

Reviewed By: #plasma, davidedmundson

Subscribers: davidre, plasma-devel

Tags: #plasma

Differential Revision: https://phabricator.kde.org/D25807
parent 5dd59771
......@@ -36,6 +36,7 @@ set (plasma_shell_SRCS
standaloneappcorona
osd.cpp
coronatesthelper.cpp
strutmanager.cpp
debug.cpp
screenpool.cpp
softwarerendernotifier.cpp
......
......@@ -21,6 +21,7 @@
*/
#include "shellcorona.h"
#include "strutmanager.h"
#include <config-plasma.h>
......@@ -107,7 +108,8 @@ ShellCorona::ShellCorona(QObject *parent)
m_addPanelsMenu(nullptr),
m_interactiveConsole(nullptr),
m_waylandPlasmaShell(nullptr),
m_closingDown(false)
m_closingDown(false),
m_strutManager(new StrutManager(this))
{
setupWaylandIntegration();
qmlRegisterUncreatableType<DesktopView>("org.kde.plasma.shell", 2, 0, "Desktop", QStringLiteral("It is not possible to create objects of type Desktop"));
......@@ -1042,6 +1044,11 @@ QRect ShellCorona::screenGeometry(int id) const
}
QRegion ShellCorona::availableScreenRegion(int id) const
{
return m_strutManager->availableScreenRegion(id);
}
QRegion ShellCorona::_availableScreenRegion(int id) const
{
DesktopView* view = m_desktopViewforId.value(id);
if (!view) {
......@@ -1062,6 +1069,11 @@ QRegion ShellCorona::availableScreenRegion(int id) const
}
QRect ShellCorona::availableScreenRect(int id) const
{
return m_strutManager->availableScreenRect(id);
}
QRect ShellCorona::_availableScreenRect(int id) const
{
DesktopView *view = m_desktopViewforId.value(id);
if (!view) {
......
......@@ -38,6 +38,7 @@ class PanelView;
class QMenu;
class QScreen;
class ScreenPool;
class StrutManager;
namespace KActivities
{
......@@ -89,6 +90,10 @@ public:
Q_INVOKABLE QRegion availableScreenRegion(int id) const override;
Q_INVOKABLE QRect availableScreenRect(int id) const override;
// plasmashellCorona's value
QRegion _availableScreenRegion(int id) const;
QRect _availableScreenRect(int id) const;
Q_INVOKABLE QStringList availableActivities() const;
PanelView *panelView(Plasma::Containment *containment) const;
......@@ -256,6 +261,8 @@ private:
KWayland::Client::PlasmaShell *m_waylandPlasmaShell;
bool m_closingDown : 1;
QString m_testModeLayout;
StrutManager *m_strutManager;
};
#endif // SHELLCORONA_H
......
#include "strutmanager.h"
#include "shellcorona.h"
#include "screenpool.h"
#include <QDBusMetaType>
#include <QDBusConnection>
#include <QDBusServiceWatcher>
#include <QDBusConnectionInterface>
StrutManager::StrutManager(ShellCorona *plasmashellCorona) : QObject(plasmashellCorona),
m_plasmashellCorona(plasmashellCorona),
m_serviceWatcher(new QDBusServiceWatcher(this))
{
qDBusRegisterMetaType<QList<QRect>>();
QDBusConnection dbus = QDBusConnection::sessionBus();
dbus.registerObject("/StrutManager", this, QDBusConnection::ExportAllSlots);
m_serviceWatcher->setConnection(dbus);
connect(m_serviceWatcher, &QDBusServiceWatcher::serviceUnregistered, [=](const QString &service) {
m_availableScreenRects.remove(service);
m_availableScreenRegions.remove(service);
m_serviceWatcher->removeWatchedService(service);
emit m_plasmashellCorona->availableScreenRectChanged();
});
}
QRect StrutManager::availableScreenRect(int id) const
{
QRect r = m_plasmashellCorona->_availableScreenRect(id);
QHash<int, QRect> service;
foreach (service, m_availableScreenRects) {
if (!service.value(id).isNull()) {
r &= service[id];
}
}
return r;
}
QRegion StrutManager::availableScreenRegion(int id) const
{
QRegion r = m_plasmashellCorona->_availableScreenRegion(id);
QHash<int, QRegion> service;
foreach (service, m_availableScreenRegions) {
if (!service.value(id).isNull()) {
r &= service[id];
}
}
return r;
}
void StrutManager::setAvailableScreenRect(const QString &service, const QString &screenName, const QRect &rect) {
int id = m_plasmashellCorona->screenPool()->id(screenName);
if (id == -1 || m_availableScreenRects.value(service).value(id) == rect || !addWatchedService(service)) {
return;
}
m_availableScreenRects[service][id] = rect;
emit m_plasmashellCorona->availableScreenRectChanged();
}
void StrutManager::setAvailableScreenRegion(const QString &service, const QString &screenName, const QList<QRect> &rects) {
int id = m_plasmashellCorona->screenPool()->id(screenName);
QRegion region;
foreach(QRect rect, rects) {
region += rect;
}
if (id == -1 || m_availableScreenRegions.value(service).value(id) == region || !addWatchedService(service)) {
return;
}
m_availableScreenRegions[service][id] = region;
emit m_plasmashellCorona->availableScreenRegionChanged();
}
bool StrutManager::addWatchedService(const QString &service) {
if (!m_serviceWatcher->watchedServices().contains(service)) {
if (!QDBusConnection::sessionBus().interface()->isServiceRegistered(service)) {
return false;
}
m_serviceWatcher->addWatchedService(service);
}
return true;
}
#ifndef STRUTMANAGER_H
#define STRUTMANAGER_H
#include <QObject>
#include <QHash>
class QDBusServiceWatcher;
class ShellCorona;
class StrutManager : public QObject
{
Q_OBJECT
Q_CLASSINFO("D-Bus Interface","org.kde.PlasmaShell.StrutManager")
public:
explicit StrutManager(ShellCorona *plasmashellCorona);
QRect availableScreenRect(int id) const;
QRegion availableScreenRegion(int id) const;
public Q_SLOTS:
void setAvailableScreenRect(const QString &service, const QString &screenName, const QRect &rect);
void setAvailableScreenRegion(const QString &service, const QString &screenName, const QList<QRect> &rects);
private:
ShellCorona *m_plasmashellCorona;
QDBusServiceWatcher *m_serviceWatcher;
bool addWatchedService(const QString &service);
QHash <const QString, QHash<int, QRect>> m_availableScreenRects;
QHash <const QString, QHash<int, QRegion>> m_availableScreenRegions;
};
#endif
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment