// AUTOGENERATED COPYRIGHT HEADER START // Copyright (C) 2023 Michael Fabian 'Xaymar' Dirks // AUTOGENERATED COPYRIGHT HEADER END #include "ui-obs-browser-widget.hpp" #include "warning-disable.hpp" #include #include #include #include #ifdef D_PLATFORM_LINUX #include #include #endif #include "warning-enable.hpp" #include "plugin.hpp" streamfx::ui::obs_browser_cef::obs_browser_cef() { // Load the "obs-browser" module. _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("Failed to load obs-browser module."); } // Create a QCef instance and initialize it. _cef = fn(); if (!_cef) { throw std::runtime_error("Failed to create or get QCef instance."); } _cef->init_browser(); _cef->wait_for_browser_init(); // Create a generic Cookie manager for widgets. _cookie = _cef->create_cookie_manager(streamfx::config_file_path("cookies").u8string(), false); } streamfx::ui::obs_browser_cef::~obs_browser_cef() { delete _cookie; delete _cef; } streamfx::obs::QCef* streamfx::ui::obs_browser_cef::cef() { return _cef; } streamfx::obs::QCefCookieManager* streamfx::ui::obs_browser_cef::cookie_manager() { return _cookie; } std::shared_ptr streamfx::ui::obs_browser_cef::instance() { static std::weak_ptr ptr; static std::mutex lock; std::lock_guard lg(lock); if (!ptr.expired()) { return ptr.lock(); } std::shared_ptr sintance{new obs_browser_cef()}; ptr = sintance; return sintance; } streamfx::ui::obs_browser_widget::obs_browser_widget(QUrl url, QWidget* parent) : QWidget(parent) { // Create Layout auto layout = new QGridLayout(this); layout->setContentsMargins(0, 0, 0, 0); layout->setSpacing(0); // Create CEF Widget _cef = obs_browser_cef::instance(); _widget = _cef->cef()->create_widget(this, url.toString().toStdString(), _cef->cookie_manager()); if (!_widget) { throw std::runtime_error("Failed to create CEF Widget."); } _widget->allowAllPopups(false); _widget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); layout->addWidget(_widget, 0, 0); // This fixes a strange issue where Qt just does not update the size of the QCefWidget. // I do not know why this is, all I know is that this is absolutely necessary for QCefWidget. auto test = new QWidget(this); test->setFixedSize(0, 0); layout->addWidget(test, 1, 0); } streamfx::ui::obs_browser_widget::~obs_browser_widget() {} streamfx::obs::QCefWidget* streamfx::ui::obs_browser_widget::cefwidget() { return _widget; } void streamfx::ui::obs_browser_widget::set_url(QUrl url) { _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; }