[server] Add a method IdleInterface::simulateUserActivity
Summary: So far only the client was able to simulate user activity. This new method allows the server to also simulate user activity on all created idle timeouts. This is required by KWin to prevent idle timeouts when the user interacts through KDE Connect's virtual touchpad. In that situation the mouse pointer is used without updating the input time stamp as it doesn't come from "real" input devices and thus the idle timeout prevention is not activated. Reviewers: #frameworks, #plasma, #kwin Subscribers: plasma-devel Tags: #plasma_on_wayland, #frameworks Differential Revision: https://phabricator.kde.org/D9510
This commit is contained in:
parent
e087a3666b
commit
1a5762b9d7
3 changed files with 63 additions and 17 deletions
|
@ -42,6 +42,7 @@ private Q_SLOTS:
|
|||
|
||||
void testTimeout();
|
||||
void testSimulateUserActivity();
|
||||
void testServerSimulateUserActivity();
|
||||
void testIdleInhibit();
|
||||
void testIdleInhibitBlocksTimeout();
|
||||
|
||||
|
@ -188,6 +189,34 @@ void IdleTest::testSimulateUserActivity()
|
|||
m_display->dispatchEvents();
|
||||
}
|
||||
|
||||
void IdleTest::testServerSimulateUserActivity()
|
||||
{
|
||||
// this test verifies that simulate user activity doesn't fire the timer
|
||||
QScopedPointer<IdleTimeout> timeout(m_idle->getTimeout(6000, m_seat));
|
||||
QVERIFY(timeout->isValid());
|
||||
QSignalSpy idleSpy(timeout.data(), &IdleTimeout::idle);
|
||||
QVERIFY(idleSpy.isValid());
|
||||
QSignalSpy resumedFormIdleSpy(timeout.data(), &IdleTimeout::resumeFromIdle);
|
||||
QVERIFY(resumedFormIdleSpy.isValid());
|
||||
m_connection->flush();
|
||||
|
||||
QTest::qWait(4000);
|
||||
m_idleInterface->simulateUserActivity();
|
||||
// waiting default five sec should fail
|
||||
QVERIFY(!idleSpy.wait());
|
||||
// another 2 sec should fire
|
||||
QVERIFY(idleSpy.wait(2000));
|
||||
|
||||
// now simulating user activity should emit a resumedFromIdle
|
||||
QVERIFY(resumedFormIdleSpy.isEmpty());
|
||||
m_idleInterface->simulateUserActivity();
|
||||
QVERIFY(resumedFormIdleSpy.wait());
|
||||
|
||||
timeout.reset();
|
||||
m_connection->flush();
|
||||
m_display->dispatchEvents();
|
||||
}
|
||||
|
||||
void IdleTest::testIdleInhibit()
|
||||
{
|
||||
QCOMPARE(m_idleInterface->isInhibited(), false);
|
||||
|
|
|
@ -39,6 +39,7 @@ public:
|
|||
Private(IdleInterface *q, Display *d);
|
||||
|
||||
int inhibitCount = 0;
|
||||
QVector<IdleTimeoutInterface*> idleTimeouts;
|
||||
|
||||
private:
|
||||
void bind(wl_client *client, uint32_t version, uint32_t id) override;
|
||||
|
@ -61,6 +62,8 @@ public:
|
|||
~Private();
|
||||
void setup(quint32 timeout);
|
||||
|
||||
void simulateUserActivity();
|
||||
|
||||
SeatInterface *seat;
|
||||
QTimer *timer = nullptr;
|
||||
|
||||
|
@ -98,6 +101,9 @@ void IdleInterface::Private::getIdleTimeoutCallback(wl_client *client, wl_resour
|
|||
delete idleTimeout;
|
||||
return;
|
||||
}
|
||||
p->idleTimeouts << idleTimeout;
|
||||
QObject::connect(idleTimeout, &IdleTimeoutInterface::aboutToBeUnbound, p->q,
|
||||
std::bind(&QVector<IdleTimeoutInterface*>::removeOne, p->idleTimeouts, idleTimeout));
|
||||
idleTimeout->d_func()->setup(timeout);
|
||||
}
|
||||
|
||||
|
@ -149,6 +155,14 @@ bool IdleInterface::isInhibited() const
|
|||
return d->inhibitCount > 0;
|
||||
}
|
||||
|
||||
void IdleInterface::simulateUserActivity()
|
||||
{
|
||||
Q_D();
|
||||
for (auto i : qAsConst(d->idleTimeouts)) {
|
||||
i->d_func()->simulateUserActivity();
|
||||
}
|
||||
}
|
||||
|
||||
IdleInterface::Private *IdleInterface::d_func() const
|
||||
{
|
||||
return reinterpret_cast<Private*>(d.data());
|
||||
|
@ -173,18 +187,23 @@ void IdleTimeoutInterface::Private::simulateUserActivityCallback(wl_client *clie
|
|||
{
|
||||
Q_UNUSED(client);
|
||||
Private *p = reinterpret_cast<Private*>(wl_resource_get_user_data(resource));
|
||||
if (!p->timer) {
|
||||
p->simulateUserActivity();
|
||||
}
|
||||
|
||||
void IdleTimeoutInterface::Private::simulateUserActivity()
|
||||
{
|
||||
if (!timer) {
|
||||
// not yet configured
|
||||
return;
|
||||
}
|
||||
if (qobject_cast<IdleInterface*>(p->global)->isInhibited()) {
|
||||
if (qobject_cast<IdleInterface*>(global)->isInhibited()) {
|
||||
// ignored while inhibited
|
||||
return;
|
||||
}
|
||||
if (!p->timer->isActive() && p->resource) {
|
||||
org_kde_kwin_idle_timeout_send_resumed(p->resource);
|
||||
if (!timer->isActive() && resource) {
|
||||
org_kde_kwin_idle_timeout_send_resumed(resource);
|
||||
}
|
||||
p->timer->start();
|
||||
timer->start();
|
||||
}
|
||||
|
||||
void IdleTimeoutInterface::Private::setup(quint32 timeout)
|
||||
|
@ -216,18 +235,7 @@ IdleTimeoutInterface::IdleTimeoutInterface(SeatInterface *seat, IdleInterface *p
|
|||
connect(seat, &SeatInterface::timestampChanged, this,
|
||||
[this] {
|
||||
Q_D();
|
||||
if (!d->timer) {
|
||||
// not yet configured
|
||||
return;
|
||||
}
|
||||
if (qobject_cast<IdleInterface*>(d->global)->isInhibited()) {
|
||||
// ignored while inhibited
|
||||
return;
|
||||
}
|
||||
if (!d->timer->isActive() && d->resource) {
|
||||
org_kde_kwin_idle_timeout_send_resumed(d->resource);
|
||||
}
|
||||
d->timer->start();
|
||||
d->simulateUserActivity();
|
||||
}
|
||||
);
|
||||
connect(parent, &IdleInterface::inhibitedChanged, this,
|
||||
|
|
|
@ -94,6 +94,15 @@ public:
|
|||
**/
|
||||
bool isInhibited() const;
|
||||
|
||||
/**
|
||||
* Calling this method allows the Compositor to simulate user activity.
|
||||
* This means the same action is performed as if the user interacted with
|
||||
* an input device on the SeatInterface.
|
||||
* Idle timeouts are resumed and the idle time gets restarted.
|
||||
* @since 5.42
|
||||
**/
|
||||
void simulateUserActivity();
|
||||
|
||||
Q_SIGNALS:
|
||||
/**
|
||||
* Emitted when the system gets inhibited or uninhibited.
|
||||
|
|
Loading…
Reference in a new issue