1/* This file is part of the KDE libraries
2 * SPDX-FileCopyrightText: 2009 Dario Freddi <drf at kde.org>
3 *
4 * SPDX-License-Identifier: LGPL-2.1-or-later
5 */
6
7#include "kwindowbasedidletimepoller_p.h"
8
9#include <QEvent>
10#include <QTimer>
11#include <QWindow>
12
13KWindowBasedIdleTimePoller::KWindowBasedIdleTimePoller(QObject *parent)
14 : KAbstractIdleTimePoller(parent)
15{
16}
17
18KWindowBasedIdleTimePoller::~KWindowBasedIdleTimePoller()
19{
20}
21
22bool KWindowBasedIdleTimePoller::isAvailable()
23{
24 return true;
25}
26
27bool KWindowBasedIdleTimePoller::setUpPoller()
28{
29 m_pollTimer = new QTimer(this);
30
31 // setup idle timer, with some smart polling
32 connect(sender: m_pollTimer, signal: &QTimer::timeout, context: this, slot: &KWindowBasedIdleTimePoller::poll);
33
34 m_grabber = new QWindow();
35 m_grabber->setFlag(Qt::X11BypassWindowManagerHint);
36 m_grabber->setPosition(posx: -1000, posy: -1000);
37 m_grabber->installEventFilter(filterObj: this);
38 m_grabber->setObjectName(QStringLiteral("KIdleGrabberWidget"));
39
40 return additionalSetUp();
41}
42
43void KWindowBasedIdleTimePoller::unloadPoller()
44{
45 m_pollTimer->deleteLater();
46 m_grabber->deleteLater();
47}
48
49QList<int> KWindowBasedIdleTimePoller::timeouts() const
50{
51 return m_timeouts;
52}
53
54void KWindowBasedIdleTimePoller::addTimeout(int nextTimeout)
55{
56 m_timeouts.append(t: nextTimeout);
57 poll();
58}
59
60bool KWindowBasedIdleTimePoller::eventFilter(QObject *object, QEvent *event)
61{
62 if (object == m_grabber && (event->type() == QEvent::MouseMove || event->type() == QEvent::KeyPress)) {
63 detectedActivity();
64 return true;
65 } else if (object != m_grabber) {
66 // If it's not the grabber, fallback to default event filter
67 return false;
68 }
69
70 // Otherwise, simply ignore it
71 return false;
72}
73
74void KWindowBasedIdleTimePoller::waitForActivity()
75{
76 m_grabber->show();
77 m_grabber->setMouseGrabEnabled(true);
78 m_grabber->setKeyboardGrabEnabled(true);
79}
80
81void KWindowBasedIdleTimePoller::detectedActivity()
82{
83 stopCatchingIdleEvents();
84 Q_EMIT resumingFromIdle();
85}
86
87void KWindowBasedIdleTimePoller::releaseInputLock()
88{
89 m_grabber->setMouseGrabEnabled(false);
90 m_grabber->setKeyboardGrabEnabled(false);
91 m_grabber->hide();
92}
93
94int KWindowBasedIdleTimePoller::poll()
95{
96 int idle = getIdleTime();
97
98 // Check if we reached a timeout..
99 for (int timeOut : std::as_const(t&: m_timeouts)) {
100 if ((timeOut - idle < 300 && timeOut >= idle) || (idle - timeOut < 300 && idle > timeOut)) {
101 // Bingo!
102 Q_EMIT timeoutReached(msec: timeOut);
103 }
104 }
105
106 // Let's check the timer now!
107 int mintime = 0;
108
109 for (int i : std::as_const(t&: m_timeouts)) {
110 if (i > idle && (i < mintime || mintime == 0)) {
111 mintime = i;
112 }
113 }
114
115 // qDebug() << "mintime " << mintime << "idle " << idle;
116
117 if (mintime != 0) {
118 m_pollTimer->start(msec: mintime - idle);
119 } else {
120 m_pollTimer->stop();
121 }
122
123 return idle;
124}
125
126int KWindowBasedIdleTimePoller::forcePollRequest()
127{
128 return poll();
129}
130
131void KWindowBasedIdleTimePoller::removeTimeout(int timeout)
132{
133 m_timeouts.removeOne(t: timeout);
134 poll();
135}
136
137void KWindowBasedIdleTimePoller::catchIdleEvent()
138{
139 waitForActivity();
140}
141
142void KWindowBasedIdleTimePoller::stopCatchingIdleEvents()
143{
144 releaseInputLock();
145}
146
147#include "moc_kwindowbasedidletimepoller_p.cpp"
148

source code of kidletime/src/kwindowbasedidletimepoller.cpp