File indexing completed on 2024-11-10 04:57:45
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 "input.h" 0012 #include "virtualdesktops.h" 0013 #include "wayland/surface.h" 0014 #include "window.h" 0015 #include "workspace.h" 0016 0017 #include <algorithm> 0018 #include <functional> 0019 0020 namespace KWin 0021 { 0022 0023 IdleInhibition::IdleInhibition(QObject *parent) 0024 : QObject(parent) 0025 { 0026 // Workspace is created after the wayland server is initialized. 0027 connect(kwinApp(), &Application::workspaceCreated, this, &IdleInhibition::slotWorkspaceCreated); 0028 } 0029 0030 IdleInhibition::~IdleInhibition() = default; 0031 0032 void IdleInhibition::registerClient(Window *client) 0033 { 0034 if (!client->surface()) { 0035 return; 0036 } 0037 0038 auto updateInhibit = [this, client] { 0039 update(client); 0040 }; 0041 0042 m_connections[client] = connect(client->surface(), &SurfaceInterface::inhibitsIdleChanged, this, updateInhibit); 0043 connect(client, &Window::desktopsChanged, this, updateInhibit); 0044 connect(client, &Window::minimizedChanged, this, updateInhibit); 0045 connect(client, &Window::windowHidden, this, updateInhibit); 0046 connect(client, &Window::windowShown, this, updateInhibit); 0047 connect(client, &Window::closed, this, [this, client]() { 0048 uninhibit(client); 0049 auto it = m_connections.find(client); 0050 if (it != m_connections.end()) { 0051 disconnect(it.value()); 0052 m_connections.erase(it); 0053 } 0054 }); 0055 0056 updateInhibit(); 0057 } 0058 0059 void IdleInhibition::inhibit(Window *client) 0060 { 0061 input()->addIdleInhibitor(client); 0062 // TODO: notify powerdevil? 0063 } 0064 0065 void IdleInhibition::uninhibit(Window *client) 0066 { 0067 input()->removeIdleInhibitor(client); 0068 } 0069 0070 void IdleInhibition::update(Window *client) 0071 { 0072 if (client->isInternal() || client->isUnmanaged()) { 0073 return; 0074 } 0075 0076 // TODO: Don't honor the idle inhibitor object if the shell client is not 0077 // on the current activity (currently, activities are not supported). 0078 const bool visible = client->isShown() && client->isOnCurrentDesktop(); 0079 if (visible && client->surface() && client->surface()->inhibitsIdle()) { 0080 inhibit(client); 0081 } else { 0082 uninhibit(client); 0083 } 0084 } 0085 0086 void IdleInhibition::slotWorkspaceCreated() 0087 { 0088 connect(workspace(), &Workspace::windowAdded, this, &IdleInhibition::registerClient); 0089 connect(workspace(), &Workspace::currentDesktopChanged, this, &IdleInhibition::slotDesktopChanged); 0090 } 0091 0092 void IdleInhibition::slotDesktopChanged() 0093 { 0094 workspace()->forEachWindow([this](Window *c) { 0095 update(c); 0096 }); 0097 } 0098 0099 } 0100 0101 #include "moc_idle_inhibition.cpp"