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,
|
public signal_receiver<SIGN_PRIORITY_TRAY, signals::ui::update_background,
|
||||||
signals::ui_tray::tray_pos_change, signals::ui_tray::tray_visibility> {
|
signals::ui_tray::tray_pos_change, signals::ui_tray::tray_visibility> {
|
||||||
public:
|
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();
|
~tray_manager();
|
||||||
|
|
||||||
@ -108,7 +109,7 @@ class tray_manager : public xpp::event::sink<evt::expose, evt::visibility_notify
|
|||||||
|
|
||||||
void update_width();
|
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);
|
tray_client* find_client(const xcb_window_t& win);
|
||||||
void remove_client(const tray_client& client, bool reconfigure = true);
|
void remove_client(const tray_client& client, bool reconfigure = true);
|
||||||
void remove_client(xcb_window_t win, 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_wrapper, c.m_wrapper);
|
||||||
std::swap(m_client, c.m_client);
|
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) {
|
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;
|
m_connection = c.m_connection;
|
||||||
std::swap(m_wrapper, c.m_wrapper);
|
std::swap(m_wrapper, c.m_wrapper);
|
||||||
std::swap(m_client, c.m_client);
|
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);
|
std::swap(m_size, c.m_size);
|
||||||
return *this;
|
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,
|
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) {
|
if (should_be_mapped) {
|
||||||
m_log.trace("tray(%s): Map client", m_connection.id(client()));
|
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 {
|
bool tray_manager::is_embedded(const xcb_window_t& win) {
|
||||||
return m_clients.end() !=
|
return find_client(win) != nullptr;
|
||||||
std::find_if(m_clients.begin(), m_clients.end(), [win](const auto& client) { return client.match(win); });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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) {
|
tray_client* tray_manager::find_client(const xcb_window_t& win) {
|
||||||
for (auto& client : m_clients) {
|
auto client = std::find_if(m_clients.begin(), m_clients.end(),
|
||||||
if (client.match(win)) {
|
[win](const auto& client) { return client.match(win) || client.embedder() == win; });
|
||||||
return &client;
|
|
||||||
}
|
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()) {
|
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);
|
remove_client(*client);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -680,7 +683,7 @@ void tray_manager::handle(const evt::destroy_notify& evt) {
|
|||||||
m_log.info("Systray selection unmanaged... re-activating");
|
m_log.info("Systray selection unmanaged... re-activating");
|
||||||
activate();
|
activate();
|
||||||
} else if (m_activated && is_embedded(evt->window)) {
|
} 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);
|
remove_client(evt->window);
|
||||||
redraw_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: Received map_notify");
|
||||||
m_log.trace("tray: Update container mapped flag");
|
m_log.trace("tray: Update container mapped flag");
|
||||||
redraw_window();
|
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: Received map_notify");
|
||||||
m_log.trace("tray: Set client mapped");
|
m_log.trace("tray: Set client mapped");
|
||||||
auto client = find_client(evt->window);
|
auto client = find_client(evt->window);
|
||||||
@ -710,7 +713,7 @@ void tray_manager::handle(const evt::map_notify& evt) {
|
|||||||
* Event callback : XCB_UNMAP_NOTIFY
|
* Event callback : XCB_UNMAP_NOTIFY
|
||||||
*/
|
*/
|
||||||
void tray_manager::handle(const evt::unmap_notify& evt) {
|
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: Received unmap_notify");
|
||||||
m_log.trace("tray: Set client unmapped");
|
m_log.trace("tray: Set client unmapped");
|
||||||
auto client = find_client(evt->window);
|
auto client = find_client(evt->window);
|
||||||
|
Loading…
Reference in New Issue
Block a user