diff --git a/CHANGELOG.md b/CHANGELOG.md index 1be199b8..1336f17a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -62,6 +62,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - IPC commands to change visibility of modules (`hide.`, `show.`, and `toggle.`) ([`#2108`](https://github.com/polybar/polybar/issues/2108)) +- `internal/xworkspaces`: Make the urgent hint persistent + ([`#1081`](https://github.com/polybar/polybar/issues/1081)) ### Changed - Slight changes to the value ranges the different ramp levels are responsible diff --git a/include/modules/xworkspaces.hpp b/include/modules/xworkspaces.hpp index d58cf455..3a32f131 100644 --- a/include/modules/xworkspaces.hpp +++ b/include/modules/xworkspaces.hpp @@ -68,9 +68,9 @@ namespace modules { void handle(const evt::property_notify& evt); void rebuild_clientlist(); + void rebuild_urgent_hints(); void rebuild_desktops(); void rebuild_desktop_states(); - void set_desktop_urgent(xcb_window_t window); bool input(const string& action, const string& data); @@ -91,6 +91,7 @@ namespace modules { bool m_monitorsupport{true}; vector m_desktop_names; + vector m_urgent_desktops; unsigned int m_current_desktop; string m_current_desktop_name; diff --git a/src/modules/xworkspaces.cpp b/src/modules/xworkspaces.cpp index f8b7b9b1..7a6cc954 100644 --- a/src/modules/xworkspaces.cpp +++ b/src/modules/xworkspaces.cpp @@ -119,9 +119,8 @@ namespace modules { m_current_desktop_name = m_desktop_names[m_current_desktop]; rebuild_desktop_states(); } else if (evt->atom == WM_HINTS) { - if (icccm_util::get_wm_urgency(m_connection, evt->window)) { - set_desktop_urgent(evt->window); - } + rebuild_urgent_hints(); + rebuild_desktop_states(); } else { return; } @@ -146,7 +145,21 @@ namespace modules { // rebuild entire mapping of clients to desktops m_clients.clear(); for (auto&& client : newclients) { - m_clients[client] = ewmh_util::get_desktop_from_window(client); + auto desk = ewmh_util::get_desktop_from_window(client); + m_clients[client] = desk; + } + + rebuild_urgent_hints(); + } + + /** + * Goes through all clients and updates the urgent hints on the desktop they are on. + */ + void xworkspaces_module::rebuild_urgent_hints() { + m_urgent_desktops.assign(m_desktop_names.size(), false); + for (auto&& client : ewmh_util::get_client_list()) { + auto desk = ewmh_util::get_desktop_from_window(client); + m_urgent_desktops[desk] = m_urgent_desktops[desk] || icccm_util::get_wm_urgency(m_connection, client); } } @@ -243,7 +256,9 @@ namespace modules { for (auto&& v : m_viewports) { for (auto&& d : v->desktops) { - if (d->index == m_current_desktop) { + if (m_urgent_desktops[d->index]) { + d->state = desktop_state::URGENT; + } else if (d->index == m_current_desktop) { d->state = desktop_state::ACTIVE; } else if (occupied_desks.count(d->index) > 0) { d->state = desktop_state::OCCUPIED; @@ -275,30 +290,6 @@ namespace modules { return names; } - /** - * Find window and set corresponding desktop to urgent - */ - void xworkspaces_module::set_desktop_urgent(xcb_window_t window) { - auto desk = ewmh_util::get_desktop_from_window(window); - if (desk == m_current_desktop) - // ignore if current desktop is urgent - return; - for (auto&& v : m_viewports) { - for (auto&& d : v->desktops) { - if (d->index == desk && d->state != desktop_state::URGENT) { - d->state = desktop_state::URGENT; - - d->label = m_labels.at(d->state)->clone(); - d->label->reset_tokens(); - d->label->replace_token("%index%", to_string(d->index + 1)); - d->label->replace_token("%name%", m_desktop_names[d->index]); - d->label->replace_token("%icon%", m_icons->get(m_desktop_names[d->index], DEFAULT_ICON)->get()); - return; - } - } - } - } - /** * Fetch and parse data */