99#include < obs-frontend-api.h>
1010#include < QMainWindow>
1111#include < QAction>
12+ #include < QScreen>
13+
1214#include < util/util.hpp>
1315#include < util/platform.h>
1416#include " ASIOSettingsDialog.h"
@@ -75,21 +77,49 @@ void output_start()
7577 }
7678}
7779
80+ void callback ()
81+ {
82+ QMainWindow *mainWindow = (QMainWindow *)obs_frontend_get_main_window ();
83+ QWidget *obsSettingsDialog = nullptr ;
84+ const auto topLevels = QApplication::topLevelWidgets ();
85+ for (QWidget *widget : topLevels) {
86+ if (widget->isVisible () && QString (widget->metaObject ()->className ()).contains (" OBSBasicSettings" )) {
87+ obsSettingsDialog = widget;
88+ break ;
89+ }
90+ }
91+ if (!_settingsDialog) {
92+ if (!obsSettingsDialog)
93+ _settingsDialog = new ASIOSettingsDialog (mainWindow, context.output , context.settings );
94+ else
95+ _settingsDialog = new ASIOSettingsDialog (obsSettingsDialog, context.output , context.settings );
96+ _settingsDialog->setAttribute (Qt::WA_DeleteOnClose);
97+ QObject::connect (_settingsDialog, &QObject::destroyed, []() { _settingsDialog = nullptr ; });
98+ }
99+
100+ _settingsDialog->ShowHideDialog (context.enabled );
101+ if (obsSettingsDialog) {
102+ QRect settingsRect = obsSettingsDialog->geometry ();
103+ QRect asioRect = _settingsDialog->geometry ();
104+ QPoint newPos (settingsRect.right () + 100 , settingsRect.top ());
105+ QScreen *screen = obsSettingsDialog->screen ();
106+ QRect desktopRect = screen->availableGeometry ();
107+ if (newPos.x () + asioRect.width () > desktopRect.right ())
108+ newPos.setX (desktopRect.right () - asioRect.width ());
109+ _settingsDialog->move (newPos);
110+ }
111+ }
112+
78113void addOutputUI (void )
79114{
80115 QAction *action = (QAction *)obs_frontend_add_tools_menu_qaction (obs_module_text (" AsioOutput.Menu" ));
81-
82- QMainWindow *mainWindow = (QMainWindow *)obs_frontend_get_main_window ();
116+ action->setObjectName (" asioOutputSetupAction" );
83117
84118 obs_frontend_push_ui_translation (obs_module_get_string);
85- _settingsDialog = new ASIOSettingsDialog (mainWindow, context.output , context.settings );
86119 obs_frontend_pop_ui_translation ();
87-
88- auto cb = []() {
89- _settingsDialog->ShowHideDialog ();
90- };
91-
92- action->connect (action, &QAction::triggered, cb);
120+ // the UI is added through the callback
121+ action->connect (action, &QAction::triggered, callback);
122+ action->setVisible (false );
93123}
94124
95125static void OBSEvent (enum obs_frontend_event event, void *)
@@ -120,10 +150,15 @@ void obs_module_unload(void)
120150 if (output_running)
121151 output_stop ();
122152
123- obs_output_release (context.output );
124- context.output = nullptr ;
125- obs_data_release (context.settings );
126- context.settings = nullptr ;
153+ if (context.output ) {
154+ obs_output_release (context.output );
155+ context.output = nullptr ;
156+ }
157+
158+ if (context.settings ) {
159+ obs_data_release (context.settings );
160+ context.settings = nullptr ;
161+ }
127162 obs_frontend_remove_event_callback (OBSEvent, nullptr );
128163}
129164
@@ -133,8 +168,11 @@ void obs_module_post_load(void)
133168 return ;
134169
135170 context.settings = load_settings ();
171+
136172 obs_output_t *const output = obs_output_create (" asio_output" , " asio_output" , context.settings , NULL );
173+
137174 if (output != nullptr ) {
175+ context.enabled = true ;
138176 context.output = output;
139177
140178 if (!context.settings ) {
@@ -145,5 +183,6 @@ void obs_module_post_load(void)
145183 obs_frontend_add_event_callback (OBSEvent, nullptr );
146184 } else {
147185 blog (LOG_INFO, " Failed to create ASIO output" );
186+ addOutputUI ();
148187 }
149188}
0 commit comments