Plugin Not Docking Properly

Ashmanix

Member
I've been developing a countdown timer app in c++ and have used the Qt framework to programatically build a dockable widget that then gets attached to the OBS parent window using obs_frontend_add_dock function. If I don't set the dock to floating and have it show when initialised the dock seems to open within another docked window (see attached image). If I set it to floating at the beginning then it shows ok as a floating dockable window. When I dock it on the main window it docks fine but when I close and restart OBS it doesn't save the dock location. I have two questions:

- Am I doing something wrong in the way I initialise my app as a QDockWidget? I have noticed other apps use .ui files.
- How do I get OBS to save the dock visibility setting and the dock position after restarting the app?

I have attached parts of the initialisation code below. The full code is viewable here: https://github.com/ashmanix/obs-plugin-countdown/tree/develop

Screenshot 2022-10-03 at 10.21.33.png



C++:
// Initialisation code
bool obs_module_load(void)
{
    const auto main_window =
        static_cast<QMainWindow *>(obs_frontend_get_main_window());
    obs_frontend_push_ui_translation(obs_module_get_string);
    auto countdownWidget = new CountdownDockWidget(main_window);

    // countdownWidget->setFloating(true);
    obs_frontend_add_dock(countdownWidget);
    obs_frontend_pop_ui_translation();

    blog(LOG_INFO, "plugin loaded successfully (version %s)",
         PLUGIN_VERSION);
    return true;
}
// Part of the class creation code
CountdownDockWidget::CountdownDockWidget(QWidget *parent)
    : QDockWidget("Countdown Timer", parent)
{
    countdownTimerData = new CountdownWidgetStruct;
    countdownTimerData->countdownTimerUI = new QWidget();
    countdownTimerData->countdownTimerUI->setLayout(
        SetupCountdownWidgetUI(countdownTimerData));

    setWidget(countdownTimerData->countdownTimerUI);
    // this->setMinimumSize(200, 200);
    this->setVisible(false);
    this->setFloating(true);
        
    // Other Initialisation code
}
 

Ashmanix

Member
I found a solution to the issue. I had a look at how the stats dock was rendered in the main OBS code and they do this with the QDockWidget:
C++:
statsDock = new OBSDock();
    statsDock->setObjectName(QStringLiteral("statsDock"));
    statsDock->setFeatures(QDockWidget::DockWidgetClosable |
                   QDockWidget::DockWidgetMovable |
                   QDockWidget::DockWidgetFloatable);
    statsDock->setWindowTitle(QTStr("Basic.Stats"));
    addDockWidget(Qt::BottomDockWidgetArea, statsDock);
    statsDock->setVisible(false);
    statsDock->setFloating(true);
    statsDock->resize(700, 200);

I applied these settings to my plugin and this seems to work. It will set it to floating but also hide it when the plugin is first used. You then make it visible and dock it and OBS will save it's dock position. Just setting ti to floating (without setting it invisible) would have it flicker as a floating dock sometimes on startup or closing OBS. These settings solve that.

What I've learned? GitHub and search is your friend!
 
Top