Add support for zwp_idle_inhibit_manager_v1

Summary:
This protocol allows to indicate that a wl_surface should inhibit idle
actions such as DPMS, screen locking if the surface is visible.

The protocol is quite simple: it just creates an IdleInhibitor for a
Surface. If such an IdleInhibitor exists the Surface is considered to
inhibit idle.

On the server side it is also exposed like that through the API. The
IdleInhibitorInterface is private to the library and only
SurfaceInterface is extended to expose whether it currently inhibits
idle.

CCBUG: 385956

Test Plan: New test case added

Reviewers: #frameworks, #kwin, #plasma_on_wayland

Subscribers: plasma-devel

Tags: #plasma_on_wayland, #frameworks

Differential Revision: https://phabricator.kde.org/D8396
This commit is contained in:
Martin Flöser 2017-10-20 18:28:25 +02:00
parent f5cfe92b8a
commit 665c0535fe
13 changed files with 536 additions and 0 deletions

View file

@ -10,6 +10,8 @@ set(SERVER_LIB_SRCS
dpms_interface.cpp
global.cpp
idle_interface.cpp
idleinhibit_interface.cpp
idleinhibit_interface_v1.cpp
fakeinput_interface.cpp
keyboard_interface.cpp
outputconfiguration_interface.cpp
@ -154,6 +156,11 @@ ecm_add_wayland_server_protocol(SERVER_LIB_SRCS
BASENAME xdg-foreign-unstable-v2
)
ecm_add_wayland_server_protocol(SERVER_LIB_SRCS
PROTOCOL ${KWayland_SOURCE_DIR}/src/client/protocols/idle-inhibit-unstable-v1.xml
BASENAME idle-inhibit-unstable-v1
)
add_library(KF5WaylandServer ${SERVER_LIB_SRCS})
generate_export_header(KF5WaylandServer
BASE_NAME
@ -198,6 +205,7 @@ set(SERVER_LIB_HEADERS
fakeinput_interface.h
global.h
idle_interface.h
idleinhibit_interface.h
keyboard_interface.h
outputdevice_interface.h
outputchangeset.h

View file

@ -30,6 +30,7 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
#include "../../src/client/output.h"
#include "../../src/client/pointerconstraints.h"
#include "../../src/client/pointergestures.h"
#include "../../src/client/idleinhibit.h"
#include "../../src/client/seat.h"
#include "../../src/client/relativepointer.h"
#include "../../src/client/server_decoration.h"
@ -41,6 +42,7 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
#include "../../src/server/datadevicemanager_interface.h"
#include "../../src/server/display.h"
#include "../../src/server/dpms_interface.h"
#include "../../src/server/idleinhibit_interface.h"
#include "../../src/server/output_interface.h"
#include "../../src/server/seat_interface.h"
#include "../../src/server/shell_interface.h"
@ -59,6 +61,7 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
// Wayland
#include <wayland-client-protocol.h>
#include <wayland-dpms-client-protocol.h>
#include <wayland-idle-inhibit-unstable-v1-client-protocol.h>
#include <wayland-server-decoration-client-protocol.h>
#include <wayland-text-input-v0-client-protocol.h>
#include <wayland-text-input-v2-client-protocol.h>
@ -95,6 +98,7 @@ private Q_SLOTS:
void testBindRelativePointerManagerUnstableV1();
void testBindPointerGesturesUnstableV1();
void testBindPointerConstraintsUnstableV1();
void testBindIdleIhibitManagerUnstableV1();
void testGlobalSync();
void testGlobalSyncThreaded();
void testRemoval();
@ -122,6 +126,7 @@ private:
KWayland::Server::PointerConstraintsInterface *m_pointerConstraintsV1;
KWayland::Server::BlurManagerInterface *m_blur;
KWayland::Server::ContrastManagerInterface *m_contrast;
KWayland::Server::IdleInhibitManagerInterface *m_idleInhibit;
};
@ -147,6 +152,7 @@ TestWaylandRegistry::TestWaylandRegistry(QObject *parent)
, m_pointerConstraintsV1(nullptr)
, m_blur(nullptr)
, m_contrast(nullptr)
, m_idleInhibit(nullptr)
{
}
@ -199,6 +205,9 @@ void TestWaylandRegistry::init()
m_pointerConstraintsV1 = m_display->createPointerConstraints(KWayland::Server::PointerConstraintsInterfaceVersion::UnstableV1);
m_pointerConstraintsV1->create();
QCOMPARE(m_pointerConstraintsV1->interfaceVersion(), KWayland::Server::PointerConstraintsInterfaceVersion::UnstableV1);
m_idleInhibit = m_display->createIdleInhibitManager(KWayland::Server::IdleInhibitManagerInterfaceVersion::UnstableV1);
m_idleInhibit->create();
QCOMPARE(m_idleInhibit->interfaceVersion(), KWayland::Server::IdleInhibitManagerInterfaceVersion::UnstableV1);
}
void TestWaylandRegistry::cleanup()
@ -356,6 +365,11 @@ void TestWaylandRegistry::testBindPointerConstraintsUnstableV1()
TEST_BIND(KWayland::Client::Registry::Interface::PointerConstraintsUnstableV1, SIGNAL(pointerConstraintsUnstableV1Announced(quint32,quint32)), bindPointerConstraintsUnstableV1, zwp_pointer_constraints_v1_destroy)
}
void TestWaylandRegistry::testBindIdleIhibitManagerUnstableV1()
{
TEST_BIND(KWayland::Client::Registry::Interface::IdleInhibitManagerUnstableV1, SIGNAL(idleInhibitManagerUnstableV1Announced(quint32,quint32)), bindIdleInhibitManagerUnstableV1, zwp_idle_inhibit_manager_v1_destroy)
}
#undef TEST_BIND
void TestWaylandRegistry::testRemoval()
@ -393,6 +407,8 @@ void TestWaylandRegistry::testRemoval()
QVERIFY(serverSideDecorationManagerAnnouncedSpy.isValid());
QSignalSpy blurAnnouncedSpy(&registry, &Registry::blurAnnounced);
QVERIFY(blurAnnouncedSpy.isValid());
QSignalSpy idleInhibitManagerUnstableV1AnnouncedSpy(&registry, &Registry::idleInhibitManagerUnstableV1Announced);
QVERIFY(idleInhibitManagerUnstableV1AnnouncedSpy.isValid());
QVERIFY(!registry.isValid());
registry.create(connection.display());
@ -408,6 +424,7 @@ void TestWaylandRegistry::testRemoval()
QVERIFY(!outputManagementAnnouncedSpy.isEmpty());
QVERIFY(!serverSideDecorationManagerAnnouncedSpy.isEmpty());
QVERIFY(!blurAnnouncedSpy.isEmpty());
QVERIFY(!idleInhibitManagerUnstableV1AnnouncedSpy.isEmpty());
QVERIFY(registry.hasInterface(KWayland::Client::Registry::Interface::Compositor));
@ -421,6 +438,7 @@ void TestWaylandRegistry::testRemoval()
QVERIFY(registry.hasInterface(KWayland::Client::Registry::Interface::OutputManagement));
QVERIFY(registry.hasInterface(KWayland::Client::Registry::Interface::ServerSideDecorationManager));
QVERIFY(registry.hasInterface(KWayland::Client::Registry::Interface::Blur));
QVERIFY(registry.hasInterface(KWayland::Client::Registry::Interface::IdleInhibitManagerUnstableV1));
QVERIFY(!registry.interfaces(KWayland::Client::Registry::Interface::Compositor).isEmpty());
QVERIFY(!registry.interfaces(KWayland::Client::Registry::Interface::Output).isEmpty());
@ -433,6 +451,7 @@ void TestWaylandRegistry::testRemoval()
QVERIFY(!registry.interfaces(KWayland::Client::Registry::Interface::OutputManagement).isEmpty());
QVERIFY(!registry.interfaces(KWayland::Client::Registry::Interface::ServerSideDecorationManager).isEmpty());
QVERIFY(!registry.interfaces(KWayland::Client::Registry::Interface::Blur).isEmpty());
QVERIFY(!registry.interfaces(KWayland::Client::Registry::Interface::IdleInhibitManagerUnstableV1).isEmpty());
QSignalSpy seatRemovedSpy(&registry, SIGNAL(seatRemoved(quint32)));
QVERIFY(seatRemovedSpy.isValid());
@ -444,6 +463,7 @@ void TestWaylandRegistry::testRemoval()
SubCompositor *subcompositor = registry.createSubCompositor(registry.interface(Registry::Interface::SubCompositor).name, registry.interface(Registry::Interface::SubCompositor).version, &registry);
ServerSideDecorationManager *serverSideDeco = registry.createServerSideDecorationManager(registry.interface(Registry::Interface::ServerSideDecorationManager).name, registry.interface(Registry::Interface::ServerSideDecorationManager).version, &registry);
BlurManager *blurManager = registry.createBlurManager(registry.interface(Registry::Interface::Blur).name, registry.interface(Registry::Interface::Blur).version, &registry);
auto idleInhibitManager = registry.createIdleInhibitManager(registry.interface(Registry::Interface::IdleInhibitManagerUnstableV1).name, registry.interface(Registry::Interface::IdleInhibitManagerUnstableV1).version, &registry);
connection.flush();
m_display->dispatchEvents();
@ -457,6 +477,8 @@ void TestWaylandRegistry::testRemoval()
QVERIFY(compositorObjectRemovedSpy.isValid());
QSignalSpy subcompositorObjectRemovedSpy(subcompositor, &SubCompositor::removed);
QVERIFY(subcompositorObjectRemovedSpy.isValid());
QSignalSpy idleInhibitManagerObjectRemovedSpy(idleInhibitManager, &IdleInhibitManager::removed);
QVERIFY(idleInhibitManagerObjectRemovedSpy.isValid());
delete m_seat;
QVERIFY(seatRemovedSpy.wait());
@ -547,6 +569,14 @@ void TestWaylandRegistry::testRemoval()
QVERIFY(registry.interfaces(KWayland::Client::Registry::Interface::Blur).isEmpty());
QCOMPARE(blurObjectRemovedSpy.count(), 1);
QSignalSpy idleInhibitManagerUnstableV1RemovedSpy(&registry, &Registry::idleInhibitManagerUnstableV1Removed);
QVERIFY(idleInhibitManagerUnstableV1RemovedSpy.isValid());
delete m_idleInhibit;
QVERIFY(idleInhibitManagerUnstableV1RemovedSpy.wait());
QCOMPARE(idleInhibitManagerUnstableV1RemovedSpy.first().first(), idleInhibitManagerUnstableV1AnnouncedSpy.first().first());
QVERIFY(registry.interfaces(KWayland::Client::Registry::Interface::IdleInhibitManagerUnstableV1).isEmpty());
QCOMPARE(idleInhibitManagerObjectRemovedSpy.count(), 1);
// cannot test shmRemoved as there is no functionality for it
// verify everything has been removed only once
@ -557,6 +587,7 @@ void TestWaylandRegistry::testRemoval()
QCOMPARE(subcompositorObjectRemovedSpy.count(), 1);
QCOMPARE(serverSideDecoManagerObjectRemovedSpy.count(), 1);
QCOMPARE(blurObjectRemovedSpy.count(), 1);
QCOMPARE(idleInhibitManagerObjectRemovedSpy.count(), 1);
}
void TestWaylandRegistry::testOutOfSyncRemoval()

