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 | |
9 | QT_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 | */ |
58 | QWaylandIdleInhibitManagerV1::QWaylandIdleInhibitManagerV1() |
59 | : QWaylandCompositorExtensionTemplate<QWaylandIdleInhibitManagerV1>(*new QWaylandIdleInhibitManagerV1Private()) |
60 | { |
61 | } |
62 | |
63 | /*! |
64 | Constructs a QWaylandIdleInhibitManagerV1 object for the provided \a compositor. |
65 | */ |
66 | QWaylandIdleInhibitManagerV1::QWaylandIdleInhibitManagerV1(QWaylandCompositor *compositor) |
67 | : QWaylandCompositorExtensionTemplate<QWaylandIdleInhibitManagerV1>(compositor, *new QWaylandIdleInhibitManagerV1Private()) |
68 | { |
69 | } |
70 | |
71 | /*! |
72 | Destructs a QWaylandIdleInhibitManagerV1 object. |
73 | */ |
74 | QWaylandIdleInhibitManagerV1::~QWaylandIdleInhibitManagerV1() = default; |
75 | |
76 | /*! |
77 | Initializes the extension. |
78 | */ |
79 | void 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 | */ |
95 | const wl_interface *QWaylandIdleInhibitManagerV1::interface() |
96 | { |
97 | return QWaylandIdleInhibitManagerV1Private::interface(); |
98 | } |
99 | |
100 | |
101 | void 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 | |
129 | QWaylandIdleInhibitManagerV1Private::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 | |
138 | void QWaylandIdleInhibitManagerV1Private::Inhibitor::zwp_idle_inhibitor_v1_destroy_resource(Resource *resource) |
139 | { |
140 | Q_UNUSED(resource); |
141 | delete this; |
142 | } |
143 | |
144 | void 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 | |
158 | QT_END_NAMESPACE |
159 | |
160 | #include "moc_qwaylandidleinhibitv1.cpp" |
161 | |