Skip to content

Commit 1c06c07

Browse files
committed
obs-frontend-api,UI,docs: Add browser dock functions
1 parent aa98043 commit 1c06c07

File tree

8 files changed

+276
-0
lines changed

8 files changed

+276
-0
lines changed

UI/api-interface.cpp

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@
88

99
#include <functional>
1010

11+
#ifdef ENABLE_WAYLAND
12+
#include <obs-nix-platform.h>
13+
#endif
14+
1115
using namespace std;
1216

1317
Q_DECLARE_METATYPE(OBSScene);
@@ -446,6 +450,76 @@ struct OBSStudioAPI : obs_frontend_callbacks {
446450
return true;
447451
}
448452

453+
bool obs_frontend_is_browser_available(void) override
454+
{
455+
#ifdef BROWSER_AVAILABLE
456+
#ifdef ENABLE_WAYLAND
457+
return (obs_get_nix_platform() != OBS_NIX_PLATFORM_WAYLAND);
458+
#else
459+
return true;
460+
#endif
461+
#else
462+
return false;
463+
#endif
464+
}
465+
466+
bool obs_frontend_add_browser_dock(
467+
const char *id, const char *title,
468+
struct obs_frontend_browser_params *params) override
469+
{
470+
#ifdef BROWSER_AVAILABLE
471+
if (!obs_frontend_is_browser_available())
472+
return false;
473+
474+
if (main->IsDockObjectNameUsed(QT_UTF8(id))) {
475+
blog(LOG_WARNING,
476+
"Dock id '%s' already used! "
477+
"Duplicate library?",
478+
id);
479+
return false;
480+
}
481+
482+
PluginBrowserParams dock;
483+
dock.id = QT_UTF8(id);
484+
dock.title = QT_UTF8(title);
485+
486+
dock.url = QT_UTF8(params->url);
487+
488+
for (size_t i = 0; i < params->force_popup_urls.num; i++)
489+
dock.forcePopupUrls.append(
490+
params->force_popup_urls.array[i]);
491+
492+
dock.startupScript = QT_UTF8(params->startup_script.array);
493+
494+
if (main->IsBrowserInitialised())
495+
main->AddPluginBrowserDock(dock);
496+
else
497+
main->StorePluginBrowserDock(dock);
498+
499+
return true;
500+
#else
501+
UNUSED_PARAMETER(id);
502+
UNUSED_PARAMETER(title);
503+
UNUSED_PARAMETER(params);
504+
505+
return false;
506+
#endif
507+
}
508+
509+
void obs_frontend_change_browser_dock_url(const char *id,
510+
const char *url) override
511+
{
512+
#ifdef BROWSER_AVAILABLE
513+
if (!id && !url)
514+
return;
515+
516+
main->ChangePluginBrowserDockUrl(id, url);
517+
#else
518+
UNUSED_PARAMETER(id);
519+
UNUSED_PARAMETER(url);
520+
#endif
521+
}
522+
449523
void obs_frontend_add_event_callback(obs_frontend_event_cb callback,
450524
void *private_data) override
451525
{

UI/obs-frontend-api/obs-frontend-api.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,26 @@ bool obs_frontend_add_custom_dock(const char *id, void *dock)
350350
: false;
351351
}
352352