View file

@ -25,6 +25,7 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
#include "../../src/client/compositor.h"
#include "../../src/client/connection_thread.h"
#include "../../src/client/event_queue.h"
#include "../../src/client/idleinhibit.h"
#include "../../src/client/output.h"
#include "../../src/client/surface.h"
#include "../../src/client/region.h"
@ -33,10 +34,13 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
#include "../../src/server/buffer_interface.h"
#include "../../src/server/compositor_interface.h"
#include "../../src/server/display.h"
#include "../../src/server/idleinhibit_interface.h"
#include "../../src/server/surface_interface.h"
// Wayland
#include <wayland-client-protocol.h>
using KWayland::Client::Registry;
class TestWaylandSurface : public QObject
{
Q_OBJECT
@ -62,14 +66,17 @@ private Q_SLOTS:
void testDestroyWithPendingCallback();
void testOutput();
void testDisconnect();
void testInhibit();
private:
KWayland::Server::Display *m_display;
KWayland::Server::CompositorInterface *m_compositorInterface;
KWayland::Server::IdleInhibitManagerInterface *m_idleInhibitInterface = nullptr;
KWayland::Client::ConnectionThread *m_connection;
KWayland::Client::Compositor *m_compositor;
KWayland::Client::ShmPool *m_shm;
KWayland::Client::EventQueue *m_queue;
KWayland::Client::IdleInhibitManager *m_idleInhibitManager = nullptr;
QThread *m_thread;
};
@ -100,6 +107,11 @@ void TestWaylandSurface::init()
m_compositorInterface->create();
QVERIFY(m_compositorInterface->isValid());
m_idleInhibitInterface = m_display->createIdleInhibitManager(IdleInhibitManagerInterfaceVersion::UnstableV1, m_display);
QVERIFY(m_idleInhibitInterface);
m_idleInhibitInterface->create();
QVERIFY(m_idleInhibitInterface->isValid());
// setup connection
m_connection = new KWayland::Client::ConnectionThread;
QSignalSpy connectedSpy(m_connection, SIGNAL(connected()));
@ -143,6 +155,9 @@ void TestWaylandSurface::init()
QVERIFY(m_compositor->isValid());
m_shm = registry.createShmPool(shmSpy.first().first().value<quint32>(), shmSpy.first().last().value<quint32>(), this);
QVERIFY(m_shm->isValid());
m_idleInhibitManager = registry.createIdleInhibitManager(registry.interface(Registry::Interface::IdleInhibitManagerUnstableV1).name, registry.interface(Registry::Interface::IdleInhibitManagerUnstableV1).version, this);
QVERIFY(m_idleInhibitManager->isValid());
}
void TestWaylandSurface::cleanup()
@ -1091,5 +1106,53 @@ void TestWaylandSurface::testOutput()
QCOMPARE(serverSurface->outputs(), QVector<OutputInterface*>());
}
void TestWaylandSurface::testInhibit()
{
using namespace KWayland::Client;
using namespace KWayland::Server;
QScopedPointer<Surface> s(m_compositor->createSurface());
// wait for the surface on the Server side
QSignalSpy surfaceCreatedSpy(m_compositorInterface, &CompositorInterface::surfaceCreated);
QVERIFY(surfaceCreatedSpy.isValid());
QVERIFY(surfaceCreatedSpy.wait());
auto serverSurface = surfaceCreatedSpy.first().first().value<SurfaceInterface*>();
QVERIFY(serverSurface);
QCOMPARE(serverSurface->inhibitsIdle(), false);
QSignalSpy inhibitsChangedSpy(serverSurface, &SurfaceInterface::inhibitsIdleChanged);
QVERIFY(inhibitsChangedSpy.isValid());
// now create an idle inhibition
QScopedPointer<IdleInhibitor> inhibitor1(m_idleInhibitManager->createInhibitor(s.data()));
QVERIFY(inhibitsChangedSpy.wait());
QCOMPARE(serverSurface->inhibitsIdle(), true);
// creating a second idle inhibition should not trigger the signal
QScopedPointer<IdleInhibitor> inhibitor2(m_idleInhibitManager->createInhibitor(s.data()));
QVERIFY(!inhibitsChangedSpy.wait());
QCOMPARE(serverSurface->inhibitsIdle(), true);
// and also deleting the first inhibitor should not yet change the inhibition
inhibitor1.reset();
QVERIFY(!inhibitsChangedSpy.wait());
QCOMPARE(serverSurface->inhibitsIdle(), true);
// but deleting also the second inhibitor should trigger
inhibitor2.reset();
QVERIFY(inhibitsChangedSpy.wait());
QCOMPARE(serverSurface->inhibitsIdle(), false);
QCOMPARE(inhibitsChangedSpy.count(), 2);
// recreate inhibitor1 should inhibit again
inhibitor1.reset(m_idleInhibitManager->createInhibitor(s.data()));
QVERIFY(inhibitsChangedSpy.wait());
QCOMPARE(serverSurface->inhibitsIdle(), true);
// and destroying should uninhibit
inhibitor1.reset();
QVERIFY(inhibitsChangedSpy.wait());
QCOMPARE(serverSurface->inhibitsIdle(), false);
QCOMPARE(inhibitsChangedSpy.count(), 4);
}
QTEST_GUILESS_MAIN(TestWaylandSurface)
#include "test_wayland_surface.moc"

