kwin/src/idle_inhibition.cpp
Vlad Zahorodnii a6d72d3f60 wayland: Introduce IdleDetector
The IdleDetector is an idle detection helper. Its purpose is to reduce
code duplication in our private KIdleTime plugin and the idle wayland
protocol, and make user activity simulation less error prone.
2022-06-29 20:27:50 +03:00

97 lines
2.6 KiB
C++

/*
KWin - the KDE window manager
This file is part of the KDE project.
SPDX-FileCopyrightText: 2017 Martin Flöser <mgraesslin@kde.org>
SPDX-FileCopyrightText: 2018 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "idle_inhibition.h"
#include "deleted.h"
#include "input.h"
#include "wayland/surface_interface.h"
#include "window.h"
#include "workspace.h"
#include <algorithm>
#include <functional>
using KWaylandServer::SurfaceInterface;
namespace KWin
{
IdleInhibition::IdleInhibition(QObject *parent)
: QObject(parent)
{
// Workspace is created after the wayland server is initialized.
connect(kwinApp(), &Application::workspaceCreated, this, &IdleInhibition::slotWorkspaceCreated);
}
IdleInhibition::~IdleInhibition() = default;
void IdleInhibition::registerClient(Window *client)
{
auto updateInhibit = [this, client] {
update(client);
};
m_connections[client] = connect(client->surface(), &SurfaceInterface::inhibitsIdleChanged, this, updateInhibit);
connect(client, &Window::desktopChanged, this, updateInhibit);
connect(client, &Window::clientMinimized, this, updateInhibit);
connect(client, &Window::clientUnminimized, this, updateInhibit);
connect(client, &Window::windowHidden, this, updateInhibit);
connect(client, &Window::windowShown, this, updateInhibit);
connect(client, &Window::windowClosed, this, [this, client]() {
uninhibit(client);
auto it = m_connections.find(client);
if (it != m_connections.end()) {
disconnect(it.value());
m_connections.erase(it);
}
});
updateInhibit();
}
void IdleInhibition::inhibit(Window *client)
{
input()->addIdleInhibitor(client);
// TODO: notify powerdevil?
}
void IdleInhibition::uninhibit(Window *client)
{
input()->removeIdleInhibitor(client);
}
void IdleInhibition::update(Window *client)
{
if (client->isInternal()) {
return;
}
// TODO: Don't honor the idle inhibitor object if the shell client is not
// on the current activity (currently, activities are not supported).
const bool visible = client->isShown() && client->isOnCurrentDesktop();
if (visible && client->surface() && client->surface()->inhibitsIdle()) {
inhibit(client);
} else {
uninhibit(client);
}
}
void IdleInhibition::slotWorkspaceCreated()
{
connect(workspace(), &Workspace::currentDesktopChanged, this, &IdleInhibition::slotDesktopChanged);
}
void IdleInhibition::slotDesktopChanged()
{
workspace()->forEachAbstractClient([this](Window *c) {
update(c);
});
}
}