mirror of
https://github.com/WarmUpTill/SceneSwitcher.git
synced 2026-09-07 09:05:57 -05:00
Adaptitions for kWin support on Flatpak
This commit is contained in:
@@ -1,5 +1,16 @@
|
||||
#include "platform-funcs.hpp"
|
||||
|
||||
#include "log-helper.hpp"
|
||||
#include "obs-module-helper.hpp"
|
||||
#include "plugin-state-helpers.hpp"
|
||||
#include "ui-helpers.hpp"
|
||||
|
||||
#include <obs-frontend-api.h>
|
||||
#include <QCheckBox>
|
||||
#include <QFontDatabase>
|
||||
#include <QGridLayout>
|
||||
#include <QLineEdit>
|
||||
#include <QMessageBox>
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xatom.h>
|
||||
@@ -628,27 +639,108 @@ int ignoreXerror(Display *d, XErrorEvent *e)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool warnAboutWindowDetectionUnavailable = true;
|
||||
|
||||
static bool setupWindowDetectionWarningPersistence = []() {
|
||||
AddSaveStep([](obs_data_t *obj) {
|
||||
obs_data_set_bool(obj, "warnAboutFlatpakWindowDetection",
|
||||
warnAboutWindowDetectionUnavailable);
|
||||
});
|
||||
AddLoadStep([](obs_data_t *obj) {
|
||||
obs_data_set_default_bool(
|
||||
obj, "warnAboutFlatpakWindowDetection", true);
|
||||
warnAboutWindowDetectionUnavailable = obs_data_get_bool(
|
||||
obj, "warnAboutFlatpakWindowDetection");
|
||||
});
|
||||
return true;
|
||||
}();
|
||||
|
||||
static void showWindowDetectionWarning(const char *messageId,
|
||||
const char *command)
|
||||
{
|
||||
auto mainWindow =
|
||||
static_cast<QWidget *>(obs_frontend_get_main_window());
|
||||
QMessageBox msgBox(QMessageBox::Warning,
|
||||
obs_module_text("AdvSceneSwitcher.pluginName"),
|
||||
obs_module_text(messageId), QMessageBox::Ok,
|
||||
mainWindow);
|
||||
|
||||
if (command) {
|
||||
auto commandLineEdit = new QLineEdit(command, &msgBox);
|
||||
commandLineEdit->setReadOnly(true);
|
||||
commandLineEdit->setFont(
|
||||
QFontDatabase::systemFont(QFontDatabase::FixedFont));
|
||||
commandLineEdit->setCursorPosition(0);
|
||||
auto layout = qobject_cast<QGridLayout *>(msgBox.layout());
|
||||
if (layout) {
|
||||
layout->addWidget(commandLineEdit, layout->rowCount(),
|
||||
0, 1, layout->columnCount());
|
||||
}
|
||||
}
|
||||
|
||||
auto checkbox = new QCheckBox(obs_module_text(
|
||||
"AdvSceneSwitcher.flatpakWindowDetectionWarning.doNotShowAgain"));
|
||||
msgBox.setCheckBox(checkbox);
|
||||
msgBox.exec();
|
||||
warnAboutWindowDetectionUnavailable = !checkbox->isChecked();
|
||||
}
|
||||
|
||||
static void handleWindowDetectionUnavailable(bool hasX11)
|
||||
{
|
||||
if (hasX11 || KWin) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!qEnvironmentVariableIsSet("FLATPAK_ID")) {
|
||||
return;
|
||||
}
|
||||
|
||||
const bool onKDE = qEnvironmentVariable("XDG_CURRENT_DESKTOP")
|
||||
.contains("KDE", Qt::CaseInsensitive);
|
||||
const char *messageId =
|
||||
onKDE ? "AdvSceneSwitcher.kwin.flatpakPermissionWarning"
|
||||
: "AdvSceneSwitcher.wayland.flatpakPermissionWarning";
|
||||
const char *command =
|
||||
onKDE ? "flatpak override --user --talk-name=org.kde.KWin com.obsproject.Studio"
|
||||
: nullptr;
|
||||
|
||||
blog(LOG_WARNING,
|
||||
"window detection unavailable: OBS Flatpak sandbox has no X11 "
|
||||
"access on this Wayland session and %s",
|
||||
onKDE ? "the KWin D-Bus compat call was blocked (missing "
|
||||
"'org.kde.KWin' talk-name permission)"
|
||||
: "no compatible native Wayland integration exists for "
|
||||
"this desktop");
|
||||
|
||||
AddFinishedLoadingStep([messageId, command]() {
|
||||
if (!warnAboutWindowDetectionUnavailable) {
|
||||
return;
|
||||
}
|
||||
showWindowDetectionWarning(messageId, command);
|
||||
});
|
||||
}
|
||||
|
||||
void PlatformInit()
|
||||
{
|
||||
const bool kwinAvailable = isKWinAvailable();
|
||||
KWin = kwinAvailable && registerKWinDBusListener(¬ifier) &&
|
||||
startKWinScript(KWinScriptObjectPath);
|
||||
if (KWin) {
|
||||
blog(LOG_INFO, "using KWin compat");
|
||||
} else {
|
||||
blog(LOG_INFO, "not using KWin compat");
|
||||
}
|
||||
|
||||
initProcps();
|
||||
initProc2();
|
||||
|
||||
auto display = disp();
|
||||
handleWindowDetectionUnavailable(display != nullptr);
|
||||
if (!display) {
|
||||
return;
|
||||
}
|
||||
|
||||
KWin = isKWinAvailable();
|
||||
if (!(KWin && startKWinScript(KWinScriptObjectPath) &&
|
||||
registerKWinDBusListener(¬ifier))) {
|
||||
// something bad happened while trying to initialize
|
||||
// the KWin script/dbus so disable it
|
||||
KWin = false;
|
||||
blog(LOG_INFO, "not using KWin compat");
|
||||
} else {
|
||||
blog(LOG_INFO, "using KWin compat");
|
||||
}
|
||||
|
||||
initXss();
|
||||
initProcps();
|
||||
initProc2();
|
||||
XSetErrorHandler(ignoreXerror);
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
#include <QFileDevice>
|
||||
#include <QStandardPaths>
|
||||
#include <QTextStream>
|
||||
#include <QtDBus/QDBusConnectionInterface>
|
||||
#include <QtDBus/QDBusInterface>
|
||||
@@ -96,12 +97,16 @@ bool isKWinAvailable()
|
||||
|
||||
bool startKWinScript(QString &scriptObjectPath)
|
||||
{
|
||||
// Not RuntimeLocation: under Flatpak, $XDG_RUNTIME_DIR is private to
|
||||
// the sandbox, so the unsandboxed KWin process can't read it back.
|
||||
const QString scriptPath =
|
||||
"/tmp/AdvancedSceneSwitcher/KWinFocusNotifier.js";
|
||||
QStandardPaths::writableLocation(
|
||||
QStandardPaths::CacheLocation) +
|
||||
"/AdvancedSceneSwitcher/KWinFocusNotifier.js";
|
||||
|
||||
const QString script =
|
||||
R"(var adss = "com.github.AdvancedSceneSwitcher";
|
||||
var adssPath = "/com/github/AdvancedSceneSwitcher";
|
||||
R"(var adss = "com.obsproject.Studio.Plugin.SceneSwitcher";
|
||||
var adssPath = "/com/obsproject/Studio/Plugin/SceneSwitcher";
|
||||
|
||||
function trackWindow(window) {
|
||||
var id = window.internalId.toString();
|
||||
@@ -129,7 +134,8 @@ workspace.windowActivated.connect(function(client) {
|
||||
}))";
|
||||
|
||||
if (const QDir dir; !dir.mkpath(QFileInfo(scriptPath).absolutePath())) {
|
||||
blog(LOG_ERROR, "error creating /tmp/AdvancedSceneSwitcher");
|
||||
blog(LOG_ERROR,
|
||||
"error creating KWinFocusNotifier script directory");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -198,8 +204,10 @@ bool stopKWinScript(const QString &scriptObjectPath)
|
||||
|
||||
bool registerKWinDBusListener(FocusNotifier *notifier)
|
||||
{
|
||||
static const QString serviceName = "com.github.AdvancedSceneSwitcher";
|
||||
static const QString objectPath = "/com/github/AdvancedSceneSwitcher";
|
||||
static const QString serviceName =
|
||||
"com.obsproject.Studio.Plugin.SceneSwitcher";
|
||||
static const QString objectPath =
|
||||
"/com/obsproject/Studio/Plugin/SceneSwitcher";
|
||||
auto bus = QDBusConnection::sessionBus();
|
||||
|
||||
if (bus.objectRegisteredAt(objectPath)) {
|
||||
|
||||
@@ -12,7 +12,8 @@ namespace advss {
|
||||
|
||||
class FocusNotifier final : public QObject {
|
||||
Q_OBJECT
|
||||
Q_CLASSINFO("D-Bus Interface", "com.github.AdvancedSceneSwitcher")
|
||||
Q_CLASSINFO("D-Bus Interface",
|
||||
"com.obsproject.Studio.Plugin.SceneSwitcher")
|
||||
|
||||
static std::mutex _mutex;
|
||||
static int activePID;
|
||||
|
||||
Reference in New Issue
Block a user