353+
bool obs_frontend_is_browser_available(void)
354+
{
355+
return !!callbacks_valid() ? c->obs_frontend_is_browser_available()
356+
: false;
357+
}
358+
359+
bool obs_frontend_add_browser_dock(const char *id, const char *title,
360+
struct obs_frontend_browser_params *params)
361+
{
362+
return !!callbacks_valid()
363+
? c->obs_frontend_add_browser_dock(id, title, params)
364+
: false;
365+
}
366+
367+
void obs_frontend_change_browser_dock_url(const char *id, const char *url)
368+
{
369+
if (callbacks_valid())
370+
c->obs_frontend_change_browser_dock_url(id, url);
371+
}
372+
353373
void obs_frontend_add_event_callback(obs_frontend_event_cb callback,
354374
void *private_data)
355375
{

UI/obs-frontend-api/obs-frontend-api.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
#include <obs.h>
44
#include <util/darray.h>
5+
#include <util/dstr.h>
56

67
#ifdef __cplusplus
78
extern "C" {
@@ -81,6 +82,22 @@ obs_frontend_source_list_free(struct obs_frontend_source_list *source_list)
8182
da_free(source_list->sources);
8283
}
8384

85+
struct obs_frontend_browser_params {
86+
const char *url;
87+
struct dstr startup_script;
88+
DARRAY(char *) force_popup_urls;
89+
};
90+
91+
static inline void
92+
obs_frontend_browser_params_free(struct obs_frontend_browser_params *params)
93+
{
94+
if (params->startup_script.len > 0)
95+
dstr_free(&params->startup_script);
96+
97+
if (params->force_popup_urls.num > 0)
98+
da_free(params->force_popup_urls);
99+
}
100+
84101
#endif //!SWIG
85102

86103
/* ------------------------------------------------------------------------- */
@@ -150,6 +167,14 @@ EXPORT void obs_frontend_remove_dock(const char *id);
150167
/* takes QDockWidget for dock */
151168
EXPORT bool obs_frontend_add_custom_dock(const char *id, void *dock);
152169

170+
EXPORT bool obs_frontend_is_browser_available(void);
171+
172+
EXPORT bool
173+
obs_frontend_add_browser_dock(const char *id, const char *title,
174+
struct obs_frontend_browser_params *params);
175+
EXPORT void obs_frontend_change_browser_dock_url(const char *id,
176+
const char *url);
177+
153178
typedef void (*obs_frontend_event_cb)(enum obs_frontend_event event,
154179
void *private_data);
155180

UI/obs-frontend-api/obs-frontend-internal.hpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,13 @@ struct obs_frontend_callbacks {
7373
virtual bool obs_frontend_add_custom_dock(const char *id,
7474
void *dock) = 0;
7575

76+
virtual bool obs_frontend_is_browser_available(void) = 0;
77+
virtual bool obs_frontend_add_browser_dock(
78+
const char *id, const char *title,
79+
struct obs_frontend_browser_params *params) = 0;
80+
virtual void obs_frontend_change_browser_dock_url(const char *id,
81+
const char *url) = 0;
82+
7683
virtual void
7784
obs_frontend_add_event_callback(obs_frontend_event_cb callback,
7885
void *private_data) = 0;

UI/window-basic-main-browser.cpp

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525

2626
#ifdef BROWSER_AVAILABLE
2727
#include <browser-panel.hpp>
28+
#include "window-dock-browser.hpp"
2829
#endif
2930

3031
struct QCef;
@@ -162,3 +163,68 @@ void OBSBasic::InitBrowserPanelSafeBlock()
162163
InitPanelCookieManager();
163164
#endif
164165
}
166+
167+
#ifdef BROWSER_AVAILABLE
168+
bool OBSBasic::IsBrowserInitialised()
169+
{
170+
return !!cef;
171+
}
172+
173+
void OBSBasic::StorePluginBrowserDock(const PluginBrowserParams &params)
174+
{
175+
pluginBrowserDockNames.push_back(params.id);
176+
preInitPluginBrowserDocks.push_back(params);
177+
}
178+
179+
void OBSBasic::LoadStoredPluginBrowserDock()
180+
{
181+
for (int i = 0; preInitPluginBrowserDocks.size() > i; i++)
182+
AddPluginBrowserDock(preInitPluginBrowserDocks[i]);
183+
184+
preInitPluginBrowserDocks.clear();
185+
}
186+
187+
void OBSBasic::AddPluginBrowserDock(const PluginBrowserParams &params)
188+
{
189+
static int panel_version = -1;
190+
if (panel_version == -1) {
191+
panel_version = obs_browser_qcef_version();
192+
}
193+
194+
BrowserDock *dock = new BrowserDock();
195+
dock->setObjectName(params.id);
196+
dock->resize(460, 600);
197+
dock->setMinimumSize(80, 80);
198+
dock->setWindowTitle(params.title);
199+
200+
QCefWidget *browser =
201+
cef->create_widget(dock, QT_TO_UTF8(params.url), nullptr);
202+
if (browser && panel_version >= 1)
203+
browser->allowAllPopups(true);
204+
205+
dock->SetWidget(browser);
206+
207+
if (!params.startupScript.isEmpty())
208+
browser->setStartupScript(params.startupScript.toStdString());
209+
210+
for (int i = 0; params.forcePopupUrls.size() > i; i++)
211+
cef->add_force_popup_url(params.forcePopupUrls[i].toStdString(),
212+
dock);
213+
214+
AddDockWidget(dock, Qt::RightDockWidgetArea);
215+
216+
dock->setFloating(true);
217+
dock->setVisible(false);
218+
}
219+
220+
void OBSBasic::ChangePluginBrowserDockUrl(const char *id_, const char *url)
221+
{
222+
QString id = QT_UTF8(id_);
223+
if (pluginBrowserDockNames.contains(id) &&
224+
extraDockNames.contains(id)) {
225+
int idx = extraDockNames.indexOf(id);
226+
reinterpret_cast<BrowserDock *>(extraDocks[idx].data())
227+
->cefWidget->setURL(url);
228+
}
229+
}
230+
#endif

UI/window-basic-main.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1995,6 +1995,7 @@ void OBSBasic::OBSInit()
19951995
ui->scenesDock->toggleViewAction());
19961996

19971997
LoadExtraBrowserDocks();
1998+
LoadStoredPluginBrowserDock();
19981999
}
19992000
#endif
20002001

