[nightcolor] Expose some properties to d-bus
Summary: Currently, in order to retrieve the current screen color temperature applied to all screen as well other attributes of night color manager, one has to call nightColorInfo() periodically. This goes against well established patterns in d-bus world. It is recommended to expose a bunch of d-bus properties rather than have a method that returns all relevant properties stored in a JSON object. The ugliest thing about this patch is that a lot of code is duplicated to emit the PropertiesChanged signal. Unfortunately, QtDBus doesn't take care of this and we are left with only two options - either do weird things with QMetaObject or manually emit the signal. I have picked the second option since it's more comprehensible and less magic is going on, but I have to admit that the chosen approach is ugly. I hope that "Qt 6 will fix it." CCBUG: 400418 Reviewers: #kwin, davidedmundson Reviewed By: #kwin, davidedmundson Subscribers: kwin Tags: #kwin Differential Revision: https://phabricator.kde.org/D25946
This commit is contained in:
parent
5bec89ac90
commit
33f46f6d6c
5 changed files with 328 additions and 15 deletions
|
@ -38,7 +38,6 @@ ColorCorrectDBusInterface::ColorCorrectDBusInterface(Manager *parent)
|
|||
connect(m_inhibitorWatcher, &QDBusServiceWatcher::serviceUnregistered,
|
||||
this, &ColorCorrectDBusInterface::removeInhibitorService);
|
||||
|
||||
// Argh, all this code is just to send one innocent signal...
|
||||
connect(m_manager, &Manager::inhibitedChanged, this, [this] {
|
||||
QVariantMap changedProperties;
|
||||
changedProperties.insert(QStringLiteral("inhibited"), m_manager->isInhibited());
|
||||
|
@ -58,6 +57,101 @@ ColorCorrectDBusInterface::ColorCorrectDBusInterface(Manager *parent)
|
|||
QDBusConnection::sessionBus().send(message);
|
||||
});
|
||||
|
||||
connect(m_manager, &Manager::enabledChanged, this, [this] {
|
||||
QVariantMap changedProperties;
|
||||
changedProperties.insert(QStringLiteral("enabled"), m_manager->isEnabled());
|
||||
|
||||
QDBusMessage message = QDBusMessage::createSignal(
|
||||
QStringLiteral("/ColorCorrect"),
|
||||
QStringLiteral("org.freedesktop.DBus.Properties"),
|
||||
QStringLiteral("PropertiesChanged")
|
||||
);
|
||||
|
||||
message.setArguments({
|
||||
QStringLiteral("org.kde.kwin.ColorCorrect"),
|
||||
changedProperties,
|
||||
QStringList(), // invalidated_properties
|
||||
});
|
||||
|
||||
QDBusConnection::sessionBus().send(message);
|
||||
});
|
||||
|
||||
connect(m_manager, &Manager::runningChanged, this, [this] {
|
||||
QVariantMap changedProperties;
|
||||
changedProperties.insert(QStringLiteral("running"), m_manager->isRunning());
|
||||
|
||||
QDBusMessage message = QDBusMessage::createSignal(
|
||||
QStringLiteral("/ColorCorrect"),
|
||||
QStringLiteral("org.freedesktop.DBus.Properties"),
|
||||
QStringLiteral("PropertiesChanged")
|
||||
);
|
||||
|
||||
message.setArguments({
|
||||
QStringLiteral("org.kde.kwin.ColorCorrect"),
|
||||
changedProperties,
|
||||
QStringList(), // invalidated_properties
|
||||
});
|
||||
|
||||
QDBusConnection::sessionBus().send(message);
|
||||
});
|
||||
|
||||
connect(m_manager, &Manager::currentTemperatureChanged, this, [this] {
|
||||
QVariantMap changedProperties;
|
||||
changedProperties.insert(QStringLiteral("currentTemperature"), m_manager->currentTemperature());
|
||||
|
||||
QDBusMessage message = QDBusMessage::createSignal(
|
||||
QStringLiteral("/ColorCorrect"),
|
||||
QStringLiteral("org.freedesktop.DBus.Properties"),
|
||||
QStringLiteral("PropertiesChanged")
|
||||
);
|
||||
|
||||
message.setArguments({
|
||||
QStringLiteral("org.kde.kwin.ColorCorrect"),
|
||||
changedProperties,
|
||||
QStringList(), // invalidated_properties
|
||||
});
|
||||
|
||||
QDBusConnection::sessionBus().send(message);
|
||||
});
|
||||
|
||||
connect(m_manager, &Manager::targetTemperatureChanged, this, [this] {
|
||||
QVariantMap changedProperties;
|
||||
changedProperties.insert(QStringLiteral("targetTemperature"), m_manager->targetTemperature());
|
||||
|
||||
QDBusMessage message = QDBusMessage::createSignal(
|
||||
QStringLiteral("/ColorCorrect"),
|
||||
QStringLiteral("org.freedesktop.DBus.Properties"),
|
||||
QStringLiteral("PropertiesChanged")
|
||||
);
|
||||
|
||||
message.setArguments({
|
||||
QStringLiteral("org.kde.kwin.ColorCorrect"),
|
||||
changedProperties,
|
||||
QStringList(), // invalidated_properties
|
||||
});
|
||||
|
||||
QDBusConnection::sessionBus().send(message);
|
||||
});
|
||||
|
||||
connect(m_manager, &Manager::modeChanged, this, [this] {
|
||||
QVariantMap changedProperties;
|
||||
changedProperties.insert(QStringLiteral("mode"), uint(m_manager->mode()));
|
||||
|
||||
QDBusMessage message = QDBusMessage::createSignal(
|
||||
QStringLiteral("/ColorCorrect"),
|
||||
QStringLiteral("org.freedesktop.DBus.Properties"),
|
||||
QStringLiteral("PropertiesChanged")
|
||||
);
|
||||
|
||||
message.setArguments({
|
||||
QStringLiteral("org.kde.kwin.ColorCorrect"),
|
||||
changedProperties,
|
||||
QStringList(), // invalidated_properties
|
||||
});
|
||||
|
||||
QDBusConnection::sessionBus().send(message);
|
||||
});
|
||||
|
||||
connect(m_manager, &Manager::configChange, this, &ColorCorrectDBusInterface::nightColorConfigChanged);
|
||||
new ColorCorrectAdaptor(this);
|
||||
QDBusConnection::sessionBus().registerObject(QStringLiteral("/ColorCorrect"), this);
|
||||
|
@ -68,6 +162,36 @@ bool ColorCorrectDBusInterface::isInhibited() const
|
|||
return m_manager->isInhibited();
|
||||
}
|
||||
|
||||
bool ColorCorrectDBusInterface::isEnabled() const
|
||||
{
|
||||
return m_manager->isEnabled();
|
||||
}
|
||||
|
||||
bool ColorCorrectDBusInterface::isRunning() const
|
||||
{
|
||||
return m_manager->isRunning();
|
||||
}
|
||||
|
||||
bool ColorCorrectDBusInterface::isAvailable() const
|
||||
{
|
||||
return m_manager->isAvailable();
|
||||
}
|
||||
|
||||
int ColorCorrectDBusInterface::currentTemperature() const
|
||||
{
|
||||
return m_manager->currentTemperature();
|
||||
}
|
||||
|
||||
int ColorCorrectDBusInterface::targetTemperature() const
|
||||
{
|
||||
return m_manager->targetTemperature();
|
||||
}
|
||||
|
||||
int ColorCorrectDBusInterface::mode() const
|
||||
{
|
||||
return m_manager->mode();
|
||||
}
|
||||
|
||||
QHash<QString, QVariant> ColorCorrectDBusInterface::nightColorInfo()
|
||||
{
|
||||
return m_manager->info();
|
||||
|
|
|
@ -37,12 +37,24 @@ class ColorCorrectDBusInterface : public QObject, public QDBusContext
|
|||
Q_OBJECT
|
||||
Q_CLASSINFO("D-Bus Interface", "org.kde.kwin.ColorCorrect")
|
||||
Q_PROPERTY(bool inhibited READ isInhibited)
|
||||
Q_PROPERTY(bool enabled READ isEnabled)
|
||||
Q_PROPERTY(bool running READ isRunning)
|
||||
Q_PROPERTY(bool available READ isAvailable)
|
||||
Q_PROPERTY(int currentTemperature READ currentTemperature)
|
||||
Q_PROPERTY(int targetTemperature READ targetTemperature)
|
||||
Q_PROPERTY(int mode READ mode)
|
||||
|
||||
public:
|
||||
explicit ColorCorrectDBusInterface(Manager *parent);
|
||||
~ColorCorrectDBusInterface() override = default;
|
||||
|
||||
bool isInhibited() const;
|
||||
bool isEnabled() const;
|
||||
bool isRunning() const;
|
||||
bool isAvailable() const;
|
||||
int currentTemperature() const;
|
||||
int targetTemperature() const;
|
||||
int mode() const;
|
||||
|
||||
public Q_SLOTS:
|
||||
/**
|
||||
|
|
|
@ -90,7 +90,7 @@ void Manager::init()
|
|||
// we may always read in the current config
|
||||
readConfig();
|
||||
|
||||
if (!kwinApp()->platform()->supportsGammaControl()) {
|
||||
if (!isAvailable()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -165,9 +165,10 @@ void Manager::hardReset()
|
|||
if (m_mode != NightColorMode::Constant) {
|
||||
updateSunTimings(true);
|
||||
}
|
||||
updateTargetTemperature();
|
||||
|
||||
if (kwinApp()->platform()->supportsGammaControl() && m_active && !isInhibited()) {
|
||||
m_running = true;
|
||||
if (isAvailable() && isEnabled() && !isInhibited()) {
|
||||
setRunning(true);
|
||||
commitGammaRamps(currentTargetTemp());
|
||||
}
|
||||
resetAllTimers();
|
||||
|
@ -211,6 +212,36 @@ void Manager::uninhibit()
|
|||
}
|
||||
}
|
||||
|
||||
bool Manager::isEnabled() const
|
||||
{
|
||||
return m_active;
|
||||
}
|
||||
|
||||
bool Manager::isRunning() const
|
||||
{
|
||||
return m_running;
|
||||
}
|
||||
|
||||
bool Manager::isAvailable() const
|
||||
{
|
||||
return kwinApp()->platform()->supportsGammaControl();
|
||||
}
|
||||
|
||||
int Manager::currentTemperature() const
|
||||
{
|
||||
return m_currentTemp;
|
||||
}
|
||||
|
||||
int Manager::targetTemperature() const
|
||||
{
|
||||
return m_targetTemperature;
|
||||
}
|
||||
|
||||
NightColorMode Manager::mode() const
|
||||
{
|
||||
return m_mode;
|
||||
}
|
||||
|
||||
void Manager::initShortcuts()
|
||||
{
|
||||
QAction *toggleAction = new QAction(this);
|
||||
|
@ -226,7 +257,7 @@ void Manager::readConfig()
|
|||
Settings *s = Settings::self();
|
||||
s->load();
|
||||
|
||||
m_active = s->active();
|
||||
setEnabled(s->active());
|
||||
|
||||
const NightColorMode mode = s->mode();
|
||||
switch (s->mode()) {
|
||||
|
@ -234,11 +265,11 @@ void Manager::readConfig()
|
|||
case NightColorMode::Location:
|
||||
case NightColorMode::Timings:
|
||||
case NightColorMode::Constant:
|
||||
m_mode = mode;
|
||||
setMode(mode);
|
||||
break;
|
||||
default:
|
||||
// Fallback for invalid setting values.
|
||||
m_mode = NightColorMode::Automatic;
|
||||
setMode(NightColorMode::Automatic);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -293,12 +324,12 @@ void Manager::readConfig()
|
|||
void Manager::resetAllTimers()
|
||||
{
|
||||
cancelAllTimers();
|
||||
if (kwinApp()->platform()->supportsGammaControl()) {
|
||||
m_running = m_active && !isInhibited();
|
||||
if (isAvailable()) {
|
||||
setRunning(isEnabled() && !isInhibited());
|
||||
// we do this also for active being false in order to reset the temperature back to the day value
|
||||
resetQuickAdjustTimer();
|
||||
} else {
|
||||
m_running = false;
|
||||
setRunning(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -319,6 +350,7 @@ void Manager::resetQuickAdjustTimer()
|
|||
if (m_mode != NightColorMode::Constant) {
|
||||
updateSunTimings(false);
|
||||
}
|
||||
updateTargetTemperature();
|
||||
|
||||
int tempDiff = qAbs(currentTargetTemp() - m_currentTemp);
|
||||
// allow tolerance of one TEMPERATURE_STEP to compensate if a slow update is coincidental
|
||||
|
@ -384,6 +416,8 @@ void Manager::resetSlowUpdateStartTimer()
|
|||
connect(m_slowUpdateStartTimer, &QTimer::timeout, this, &Manager::resetSlowUpdateStartTimer);
|
||||
|
||||
updateSunTimings(false);
|
||||
updateTargetTemperature();
|
||||
|
||||
const int diff = QDateTime::currentDateTime().msecsTo(m_next.first);
|
||||
if (diff <= 0) {
|
||||
qCCritical(KWIN_COLORCORRECTION) << "Error in time calculation. Deactivating Night Color.";
|
||||
|
@ -448,6 +482,19 @@ void Manager::slowUpdate(int targetTemp)
|
|||
}
|
||||
}
|
||||
|
||||
void Manager::updateTargetTemperature()
|
||||
{
|
||||
const int targetTemperature = mode() != NightColorMode::Constant && daylight() ? m_dayTargetTemp : m_nightTargetTemp;
|
||||
|
||||
if (m_targetTemperature == targetTemperature) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_targetTemperature = targetTemperature;
|
||||
|
||||
emit targetTemperatureChanged();
|
||||
}
|
||||
|
||||
void Manager::updateSunTimings(bool force)
|
||||
{
|
||||
const QDateTime todayNow = QDateTime::currentDateTime();
|
||||
|
@ -624,7 +671,7 @@ void Manager::commitGammaRamps(int temperature)
|
|||
}
|
||||
|
||||
if (o->setGammaRamp(ramp)) {
|
||||
m_currentTemp = temperature;
|
||||
setCurrentTemperature(temperature);
|
||||
m_failedCommitAttempts = 0;
|
||||
} else {
|
||||
m_failedCommitAttempts++;
|
||||
|
@ -635,7 +682,7 @@ void Manager::commitGammaRamps(int temperature)
|
|||
// TODO: On multi monitor setups we could try to rollback earlier changes for already committed outputs
|
||||
qCWarning(KWIN_COLORCORRECTION) << "Gamma Ramp commit failed too often. Deactivating color correction for now.";
|
||||
m_failedCommitAttempts = 0; // reset so we can try again later (i.e. after suspend phase or config change)
|
||||
m_running = false;
|
||||
setRunning(false);
|
||||
cancelAllTimers();
|
||||
}
|
||||
}
|
||||
|
@ -645,7 +692,7 @@ void Manager::commitGammaRamps(int temperature)
|
|||
QHash<QString, QVariant> Manager::info() const
|
||||
{
|
||||
return QHash<QString, QVariant> {
|
||||
{ QStringLiteral("Available"), kwinApp()->platform()->supportsGammaControl() },
|
||||
{ QStringLiteral("Available"), isAvailable() },
|
||||
|
||||
{ QStringLiteral("ActiveEnabled"), true},
|
||||
{ QStringLiteral("Active"), m_active},
|
||||
|
@ -798,12 +845,12 @@ bool Manager::changeConfiguration(QHash<QString, QVariant> data)
|
|||
|
||||
Settings *s = Settings::self();
|
||||
if (activeUpdate) {
|
||||
m_active = active;
|
||||
setEnabled(active);
|
||||
s->setActive(active);
|
||||
}
|
||||
|
||||
if (modeUpdate) {
|
||||
m_mode = mode;
|
||||
setMode(mode);
|
||||
s->setMode(mode);
|
||||
}
|
||||
|
||||
|
@ -861,5 +908,41 @@ void Manager::autoLocationUpdate(double latitude, double longitude)
|
|||
emit configChange(info());
|
||||
}
|
||||
|
||||
void Manager::setEnabled(bool enabled)
|
||||
{
|
||||
if (m_active == enabled) {
|
||||
return;
|
||||
}
|
||||
m_active = enabled;
|
||||
emit enabledChanged();
|
||||
}
|
||||
|
||||
void Manager::setRunning(bool running)
|
||||
{
|
||||
if (m_running == running) {
|
||||
return;
|
||||
}
|
||||
m_running = running;
|
||||
emit runningChanged();
|
||||
}
|
||||
|
||||
void Manager::setCurrentTemperature(int temperature)
|
||||
{
|
||||
if (m_currentTemp == temperature) {
|
||||
return;
|
||||
}
|
||||
m_currentTemp = temperature;
|
||||
emit currentTemperatureChanged();
|
||||
}
|
||||
|
||||
void Manager::setMode(NightColorMode mode)
|
||||
{
|
||||
if (m_mode == mode) {
|
||||
return;
|
||||
}
|
||||
m_mode = mode;
|
||||
emit modeChanged();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -144,6 +144,36 @@ public:
|
|||
*/
|
||||
void uninhibit();
|
||||
|
||||
/**
|
||||
* Returns @c true if Night Color is enabled; otherwise @c false.
|
||||
*/
|
||||
bool isEnabled() const;
|
||||
|
||||
/**
|
||||
* Returns @c true if Night Color is currently running; otherwise @c false.
|
||||
*/
|
||||
bool isRunning() const;
|
||||
|
||||
/**
|
||||
* Returns @c true if Night Color is supported by platform; otherwise @c false.
|
||||
*/
|
||||
bool isAvailable() const;
|
||||
|
||||
/**
|
||||
* Returns the current screen color temperature.
|
||||
*/
|
||||
int currentTemperature() const;
|
||||
|
||||
/**
|
||||
* Returns the target screen color temperature.
|
||||
*/
|
||||
int targetTemperature() const;
|
||||
|
||||
/**
|
||||
* Returns the mode in which Night Color is operating.
|
||||
*/
|
||||
NightColorMode mode() const;
|
||||
|
||||
// for auto tests
|
||||
void reparseConfigAndReset();
|
||||
|
||||
|
@ -159,6 +189,31 @@ Q_SIGNALS:
|
|||
*/
|
||||
void inhibitedChanged();
|
||||
|
||||
/**
|
||||
* Emitted whenever the night color manager is enabled or disabled.
|
||||
*/
|
||||
void enabledChanged();
|
||||
|
||||
/**
|
||||
* Emitted whenever the night color manager starts or stops running.
|
||||
*/
|
||||
void runningChanged();
|
||||
|
||||
/**
|
||||
* Emitted whenever the current screen color temperature has changed.
|
||||
*/
|
||||
void currentTemperatureChanged();
|
||||
|
||||
/**
|
||||
* Emitted whenever the target screen color temperature has changed.
|
||||
*/
|
||||
void targetTemperatureChanged();
|
||||
|
||||
/**
|
||||
* Emitted whenver the operation mode has changed.
|
||||
*/
|
||||
void modeChanged();
|
||||
|
||||
private:
|
||||
void initShortcuts();
|
||||
void readConfig();
|
||||
|
@ -176,6 +231,7 @@ private:
|
|||
*/
|
||||
void resetSlowUpdateTimer();
|
||||
|
||||
void updateTargetTemperature();
|
||||
void updateSunTimings(bool force);
|
||||
DateTimes getSunTimings(const QDateTime &dateTime, double latitude, double longitude, bool morning) const;
|
||||
bool checkAutomaticSunTimings() const;
|
||||
|
@ -183,6 +239,11 @@ private:
|
|||
|
||||
void commitGammaRamps(int temperature);
|
||||
|
||||
void setEnabled(bool enabled);
|
||||
void setRunning(bool running);
|
||||
void setCurrentTemperature(int temperature);
|
||||
void setMode(NightColorMode mode);
|
||||
|
||||
ColorCorrectDBusInterface *m_iface;
|
||||
|
||||
// Specifies whether Night Color is enabled.
|
||||
|
@ -217,6 +278,7 @@ private:
|
|||
QTimer *m_quickAdjustTimer = nullptr;
|
||||
|
||||
int m_currentTemp = NEUTRAL_TEMPERATURE;
|
||||
int m_targetTemperature = NEUTRAL_TEMPERATURE;
|
||||
int m_dayTargetTemp = NEUTRAL_TEMPERATURE;
|
||||
int m_nightTargetTemp = DEFAULT_NIGHT_TEMPERATURE;
|
||||
|
||||
|
|
|
@ -52,5 +52,37 @@
|
|||
This property holds a value to indicate whether Night Color is inhibited.
|
||||
-->
|
||||
<property name="inhibited" type="b" access="read"/>
|
||||
|
||||
<!--
|
||||
This property holds a value to indicate whether Night Color is enabled.
|
||||
-->
|
||||
<property name="enabled" type="b" access="read"/>
|
||||
|
||||
<!--
|
||||
This property holds a value to indicate whether Night Color is running.
|
||||
-->
|
||||
<property name="running" type="b" access="read"/>
|
||||
|
||||
<!--
|
||||
This property holds a value to indicate whether Night Color is available.
|
||||
-->
|
||||
<property name="available" type="b" access="read"/>
|
||||
|
||||
<!--
|
||||
This property holds a value to indicate the current screen color temperature.
|
||||
-->
|
||||
<property name="currentTemperature" type="u" access="read"/>
|
||||
|
||||
<!--
|
||||
This property holds a value to indicate the target screen color temperature.
|
||||
-->
|
||||
<property name="targetTemperature" type="u" access="read"/>
|
||||
|
||||
<!--
|
||||
This property holds a value to indicate the operating mode.
|
||||
|
||||
Valid modes: 0 - automatic, 1 - location, 2 - timings, 3 - constant.
|
||||
-->
|
||||
<property name="mode" type="u" access="read"/>
|
||||
</interface>
|
||||
</node>
|
||||
|
|
Loading…
Reference in a new issue