From d0738891263560888317f4c5b718be4dd5ed8f37 Mon Sep 17 00:00:00 2001 From: Michael Fabian 'Xaymar' Dirks Date: Thu, 9 Mar 2023 15:36:53 +0100 Subject: [PATCH] ui/obs-browser-widget: Prevent unwanted crashes or corruptions on Wayland The obs-browser module does not work well on Wayland, so removing it there appears to be the best option for now. --- source/ui/ui-obs-browser-widget.cpp | 37 +++++++++++++++++++++++++---- source/ui/ui-obs-browser-widget.hpp | 3 +++ source/ui/ui.cpp | 9 +++++-- 3 files changed, 43 insertions(+), 6 deletions(-) diff --git a/source/ui/ui-obs-browser-widget.cpp b/source/ui/ui-obs-browser-widget.cpp index fd1b9dca..23a28844 100644 --- a/source/ui/ui-obs-browser-widget.cpp +++ b/source/ui/ui-obs-browser-widget.cpp @@ -6,9 +6,13 @@ #include "plugin.hpp" #include "warning-disable.hpp" -#include - #include <../plugins/obs-browser/panel/browser-panel.hpp> + +#include +#ifdef D_PLATFORM_LINUX +#include +#include +#endif #include "warning-enable.hpp" streamfx::ui::obs_browser_cef::obs_browser_cef() @@ -17,13 +21,13 @@ streamfx::ui::obs_browser_cef::obs_browser_cef() _module = util::library::load(obs_get_module("obs-browser")); auto fn = reinterpret_cast(_module->load_symbol("obs_browser_create_qcef")); if (!fn) { - throw std::runtime_error("Unable to create Browser Panel."); + throw std::runtime_error("Failed to load obs-browser module."); } // Create a QCef instance and initialize it. _cef = fn(); if (!_cef) { - throw std::runtime_error("Unable to initialize for CEF-based Browser Panel."); + throw std::runtime_error("Failed to create or get QCef instance."); } reinterpret_cast(_cef)->init_browser(); reinterpret_cast(_cef)->wait_for_browser_init(); @@ -91,3 +95,28 @@ void streamfx::ui::obs_browser_widget::set_url(QUrl url) { dynamic_cast(_widget)->setURL(url.toString().toStdString()); } + +bool streamfx::ui::obs_browser_widget::is_available() +{ +#ifdef D_PLATFORM_LINUX + const char env_key[] = "XDG_SESSION_TYPE"; + const char wayland[] = "wayland"; +#ifdef __STDC_LIB_EXT1__ + char env_value[2048]; + size_t env_value_len = sizeof(env_value); + if (getenv_s(&env_value_len, env_value, sizeof(env_key), env_key) == 0) { + if (sizeof(wayland) == env_value_len) { + if (strncmp(wayland, env_value, sizeof(wayland)) == 0) { + return false; + } + } + } +#else + const char* env_value = getenv(env_key); + if (strncmp(env_value, wayland, sizeof(wayland)) == 0) { + return false; + } +#endif +#endif + return true; +} diff --git a/source/ui/ui-obs-browser-widget.hpp b/source/ui/ui-obs-browser-widget.hpp index c148ded9..47dca163 100644 --- a/source/ui/ui-obs-browser-widget.hpp +++ b/source/ui/ui-obs-browser-widget.hpp @@ -45,5 +45,8 @@ namespace streamfx::ui { virtual ~obs_browser_widget(); void set_url(QUrl url); + + public: + static bool is_available(); }; } // namespace streamfx::ui diff --git a/source/ui/ui.cpp b/source/ui/ui.cpp index 0a2ab673..ffe74fa1 100644 --- a/source/ui/ui.cpp +++ b/source/ui/ui.cpp @@ -110,8 +110,13 @@ void streamfx::ui::handler::on_obs_loaded() _translator = new streamfx::ui::translator(this); QCoreApplication::installTranslator(_translator); - // Pre-load CEF. - _obs_browser_cef = streamfx::ui::obs_browser_cef::instance(); + // Pre-load CEF if available. + if (streamfx::ui::obs_browser_widget::is_available()) { + try { + _obs_browser_cef = streamfx::ui::obs_browser_cef::instance(); + } catch (...) { + } + } // Create the 'About StreamFX' dialog. _about_dialog = new streamfx::ui::about();