From 5d4197f0a6f08e8c1e8a68aca7bcc7cd4306d682 Mon Sep 17 00:00:00 2001 From: Clayton Groeneveld Date: Sun, 17 Jan 2021 01:38:53 -0600 Subject: [PATCH 1/2] Use new module function to find obs-browser lib Requires https://github.com/obsproject/obs-studio/pull/3871 --- panel/browser-panel.hpp | 41 ++++++++++++++++++++++++++--------------- 1 file changed, 26 insertions(+), 15 deletions(-) diff --git a/panel/browser-panel.hpp b/panel/browser-panel.hpp index b0b5b0931..fe209d816 100644 --- a/panel/browser-panel.hpp +++ b/panel/browser-panel.hpp @@ -1,5 +1,6 @@ #pragma once +#include #include #include #include @@ -72,36 +73,46 @@ struct QCef { QObject *obj) = 0; }; -static inline void *obs_browser_dlsym(const char *name) +static inline void *get_browser_lib() { -#if defined(_WIN32) - void *lib = os_dlopen("obs-browser"); -#elif defined(__APPLE__) - void *lib = RTLD_DEFAULT; -#else - void *lib = os_dlopen("../obs-plugins/obs-browser"); -#endif - if (!lib) { + obs_module_t *browserModule = obs_get_module("obs-browser"); + + if (!browserModule) return nullptr; - } - return os_dlsym(lib, name); + return obs_get_module_lib(browserModule); } static inline QCef *obs_browser_init_panel(void) { - QCef *(*create_qcef)(void) = (decltype(create_qcef))obs_browser_dlsym( - "obs_browser_create_qcef"); + void *lib = get_browser_lib(); + QCef *(*create_qcef)(void) = nullptr; + + if (!lib) + return nullptr; + + create_qcef = + (decltype(create_qcef))os_dlsym(lib, "obs_browser_create_qcef"); + if (!create_qcef) return nullptr; + return create_qcef(); } static inline int obs_browser_qcef_version(void) { - int (*qcef_version)(void) = (decltype(qcef_version))obs_browser_dlsym( - "obs_browser_qcef_version_export"); + void *lib = get_browser_lib(); + int (*qcef_version)(void) = nullptr; + + if (!lib) + return 0; + + qcef_version = (decltype(qcef_version))os_dlsym( + lib, "obs_browser_qcef_version_export"); + if (!qcef_version) return 0; + return qcef_version(); } From 3cd1a98d52950aa8ef7bb341164c4117801abf12 Mon Sep 17 00:00:00 2001 From: Clayton Groeneveld Date: Sun, 17 Jan 2021 01:39:23 -0600 Subject: [PATCH 2/2] Add Linux browser panel support This adds browser panel and service integration support to Linux. --- CMakeLists.txt | 4 +- panel/browser-panel-internal.hpp | 2 + panel/browser-panel.cpp | 84 +++++++++++++++++++++++--------- 3 files changed, 64 insertions(+), 26 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index caf483fd6..9a8508a9a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -137,9 +137,7 @@ if (APPLE) ) endif() -# only allow browser panels on win32 for now -- other operating systems -# need more testing -if((WIN32 OR APPLE) AND BROWSER_PANEL_SUPPORT_ENABLED) +if(BROWSER_PANEL_SUPPORT_ENABLED) list(APPEND obs-browser_SOURCES panel/browser-panel.cpp panel/browser-panel-client.cpp diff --git a/panel/browser-panel-internal.hpp b/panel/browser-panel-internal.hpp index 55df3db20..c9dd54e63 100644 --- a/panel/browser-panel-internal.hpp +++ b/panel/browser-panel-internal.hpp @@ -55,6 +55,8 @@ class QCefWidgetInternal : public QCefWidget { std::string script; CefRefPtr rqc; QTimer timer; + QPointer window; + QPointer container; bool allowAllPopups_ = false; virtual void resizeEvent(QResizeEvent *event) override; diff --git a/panel/browser-panel.cpp b/panel/browser-panel.cpp index 7d4a08e91..785542da4 100644 --- a/panel/browser-panel.cpp +++ b/panel/browser-panel.cpp @@ -20,6 +20,10 @@ #include #include +#if !defined(_WIN32) && !defined(__APPLE__) +#include +#endif + extern bool QueueCEFTask(std::function task); extern "C" void obs_browser_initialize(void); extern os_event_t *cef_started_event; @@ -86,6 +90,7 @@ struct QCefCookieManagerInternal : QCefCookieManager { BPtr rpath = obs_module_config_path(storage_path.c_str()); if (os_mkdirs(rpath.Get()) == MKDIR_ERROR) throw "Failed to create cookie directory"; + BPtr path = os_get_abs_path_ptr(rpath.Get()); #if CHROME_VERSION_BUILD < 3770 @@ -171,6 +176,9 @@ QCefWidgetInternal::QCefWidgetInternal(QWidget *parent, const std::string &url_, setAttribute(Qt::WA_NativeWindow); setFocusPolicy(Qt::ClickFocus); + + window = new QWindow(); + window->setFlags(Qt::FramelessWindowHint); } QCefWidgetInternal::~QCefWidgetInternal() @@ -231,28 +239,28 @@ void QCefWidgetInternal::closeBrowser() void QCefWidgetInternal::Init() { - WId id = winId(); + WId handle = window->winId(); - bool success = QueueCEFTask([this, id]() { + QSize size = this->size(); +#ifdef SUPPORTS_FRACTIONAL_SCALING + size *= devicePixelRatioF(); +#else + size *= devicePixelRatio(); +#endif + + bool success = QueueCEFTask([this, handle, size]() { CefWindowInfo windowInfo; /* Make sure Init isn't called more than once. */ if (cefBrowser) return; - QSize size = this->size(); #ifdef _WIN32 -#ifdef SUPPORTS_FRACTIONAL_SCALING - size *= devicePixelRatioF(); -#elif - size *= devicePixelRatio(); -#endif RECT rc = {0, 0, size.width(), size.height()}; - windowInfo.SetAsChild((HWND)id, rc); -#elif __APPLE__ - windowInfo.SetAsChild((CefWindowHandle)id, 0, 0, size.width(), - size.height()); +#else + CefRect rc = {0, 0, size.width(), size.height()}; #endif + windowInfo.SetAsChild((CefWindowHandle)handle, rc); CefRefPtr browserClient = new QCefBrowserClient(this, script, allowAllPopups_); @@ -264,13 +272,19 @@ void QCefWidgetInternal::Init() CefRefPtr(), #endif rqc); -#ifdef _WIN32 - Resize(); -#endif }); - if (success) + if (success) { timer.stop(); + + if (!container) { + container = + QWidget::createWindowContainer(window, this); + container->show(); + } + + Resize(); + } } void QCefWidgetInternal::resizeEvent(QResizeEvent *event) @@ -281,23 +295,47 @@ void QCefWidgetInternal::resizeEvent(QResizeEvent *event) void QCefWidgetInternal::Resize() { -#ifdef _WIN32 #ifdef SUPPORTS_FRACTIONAL_SCALING QSize size = this->size() * devicePixelRatioF(); -#elif +#else QSize size = this->size() * devicePixelRatio(); #endif - QueueCEFTask([this, size]() { + bool success = QueueCEFTask([this, size]() { if (!cefBrowser) return; - HWND hwnd = cefBrowser->GetHost()->GetWindowHandle(); - SetWindowPos(hwnd, nullptr, 0, 0, size.width(), size.height(), + + CefWindowHandle handle = + cefBrowser->GetHost()->GetWindowHandle(); + + if (!handle) + return; + +#ifdef _WIN32 + SetWindowPos((HWND)handle, nullptr, 0, 0, size.width(), + size.height(), SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOZORDER); - SendMessage(hwnd, WM_SIZE, 0, + SendMessage((HWND)handle, WM_SIZE, 0, MAKELPARAM(size.width(), size.height())); - }); +#elif __APPLE__ +#else + Display *xDisplay = cef_get_xdisplay(); + + if (!xDisplay) + return; + + XWindowChanges changes = {0}; + changes.x = 0; + changes.y = 0; + changes.width = size.width(); + changes.height = size.height(); + XConfigureWindow(xDisplay, (Window)handle, + CWX | CWY | CWHeight | CWWidth, &changes); #endif + }); + + if (success && container) + container->resize(size.width(), size.height()); } void QCefWidgetInternal::showEvent(QShowEvent *event)