From 0b74a01313af5a94ac3dccea0dc053ac6aecdb20 Mon Sep 17 00:00:00 2001 From: houmain Date: Mon, 25 Jan 2021 15:56:41 +0100 Subject: [PATCH] Updating context when window title changes --- src/linux/client/FocusedWindow.cpp | 24 +++++++++++++----------- src/win32/FocusedWindow.cpp | 13 ++++++++----- 2 files changed, 21 insertions(+), 16 deletions(-) diff --git a/src/linux/client/FocusedWindow.cpp b/src/linux/client/FocusedWindow.cpp index be5bf295..3b573e3c 100644 --- a/src/linux/client/FocusedWindow.cpp +++ b/src/linux/client/FocusedWindow.cpp @@ -28,27 +28,29 @@ class FocusedWindow { m_net_active_window_atom = XInternAtom(m_display, "_NET_ACTIVE_WINDOW", False); m_net_wm_name_atom = XInternAtom(m_display, "_NET_WM_NAME", False); m_utf8_string_atom = XInternAtom(m_display, "UTF8_STRING", False); + XSetErrorHandler([](Display*, XErrorEvent*) { return 0; }); return true; } bool update() { const auto window = get_focused_window(); - if (window == m_focused_window) + auto window_title = get_window_title(window); + if (window == m_focused_window && + window_title == m_focused_window_title) return false; - // TODO: is there a better way to prevent races? - const auto handler = XSetErrorHandler(&ignore_errors); - m_focused_window = window; - m_focused_window_class = get_window_class(window); - m_focused_window_title = get_window_title(window); - XSetErrorHandler(handler); + // window handles can become invalid any time + auto window_class = get_window_class(window); + if (window_class.empty() || window_title.empty()) + return false; + m_focused_window = window; + m_focused_window_class = std::move(window_class); + m_focused_window_title = std::move(window_title); return true; } private: - static int ignore_errors(Display*, XErrorEvent*) { return 0; } - Window get_focused_window() { auto type = Atom{ }; auto format = 0; @@ -68,7 +70,7 @@ class FocusedWindow { std::string get_window_class(Window window) { auto ch = XClassHint{ }; - if (m_focused_window && + if (window && XGetClassHint(m_display, window, &ch) != 0) { const auto result = std::string(ch.res_name); XFree(ch.res_name); @@ -84,7 +86,7 @@ class FocusedWindow { auto length = 0ul; auto rest = 0ul; auto data = std::add_pointer_t{ }; - if (m_focused_window && + if (window && XGetWindowProperty(m_display, window, m_net_wm_name_atom, 0, 1024, False, m_utf8_string_atom, &type, &format, &length, &rest, &data) == Success && diff --git a/src/win32/FocusedWindow.cpp b/src/win32/FocusedWindow.cpp index 0f7042fc..ee5e2f5c 100644 --- a/src/win32/FocusedWindow.cpp +++ b/src/win32/FocusedWindow.cpp @@ -2,26 +2,29 @@ #include "FocusedWindow.h" #include "win.h" #include +#include class FocusedWindow { public: - HWND current() const { return m_current; } const std::string& get_class() const { return m_class; } const std::string& get_title() const { return m_title; } bool update() { const auto hwnd = GetForegroundWindow(); - if (hwnd == m_current) + + auto buffer = std::array(); + GetWindowTextA(hwnd, buffer.data(), static_cast(buffer.size())); + + if (hwnd == m_current && + !std::strcmp(buffer.data(), m_title.c_str())) return false; m_current = hwnd; + m_title = buffer.data(); - auto buffer = std::array(); GetClassNameA(hwnd, buffer.data(), static_cast(buffer.size())); m_class = buffer.data(); - GetWindowTextA(hwnd, buffer.data(), static_cast(buffer.size())); - m_title = buffer.data(); return true; }