File indexing completed on 2024-05-19 16:34:58

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 <kwinglobals.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(fieldName).toStringList();
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 fetchRequestedInterfaces(const QString &executablePath)
0054 {
0055     return fetchProcessServiceField(executablePath, s_waylandInterfaceName);
0056 }
0057 
0058 static inline QStringList fetchRestrictedDBusInterfacesFromPid(const uint pid)
0059 {
0060     const auto executablePath = QFileInfo(QStringLiteral("/proc/%1/exe").arg(pid)).symLinkTarget();
0061     return fetchProcessServiceField(executablePath, s_dbusRestrictedInterfaceName);
0062 }
0063 
0064 } // namespace