| 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 | \nativetype 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(surface: m_surface.data()); |
| 148 | Q_ASSERT(surfacePrivate->idleInhibitors.contains(this)); |
| 149 | surfacePrivate->idleInhibitors.removeOne(t: 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 | |