Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 74 additions & 0 deletions UI/api-interface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@

#include <functional>

#ifdef ENABLE_WAYLAND
#include <obs-nix-platform.h>
#endif

using namespace std;

Q_DECLARE_METATYPE(OBSScene);
Expand Down Expand Up @@ -445,6 +449,76 @@ struct OBSStudioAPI : obs_frontend_callbacks {
return true;
}

bool obs_frontend_is_browser_available(void) override
{
#ifdef BROWSER_AVAILABLE
#ifdef ENABLE_WAYLAND
return (obs_get_nix_platform() != OBS_NIX_PLATFORM_WAYLAND);
#else
return true;
#endif
#else
return false;
#endif
}

bool obs_frontend_add_browser_dock(
const char *id, const char *title,
struct obs_frontend_browser_params *params) override
{
#ifdef BROWSER_AVAILABLE
if (!obs_frontend_is_browser_available())
return false;

if (main->IsDockObjectNameUsed(QT_UTF8(id))) {
blog(LOG_WARNING,
"Dock id '%s' already used! "
"Duplicate library?",
id);
return false;
}

PluginBrowserParams dock;
dock.id = QT_UTF8(id);
dock.title = QT_UTF8(title);

dock.url = QT_UTF8(params->url);

for (size_t i = 0; i < params->force_popup_urls.num; i++)
dock.forcePopupUrls.append(
params->force_popup_urls.array[i]);

dock.startupScript = QT_UTF8(params->startup_script.array);

if (main->IsBrowserInitialised())
main->AddPluginBrowserDock(dock);
else
main->StorePluginBrowserDock(dock);

return true;
#else
UNUSED_PARAMETER(id);
UNUSED_PARAMETER(title);
UNUSED_PARAMETER(params);

return false;
#endif
}

void obs_frontend_change_browser_dock_url(const char *id,
const char *url) override
{
#ifdef BROWSER_AVAILABLE
if (!id && !url)
return;

main->ChangePluginBrowserDockUrl(id, url);
#else
UNUSED_PARAMETER(id);
UNUSED_PARAMETER(url);
#endif
}

void obs_frontend_add_event_callback(obs_frontend_event_cb callback,
void *private_data) override
{
Expand Down
20 changes: 20 additions & 0 deletions UI/obs-frontend-api/obs-frontend-api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,26 @@ bool obs_frontend_add_custom_qdock(const char *id, void *dock)
: false;
}

bool obs_frontend_is_browser_available(void)
{
return !!callbacks_valid() ? c->obs_frontend_is_browser_available()
: false;
}

bool obs_frontend_add_browser_dock(const char *id, const char *title,
struct obs_frontend_browser_params *params)
{
return !!callbacks_valid()
? c->obs_frontend_add_browser_dock(id, title, params)
: false;
}

void obs_frontend_change_browser_dock_url(const char *id, const char *url)
{
if (callbacks_valid())
c->obs_frontend_change_browser_dock_url(id, url);
}