View file

@ -25,6 +25,7 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
#include "outputmanagement_interface.h"
#include "outputdevice_interface.h"
#include "idle_interface.h"
#include "idleinhibit_interface_p.h"
#include "fakeinput_interface.h"
#include "logging_p.h"
#include "output_interface.h"
@ -420,6 +421,18 @@ XdgForeignInterface *Display::createXdgForeignInterface(QObject *parent)
return foreign;
}
IdleInhibitManagerInterface *Display::createIdleInhibitManager(const IdleInhibitManagerInterfaceVersion &version, QObject *parent)
{
IdleInhibitManagerInterface *i = nullptr;
switch (version) {
case IdleInhibitManagerInterfaceVersion::UnstableV1:
i = new IdleInhibitManagerUnstableV1Interface(this, parent);
break;
}
connect(this, &Display::aboutToTerminate, i, [this,i] { delete i; });
return i;
}
void Display::createShm()
{
Q_ASSERT(d->display);

View file

@ -53,6 +53,8 @@ class CompositorInterface;
class DataDeviceManagerInterface;
class DpmsManagerInterface;
class IdleInterface;
enum class IdleInhibitManagerInterfaceVersion;
class IdleInhibitManagerInterface;
class FakeInputInterface;
class OutputInterface;
class OutputDeviceInterface;
@ -227,6 +229,15 @@ public:
* @since 5.40
**/
XdgForeignInterface *createXdgForeignInterface(QObject *parent = nullptr);
/**
* Creates the IdleInhibitManagerInterface in interface @p version.
*
* @returns The created manager object
* @since 5.41
**/
IdleInhibitManagerInterface *createIdleInhibitManager(const IdleInhibitManagerInterfaceVersion &version, QObject *parent = nullptr);
/**
* Gets the ClientConnection for the given @p client.
* If there is no ClientConnection yet for the given @p client, it will be created.

View file

@ -0,0 +1,53 @@
/****************************************************************************
Copyright 2017 Martin Flöser <mgraesslin@kde.org>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) version 3, or any
later version accepted by the membership of KDE e.V. (or its
successor approved by the membership of KDE e.V.), which shall
act as a proxy defined in Section 6 of version 3 of the license.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library. If not, see <http://www.gnu.org/licenses/>.
****************************************************************************/
#include "idleinhibit_interface_p.h"
namespace KWayland
{
namespace Server
{
IdleInhibitManagerInterface::Private::Private(IdleInhibitManagerInterface *q, Display *d, const wl_interface *interface, quint32 version, IdleInhibitManagerInterfaceVersion interfaceVersion)
: Global::Private(d, interface, version)
, interfaceVersion(interfaceVersion)
, q(q)
{
}
IdleInhibitManagerInterface::IdleInhibitManagerInterface(Private *d, QObject *parent)
: Global(d, parent)
{
}
IdleInhibitManagerInterface::~IdleInhibitManagerInterface() = default;
IdleInhibitManagerInterfaceVersion IdleInhibitManagerInterface::interfaceVersion() const
{
Q_D();
return d->interfaceVersion;
}
IdleInhibitManagerInterface::Private *IdleInhibitManagerInterface::d_func() const
{
return reinterpret_cast<Private*>(d.data());
}
}
}

View file

@ -0,0 +1,77 @@
/****************************************************************************
Copyright 2017 Martin Flöser <mgraesslin@kde.org>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) version 3, or any
later version accepted by the membership of KDE e.V. (or its
successor approved by the membership of KDE e.V.), which shall
act as a proxy defined in Section 6 of version 3 of the license.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library. If not, see <http://www.gnu.org/licenses/>.
****************************************************************************/
#ifndef KWAYLAND_SERVER_IDLEINHIBIT_H
#define KWAYLAND_SERVER_IDLEINHIBIT_H
#include "global.h"
#include "resource.h"
#include <KWayland/Server/kwaylandserver_export.h>
namespace KWayland
{
namespace Server
{
class Display;
/**
* Enum describing the interface versions the IdleInhibitManagerInterface can support.
*
* @since 5.41
**/
enum class IdleInhibitManagerInterfaceVersion {
/**
* zwp_idle_inhibit_manager_v1
**/
UnstableV1
};
/**
* The IdleInhibitorManagerInterface is used by clients to inhibit idle on a
* SurfaceInterface. Whether a SurfaceInterface inhibits idle is exposes through
* @link{SurfaceInterface::inhibitsIdle}.
*
* @since 5.41
**/
class KWAYLANDSERVER_EXPORT IdleInhibitManagerInterface : public Global
{
Q_OBJECT
public:
virtual ~IdleInhibitManagerInterface();
/**
* @returns The interface version used by this IdleInhibitManagerInterface
**/
IdleInhibitManagerInterfaceVersion interfaceVersion() const;
protected:
class Private;
explicit IdleInhibitManagerInterface(Private *d, QObject *parent = nullptr);
private:
Private *d_func() const;
};
}
}
#endif

View file

@ -0,0 +1,96 @@
/****************************************************************************
Copyright 2017 Martin Flöser <mgraesslin@kde.org>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) version 3, or any
later version accepted by the membership of KDE e.V. (or its
successor approved by the membership of KDE e.V.), which shall
act as a proxy defined in Section 6 of version 3 of the license.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library. If not, see <http://www.gnu.org/licenses/>.
****************************************************************************/
#ifndef KWAYLAND_SERVER_IDLEINHIBIT_P_H
#define KWAYLAND_SERVER_IDLEINHIBIT_P_H
#include "idleinhibit_interface.h"
#include "global_p.h"
#include "resource_p.h"
#include <wayland-idle-inhibit-unstable-v1-server-protocol.h>
namespace KWayland
{
namespace Server
{
class Q_DECL_HIDDEN IdleInhibitManagerUnstableV1Interface : public IdleInhibitManagerInterface
{
Q_OBJECT
public:
explicit IdleInhibitManagerUnstableV1Interface(Display *display, QObject *parent = nullptr);
~IdleInhibitManagerUnstableV1Interface() override;
private:
class Private;
};
class Q_DECL_HIDDEN IdleInhibitManagerInterface::Private : public Global::Private
{
public:
IdleInhibitManagerInterfaceVersion interfaceVersion;
protected:
Private(IdleInhibitManagerInterface *q, Display *d, const wl_interface *interface, quint32 version, IdleInhibitManagerInterfaceVersion interfaceVersion);
IdleInhibitManagerInterface *q;
};
class Q_DECL_HIDDEN IdleInhibitorInterface : public Resource
{
Q_OBJECT
public:
explicit IdleInhibitorInterface(IdleInhibitManagerInterface *c, wl_resource *parentResource);
virtual ~IdleInhibitorInterface();
/**
* @returns The interface version used by this IdleInhibitorInterface
**/
IdleInhibitManagerInterfaceVersion interfaceVersion() const;
protected:
class Private;
private:
Private *d_func() const;
friend class IdleInhibitManagerUnstableV1Interface;
};
class Q_DECL_HIDDEN IdleInhibitorInterface::Private : public Resource::Private
{
public:
Private(IdleInhibitorInterface *q, IdleInhibitManagerInterface *m, wl_resource *parentResource);
~Private();
private:
IdleInhibitorInterface *q_func() {
return reinterpret_cast<IdleInhibitorInterface *>(q);
}
static const struct zwp_idle_inhibitor_v1_interface s_interface;
};
}
}
#endif

View file

@ -0,0 +1,139 @@
/****************************************************************************
Copyright 2017 Martin Flöser <mgraesslin@kde.org>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) version 3, or any
later version accepted by the membership of KDE e.V. (or its
successor approved by the membership of KDE e.V.), which shall
act as a proxy defined in Section 6 of version 3 of the license.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library. If not, see <http://www.gnu.org/licenses/>.
****************************************************************************/
#include "idleinhibit_interface_p.h"
#include "display.h"
#include "surface_interface_p.h"
namespace KWayland
{
namespace Server
{
class Q_DECL_HIDDEN IdleInhibitManagerUnstableV1Interface::Private : public IdleInhibitManagerInterface::Private
{
public:
Private(IdleInhibitManagerUnstableV1Interface *q, Display *d);
private:
void bind(wl_client *client, uint32_t version, uint32_t id) override;
static void unbind(wl_resource *resource);
static Private *cast(wl_resource *r) {
return reinterpret_cast<Private*>(wl_resource_get_user_data(r));
}
static void destroyCallback(wl_client *client, wl_resource *resource);
static void createInhibitorCallback(wl_client *client, wl_resource *resource, uint32_t id, wl_resource * surface);
static const struct zwp_idle_inhibit_manager_v1_interface s_interface;
static const quint32 s_version;
};
const quint32 IdleInhibitManagerUnstableV1Interface::Private::s_version = 1;
#ifndef DOXYGEN_SHOULD_SKIP_THIS
const struct zwp_idle_inhibit_manager_v1_interface IdleInhibitManagerUnstableV1Interface::Private::s_interface = {
destroyCallback,
createInhibitorCallback
};
#endif
IdleInhibitManagerUnstableV1Interface::Private::Private(IdleInhibitManagerUnstableV1Interface *q, Display *d)
: IdleInhibitManagerInterface::Private(q, d, &zwp_idle_inhibit_manager_v1_interface, s_version, IdleInhibitManagerInterfaceVersion::UnstableV1)
{
}
void IdleInhibitManagerUnstableV1Interface::Private::destroyCallback(wl_client *client, wl_resource *resource)
{
Q_UNUSED(client)
wl_resource_destroy(resource);
}
void IdleInhibitManagerUnstableV1Interface::Private::createInhibitorCallback(wl_client *client, wl_resource *resource, uint32_t id, wl_resource *surface)
{
auto s = SurfaceInterface::get(surface);
if (!s) {
// send error?
return;
}
auto q = cast(resource);
auto inhibitor = new IdleInhibitorInterface(q->q, resource);
inhibitor->d_func()->create(q->display->getConnection(client), version, id);
s->d_func()->installIdleInhibitor(inhibitor);
}
void IdleInhibitManagerUnstableV1Interface::Private::bind(wl_client *client, uint32_t version, uint32_t id)
{
auto c = display->getConnection(client);
wl_resource *resource = c->createResource(&zwp_idle_inhibit_manager_v1_interface, qMin(version, s_version), id);
if (!resource) {
wl_client_post_no_memory(client);
return;
}
wl_resource_set_implementation(resource, &s_interface, this, unbind);
// TODO: should we track?
}
void IdleInhibitManagerUnstableV1Interface::Private::unbind(wl_resource *resource)
{
Q_UNUSED(resource)
// TODO: implement?
}
IdleInhibitManagerUnstableV1Interface::IdleInhibitManagerUnstableV1Interface(Display *display, QObject *parent)
: IdleInhibitManagerInterface(new Private(this, display), parent)
{
}
IdleInhibitManagerUnstableV1Interface::~IdleInhibitManagerUnstableV1Interface() = default;
#ifndef DOXYGEN_SHOULD_SKIP_THIS
const struct zwp_idle_inhibitor_v1_interface IdleInhibitorInterface::Private::s_interface = {
resourceDestroyedCallback
};
#endif
IdleInhibitorInterface::Private::Private(IdleInhibitorInterface *q, IdleInhibitManagerInterface *c, wl_resource *parentResource)
: Resource::Private(q, c, parentResource, &zwp_idle_inhibitor_v1_interface, &s_interface)
{
}
IdleInhibitorInterface::Private::~Private()
{
if (resource) {
wl_resource_destroy(resource);
resource = nullptr;
}
}
IdleInhibitorInterface::IdleInhibitorInterface(IdleInhibitManagerInterface *m, wl_resource *parentResource)
: Resource(new Private(this, m, parentResource))
{
}
IdleInhibitorInterface::~IdleInhibitorInterface() = default;
IdleInhibitorInterface::Private *IdleInhibitorInterface::d_func() const
{
return reinterpret_cast<Private*>(d.data());
}
}
}

View file

@ -22,6 +22,7 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
#include "buffer_interface.h"
#include "clientconnection.h"
#include "compositor_interface.h"
#include "idleinhibit_interface_p.h"
#include "pointerconstraints_interface_p.h"
#include "region_interface.h"
#include "subcompositor_interface.h"
@ -213,6 +214,22 @@ void SurfaceInterface::Private::installPointerConstraint(LockedPointerInterface
emit q_func()->pointerConstraintsChanged();
}
void SurfaceInterface::Private::installIdleInhibitor(IdleInhibitorInterface *inhibitor)
{
idleInhibitors << inhibitor;
QObject::connect(inhibitor, &IdleInhibitorInterface::aboutToBeUnbound, q,
[this, inhibitor] {
idleInhibitors.removeOne(inhibitor);
if (idleInhibitors.isEmpty()) {
emit q_func()->inhibitsIdleChanged();
}
}
);
if (idleInhibitors.count() == 1) {
emit q_func()->inhibitsIdleChanged();
}
}
void SurfaceInterface::Private::installPointerConstraint(ConfinedPointerInterface *confinement)
{
Q_ASSERT(lockedPointer.isNull());
@ -856,6 +873,12 @@ QPointer<ConfinedPointerInterface> SurfaceInterface::confinedPointer() const
return d->confinedPointer;
}
bool SurfaceInterface::inhibitsIdle() const
{
Q_D();
return !d->idleInhibitors.isEmpty();
}
SurfaceInterface::Private *SurfaceInterface::d_func() const
{
return reinterpret_cast<Private*>(d.data());

View file

@ -40,6 +40,7 @@ class ConfinedPointerInterface;
class ContrastInterface;
class ContrastManagerInterface;
class CompositorInterface;
class IdleInhibitManagerUnstableV1Interface;
class LockedPointerInterface;
class PointerConstraintsUnstableV1Interface;
class ShadowManagerInterface;
@ -242,6 +243,13 @@ public:
**/
QPointer<LockedPointerInterface> lockedPointer() const;
/**
* @returns Whether this SurfaceInterface wants idle to be inhibited on the Output it is shown
* @see inhibitsIdleChanged
* @since 5.41
**/
bool inhibitsIdle() const;
/**
* @returns The SurfaceInterface for the @p native resource.
**/
@ -308,6 +316,13 @@ Q_SIGNALS:
**/
void pointerConstraintsChanged();
/**
* Emitted whenever the SurfaceInterface starts/ends to inhibit idle.
* @see inhibitsIdle
* @since 5.41
**/
void inhibitsIdleChanged();
private:
friend class CompositorInterface;
friend class SubSurfaceInterface;
@ -315,6 +330,7 @@ private:
friend class BlurManagerInterface;
friend class SlideManagerInterface;
friend class ContrastManagerInterface;
friend class IdleInhibitManagerUnstableV1Interface;
friend class PointerConstraintsUnstableV1Interface;
explicit SurfaceInterface(CompositorInterface *parent, wl_resource *parentResource);

View file

@ -32,6 +32,8 @@ namespace KWayland
namespace Server
{
class IdleInhibitorInterface;
class SurfaceInterface::Private : public Resource::Private
{
public:
@ -77,6 +79,7 @@ public:
void setSlide(const QPointer<SlideInterface> &slide);
void installPointerConstraint(LockedPointerInterface *lock);
void installPointerConstraint(ConfinedPointerInterface *confinement);
void installIdleInhibitor(IdleInhibitorInterface *inhibitor);
void commitSubSurface();
void commit();
@ -98,6 +101,7 @@ public:
QPointer<LockedPointerInterface> lockedPointer;
QPointer<ConfinedPointerInterface> confinedPointer;
QHash<OutputInterface*, QMetaObject::Connection> outputDestroyedConnections;
QVector<IdleInhibitorInterface*> idleInhibitors;
private:
QMetaObject::Connection constrainsOneShotConnection;

View file

@ -58,3 +58,5 @@ zwp_pointer_gesture_pinch_v1;PointerPinchGestureUnstableV1
zwp_pointer_constraints_v1;PointerConstraints
zwp_locked_pointer_v1;LockedPointer
zwp_confined_pointer_v1;ConfinedPointer
zwp_idle_inhibit_manager_v1;IdleInhibitManager
zwp_idle_inhibitor_v1;IdleInhibitor