Changeset View
Changeset View
Standalone View
Standalone View
kcms/touchpadx/src/kded/kded.cpp
- This file was added.
1 | /* | ||||
---|---|---|---|---|---|
2 | * Copyright (C) 2013 Alexander Mezin <mezin.alexander@gmail.com> | ||||
3 | * | ||||
4 | * This program is free software; you can redistribute it and/or modify | ||||
5 | * it under the terms of the GNU General Public License as published by | ||||
6 | * the Free Software Foundation; either version 2 of the License, or | ||||
7 | * (at your option) any later version. | ||||
8 | * | ||||
9 | * This program is distributed in the hope that it will be useful, | ||||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||||
12 | * GNU General Public License for more details. | ||||
13 | * | ||||
14 | * You should have received a copy of the GNU General Public License | ||||
15 | * along with this program; if not, write to the Free Software | ||||
16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||||
17 | */ | ||||
18 | | ||||
19 | #include "kded.h" | ||||
20 | | ||||
21 | #include <QDebug> | ||||
22 | #include <QDBusConnection> | ||||
23 | #include <QDBusMessage> | ||||
24 | #include <QDBusConnectionInterface> | ||||
25 | #include <KNotification> | ||||
26 | #include <KLocalizedString> | ||||
27 | | ||||
28 | #include "plugins.h" | ||||
29 | #include "kdedactions.h" | ||||
30 | | ||||
31 | bool TouchpadDisabler::workingTouchpadFound() const | ||||
32 | { | ||||
33 | return m_workingTouchpadFound; | ||||
34 | } | ||||
35 | | ||||
36 | void TouchpadDisabler::serviceRegistered(const QString &service) | ||||
37 | { | ||||
38 | if (!m_dependecies.removeWatchedService(service)) { | ||||
39 | return; | ||||
40 | } | ||||
41 | | ||||
42 | if (m_dependecies.watchedServices().isEmpty()) { | ||||
43 | lateInit(); | ||||
44 | } | ||||
45 | } | ||||
46 | | ||||
47 | TouchpadDisabler::TouchpadDisabler(QObject *parent, const QVariantList &) | ||||
48 | : KDEDModule(parent), m_backend(TouchpadBackend::implementation()), | ||||
49 | m_userRequestedState(true), m_touchpadEnabled(true), m_workingTouchpadFound(false), m_keyboardActivity(false), m_mouse(false) | ||||
50 | { | ||||
51 | if (!m_backend) { | ||||
52 | return; | ||||
53 | } | ||||
54 | | ||||
55 | m_dependecies.addWatchedService("org.kde.plasmashell"); | ||||
56 | m_dependecies.addWatchedService("org.kde.kglobalaccel"); | ||||
57 | connect(&m_dependecies, SIGNAL(serviceRegistered(QString)), | ||||
58 | SLOT(serviceRegistered(QString))); | ||||
59 | | ||||
60 | connect(m_backend, SIGNAL(mousesChanged()), SLOT(mousePlugged())); | ||||
61 | connect(m_backend, SIGNAL(keyboardActivityStarted()), | ||||
62 | SLOT(keyboardActivityStarted())); | ||||
63 | connect(m_backend, SIGNAL(keyboardActivityFinished()), | ||||
64 | SLOT(keyboardActivityFinished())); | ||||
65 | connect(m_backend, SIGNAL(touchpadStateChanged()), | ||||
66 | SLOT(updateCurrentState())); | ||||
67 | | ||||
68 | connect(m_backend, SIGNAL(touchpadReset()), SLOT(handleReset())); | ||||
69 | | ||||
70 | m_keyboardActivityTimeout.setSingleShot(true); | ||||
71 | connect(&m_keyboardActivityTimeout, SIGNAL(timeout()), | ||||
72 | SLOT(timerElapsed())); | ||||
73 | | ||||
74 | updateCurrentState(); | ||||
75 | m_userRequestedState = m_touchpadEnabled; | ||||
76 | reloadSettings(); | ||||
77 | | ||||
78 | m_dependecies.setWatchMode(QDBusServiceWatcher::WatchForRegistration); | ||||
79 | m_dependecies.setConnection(QDBusConnection::sessionBus()); | ||||
80 | QDBusPendingCall async = QDBusConnection::sessionBus().interface()->asyncCall(QLatin1String("ListNames")); | ||||
81 | QDBusPendingCallWatcher *callWatcher = new QDBusPendingCallWatcher(async, this); | ||||
82 | connect(callWatcher, SIGNAL(finished(QDBusPendingCallWatcher*)), | ||||
83 | this, SLOT(serviceNameFetchFinished(QDBusPendingCallWatcher*))); | ||||
84 | | ||||
85 | | ||||
86 | QDBusConnection::systemBus().connect(QStringLiteral("org.freedesktop.login1"), | ||||
87 | QStringLiteral("/org/freedesktop/login1"), | ||||
88 | QStringLiteral("org.freedesktop.login1.Manager"), | ||||
89 | QStringLiteral("PrepareForSleep"), | ||||
90 | this, | ||||
91 | SLOT(onPrepareForSleep(bool))); | ||||
92 | } | ||||
93 | | ||||
94 | void TouchpadDisabler::serviceNameFetchFinished(QDBusPendingCallWatcher *callWatcher) | ||||
95 | { | ||||
96 | QDBusPendingReply<QStringList> reply = *callWatcher; | ||||
97 | callWatcher->deleteLater(); | ||||
98 | | ||||
99 | if (reply.isError() || reply.value().isEmpty()) { | ||||
100 | qWarning() << "Error: Couldn't get registered services list from session bus"; | ||||
101 | return; | ||||
102 | } | ||||
103 | | ||||
104 | QStringList allServices = reply.value(); | ||||
105 | Q_FOREACH (const QString &service, m_dependecies.watchedServices()) { | ||||
106 | if (allServices.contains(service)) { | ||||
107 | serviceRegistered(service); | ||||
108 | } | ||||
109 | } | ||||
110 | } | ||||
111 | | ||||
112 | bool TouchpadDisabler::isEnabled() const | ||||
113 | { | ||||
114 | return m_touchpadEnabled; | ||||
115 | } | ||||
116 | | ||||
117 | void TouchpadDisabler::updateCurrentState() | ||||
118 | { | ||||
119 | updateWorkingTouchpadFound(); | ||||
120 | if (!m_backend->isTouchpadAvailable()) { | ||||
121 | return; | ||||
122 | } | ||||
123 | bool newEnabled = m_backend->isTouchpadEnabled(); | ||||
124 | if (newEnabled != m_touchpadEnabled) { | ||||
125 | m_touchpadEnabled = newEnabled; | ||||
126 | Q_EMIT enabledChanged(m_touchpadEnabled); | ||||
127 | } | ||||
128 | } | ||||
129 | | ||||
130 | void TouchpadDisabler::toggle() | ||||
131 | { | ||||
132 | m_userRequestedState = !m_touchpadEnabled; | ||||
133 | m_backend->setTouchpadEnabled(m_userRequestedState); | ||||
134 | } | ||||
135 | | ||||
136 | void TouchpadDisabler::disable() | ||||
137 | { | ||||
138 | m_userRequestedState = false; | ||||
139 | m_backend->setTouchpadEnabled(false); | ||||
140 | } | ||||
141 | | ||||
142 | void TouchpadDisabler::enable() | ||||
143 | { | ||||
144 | m_userRequestedState = true; | ||||
145 | m_backend->setTouchpadEnabled(true); | ||||
146 | } | ||||
147 | | ||||
148 | void TouchpadDisabler::reloadSettings() | ||||
149 | { | ||||
150 | m_settings.load(); | ||||
151 | m_keyboardActivityTimeout.setInterval( | ||||
152 | m_settings.keyboardActivityTimeoutMs()); | ||||
153 | | ||||
154 | m_keyboardDisableState = | ||||
155 | m_settings.onlyDisableTapAndScrollOnKeyboardActivity() ? | ||||
156 | TouchpadBackend::TouchpadTapAndScrollDisabled : | ||||
157 | TouchpadBackend::TouchpadFullyDisabled; | ||||
158 | | ||||
159 | mousePlugged(); | ||||
160 | | ||||
161 | m_backend->watchForEvents(m_settings.disableOnKeyboardActivity()); | ||||
162 | } | ||||
163 | | ||||
164 | void TouchpadDisabler::keyboardActivityStarted() | ||||
165 | { | ||||
166 | if (m_keyboardActivity || !m_settings.disableOnKeyboardActivity()) { | ||||
167 | return; | ||||
168 | } | ||||
169 | | ||||
170 | m_keyboardActivityTimeout.stop(); | ||||
171 | m_keyboardActivity = true; | ||||
172 | m_backend->setTouchpadOff(m_keyboardDisableState); | ||||
173 | } | ||||
174 | | ||||
175 | void TouchpadDisabler::keyboardActivityFinished() | ||||
176 | { | ||||
177 | if (!m_keyboardActivity) { | ||||
178 | keyboardActivityStarted(); | ||||
179 | } | ||||
180 | m_keyboardActivityTimeout.start(); | ||||
181 | } | ||||
182 | | ||||
183 | void TouchpadDisabler::timerElapsed() | ||||
184 | { | ||||
185 | if (!m_keyboardActivity) { | ||||
186 | return; | ||||
187 | } | ||||
188 | | ||||
189 | m_keyboardActivity = false; | ||||
190 | m_backend->setTouchpadOff(TouchpadBackend::TouchpadEnabled); | ||||
191 | } | ||||
192 | | ||||
193 | void TouchpadDisabler::mousePlugged() | ||||
194 | { | ||||
195 | if (!m_dependecies.watchedServices().isEmpty()) { | ||||
196 | return; | ||||
197 | } | ||||
198 | | ||||
199 | bool pluggedIn = isMousePluggedIn(); | ||||
200 | Q_EMIT mousePluggedInChanged(pluggedIn); | ||||
201 | | ||||
202 | bool disable = pluggedIn && m_settings.disableWhenMousePluggedIn(); | ||||
203 | if (m_mouse == disable) { | ||||
204 | return; | ||||
205 | } | ||||
206 | m_mouse = disable; | ||||
207 | | ||||
208 | bool newState = disable ? false : m_userRequestedState; | ||||
209 | if (newState == m_touchpadEnabled) { | ||||
210 | return; | ||||
211 | } | ||||
212 | | ||||
213 | // If the disable is caused by plugin mouse, show the message, otherwise it might | ||||
214 | // be user already disables touchpad themselves. | ||||
215 | if (!newState && disable) { | ||||
216 | showNotification("TouchpadDisabled", | ||||
217 | i18n("Touchpad was disabled because a mouse was plugged in")); | ||||
218 | } | ||||
219 | if (newState) { | ||||
220 | showNotification("TouchpadEnabled", | ||||
221 | i18n("Touchpad was enabled because the mouse was unplugged")); | ||||
222 | } | ||||
223 | | ||||
224 | m_backend->setTouchpadEnabled(newState); | ||||
225 | } | ||||
226 | | ||||
227 | void TouchpadDisabler::showNotification(const QString &name, const QString &text) | ||||
228 | { | ||||
229 | KNotification::event(name, text, QPixmap(), //Icon is specified in .notifyrc | ||||
230 | 0, | ||||
231 | KNotification::CloseOnTimeout, | ||||
232 | "kcm_touchpad"); // this has to match the name of the .notifyrc file | ||||
233 | //TouchpadPluginFactory::componentData()); | ||||
234 | } | ||||
235 | | ||||
236 | bool TouchpadDisabler::isMousePluggedIn() const | ||||
237 | { | ||||
238 | return !m_backend->listMouses(m_settings.mouseBlacklist()).isEmpty(); | ||||
239 | } | ||||
240 | | ||||
241 | void TouchpadDisabler::lateInit() | ||||
242 | { | ||||
243 | TouchpadGlobalActions *actions = new TouchpadGlobalActions(false, this); | ||||
244 | connect(actions, &TouchpadGlobalActions::enableTriggered, this, [this] { | ||||
245 | enable(); | ||||
246 | showOsd(); | ||||
247 | }); | ||||
248 | connect(actions, &TouchpadGlobalActions::disableTriggered, this, [this] { | ||||
249 | disable(); | ||||
250 | showOsd(); | ||||
251 | }); | ||||
252 | connect(actions, &TouchpadGlobalActions::toggleTriggered, this, [this] { | ||||
253 | toggle(); | ||||
254 | showOsd(); | ||||
255 | }); | ||||
256 | | ||||
257 | updateCurrentState(); | ||||
258 | mousePlugged(); | ||||
259 | } | ||||
260 | | ||||
261 | void touchpadApplySavedConfig(); | ||||
262 | | ||||
263 | void TouchpadDisabler::handleReset() | ||||
264 | { | ||||
265 | updateCurrentState(); | ||||
266 | if (!m_workingTouchpadFound) { | ||||
267 | return; | ||||
268 | } | ||||
269 | touchpadApplySavedConfig(); | ||||
270 | m_backend->setTouchpadEnabled(m_userRequestedState); | ||||
271 | } | ||||
272 | | ||||
273 | void TouchpadDisabler::updateWorkingTouchpadFound() | ||||
274 | { | ||||
275 | bool newWorkingTouchpadFound = m_backend && m_backend->isTouchpadAvailable(); | ||||
276 | if (newWorkingTouchpadFound != m_workingTouchpadFound) { | ||||
277 | m_workingTouchpadFound = newWorkingTouchpadFound; | ||||
278 | Q_EMIT workingTouchpadFoundChanged(m_workingTouchpadFound); | ||||
279 | } | ||||
280 | } | ||||
281 | | ||||
282 | void TouchpadDisabler::onPrepareForSleep(bool sleep) | ||||
283 | { | ||||
284 | m_preparingForSleep = sleep; | ||||
285 | } | ||||
286 | | ||||
287 | void TouchpadDisabler::showOsd() | ||||
288 | { | ||||
289 | if (m_preparingForSleep) { | ||||
290 | return; | ||||
291 | } | ||||
292 | | ||||
293 | QDBusMessage msg = QDBusMessage::createMethodCall( | ||||
294 | QStringLiteral("org.kde.plasmashell"), | ||||
295 | QStringLiteral("/org/kde/osdService"), | ||||
296 | QStringLiteral("org.kde.osdService"), | ||||
297 | QStringLiteral("touchpadEnabledChanged") | ||||
298 | ); | ||||
299 | | ||||
300 | msg.setArguments({m_backend->isTouchpadEnabled()}); | ||||
301 | | ||||
302 | QDBusConnection::sessionBus().asyncCall(msg); | ||||
303 | } |