void obs_frontend_add_event_callback(obs_frontend_event_cb callback,
void *private_data)
{
Expand Down
25 changes: 25 additions & 0 deletions UI/obs-frontend-api/obs-frontend-api.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include <obs.h>
#include <util/darray.h>
#include <util/dstr.h>

#ifdef __cplusplus
extern "C" {
Expand Down Expand Up @@ -81,6 +82,22 @@ obs_frontend_source_list_free(struct obs_frontend_source_list *source_list)
da_free(source_list->sources);
}

struct obs_frontend_browser_params {
const char *url;
struct dstr startup_script;
DARRAY(char *) force_popup_urls;
};

static inline void
obs_frontend_browser_params_free(struct obs_frontend_browser_params *params)
{
if (params->startup_script.len > 0)
dstr_free(&params->startup_script);

if (params->force_popup_urls.num > 0)
da_free(params->force_popup_urls);
}

#endif //!SWIG

/* ------------------------------------------------------------------------- */
Expand Down Expand Up @@ -150,6 +167,14 @@ EXPORT void obs_frontend_remove_dock(const char *id);
/* takes QDockWidget for dock */
EXPORT bool obs_frontend_add_custom_qdock(const char *id, void *dock);

EXPORT bool obs_frontend_is_browser_available(void);

EXPORT bool
obs_frontend_add_browser_dock(const char *id, const char *title,
struct obs_frontend_browser_params *params);
EXPORT void obs_frontend_change_browser_dock_url(const char *id,
const char *url);

typedef void (*obs_frontend_event_cb)(enum obs_frontend_event event,
void *private_data);

Expand Down
7 changes: 7 additions & 0 deletions UI/obs-frontend-api/obs-frontend-internal.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,13 @@ struct obs_frontend_callbacks {
virtual bool obs_frontend_add_custom_qdock(const char *id,
void *dock) = 0;

virtual bool obs_frontend_is_browser_available(void) = 0;
virtual bool obs_frontend_add_browser_dock(
const char *id, const char *title,
struct obs_frontend_browser_params *params) = 0;
virtual void obs_frontend_change_browser_dock_url(const char *id,
const char *url) = 0;

virtual void
obs_frontend_add_event_callback(obs_frontend_event_cb callback,
void *private_data) = 0;
Expand Down
68 changes: 68 additions & 0 deletions UI/window-basic-main-browser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@

#ifdef BROWSER_AVAILABLE
#include <browser-panel.hpp>
#include "window-dock-browser.hpp"
#endif

struct QCef;
Expand Down Expand Up @@ -162,3 +163,70 @@ void OBSBasic::InitBrowserPanelSafeBlock()
InitPanelCookieManager();
#endif
}

#ifdef BROWSER_AVAILABLE
bool OBSBasic::IsBrowserInitialised()
{
return !!cef;
}

void OBSBasic::StorePluginBrowserDock(const PluginBrowserParams &params)
{
pluginBrowserDockNames.push_back(params.id);
preInitPluginBrowserDocks.push_back(params);
}

void OBSBasic::LoadStoredPluginBrowserDock()
{
for (int i = 0; preInitPluginBrowserDocks.size() > i; i++)
AddPluginBrowserDock(preInitPluginBrowserDocks[i]);

preInitPluginBrowserDocks.clear();
}

void OBSBasic::AddPluginBrowserDock(const PluginBrowserParams &params)
{
static int panel_version = -1;
if (panel_version == -1) {
panel_version = obs_browser_qcef_version();
}

BrowserDock *dock = new BrowserDock();
dock->setObjectName(params.id);
dock->resize(460, 600);
dock->setMinimumSize(80, 80);
dock->setWindowTitle(params.title);

QCefWidget *browser =
cef->create_widget(dock, QT_TO_UTF8(params.url), nullptr);
if (browser && panel_version >= 1)
browser->allowAllPopups(true);

dock->SetWidget(browser);

if (!params.startupScript.isEmpty())
browser->setStartupScript(params.startupScript.toStdString());

for (int i = 0; params.forcePopupUrls.size() > i; i++)
cef->add_force_popup_url(params.forcePopupUrls[i].toStdString(),
dock);

if (!pluginBrowserDockNames.contains(dock->objectName()))
pluginBrowserDockNames.push_back(dock->objectName());
AddDockWidget(dock, Qt::RightDockWidgetArea);

dock->setFloating(true);
dock->setVisible(false);
}

void OBSBasic::ChangePluginBrowserDockUrl(const char *id_, const char *url)
{
QString id = QT_UTF8(id_);
if (pluginBrowserDockNames.contains(id) &&
extraDockNames.contains(id)) {
int idx = extraDockNames.indexOf(id);
reinterpret_cast<BrowserDock *>(extraDocks[idx].data())
->cefWidget->setURL(url);
}
}
#endif
8 changes: 8 additions & 0 deletions UI/window-basic-main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2152,6 +2152,7 @@ void OBSBasic::OBSInit()
ui->scenesDock->toggleViewAction());

LoadExtraBrowserDocks();
LoadStoredPluginBrowserDock();
}
#endif

