File indexing completed on 2024-05-19 16:31:39

0001 /*
0002  * SPDX-FileCopyrightText: 2019 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
0003  *
0004  * SPDX-License-Identifier: GPL-2.0-or-later
0005  */
0006 
0007 #include "inhibitor.h"
0008 
0009 #include <QDBusConnection>
0010 #include <QDBusMessage>
0011 #include <QDBusPendingCallWatcher>
0012 #include <QDBusPendingReply>
0013 #include <QLoggingCategory>
0014 
0015 Q_LOGGING_CATEGORY(NIGHTCOLOR_CONTROL, "org.kde.plasma.nightcolorcontrol")
0016 
0017 static const QString s_serviceName = QStringLiteral("org.kde.NightColor");
0018 static const QString s_path = QStringLiteral("/ColorCorrect");
0019 static const QString s_interface = QStringLiteral("org.kde.kwin.ColorCorrect");
0020 
0021 class Inhibitor::Private
0022 {
0023 public:
0024     uint cookie = 0;
0025     State state = Uninhibited;
0026     bool pendingUninhibit = false;
0027 };
0028 
0029 Inhibitor::Inhibitor(QObject *parent)
0030     : QObject(parent)
0031     , d(new Private)
0032 {
0033 }
0034 
0035 Inhibitor::~Inhibitor()
0036 {
0037     uninhibit();
0038 }
0039 
0040 Inhibitor::State Inhibitor::state() const
0041 {
0042     return d->state;
0043 }
0044 
0045 void Inhibitor::inhibit()
0046 {
0047     if (d->state == Inhibited) {
0048         return;
0049     }
0050 
0051     d->pendingUninhibit = false;
0052 
0053     if (d->state == Inhibiting) {
0054         return;
0055     }
0056 
0057     QDBusMessage message = QDBusMessage::createMethodCall(s_serviceName, s_path, s_interface, QStringLiteral("inhibit"));
0058 
0059     QDBusPendingReply<uint> cookie = QDBusConnection::sessionBus().asyncCall(message);
0060     QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(cookie, this);
0061 
0062     connect(watcher, &QDBusPendingCallWatcher::finished, this, [this](QDBusPendingCallWatcher *self) {
0063         const bool wasPendingUninhibit = d->pendingUninhibit;
0064         d->pendingUninhibit = false;
0065 
0066         const QDBusPendingReply<uint> reply = *self;
0067         self->deleteLater();
0068 
0069         if (reply.isError()) {
0070             qCWarning(NIGHTCOLOR_CONTROL()) << "Could not inhibit Night Color:" << reply.error().message();
0071             d->state = Uninhibited;
0072             Q_EMIT stateChanged();
0073             return;
0074         }
0075 
0076         d->cookie = reply.value();
0077         d->state = Inhibited;
0078         Q_EMIT stateChanged();
0079 
0080         if (wasPendingUninhibit) {
0081             uninhibit();
0082         }
0083     });
0084 
0085     d->state = Inhibiting;
0086     Q_EMIT stateChanged();
0087 }
0088 
0089 void Inhibitor::uninhibit()
0090 {
0091     if (d->state == Uninhibiting || d->state == Uninhibited) {
0092         return;
0093     }
0094 
0095     if (d->state == Inhibiting) {
0096         d->pendingUninhibit = true;
0097         return;
0098     }
0099 
0100     QDBusMessage message = QDBusMessage::createMethodCall(s_serviceName, s_path, s_interface, QStringLiteral("uninhibit"));
0101     message.setArguments({d->cookie});
0102 
0103     QDBusPendingReply<void> reply = QDBusConnection::sessionBus().asyncCall(message);
0104     QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(reply, this);
0105 
0106     connect(watcher, &QDBusPendingCallWatcher::finished, this, [this](QDBusPendingCallWatcher *self) {
0107         self->deleteLater();
0108 
0109         if (d->state != Uninhibiting) {
0110             return;
0111         }
0112 
0113         const QDBusPendingReply<void> reply = *self;
0114         if (reply.isError()) {
0115             qCWarning(NIGHTCOLOR_CONTROL) << "Could not uninhibit Night Color:" << reply.error().message();
0116         }
0117 
0118         d->state = Uninhibited;
0119         Q_EMIT stateChanged();
0120     });
0121 
0122     d->state = Uninhibiting;
0123     Q_EMIT stateChanged();
0124 }