@@ -9987,6 +9988,10 @@ void OBSBasic::RemoveDockWidget(const QString &name)
99879988
extraDockNames.removeAt(idx);
99889989
extraDocks[idx].clear();
99899990
extraDocks.removeAt(idx);
9991+
#ifdef BROWSER_AVAILABLE
9992+
if (pluginBrowserDockNames.contains(name))
9993+
pluginBrowserDockNames.removeAll(name);
9994+
#endif
99909995
} else if (extraCustomDockNames.contains(name)) {
99919996
int idx = extraCustomDockNames.indexOf(name);
99929997
extraCustomDockNames.removeAt(idx);
@@ -10007,6 +10012,9 @@ bool OBSBasic::IsDockObjectNameUsed(const QString &name)
1000710012
list << oldExtraDockNames;
1000810013
list << extraDockNames;
1000910014
list << extraCustomDockNames;
10015+
#ifdef BROWSER_AVAILABLE
10016+
list << pluginBrowserDockNames;
10017+
#endif
1001010018

1001110019
return list.contains(name);
1001210020
}

UI/window-basic-main.hpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,16 @@ class ColorSelect : public QWidget {
137137
std::unique_ptr<Ui::ColorSelect> ui;
138138
};
139139

140+
#ifdef BROWSER_AVAILABLE
141+
struct PluginBrowserParams {
142+
QString id;
143+
QString title;
144+
QString url;
145+
QString startupScript;
146+
QStringList forcePopupUrls;
147+
};
148+
#endif
149+
140150
class OBSBasic : public OBSMainWindow {
141151
Q_OBJECT
142152
Q_PROPERTY(QIcon imageIcon READ GetImageIcon WRITE SetImageIcon
@@ -565,6 +575,15 @@ class OBSBasic : public OBSMainWindow {
565575
void ManageExtraBrowserDocks();
566576
void AddExtraBrowserDock(const QString &title, const QString &url,
567577
const QString &uuid, bool firstCreate);
578+
579+
QStringList pluginBrowserDockNames;
580+
QList<PluginBrowserParams> preInitPluginBrowserDocks;
581+
582+
bool IsBrowserInitialised();
583+
void StorePluginBrowserDock(const PluginBrowserParams &params);
584+
void LoadStoredPluginBrowserDock();
585+
void AddPluginBrowserDock(const PluginBrowserParams &params);
586+
void ChangePluginBrowserDockUrl(const char *id, const char *url);
568587
#endif
569588

570589
QIcon imageIcon;

docs/sphinx/reference-frontend-api.rst

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,22 @@ Structures/Enumerations
210210
211211
obs_frontend_source_list_free(&scenes);
212212
213+
.. type:: struct obs_frontend_browser_params
214+
215+
- const char* **url**
216+
- struct dstr **startup_script**
217+
- DARRAY(char*) **force_popup_urls**
218+
219+
.. code:: cpp
220+
221+
struct obs_frontend_browser_params params = {0};
222+
223+
params.url = "https://obsproject.com/";
224+
225+
obs_frontend_add_browser_dock("example", "Example", &params);
226+
227+
obs_frontend_browser_params_free(&params);
228+
213229
.. type:: void (*obs_frontend_cb)(void *private_data)
214230

215231
Frontend tool menu callback
@@ -238,6 +254,14 @@ Functions
238254

239255
---------------------------------------
240256

257+
.. function:: void obs_frontend_browser_params_free(struct obs_frontend_browser_params *params)
258+
259+
Frees the startup script and force popup URLs if not empty.
260+
261+
:param params: Browser parameters with dynamic types to free
262+
263+
---------------------------------------
264+
241265
.. function:: void *obs_frontend_get_main_window(void)
242266

243267
:return: The QMainWindow pointer to the OBS Studio window
@@ -485,6 +509,39 @@ Functions
485509

486510
---------------------------------------
487511

512+
.. function:: bool obs_frontend_is_browser_available(void)
513+
514+
:return: If browser feature is available (built with obs-browser or
515+
not runnning under Wayland)
516+
517+
---------------------------------------
518+
519+
.. function:: bool obs_frontend_add_browser_dock(const char *id, const char *title, struct obs_frontend_browser_params* params)
520+
521+
Adds a browser dock with the widget to the UI with a toggle in the Docks
522+
menu.
523+
524+
Note: Use :c:func:`obs_frontend_remove_dock` to remove the dock
525+
and the id from the UI.
526+
527+
:param id: Unique identifier of the dock
528+
:param title: Window title of the dock
529+
:param params: Parameters of the browser widget
530+
:return: *true* if the dock was added, *false* if the id was already
531+
used
532+
533+
---------------------------------------
534+
535+
.. function:: void obs_frontend_change_browser_dock_url(const char *id, const char *url)
536+
537+
Change the URL of browser dock created with
538+
:c:func:`obs_frontend_add_browser_dock`.
539+
540+
:param id: Unique identifier of the targeted browser dock
541+
:param url: New URL
542+
543+
---------------------------------------
544+
488545
.. function:: void obs_frontend_add_event_callback(obs_frontend_event_cb callback, void *private_data)
489546

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

0 commit comments

Comments
 (0)