File indexing completed on 2024-04-28 16:48:48

0001 /*
0002     KWin - the KDE window manager
0003     This file is part of the KDE project.
0004 
0005     SPDX-FileCopyrightText: 2017 Martin Flöser <mgraesslin@kde.org>
0006     SPDX-FileCopyrightText: 2018 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
0007 
0008     SPDX-License-Identifier: GPL-2.0-or-later
0009 */
0010 #include "idle_inhibition.h"
0011 #include "deleted.h"
0012 #include "input.h"
0013 #include "wayland/surface_interface.h"
0014 #include "window.h"
0015 #include "workspace.h"
0016 
0017 #include <algorithm>
0018 #include <functional>
0019 
0020 using KWaylandServer::SurfaceInterface;
0021 
0022 namespace KWin
0023 {
0024 
0025 IdleInhibition::IdleInhibition(QObject *parent)
0026     : QObject(parent)
0027 {
0028     // Workspace is created after the wayland server is initialized.
0029     connect(kwinApp(), &Application::workspaceCreated, this, &IdleInhibition::slotWorkspaceCreated);
0030 }
0031 
0032 IdleInhibition::~IdleInhibition() = default;
0033 
0034 void IdleInhibition::registerClient(Window *client)
0035 {
0036     auto updateInhibit = [this, client] {
0037         update(client);
0038     };
0039 
0040     m_connections[client] = connect(client->surface(), &SurfaceInterface::inhibitsIdleChanged, this, updateInhibit);
0041     connect(client, &Window::desktopChanged, this, updateInhibit);
0042     connect(client, &Window::clientMinimized, this, updateInhibit);
0043     connect(client, &Window::clientUnminimized, this, updateInhibit);
0044     connect(client, &Window::windowHidden, this, updateInhibit);
0045     connect(client, &Window::windowShown, this, updateInhibit);
0046     connect(client, &Window::windowClosed, this, [this, client]() {
0047         uninhibit(client);
0048         auto it = m_connections.find(client);
0049         if (it != m_connections.end()) {
0050             disconnect(it.value());
0051             m_connections.erase(it);
0052         }
0053     });
0054 
0055     updateInhibit();
0056 }
0057 
0058 void IdleInhibition::inhibit(Window *client)
0059 {
0060     input()->addIdleInhibitor(client);
0061     // TODO: notify powerdevil?
0062 }
0063 
0064 void IdleInhibition::uninhibit(Window *client)
0065 {
0066     input()->removeIdleInhibitor(client);
0067 }
0068 
0069 void IdleInhibition::update(Window *client)
0070 {
0071     if (client->isInternal()) {
0072         return;
0073     }
0074 
0075     // TODO: Don't honor the idle inhibitor object if the shell client is not
0076     // on the current activity (currently, activities are not supported).
0077     const bool visible = client->isShown() && client->isOnCurrentDesktop();
0078     if (visible && client->surface() && client->surface()->inhibitsIdle()) {
0079         inhibit(client);
0080     } else {
0081         uninhibit(client);
0082     }
0083 }
0084 
0085 void IdleInhibition::slotWorkspaceCreated()
0086 {
0087     connect(workspace(), &Workspace::currentDesktopChanged, this, &IdleInhibition::slotDesktopChanged);
0088 }
0089 
0090 void IdleInhibition::slotDesktopChanged()
0091 {
0092     workspace()->forEachAbstractClient([this](Window *c) {
0093         update(c);
0094     });
0095 }
0096 
0097 }