diff --git a/include/x11/tray_manager.hpp b/include/x11/tray_manager.hpp index 1a5d50f0..129cf025 100644 --- a/include/x11/tray_manager.hpp +++ b/include/x11/tray_manager.hpp @@ -35,32 +35,12 @@ using std::atomic; class connection; class bg_slice; -// TODO move mutable options into tray_manager class struct tray_settings { - bool running{false}; - - /** - * Specifies the top-left corner of the tray area relative to inner area of the bar. - */ - position pos{0, 0}; - - /** - * Current dimensions of the tray window. - * - * TODO setting almost never used -> refactor - */ - size win_size{0, 0}; - /** * Dimensions for client windows. */ size client_size{0, 0}; - /** - * Number of clients currently mapped. - */ - int num_mapped_clients{0}; - /** * Number of pixels added between tray icons */ @@ -90,8 +70,7 @@ class tray_manager ~tray_manager(); - // TODO only expose necessary information (e.g. running) - const tray_settings settings() const; + bool running() const; void setup(const string& tray_module_name); void activate(); @@ -126,7 +105,6 @@ class tray_manager int calculate_y() const; unsigned calculate_w() const; - unsigned calculate_h() const; int calculate_client_y(); @@ -134,8 +112,6 @@ class tray_manager 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); - int mapped_clients() const; - bool has_mapped_clients() const; bool change_visibility(bool visible); void handle(const evt::expose& evt) override; @@ -164,11 +140,30 @@ class tray_manager tray_settings m_opts{}; const bar_settings& m_bar_opts; - xcb_atom_t m_atom{0}; - xcb_window_t m_othermanager{0}; + /** + * Systray selection atom _NET_SYSTEM_TRAY_Sn + */ + xcb_atom_t m_atom{XCB_NONE}; + /** + * Owner of systray selection (if we don't own it) + */ + xcb_window_t m_othermanager{XCB_NONE}; + + /** + * Specifies the top-left corner of the tray area relative to inner area of the bar. + */ + position m_pos{0, 0}; + + /** + * Current width of the tray. + */ + unsigned m_tray_width{0}; + + /** + * Whether the tray is running + */ atomic m_activated{false}; - atomic m_mapped{false}; atomic m_hidden{false}; atomic m_acquired_selection{false}; diff --git a/src/components/bar.cpp b/src/components/bar.cpp index 220fcb5a..5e2eb0d3 100644 --- a/src/components/bar.cpp +++ b/src/components/bar.cpp @@ -840,7 +840,7 @@ void bar::handle(const evt::button_press& evt) { */ void bar::handle(const evt::expose& evt) { if (evt->window == m_opts.x_data.window && evt->count == 0) { - if (m_tray->settings().running) { + if (m_tray->running()) { broadcast_visibility(); } diff --git a/src/x11/tray_manager.cpp b/src/x11/tray_manager.cpp index 62167868..13d883b5 100644 --- a/src/x11/tray_manager.cpp +++ b/src/x11/tray_manager.cpp @@ -75,9 +75,6 @@ void tray_manager::setup(const string& tray_module_name) { } auto inner_area = m_bar_opts.inner_area(); - m_opts.win_size.w = 0; - m_opts.win_size.h = inner_area.height; - unsigned client_height = inner_area.height; auto maxsize = conf.get(bs, "tray-maxsize", 16); @@ -86,12 +83,11 @@ void tray_manager::setup(const string& tray_module_name) { client_height = maxsize; } - m_opts.client_size = {client_height, client_height}; - // Apply user-defined scaling auto scale = conf.get(bs, "tray-scale", 1.0); - m_opts.client_size.w *= scale; - m_opts.win_size.h *= scale; + client_height *= scale; + + m_opts.client_size = {client_height, client_height}; // Set user-defined foreground and background colors. // TODO maybe remove @@ -108,11 +104,8 @@ void tray_manager::setup(const string& tray_module_name) { activate(); } -/** - * Get the settings container - */ -const tray_settings tray_manager::settings() const { - return m_opts; +bool tray_manager::running() const { + return m_activated; } /** @@ -125,7 +118,6 @@ void tray_manager::activate() { m_log.info("Activating tray manager"); m_activated = true; - m_opts.running = true; m_sig.attach(this); @@ -167,7 +159,6 @@ void tray_manager::deactivate(bool clear_selection) { m_log.info("Deactivating tray manager"); m_activated = false; - m_opts.running = false; m_sig.detach(this); @@ -179,8 +170,6 @@ void tray_manager::deactivate(bool clear_selection) { m_log.trace("tray: Unembed clients"); m_clients.clear(); - m_opts.win_size.w = 0; - m_opts.num_mapped_clients = 0; m_acquired_selection = false; m_connection.flush(); @@ -197,20 +186,18 @@ void tray_manager::reconfigure() { } else if (m_mtx.try_lock()) { std::unique_lock guard(m_mtx, std::adopt_lock); - try { - reconfigure_clients(); - } catch (const exception& err) { - m_log.err("Failed to reconfigure tray clients (%s)", err.what()); - } try { reconfigure_window(); } catch (const exception& err) { m_log.err("Failed to reconfigure tray window (%s)", err.what()); } - m_opts.num_mapped_clients = mapped_clients(); + try { + reconfigure_clients(); + } catch (const exception& err) { + m_log.err("Failed to reconfigure tray clients (%s)", err.what()); + } guard.unlock(); - refresh_window(); m_connection.flush(); } @@ -221,15 +208,8 @@ void tray_manager::reconfigure() { * Reconfigure container window */ void tray_manager::reconfigure_window() { - m_log.trace("tray: Reconfigure window (hidden=%i, clients=%i, mapped_clients=%i)", static_cast(m_hidden), - m_clients.size(), mapped_clients()); - - if (!m_opts.selection_owner) { - return; - } - - auto width = calculate_w(); - m_opts.win_size.w = width; + m_log.trace("tray: Reconfigure window (hidden=%i, clients=%i)", static_cast(m_hidden), m_clients.size()); + m_tray_width = calculate_w(); } /** @@ -248,11 +228,12 @@ void tray_manager::reconfigure_clients() { x += m_opts.client_size.w + m_opts.spacing; } catch (const xpp::x::error::window& err) { // TODO print error + m_log.err("Failed to reconfigure client (%s), removing ... (%s)", m_connection.id(it->client()), err.what()); remove_client(*it, false); } } - m_sig.emit(signals::ui_tray::tray_width_change{calculate_w()}); + m_sig.emit(signals::ui_tray::tray_width_change{m_tray_width}); } /** @@ -279,7 +260,6 @@ void tray_manager::refresh_window() { } m_connection.flush(); - m_opts.win_size.w = calculate_w(); } /** @@ -438,11 +418,11 @@ void tray_manager::process_docking_request(xcb_window_t win) { * Calculate x position of tray window */ int tray_manager::calculate_x() const { - return m_bar_opts.inner_area(false).x + m_opts.pos.x; + return m_bar_opts.inner_area(false).x + m_pos.x; } int tray_manager::calculate_y() const { - return m_bar_opts.inner_area(false).y + m_opts.pos.y; + return m_bar_opts.inner_area(false).y + m_pos.y; } unsigned tray_manager::calculate_w() const { @@ -457,18 +437,11 @@ unsigned tray_manager::calculate_w() const { return count ? width : 0; } -/** - * Calculate height of tray window - */ -unsigned tray_manager::calculate_h() const { - return m_opts.win_size.h; -} - /** * Calculate y position of client window */ int tray_manager::calculate_client_y() { - return (m_opts.win_size.h - m_opts.client_size.h) / 2; + return (m_bar_opts.inner_area(true).height - m_opts.client_size.h) / 2; } /** @@ -510,17 +483,6 @@ void tray_manager::remove_client(xcb_window_t win, bool reconfigure) { } } -/** - * Get number of mapped clients - */ -int tray_manager::mapped_clients() const { - return std::count_if(m_clients.begin(), m_clients.end(), [](const auto& c) { return c.mapped(); }); -} - -bool tray_manager::has_mapped_clients() const { - return std::find_if(m_clients.begin(), m_clients.end(), [](const auto& c) { return c.mapped(); }) != m_clients.end(); -} - bool tray_manager::change_visibility(bool visible) { if (!m_activated || m_hidden == !visible) { return false; @@ -727,13 +689,14 @@ void tray_manager::handle(const evt::map_notify& evt) { if (m_activated && evt->window == m_opts.selection_owner) { m_log.trace("tray: Received map_notify"); m_log.trace("tray: Update container mapped flag"); - m_mapped = true; redraw_window(); } else if (is_embedded(evt->window)) { m_log.trace("tray: Received map_notify"); m_log.trace("tray: Set client mapped"); - find_client(evt->window)->mapped(true); - if (mapped_clients() > m_opts.num_mapped_clients) { + auto client = find_client(evt->window); + + if (!client->mapped()) { + client->mapped(true); reconfigure(); } } @@ -743,14 +706,15 @@ 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 && evt->window == m_opts.selection_owner) { - m_log.trace("tray: Received unmap_notify"); - m_log.trace("tray: Update container mapped flag"); - m_mapped = false; - } else if (m_activated && is_embedded(evt->window)) { + if (m_activated && is_embedded(evt->window)) { m_log.trace("tray: Received unmap_notify"); m_log.trace("tray: Set client unmapped"); - find_client(evt->window)->mapped(false); + auto client = find_client(evt->window); + + if (client->mapped()) { + client->mapped(false); + reconfigure(); + } } } @@ -771,9 +735,12 @@ bool tray_manager::on(const signals::ui::update_background&) { } bool tray_manager::on(const signals::ui_tray::tray_pos_change& evt) { - m_opts.pos.x = std::max(0, std::min(evt.cast(), (int)(m_bar_opts.size.w - calculate_w()))); + int new_x = std::max(0, std::min(evt.cast(), (int)(m_bar_opts.size.w - m_tray_width))); - reconfigure_window(); + if (new_x != m_pos.x) { + m_pos.x = new_x; + reconfigure(); + } return true; }