Expand Down Expand Up @@ -10332,6 +10333,10 @@ void OBSBasic::RemoveDockWidget(const QString &name)
extraDockNames.removeAt(idx);
extraDocks[idx].clear();
extraDocks.removeAt(idx);
#ifdef BROWSER_AVAILABLE
if (pluginBrowserDockNames.contains(name))
pluginBrowserDockNames.removeAll(name);
#endif
} else if (extraCustomDockNames.contains(name)) {
int idx = extraCustomDockNames.indexOf(name);
extraCustomDockNames.removeAt(idx);
Expand All @@ -10352,6 +10357,9 @@ bool OBSBasic::IsDockObjectNameUsed(const QString &name)
list << oldExtraDockNames;
list << extraDockNames;
list << extraCustomDockNames;
#ifdef BROWSER_AVAILABLE
list << pluginBrowserDockNames;
#endif

return list.contains(name);
}
Expand Down
19 changes: 19 additions & 0 deletions UI/window-basic-main.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,16 @@ class ColorSelect : public QWidget {
std::unique_ptr<Ui::ColorSelect> ui;
};

#ifdef BROWSER_AVAILABLE
struct PluginBrowserParams {
QString id;
QString title;
QString url;
QString startupScript;
QStringList forcePopupUrls;
};
#endif

class OBSBasic : public OBSMainWindow {
Q_OBJECT
Q_PROPERTY(QIcon imageIcon READ GetImageIcon WRITE SetImageIcon
Expand Down Expand Up @@ -572,6 +582,15 @@ class OBSBasic : public OBSMainWindow {
void ManageExtraBrowserDocks();
void AddExtraBrowserDock(const QString &title, const QString &url,
const QString &uuid, bool firstCreate);

QStringList pluginBrowserDockNames;
QList<PluginBrowserParams> preInitPluginBrowserDocks;

bool IsBrowserInitialised();
void StorePluginBrowserDock(const PluginBrowserParams &params);
void LoadStoredPluginBrowserDock();
void AddPluginBrowserDock(const PluginBrowserParams &params);
void ChangePluginBrowserDockUrl(const char *id, const char *url);
#endif

QIcon imageIcon;
Expand Down
57 changes: 57 additions & 0 deletions docs/sphinx/reference-frontend-api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,22 @@ Structures/Enumerations

obs_frontend_source_list_free(&scenes);

.. type:: struct obs_frontend_browser_params

- const char* **url**
- struct dstr **startup_script**
- DARRAY(char*) **force_popup_urls**

.. code:: cpp

struct obs_frontend_browser_params params = {0};

params.url = "https://obsproject.com/";

obs_frontend_add_browser_dock("example", "Example", &params);

obs_frontend_browser_params_free(&params);

.. type:: void (*obs_frontend_cb)(void *private_data)

Frontend tool menu callback
Expand Down Expand Up @@ -242,6 +258,14 @@ Functions

---------------------------------------

.. function:: void obs_frontend_browser_params_free(struct obs_frontend_browser_params *params)

Frees the startup script and force popup URLs if not empty.

:param params: Browser parameters with dynamic types to free

---------------------------------------

.. function:: void *obs_frontend_get_main_window(void)

:return: The QMainWindow pointer to the OBS Studio window
Expand Down Expand Up @@ -491,6 +515,39 @@ Functions

---------------------------------------

.. function:: bool obs_frontend_is_browser_available(void)

:return: If browser feature is available (built with obs-browser or
not runnning under Wayland)

---------------------------------------

.. function:: bool obs_frontend_add_browser_dock(const char *id, const char *title, struct obs_frontend_browser_params* params)

Adds a browser dock with the widget to the UI with a toggle in the Docks
menu.

Note: Use :c:func:`obs_frontend_remove_dock` to remove the dock
and the id from the UI.

:param id: Unique identifier of the dock
:param title: Window title of the dock
:param params: Parameters of the browser widget
:return: *true* if the dock was added, *false* if the id was already
used

---------------------------------------

.. function:: void obs_frontend_change_browser_dock_url(const char *id, const char *url)

Change the URL of browser dock created with
:c:func:`obs_frontend_add_browser_dock`.

:param id: Unique identifier of the targeted browser dock
:param url: New URL

---------------------------------------

.. function:: void obs_frontend_add_event_callback(obs_frontend_event_cb callback, void *private_data)

Adds a callback that will be called when a frontend event occurs.
Expand Down