diff --git a/src/WindowFilter.cpp b/src/WindowFilter.cpp index e41b131c..d32d3a8b 100644 --- a/src/WindowFilter.cpp +++ b/src/WindowFilter.cpp @@ -1,10 +1,14 @@ #include "WindowFilter.hpp" // To prevent usage of statics (TLS breaks the present thread...?) -WindowFilter g_window_filter{}; +std::unique_ptr g_window_filter{}; WindowFilter& WindowFilter::get() { - return g_window_filter; + if (g_window_filter == nullptr) { + g_window_filter = std::make_unique(); + } + + return *g_window_filter; } WindowFilter::WindowFilter() { @@ -14,22 +18,21 @@ WindowFilter::WindowFilter() { while (!s.stop_requested()) { std::this_thread::sleep_for(std::chrono::milliseconds{100}); + m_last_job_tick = std::chrono::steady_clock::now(); + if (m_window_jobs.empty()) { return; } - std::vector window_jobs{}; - - { - std::scoped_lock _{m_mutex}; - window_jobs = std::move(m_window_jobs); - } + std::scoped_lock _{m_mutex}; - for (const auto hwnd : window_jobs) { + for (const auto hwnd : m_window_jobs) { if (is_filtered_nocache(hwnd)) { filter_window(hwnd); } } + + m_window_jobs.clear(); } }); } @@ -50,11 +53,17 @@ bool WindowFilter::is_filtered(HWND hwnd) { return true; } + // If there is a job for this window, filter it until the job is done + if (m_window_jobs.find(hwnd) != m_window_jobs.end()) { + // If the thread is dead for some reason, do not filter it. + return std::chrono::steady_clock::now() - m_last_job_tick <= std::chrono::seconds{2}; + } + // if we havent even seen this window yet, add it to the job queue // and return true; if (m_seen_windows.find(hwnd) == m_seen_windows.end()) { m_seen_windows.insert(hwnd); - m_window_jobs.push_back(hwnd); + m_window_jobs.insert(hwnd); return true; } diff --git a/src/WindowFilter.hpp b/src/WindowFilter.hpp index f6732e75..2a731762 100644 --- a/src/WindowFilter.hpp +++ b/src/WindowFilter.hpp @@ -7,6 +7,7 @@ #include #include #include +#include class WindowFilter { public: @@ -27,9 +28,10 @@ class WindowFilter { bool is_filtered_nocache(HWND hwnd); std::recursive_mutex m_mutex{}; - std::vector m_window_jobs{}; + std::unordered_set m_window_jobs{}; std::unique_ptr m_job_thread{}; std::unordered_set m_seen_windows{}; std::unordered_set m_filtered_windows{}; + std::chrono::time_point m_last_job_tick{}; }; \ No newline at end of file