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:
parent
1127792ccf
commit
901183a60a
@ -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);
|
||||
|
@ -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()));
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user