mirror of
https://invent.kde.org/marcoa/shift-shell.git
synced 2026-04-26 14:23:09 +00:00
269 lines
8.3 KiB
C++
269 lines
8.3 KiB
C++
|
|
// SPDX-FileCopyrightText: 2025 Devin Lin <devin@kde.org>
|
||
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||
|
|
|
||
|
|
#include "panelsettingsdbusobjectmanager.h"
|
||
|
|
#include "panelsadaptor.h"
|
||
|
|
|
||
|
|
#include <kscreen/configmonitor.h>
|
||
|
|
#include <kscreen/getconfigoperation.h>
|
||
|
|
#include <kscreen/output.h>
|
||
|
|
|
||
|
|
using namespace Qt::Literals::StringLiterals;
|
||
|
|
|
||
|
|
const QString CONFIG_FILE = u"plasmamobilerc"_s;
|
||
|
|
const QString PANELS_CONFIG_GROUP = u"Panels"_s;
|
||
|
|
|
||
|
|
// Orientations
|
||
|
|
const QString TOP_CONFIG_GROUP = u"WhenOnTop"_s;
|
||
|
|
const QString LEFT_CONFIG_GROUP = u"WhenOnLeft"_s;
|
||
|
|
const QString RIGHT_CONFIG_GROUP = u"WhenOnRight"_s;
|
||
|
|
const QString BOTTOM_CONFIG_GROUP = u"WhenOnBottom"_s;
|
||
|
|
|
||
|
|
QString mapRotationToTopPosition(KScreen::Output::Rotation rotation)
|
||
|
|
{
|
||
|
|
switch (rotation) {
|
||
|
|
case KScreen::Output::Rotation::Left:
|
||
|
|
return RIGHT_CONFIG_GROUP;
|
||
|
|
case KScreen::Output::Rotation::Inverted:
|
||
|
|
return BOTTOM_CONFIG_GROUP;
|
||
|
|
case KScreen::Output::Rotation::Right:
|
||
|
|
return LEFT_CONFIG_GROUP;
|
||
|
|
default:
|
||
|
|
return TOP_CONFIG_GROUP;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
QString mapRotationToBottomPosition(KScreen::Output::Rotation rotation)
|
||
|
|
{
|
||
|
|
switch (rotation) {
|
||
|
|
case KScreen::Output::Rotation::Left:
|
||
|
|
return LEFT_CONFIG_GROUP;
|
||
|
|
case KScreen::Output::Rotation::Inverted:
|
||
|
|
return TOP_CONFIG_GROUP;
|
||
|
|
case KScreen::Output::Rotation::Right:
|
||
|
|
return RIGHT_CONFIG_GROUP;
|
||
|
|
default:
|
||
|
|
return BOTTOM_CONFIG_GROUP;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
PanelSettingsDBusObjectManager::PanelSettingsDBusObjectManager(QObject *parent)
|
||
|
|
: QObject{parent}
|
||
|
|
{
|
||
|
|
}
|
||
|
|
|
||
|
|
void PanelSettingsDBusObjectManager::registerObjects()
|
||
|
|
{
|
||
|
|
if (m_initialized) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
m_initialized = true;
|
||
|
|
|
||
|
|
// Fetch kscreen config
|
||
|
|
connect(new KScreen::GetConfigOperation(), &KScreen::GetConfigOperation::finished, this, [this](auto *op) {
|
||
|
|
m_kscreenConfig = qobject_cast<KScreen::GetConfigOperation *>(op)->config();
|
||
|
|
if (!m_kscreenConfig) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
KScreen::ConfigMonitor::instance()->addConfig(m_kscreenConfig);
|
||
|
|
|
||
|
|
// Listen to all new screens and create a new output
|
||
|
|
connect(m_kscreenConfig.data(), &KScreen::Config::outputAdded, this, [this](const auto &output) {
|
||
|
|
if (!output) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
auto *obj = new PanelSettingsDBusObject{this};
|
||
|
|
obj->registerObject(output);
|
||
|
|
m_dbusObjects.push_back(obj);
|
||
|
|
});
|
||
|
|
|
||
|
|
// Remove the corresponding object when a screen is removed
|
||
|
|
connect(m_kscreenConfig.data(), &KScreen::Config::outputRemoved, this, [this](const auto outputId) {
|
||
|
|
for (int i = 0; i < m_dbusObjects.size(); ++i) {
|
||
|
|
if (m_dbusObjects[i]->outputId() == outputId) {
|
||
|
|
m_dbusObjects[i]->deleteLater();
|
||
|
|
m_dbusObjects.remove(i);
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
});
|
||
|
|
|
||
|
|
// Add all current screens as dbus objects
|
||
|
|
for (KScreen::OutputPtr output : m_kscreenConfig->outputs()) {
|
||
|
|
if (!output) {
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
|
||
|
|
auto *obj = new PanelSettingsDBusObject{this};
|
||
|
|
obj->registerObject(output);
|
||
|
|
m_dbusObjects.push_back(obj);
|
||
|
|
}
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
PanelSettingsDBusObject::PanelSettingsDBusObject(QObject *parent)
|
||
|
|
: QObject{parent}
|
||
|
|
, m_config{KSharedConfig::openConfig(CONFIG_FILE)}
|
||
|
|
{
|
||
|
|
// Listen to config changes and reload
|
||
|
|
m_configWatcher = KConfigWatcher::create(m_config);
|
||
|
|
connect(m_configWatcher.data(), &KConfigWatcher::configChanged, this, [this](const KConfigGroup &group, const QByteArrayList &names) -> void {
|
||
|
|
Q_UNUSED(names)
|
||
|
|
Q_UNUSED(group)
|
||
|
|
updateFields();
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
void PanelSettingsDBusObject::registerObject(KScreen::OutputPtr output)
|
||
|
|
{
|
||
|
|
m_output = output;
|
||
|
|
|
||
|
|
if (!m_output) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
m_outputId = m_output->id();
|
||
|
|
m_outputName = m_output->name();
|
||
|
|
|
||
|
|
// Listen to when the rotation or scale changes to refresh the fields
|
||
|
|
connect(m_output.data(), &KScreen::Output::rotationChanged, this, &PanelSettingsDBusObject::updateFields);
|
||
|
|
connect(m_output.data(), &KScreen::Output::scaleChanged, this, &PanelSettingsDBusObject::updateFields);
|
||
|
|
updateFields();
|
||
|
|
|
||
|
|
new PlasmashellMobilePanelsAdaptor{this};
|
||
|
|
|
||
|
|
// Register the screen DBus object
|
||
|
|
QString objectName = m_output->name().replace("-", ""); // DBus doesn't allow dashes
|
||
|
|
QDBusConnection::sessionBus().registerObject(QStringLiteral("/Mobile/Panels/") + objectName, this);
|
||
|
|
}
|
||
|
|
|
||
|
|
void PanelSettingsDBusObject::updateFields()
|
||
|
|
{
|
||
|
|
if (!m_output) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
auto group = KConfigGroup{m_config, PANELS_CONFIG_GROUP};
|
||
|
|
auto topGroup = KConfigGroup{&group, mapRotationToTopPosition(m_output->rotation())};
|
||
|
|
auto bottomGroup = KConfigGroup{&group, mapRotationToBottomPosition(m_output->rotation())};
|
||
|
|
|
||
|
|
// Divide values by the display's scale for scaling independent sizing
|
||
|
|
setStatusBarHeight(topGroup.readEntry(u"statusBarHeight"_s, -1.0) / m_output->scale());
|
||
|
|
setStatusBarLeftPadding(topGroup.readEntry(u"statusBarLeftPadding"_s, 0.0) / m_output->scale());
|
||
|
|
setStatusBarRightPadding(topGroup.readEntry(u"statusBarRightPadding"_s, 0.0) / m_output->scale());
|
||
|
|
setStatusBarCenterSpacing(topGroup.readEntry(u"statusBarCenterSpacing"_s, 0.0) / m_output->scale());
|
||
|
|
setNavigationPanelHeight(bottomGroup.readEntry(u"navigationPanelHeight"_s, -1.0) / m_output->scale());
|
||
|
|
setNavigationPanelLeftPadding(bottomGroup.readEntry(u"navigationPanelLeftPadding"_s, 0.0) / m_output->scale());
|
||
|
|
setNavigationPanelRightPadding(bottomGroup.readEntry(u"navigationPanelRightPadding"_s, 0.0) / m_output->scale());
|
||
|
|
}
|
||
|
|
|
||
|
|
int PanelSettingsDBusObject::outputId() const
|
||
|
|
{
|
||
|
|
return m_outputId;
|
||
|
|
}
|
||
|
|
|
||
|
|
QString PanelSettingsDBusObject::outputName() const
|
||
|
|
{
|
||
|
|
return m_outputName;
|
||
|
|
}
|
||
|
|
|
||
|
|
qreal PanelSettingsDBusObject::statusBarHeight() const
|
||
|
|
{
|
||
|
|
return m_statusBarHeight;
|
||
|
|
}
|
||
|
|
|
||
|
|
void PanelSettingsDBusObject::setStatusBarHeight(qreal statusBarHeight)
|
||
|
|
{
|
||
|
|
if (statusBarHeight == m_statusBarHeight) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
m_statusBarHeight = statusBarHeight;
|
||
|
|
Q_EMIT statusBarHeightChanged();
|
||
|
|
}
|
||
|
|
|
||
|
|
qreal PanelSettingsDBusObject::statusBarLeftPadding() const
|
||
|
|
{
|
||
|
|
return m_statusBarLeftPadding;
|
||
|
|
}
|
||
|
|
|
||
|
|
void PanelSettingsDBusObject::setStatusBarLeftPadding(qreal statusBarLeftPadding)
|
||
|
|
{
|
||
|
|
if (statusBarLeftPadding == m_statusBarLeftPadding) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
m_statusBarLeftPadding = statusBarLeftPadding;
|
||
|
|
Q_EMIT statusBarLeftPaddingChanged();
|
||
|
|
}
|
||
|
|
|
||
|
|
qreal PanelSettingsDBusObject::statusBarRightPadding() const
|
||
|
|
{
|
||
|
|
return m_statusBarRightPadding;
|
||
|
|
}
|
||
|
|
|
||
|
|
void PanelSettingsDBusObject::setStatusBarRightPadding(qreal statusBarRightPadding)
|
||
|
|
{
|
||
|
|
if (statusBarRightPadding == m_statusBarRightPadding) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
m_statusBarRightPadding = statusBarRightPadding;
|
||
|
|
Q_EMIT statusBarRightPaddingChanged();
|
||
|
|
}
|
||
|
|
|
||
|
|
qreal PanelSettingsDBusObject::statusBarCenterSpacing() const
|
||
|
|
{
|
||
|
|
return m_statusBarCenterSpacing;
|
||
|
|
}
|
||
|
|
|
||
|
|
void PanelSettingsDBusObject::setStatusBarCenterSpacing(qreal statusBarCenterSpacing)
|
||
|
|
{
|
||
|
|
if (statusBarCenterSpacing == m_statusBarCenterSpacing) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
m_statusBarCenterSpacing = statusBarCenterSpacing;
|
||
|
|
Q_EMIT statusBarCenterSpacingChanged();
|
||
|
|
}
|
||
|
|
|
||
|
|
qreal PanelSettingsDBusObject::navigationPanelHeight() const
|
||
|
|
{
|
||
|
|
return m_navigationPanelHeight;
|
||
|
|
}
|
||
|
|
|
||
|
|
void PanelSettingsDBusObject::setNavigationPanelHeight(qreal navigationPanelHeight)
|
||
|
|
{
|
||
|
|
if (navigationPanelHeight == m_navigationPanelHeight) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
m_navigationPanelHeight = navigationPanelHeight;
|
||
|
|
Q_EMIT navigationPanelHeightChanged();
|
||
|
|
}
|
||
|
|
|
||
|
|
qreal PanelSettingsDBusObject::navigationPanelLeftPadding() const
|
||
|
|
{
|
||
|
|
return m_navigationPanelLeftPadding;
|
||
|
|
}
|
||
|
|
|
||
|
|
void PanelSettingsDBusObject::setNavigationPanelLeftPadding(qreal navigationPanelLeftPadding)
|
||
|
|
{
|
||
|
|
if (navigationPanelLeftPadding == m_navigationPanelLeftPadding) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
m_navigationPanelLeftPadding = navigationPanelLeftPadding;
|
||
|
|
Q_EMIT navigationPanelLeftPaddingChanged();
|
||
|
|
}
|
||
|
|
|
||
|
|
qreal PanelSettingsDBusObject::navigationPanelRightPadding() const
|
||
|
|
{
|
||
|
|
return m_navigationPanelRightPadding;
|
||
|
|
}
|
||
|
|
|
||
|
|
void PanelSettingsDBusObject::setNavigationPanelRightPadding(qreal navigationPanelRightPadding)
|
||
|
|
{
|
||
|
|
if (navigationPanelRightPadding == m_navigationPanelRightPadding) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
m_navigationPanelRightPadding = navigationPanelRightPadding;
|
||
|
|
Q_EMIT navigationPanelRightPaddingChanged();
|
||
|
|
}
|