Skip to content
Closed
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
89 changes: 88 additions & 1 deletion frontend/oauth/TwitchAuth.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <ui-config.h>

#include <QUuid>
#include <QSystemTrayIcon>

#include "moc_TwitchAuth.cpp"

Expand Down Expand Up @@ -52,13 +53,87 @@ TwitchAuth::~TwitchAuth()
return;

OBSBasic *main = OBSBasic::Get();
if (eventFilterInstalled)
main->removeEventFilter(this);

main->RemoveDockWidget(TWITCH_CHAT_DOCK_NAME);
main->RemoveDockWidget(TWITCH_INFO_DOCK_NAME);
main->RemoveDockWidget(TWITCH_STATS_DOCK_NAME);
main->RemoveDockWidget(TWITCH_FEED_DOCK_NAME);
}

bool TwitchAuth::ShouldHideTwitchDocksOnStartup()
{
OBSBasic *main = OBSBasic::Get();
bool sysTrayEnabled = config_get_bool(App()->GetUserConfig(), "BasicWindow", "SysTrayEnabled");

return QSystemTrayIcon::isSystemTrayAvailable() && !main->isVisible() && sysTrayEnabled;
}

void TwitchAuth::InstallDockVisibilityRestore()
{
if (eventFilterInstalled)
return;

OBSBasic::Get()->installEventFilter(this);
eventFilterInstalled = true;
}

void TwitchAuth::DeferDockVisibility(QDockWidget *dock)
{
if (!dock)
return;

for (auto &deferredDock : deferredDocks) {
if (deferredDock.first == dock) {
dock->setVisible(false);
return;
}
}

deferredDocks.emplace_back(dock, dock->isVisible());
dock->setVisible(false);
deferredDockVisibilityRestore = true;
InstallDockVisibilityRestore();
}

void TwitchAuth::HideDeferredDocks()
{
for (auto &deferredDock : deferredDocks) {
if (deferredDock.first)
deferredDock.first->setVisible(false);
}
}

void TwitchAuth::RestoreDeferredDockVisibility()
{
if (!deferredDockVisibilityRestore)
return;

for (auto &deferredDock : deferredDocks) {
if (deferredDock.first)
deferredDock.first->setVisible(deferredDock.second);
}

deferredDockVisibilityRestore = false;
deferredDocks.clear();

if (eventFilterInstalled) {
OBSBasic::Get()->removeEventFilter(this);
eventFilterInstalled = false;
}
}

bool TwitchAuth::eventFilter(QObject *obj, QEvent *event)
{
if (!deferredDockVisibilityRestore || event->type() != QEvent::Show || obj != OBSBasic::Get())
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Restore deferred dock visibility before saving state

The deferred visibility is only restored on QEvent::Show, so when OBS starts minimized to tray and the user exits from the tray without ever showing the main window, the Twitch docks remain force-hidden. On shutdown, OBSBasic::saveAll() calls Auth::Save(), and TwitchAuth::SaveInternal() persists main->saveState() with those hidden flags, which silently overwrites the user's previous Twitch dock visibility for future launches.

Useful? React with 👍 / 👎.

return QObject::eventFilter(obj, event);

RestoreDeferredDockVisibility();

return QObject::eventFilter(obj, event);
}

bool TwitchAuth::MakeApiRequest(const char *path, Json &json_out)
{
std::string client_id = TWITCH_CLIENTID;
Expand Down Expand Up @@ -276,6 +351,10 @@ void TwitchAuth::LoadUI()
main->restoreState(dockState);
}

if (ShouldHideTwitchDocksOnStartup()) {
DeferDockVisibility(chat);
}

TryLoadSecondaryUIPanes();

uiLoaded = true;
Expand Down Expand Up @@ -396,9 +475,17 @@ void TwitchAuth::LoadSecondaryUIPanes()
const char *dockStateStr = config_get_string(main->Config(), service(), "DockState");
QByteArray dockState = QByteArray::fromBase64(QByteArray(dockStateStr));

if (main->isVisible() || !main->isMaximized())
if (ShouldHideTwitchDocksOnStartup() || main->isVisible() || !main->isMaximized())
main->restoreState(dockState);
}

if (ShouldHideTwitchDocksOnStartup()) {
DeferDockVisibility(main->findChild<QDockWidget *>(TWITCH_CHAT_DOCK_NAME));
HideDeferredDocks();
DeferDockVisibility(info);
DeferDockVisibility(stats);
DeferDockVisibility(feed);
}
}

/* Twitch.tv has an OAuth for itself. If we try to load multiple panel pages
Expand Down
16 changes: 15 additions & 1 deletion frontend/oauth/TwitchAuth.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,20 @@

#include <json11.hpp>

#include <utility>
#include <vector>

#include <QDockWidget>
#include <QEvent>
#include <QPointer>
#include <QTimer>

class TwitchAuth : public OAuthStreamKey {
Q_OBJECT

bool uiLoaded = false;
bool deferredDockVisibilityRestore = false;
bool eventFilterInstalled = false;
std::vector<std::pair<QPointer<QDockWidget>, bool>> deferredDocks;

std::string name;
std::string uuid;
Expand All @@ -23,6 +31,12 @@ class TwitchAuth : public OAuthStreamKey {
bool GetChannelInfo();

virtual void LoadUI() override;
bool eventFilter(QObject *obj, QEvent *event) override;
void DeferDockVisibility(QDockWidget *dock);
void HideDeferredDocks();
void InstallDockVisibilityRestore();
void RestoreDeferredDockVisibility();
bool ShouldHideTwitchDocksOnStartup();

public:
TwitchAuth(const Def &d);
Expand Down