File indexing completed on 2025-02-16 11:23:08
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 }