From 6605c1920215e33a1dd97f3a1da8dc305b24bc23 Mon Sep 17 00:00:00 2001 From: WarmUpTill Date: Mon, 21 Aug 2023 21:34:15 +0200 Subject: [PATCH] Add OBS windows to GetWindowList() --- src/win/advanced-scene-switcher-win.cpp | 65 ++++++++++++++++++++++--- 1 file changed, 59 insertions(+), 6 deletions(-) diff --git a/src/win/advanced-scene-switcher-win.cpp b/src/win/advanced-scene-switcher-win.cpp index af33a8eb..87ed27f6 100644 --- a/src/win/advanced-scene-switcher-win.cpp +++ b/src/win/advanced-scene-switcher-win.cpp @@ -15,6 +15,9 @@ #include #include #include +#include +#include +#include namespace advss { @@ -102,10 +105,61 @@ static VOID EnumWindowsWithMetro(__in WNDENUMPROC lpEnumFunc, } } +// Asynchronously updates the OBS window list and returns the state of the last +// successful update +const std::vector getOBSWindows() +{ + struct OBSWindowListHelper { + std::vector windows; + std::atomic_bool done; + }; + static OBSWindowListHelper obsWindowListHelper1 = {{}, {true}}; + static OBSWindowListHelper obsWindowListHelper2 = {{}, {false}}; + auto getQtWindowList = [](void *param) { + auto list = reinterpret_cast(param); + for (auto w : QApplication::topLevelWidgets()) { + auto title = w->windowTitle(); + if (!title.isEmpty()) { + list->windows.emplace_back(title.toStdString()); + } + } + list->done = true; + }; + + static OBSWindowListHelper *lastDoneHelper = &obsWindowListHelper2; + static OBSWindowListHelper *pendingHelper = &obsWindowListHelper1; + static std::mutex mutex; + + /* ------------------------------------------------------------------ */ + + std::lock_guard lock(mutex); + if (pendingHelper->done) { // Check if swap is needed + auto temp = lastDoneHelper; + lastDoneHelper = pendingHelper; + pendingHelper = temp; + pendingHelper->done = false; + pendingHelper->windows.clear(); + obs_queue_task(OBS_TASK_UI, getQtWindowList, pendingHelper, + false); + } + + return lastDoneHelper->windows; +} + void GetWindowList(std::vector &windows) { windows.resize(0); EnumWindowsWithMetro(GetTitleCB, reinterpret_cast(&windows)); + + // Also add OBS windows + for (const auto &window : getOBSWindows()) { + if (!window.empty()) { + windows.emplace_back(window); + } + } + + // Add entry for OBS Studio itself - see GetCurrentWindowTitle() + windows.emplace_back("OBS"); } void GetWindowList(QStringList &windows) @@ -117,9 +171,6 @@ void GetWindowList(QStringList &windows) for (auto window : w) { windows << QString::fromStdString(window); } - - // Add entry for OBS Studio itself, see GetCurrentWindowTitle - windows << QString("OBS"); } void GetCurrentWindowTitle(std::string &title) @@ -128,9 +179,11 @@ void GetCurrentWindowTitle(std::string &title) DWORD pid; DWORD thid; thid = GetWindowThreadProcessId(window, &pid); - // GetWindowText will freeze if the control it is reading was created in another thread. - // It does not directly read the control. - // Instead it waits for the thread that created the control to process a WM_GETTEXT message. + // GetWindowText will freeze if the control it is reading was created + // in another thread. + // In this case it does not directly read the control. + // Instead it waits for the thread that created the control to process a + // WM_GETTEXT message. // So if that thread is frozen in a WaitFor... call you have a deadlock. if (GetCurrentProcessId() == pid) { title = "OBS";