1// Copyright (C) 2019 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3
4#include <QtWaylandCompositor/QWaylandCompositor>
5#include <QtWaylandCompositor/private/qwaylandsurface_p.h>
6
7#include "qwaylandidleinhibitv1_p.h"
8
9QT_BEGIN_NAMESPACE
10
11/*!
12 \class QWaylandIdleInhibitManagerV1
13 \inmodule QtWaylandCompositor
14 \since 5.14
15 \brief Provides an extension that allows to inhibit the idle behavior of the compositor.
16 \sa QWaylandSurface::inhibitsIdle
17
18 The QWaylandIdleInhibitV1 extension provides a way for a client to inhibit the idle behavior of
19 the compositor when a specific surface is visually relevant to the user.
20
21 QWaylandIdleInhibitManagerV1 corresponds to the Wayland interface, \c zwp_idle_inhibit_manager_v1.
22
23 Inhibited surfaces have the QWaylandSurface::inhibitsIdle property set to \c true.
24*/
25
26/*!
27 \qmltype IdleInhibitManagerV1
28 \instantiates QWaylandIdleInhibitManagerV1
29 \inqmlmodule QtWayland.Compositor
30 \since 5.14
31 \brief Provides an extension that allows to inhibit the idle behavior of the compositor.
32 \sa WaylandSurface::inhibitsIdle
33
34 The IdleInhibitManagerV1 extension provides a way for a client to inhibit the idle behavior of
35 the compositor when a specific surface is visually relevant to the user.
36
37 IdleInhibitManagerV1 corresponds to the Wayland interface, \c zwp_idle_inhibit_manager_v1.
38
39 To provide the functionality of the extension in a compositor, create an instance of the
40 IdleInhibitManagerV1 component and add it to the list of extensions supported by the compositor:
41
42 \qml
43 import QtWayland.Compositor
44
45 WaylandCompositor {
46 IdleInhibitManagerV1 {
47 // ...
48 }
49 }
50 \endqml
51
52 Inhibited surfaces have the WaylandSurface::inhibitsIdle property set to \c true.
53*/
54
55/*!
56 Constructs a QWaylandIdleInhibitManagerV1 object.
57*/
58QWaylandIdleInhibitManagerV1::QWaylandIdleInhibitManagerV1()
59 : QWaylandCompositorExtensionTemplate<QWaylandIdleInhibitManagerV1>(*new QWaylandIdleInhibitManagerV1Private())
60{
61}
62
63/*!
64 Constructs a QWaylandIdleInhibitManagerV1 object for the provided \a compositor.
65*/
66QWaylandIdleInhibitManagerV1::QWaylandIdleInhibitManagerV1(QWaylandCompositor *compositor)
67 : QWaylandCompositorExtensionTemplate<QWaylandIdleInhibitManagerV1>(compositor, *new QWaylandIdleInhibitManagerV1Private())
68{
69}
70
71/*!
72 Destructs a QWaylandIdleInhibitManagerV1 object.
73*/
74QWaylandIdleInhibitManagerV1::~QWaylandIdleInhibitManagerV1() = default;
75
76/*!
77 Initializes the extension.
78*/
79void QWaylandIdleInhibitManagerV1::initialize()
80{
81 Q_D(QWaylandIdleInhibitManagerV1);
82
83 QWaylandCompositorExtensionTemplate::initialize();
84 QWaylandCompositor *compositor = static_cast<QWaylandCompositor *>(extensionContainer());
85 if (!compositor) {
86 qCWarning(qLcWaylandCompositor) << "Failed to find QWaylandCompositor when initializing QWaylandIdleInhibitManagerV1";
87 return;
88 }
89 d->init(compositor->display(), d->interfaceVersion());
90}
91
92/*!
93 Returns the Wayland interface for the QWaylandIdleInhibitManagerV1.
94*/
95const wl_interface *QWaylandIdleInhibitManagerV1::interface()
96{
97 return QWaylandIdleInhibitManagerV1Private::interface();
98}
99
100
101void QWaylandIdleInhibitManagerV1Private::zwp_idle_inhibit_manager_v1_create_inhibitor(Resource *resource, uint id, wl_resource *surfaceResource)
102{
103 auto *surface = QWaylandSurface::fromResource(resource: surfaceResource);
104 if (!surface) {
105 qCWarning(qLcWaylandCompositor) << "Couldn't find surface requested for creating an inhibitor";
106 wl_resource_post_error(resource->handle, WL_DISPLAY_ERROR_INVALID_OBJECT,
107 "invalid wl_surface@%d", wl_resource_get_id(resource: surfaceResource));
108 return;
109 }
110
111 auto *surfacePrivate = QWaylandSurfacePrivate::get(surface);
112 if (!surfacePrivate) {
113 wl_resource_post_no_memory(resource->handle);
114 return;
115 }
116
117 auto *inhibitor = new Inhibitor(surface, resource->client(), id, resource->version());
118 if (!inhibitor) {
119 wl_resource_post_no_memory(resource->handle);
120 return;
121 }
122 surfacePrivate->idleInhibitors.append(inhibitor);
123
124 if (surfacePrivate->idleInhibitors.size() == 1)
125 Q_EMIT surface->inhibitsIdleChanged();
126}
127
128
129QWaylandIdleInhibitManagerV1Private::Inhibitor::Inhibitor(QWaylandSurface *surface,
130 wl_client *client,
131 quint32 id, quint32 version)
132 : QtWaylandServer::zwp_idle_inhibitor_v1(client, id, qMin<quint32>(version, interfaceVersion()))
133 , m_surface(surface)
134{
135 Q_ASSERT(surface);
136}
137
138void QWaylandIdleInhibitManagerV1Private::Inhibitor::zwp_idle_inhibitor_v1_destroy_resource(Resource *resource)
139{
140 Q_UNUSED(resource);
141 delete this;
142}
143
144void QWaylandIdleInhibitManagerV1Private::Inhibitor::zwp_idle_inhibitor_v1_destroy(Resource *resource)
145{
146 if (m_surface) {
147 auto *surfacePrivate = QWaylandSurfacePrivate::get(m_surface.data());
148 Q_ASSERT(surfacePrivate->idleInhibitors.contains(this));
149 surfacePrivate->idleInhibitors.removeOne(this);
150
151 if (surfacePrivate->idleInhibitors.isEmpty())
152 Q_EMIT m_surface.data()->inhibitsIdleChanged();
153 }
154
155 wl_resource_destroy(resource->handle);
156}
157
158QT_END_NAMESPACE
159
160#include "moc_qwaylandidleinhibitv1.cpp"
161

source code of qtwayland/src/compositor/extensions/qwaylandidleinhibitv1.cpp