idle_interface.cpp 3.85 KB
Newer Older
1
2
3
4
5
/*
    SPDX-FileCopyrightText: 2015 Martin Gräßlin <mgraesslin@kde.org>

    SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
*/
6
#include "idle_interface_p.h"
7
8
9
#include "display.h"
#include "seat_interface.h"

10
namespace KWaylandServer
11
12
{

13
static const quint32 s_version = 1;
14

15
16
17
IdleInterfacePrivate::IdleInterfacePrivate(IdleInterface *_q, Display *display)
    : QtWaylandServer::org_kde_kwin_idle(*display, s_version)
    , q(_q)
18
19
20
{
}

21
void IdleInterfacePrivate::org_kde_kwin_idle_get_idle_timeout(Resource *resource, uint32_t id, wl_resource *seat, uint32_t timeout)
22
23
24
25
{
    SeatInterface *s = SeatInterface::get(seat);
    Q_ASSERT(s);

26
27
28
    wl_resource *idleTimoutResource = wl_resource_create(resource->client(), &org_kde_kwin_idle_timeout_interface, resource->version(), id);
    if (!idleTimoutResource) {
        wl_client_post_no_memory(resource->client());
29
30
31
        return;
    }

32
33
34
35
36
37
38
    IdleTimeoutInterface *idleTimeout = new IdleTimeoutInterface(s, q, idleTimoutResource);
    idleTimeouts << idleTimeout;

    QObject::connect(idleTimeout, &IdleTimeoutInterface::destroyed, q, [this, idleTimeout]() {
        idleTimeouts.removeOne(idleTimeout);
    });
    idleTimeout->setup(timeout);
39
40
41
}

IdleInterface::IdleInterface(Display *display, QObject *parent)
42
43
    : QObject(parent)
    , d(new IdleInterfacePrivate(this, display))
44
45
46
47
48
{
}

IdleInterface::~IdleInterface() = default;

49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
void IdleInterface::inhibit()
{
    d->inhibitCount++;
    if (d->inhibitCount == 1) {
        emit inhibitedChanged();
    }
}

void IdleInterface::uninhibit()
{
    d->inhibitCount--;
    if (d->inhibitCount == 0) {
        emit inhibitedChanged();
    }
}

bool IdleInterface::isInhibited() const
{
    return d->inhibitCount > 0;
}

70
71
72
void IdleInterface::simulateUserActivity()
{
    for (auto i : qAsConst(d->idleTimeouts)) {
73
        i->simulateUserActivity();
74
75
76
    }
}

77
78
79
80
81
IdleTimeoutInterface::IdleTimeoutInterface(SeatInterface *seat, IdleInterface *manager, wl_resource *resource)
    : QObject()
    , QtWaylandServer::org_kde_kwin_idle_timeout(resource)
    , seat(seat)
    , manager(manager)
82
{
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
    connect(seat, &SeatInterface::timestampChanged, this,
        [this] {
            simulateUserActivity();
        }
    );
    connect(manager, &IdleInterface::inhibitedChanged, this,
        [this, manager] {
            if (!timer) {
                // not yet configured
                return;
            }
            if (manager->isInhibited()) {
                if (!timer->isActive()) {
                    send_resumed();
                }
                timer->stop();
            } else {
                timer->start();
            }
        }
    );
104
105
}

106
IdleTimeoutInterface::~IdleTimeoutInterface() = default;
107

108
void IdleTimeoutInterface::org_kde_kwin_idle_timeout_release(Resource *resource)
109
{
110
    wl_resource_destroy(resource->handle);
111
112
}

113
void IdleTimeoutInterface::org_kde_kwin_idle_timeout_destroy_resource(Resource *resource)
114
{
115
116
    Q_UNUSED(resource)
    delete this;
117
118
}

119
120
121
122
123
124
void IdleTimeoutInterface::org_kde_kwin_idle_timeout_simulate_user_activity(Resource *resource)
{
    Q_UNUSED(resource)
    simulateUserActivity();
}
void IdleTimeoutInterface::simulateUserActivity()
125
126
{
    if (!timer) {
127
128
129
        // not yet configured
        return;
    }
130
    if (manager->isInhibited()) {
131
132
133
        // ignored while inhibited
        return;
    }
134
135
    if (!timer->isActive()) {
        send_resumed();
136
    }
137
    timer->start();
138
139
}

140
void IdleTimeoutInterface::setup(quint32 timeout)
141
142
143
144
{
    if (timer) {
        return;
    }
145
    timer = new QTimer(this);
146
    timer->setSingleShot(true);
147
148
    // less than 500 msec is not idle by definition
    timer->setInterval(qMax(timeout, 500u));
149
    QObject::connect(timer, &QTimer::timeout, this,
150
        [this] {
151
            send_idle();
152
153
        }
    );
154
    if (manager->isInhibited()) {
155
156
157
        // don't start if inhibited
        return;
    }
158
159
160
    timer->start();
}
}