133 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			133 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			C++
		
	
	
	
| // AUTOGENERATED COPYRIGHT HEADER START
 | |
| // Copyright (C) 2023 Michael Fabian 'Xaymar' Dirks <info@xaymar.com>
 | |
| // AUTOGENERATED COPYRIGHT HEADER END
 | |
| 
 | |
| #include "ui-obs-browser-widget.hpp"
 | |
| 
 | |
| #include "warning-disable.hpp"
 | |
| #include <QGridLayout>
 | |
| #include <QLabel>
 | |
| 
 | |
| #include <mutex>
 | |
| #include <stdexcept>
 | |
| #ifdef D_PLATFORM_LINUX
 | |
| #include <errno.h>
 | |
| #include <stdlib.h>
 | |
| #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<streamfx::obs::QCef* (*)(void)>(_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> streamfx::ui::obs_browser_cef::instance()
 | |
| {
 | |
| 	static std::weak_ptr<obs_browser_cef> ptr;
 | |
| 	static std::mutex                     lock;
 | |
| 
 | |
| 	std::lock_guard<decltype(lock)> lg(lock);
 | |
| 	if (!ptr.expired()) {
 | |
| 		return ptr.lock();
 | |
| 	}
 | |
| 
 | |
| 	std::shared_ptr<obs_browser_cef> 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;
 | |
| }
 |