1 /*
2 * SPDX-FileCopyrightText: 2012~2017 CSSlayer <wengxt@gmail.com>
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
8 #include "fcitxqtwatcher_p.h"
9 #include <QDBusConnection>
10 #include <QDBusConnectionInterface>
11 #include <QDBusServiceWatcher>
12 #include <QDir>
13
14 namespace fcitx {
15
FcitxQtWatcher(QObject * parent)16 FcitxQtWatcher::FcitxQtWatcher(QObject *parent)
17 : QObject(parent), d_ptr(new FcitxQtWatcherPrivate(this)) {}
18
FcitxQtWatcher(const QDBusConnection & connection,QObject * parent)19 FcitxQtWatcher::FcitxQtWatcher(const QDBusConnection &connection,
20 QObject *parent)
21 : FcitxQtWatcher(parent) {
22 setConnection(connection);
23 }
24
~FcitxQtWatcher()25 FcitxQtWatcher::~FcitxQtWatcher() { delete d_ptr; }
26
availability() const27 bool FcitxQtWatcher::availability() const {
28 Q_D(const FcitxQtWatcher);
29 return d->availability_;
30 }
31
setConnection(const QDBusConnection & connection)32 void FcitxQtWatcher::setConnection(const QDBusConnection &connection) {
33 Q_D(FcitxQtWatcher);
34 return d->serviceWatcher_.setConnection(connection);
35 }
36
connection() const37 QDBusConnection FcitxQtWatcher::connection() const {
38 Q_D(const FcitxQtWatcher);
39 return d->serviceWatcher_.connection();
40 }
41
setWatchPortal(bool portal)42 void FcitxQtWatcher::setWatchPortal(bool portal) {
43 Q_D(FcitxQtWatcher);
44 d->watchPortal_ = portal;
45 }
46
watchPortal() const47 bool FcitxQtWatcher::watchPortal() const {
48 Q_D(const FcitxQtWatcher);
49 return d->watchPortal_;
50 }
51
serviceName() const52 QString FcitxQtWatcher::serviceName() const {
53 Q_D(const FcitxQtWatcher);
54 if (d->mainPresent_) {
55 return FCITX_MAIN_SERVICE_NAME;
56 }
57 if (d->portalPresent_) {
58 return FCITX_PORTAL_SERVICE_NAME;
59 }
60 return QString();
61 }
62
setAvailability(bool availability)63 void FcitxQtWatcher::setAvailability(bool availability) {
64 Q_D(FcitxQtWatcher);
65 if (d->availability_ != availability) {
66 d->availability_ = availability;
67 Q_EMIT availabilityChanged(d->availability_);
68 }
69 }
70
watch()71 void FcitxQtWatcher::watch() {
72 Q_D(FcitxQtWatcher);
73 if (d->watched_) {
74 return;
75 }
76
77 connect(&d->serviceWatcher_, &QDBusServiceWatcher::serviceOwnerChanged,
78 this, &FcitxQtWatcher::imChanged);
79 d->serviceWatcher_.addWatchedService(FCITX_MAIN_SERVICE_NAME);
80 if (d->watchPortal_) {
81 d->serviceWatcher_.addWatchedService(FCITX_PORTAL_SERVICE_NAME);
82 }
83
84 if (connection().interface()->isServiceRegistered(
85 FCITX_MAIN_SERVICE_NAME)) {
86 d->mainPresent_ = true;
87 }
88 if (d->watchPortal_ && connection().interface()->isServiceRegistered(
89 FCITX_PORTAL_SERVICE_NAME)) {
90 d->portalPresent_ = true;
91 }
92
93 updateAvailability();
94
95 d->watched_ = true;
96 }
97
unwatch()98 void FcitxQtWatcher::unwatch() {
99 Q_D(FcitxQtWatcher);
100 if (!d->watched_) {
101 return;
102 }
103 disconnect(&d->serviceWatcher_, &QDBusServiceWatcher::serviceOwnerChanged,
104 this, &FcitxQtWatcher::imChanged);
105 d->mainPresent_ = false;
106 d->portalPresent_ = false;
107 d->watched_ = false;
108 updateAvailability();
109 }
110
isWatching() const111 bool FcitxQtWatcher::isWatching() const {
112 Q_D(const FcitxQtWatcher);
113 return d->watched_;
114 }
115
imChanged(const QString & service,const QString &,const QString & newOwner)116 void FcitxQtWatcher::imChanged(const QString &service, const QString &,
117 const QString &newOwner) {
118 Q_D(FcitxQtWatcher);
119 if (service == FCITX_MAIN_SERVICE_NAME) {
120 if (!newOwner.isEmpty()) {
121 d->mainPresent_ = true;
122 } else {
123 d->mainPresent_ = false;
124 }
125 } else if (service == FCITX_PORTAL_SERVICE_NAME) {
126 if (!newOwner.isEmpty()) {
127 d->portalPresent_ = true;
128 } else {
129 d->portalPresent_ = false;
130 }
131 }
132
133 updateAvailability();
134 }
135
updateAvailability()136 void FcitxQtWatcher::updateAvailability() {
137 Q_D(FcitxQtWatcher);
138 setAvailability(d->mainPresent_ || d->portalPresent_);
139 }
140 } // namespace fcitx
141