tray: Fix tray not updating after (un)map_notify

The issue was that the event was for the wrapper window and that the
tray_client's move constructors didn't correctly copy over all data and
so when the m_clients vector grew, it corrupted the state of all
existing clients.
This commit is contained in:
patrick96 2022-09-03 22:34:00 +02:00
parent 1127792ccf
commit 901183a60a
No known key found for this signature in database
GPG Key ID: 521E5E03AEBCA1A7
3 changed files with 31 additions and 18 deletions

View File

@ -64,7 +64,8 @@ class tray_manager : public xpp::event::sink<evt::expose, evt::visibility_notify
public signal_receiver<SIGN_PRIORITY_TRAY, signals::ui::update_background,
signals::ui_tray::tray_pos_change, signals::ui_tray::tray_visibility> {
public:
explicit tray_manager(connection& conn, signal_emitter& emitter, const logger& logger, const bar_settings& bar_opts, on_update on_update);
explicit tray_manager(connection& conn, signal_emitter& emitter, const logger& logger, const bar_settings& bar_opts,
on_update on_update);
~tray_manager();
@ -108,7 +109,7 @@ class tray_manager : public xpp::event::sink<evt::expose, evt::visibility_notify
void update_width();
bool is_embedded(const xcb_window_t& win) const;
bool is_embedded(const xcb_window_t& win);
tray_client* find_client(const xcb_window_t& win);
void remove_client(const tray_client& client, bool reconfigure = true);
void remove_client(xcb_window_t win, bool reconfigure = true);

View File

@ -68,9 +68,14 @@ tray_client::~tray_client() {
}
}
tray_client::tray_client(tray_client&& c) : m_log(c.m_log), m_connection(c.m_connection), m_size(c.m_size) {
tray_client::tray_client(tray_client&& c) : m_log(c.m_log), m_connection(c.m_connection) {
std::swap(m_wrapper, c.m_wrapper);
std::swap(m_client, c.m_client);
std::swap(m_xembed_supported, c.m_xembed_supported);
std::swap(m_xembed, c.m_xembed);
std::swap(m_mapped, c.m_mapped);
std::swap(m_hidden, c.m_hidden);
std::swap(m_size, c.m_size);
}
tray_client& tray_client::operator=(tray_client&& c) {
@ -78,6 +83,10 @@ tray_client& tray_client::operator=(tray_client&& c) {
m_connection = c.m_connection;
std::swap(m_wrapper, c.m_wrapper);
std::swap(m_client, c.m_client);
std::swap(m_xembed_supported, c.m_xembed_supported);
std::swap(m_xembed, c.m_xembed);
std::swap(m_mapped, c.m_mapped);
std::swap(m_hidden, c.m_hidden);
std::swap(m_size, c.m_size);
return *this;
}
@ -196,7 +205,7 @@ void tray_client::ensure_state() const {
}
m_log.trace("tray(%s): ensure_state (hidden=%i, mapped=%i, should_be_mapped=%i)", m_connection.id(client()), m_hidden,
mapped(), should_be_mapped);
m_mapped, should_be_mapped);
if (should_be_mapped) {
m_log.trace("tray(%s): Map client", m_connection.id(client()));

View File

@ -449,23 +449,26 @@ int tray_manager::calculate_client_y() {
}
/**
* Check if the given window is embedded
* Check if the given window is embedded.
*
* The given window ID can be the ID of the wrapper or the embedded window
*/
bool tray_manager::is_embedded(const xcb_window_t& win) const {
return m_clients.end() !=
std::find_if(m_clients.begin(), m_clients.end(), [win](const auto& client) { return client.match(win); });
bool tray_manager::is_embedded(const xcb_window_t& win) {
return find_client(win) != nullptr;
}
/**
* Find tray client by window
* Find tray client object from the wrapper or embedded window
*/
tray_client* tray_manager::find_client(const xcb_window_t& win) {
for (auto& client : m_clients) {
if (client.match(win)) {
return &client;
}
auto client = std::find_if(m_clients.begin(), m_clients.end(),
[win](const auto& client) { return client.match(win) || client.embedder() == win; });
if (client == m_clients.end()) {
return nullptr;
} else {
return &(*client);
}
return nullptr;
}
/**
@ -667,7 +670,7 @@ void tray_manager::handle(const evt::reparent_notify& evt) {
}
if (evt->parent != client->embedder()) {
m_log.trace("tray: Received reparent_notify for client, remove...");
m_log.info("tray: Received reparent_notify for client, remove...");
remove_client(*client);
}
}
@ -680,7 +683,7 @@ void tray_manager::handle(const evt::destroy_notify& evt) {
m_log.info("Systray selection unmanaged... re-activating");
activate();
} else if (m_activated && is_embedded(evt->window)) {
m_log.trace("tray: Received destroy_notify for client, remove...");
m_log.info("tray: Received destroy_notify for client, remove...");
remove_client(evt->window);
redraw_window();
}
@ -694,7 +697,7 @@ void tray_manager::handle(const evt::map_notify& evt) {
m_log.trace("tray: Received map_notify");
m_log.trace("tray: Update container mapped flag");
redraw_window();
} else if (is_embedded(evt->window)) { // TODO FIXME evt->window points to the wrapper window
} else if (is_embedded(evt->window)) {
m_log.trace("tray: Received map_notify");
m_log.trace("tray: Set client mapped");
auto client = find_client(evt->window);
@ -710,7 +713,7 @@ void tray_manager::handle(const evt::map_notify& evt) {
* Event callback : XCB_UNMAP_NOTIFY
*/
void tray_manager::handle(const evt::unmap_notify& evt) {
if (m_activated && is_embedded(evt->window)) { // TODO FIXME evt->window points to the wrapper window
if (m_activated && is_embedded(evt->window)) {
m_log.trace("tray: Received unmap_notify");
m_log.trace("tray: Set client unmapped");
auto client = find_client(evt->window);