File indexing completed on 2024-05-19 05:32:29

0001 /*
0002     KWin - the KDE window manager
0003     This file is part of the KDE project.
0004 
0005     SPDX-FileCopyrightText: 2020 Méven Car <meven.car@enioka.com>
0006 
0007     SPDX-License-Identifier: GPL-2.0-or-later
0008 */
0009 
0010 #pragma once
0011 
0012 // cmake stuff
0013 #include <config-kwin.h>
0014 // kwin
0015 #include "effect/globals.h"
0016 // Qt
0017 #include <QFileInfo>
0018 #include <QLoggingCategory>
0019 #include <QProcess>
0020 // KF
0021 #include <KApplicationTrader>
0022 
0023 namespace KWin
0024 {
0025 
0026 const static QString s_waylandInterfaceName = QStringLiteral("X-KDE-Wayland-Interfaces");
0027 const static QString s_dbusRestrictedInterfaceName = QStringLiteral("X-KDE-DBUS-Restricted-Interfaces");
0028 
0029 static QStringList fetchProcessServiceField(const QString &executablePath, const QString &fieldName)
0030 {
0031     // needed to be able to use the logging category in a header static function
0032     static QLoggingCategory KWIN_UTILS("KWIN_UTILS", QtWarningMsg);
0033     const auto servicesFound = KApplicationTrader::query([&executablePath](const KService::Ptr &service) {
0034         const auto splitCommandList = QProcess::splitCommand(service->exec());
0035         if (splitCommandList.isEmpty()) {
0036             return false;
0037         }
0038         return QFileInfo(splitCommandList.first()).canonicalFilePath() == executablePath;
0039     });
0040 
0041     if (servicesFound.isEmpty()) {
0042         qCDebug(KWIN_UTILS) << "Could not find the desktop file for" << executablePath;
0043         return {};
0044     }
0045 
0046     const auto fieldValues = servicesFound.first()->property<QStringList>(fieldName);
0047     if (KWIN_UTILS().isDebugEnabled()) {
0048         qCDebug(KWIN_UTILS) << "Interfaces found for" << executablePath << fieldName << ":" << fieldValues;
0049     }
0050     return fieldValues;
0051 }
0052 
0053 static inline QStringList fetchRequestedInterfacesForDesktopId(const QString &desktopId)
0054 {
0055     const auto service = KService::serviceByDesktopName(desktopId);
0056     if (!service) {
0057         return {};
0058     }
0059     return service->property<QStringList>(s_waylandInterfaceName);
0060 }
0061 
0062 static inline QStringList fetchRequestedInterfaces(const QString &executablePath)
0063 {
0064     return fetchProcessServiceField(executablePath, s_waylandInterfaceName);
0065 }
0066 
0067 static inline QStringList fetchRestrictedDBusInterfacesFromPid(const uint pid)
0068 {
0069     const auto executablePath = QFileInfo(QStringLiteral("/proc/%1/exe").arg(pid)).symLinkTarget();
0070     return fetchProcessServiceField(executablePath, s_dbusRestrictedInterfaceName);
0071 }
0072 
0073 } // namespace