File indexing completed on 2024-12-08 03:39:45
0001 /* This file is part of the KDE libraries 0002 * SPDX-FileCopyrightText: 2009 Dario Freddi <drf at kde.org> 0003 * 0004 * SPDX-License-Identifier: LGPL-2.1-or-later 0005 */ 0006 0007 #include "kwindowbasedidletimepoller_p.h" 0008 0009 #include <QEvent> 0010 #include <QTimer> 0011 #include <QWindow> 0012 0013 KWindowBasedIdleTimePoller::KWindowBasedIdleTimePoller(QObject *parent) 0014 : KAbstractIdleTimePoller(parent) 0015 { 0016 } 0017 0018 KWindowBasedIdleTimePoller::~KWindowBasedIdleTimePoller() 0019 { 0020 } 0021 0022 bool KWindowBasedIdleTimePoller::isAvailable() 0023 { 0024 return true; 0025 } 0026 0027 bool KWindowBasedIdleTimePoller::setUpPoller() 0028 { 0029 m_pollTimer = new QTimer(this); 0030 0031 // setup idle timer, with some smart polling 0032 connect(m_pollTimer, &QTimer::timeout, this, &KWindowBasedIdleTimePoller::poll); 0033 0034 m_grabber = new QWindow(); 0035 m_grabber->setFlag(Qt::X11BypassWindowManagerHint); 0036 m_grabber->setPosition(-1000, -1000); 0037 m_grabber->installEventFilter(this); 0038 m_grabber->setObjectName(QStringLiteral("KIdleGrabberWidget")); 0039 0040 return additionalSetUp(); 0041 } 0042 0043 void KWindowBasedIdleTimePoller::unloadPoller() 0044 { 0045 m_pollTimer->deleteLater(); 0046 m_grabber->deleteLater(); 0047 } 0048 0049 QList<int> KWindowBasedIdleTimePoller::timeouts() const 0050 { 0051 return m_timeouts; 0052 } 0053 0054 void KWindowBasedIdleTimePoller::addTimeout(int nextTimeout) 0055 { 0056 m_timeouts.append(nextTimeout); 0057 poll(); 0058 } 0059 0060 bool KWindowBasedIdleTimePoller::eventFilter(QObject *object, QEvent *event) 0061 { 0062 if (object == m_grabber && (event->type() == QEvent::MouseMove || event->type() == QEvent::KeyPress)) { 0063 detectedActivity(); 0064 return true; 0065 } else if (object != m_grabber) { 0066 // If it's not the grabber, fallback to default event filter 0067 return false; 0068 } 0069 0070 // Otherwise, simply ignore it 0071 return false; 0072 } 0073 0074 void KWindowBasedIdleTimePoller::waitForActivity() 0075 { 0076 m_grabber->show(); 0077 m_grabber->setMouseGrabEnabled(true); 0078 m_grabber->setKeyboardGrabEnabled(true); 0079 } 0080 0081 void KWindowBasedIdleTimePoller::detectedActivity() 0082 { 0083 stopCatchingIdleEvents(); 0084 Q_EMIT resumingFromIdle(); 0085 } 0086 0087 void KWindowBasedIdleTimePoller::releaseInputLock() 0088 { 0089 m_grabber->setMouseGrabEnabled(false); 0090 m_grabber->setKeyboardGrabEnabled(false); 0091 m_grabber->hide(); 0092 } 0093 0094 int KWindowBasedIdleTimePoller::poll() 0095 { 0096 int idle = getIdleTime(); 0097 0098 // Check if we reached a timeout.. 0099 for (int timeOut : std::as_const(m_timeouts)) { 0100 if ((timeOut - idle < 300 && timeOut >= idle) || (idle - timeOut < 300 && idle > timeOut)) { 0101 // Bingo! 0102 Q_EMIT timeoutReached(timeOut); 0103 } 0104 } 0105 0106 // Let's check the timer now! 0107 int mintime = 0; 0108 0109 for (int i : std::as_const(m_timeouts)) { 0110 if (i > idle && (i < mintime || mintime == 0)) { 0111 mintime = i; 0112 } 0113 } 0114 0115 // qDebug() << "mintime " << mintime << "idle " << idle; 0116 0117 if (mintime != 0) { 0118 m_pollTimer->start(mintime - idle); 0119 } else { 0120 m_pollTimer->stop(); 0121 } 0122 0123 return idle; 0124 } 0125 0126 int KWindowBasedIdleTimePoller::forcePollRequest() 0127 { 0128 return poll(); 0129 } 0130 0131 void KWindowBasedIdleTimePoller::removeTimeout(int timeout) 0132 { 0133 m_timeouts.removeOne(timeout); 0134 poll(); 0135 } 0136 0137 void KWindowBasedIdleTimePoller::catchIdleEvent() 0138 { 0139 waitForActivity(); 0140 } 0141 0142 void KWindowBasedIdleTimePoller::stopCatchingIdleEvents() 0143 { 0144 releaseInputLock(); 0145 } 0146 0147 #include "moc_kwindowbasedidletimepoller_p.cpp"