diff --git a/include/components/renderer.hpp b/include/components/renderer.hpp index 390d7cbe..feab5cc1 100644 --- a/include/components/renderer.hpp +++ b/include/components/renderer.hpp @@ -12,7 +12,6 @@ #include "events/signal_fwd.hpp" #include "events/signal_receiver.hpp" #include "x11/extensions/fwd.hpp" -#include "x11/tray_manager.hpp" #include "x11/types.hpp" POLYBAR_NS @@ -47,10 +46,10 @@ class renderer : public renderer_interface, public signal_receiver { public: using make_type = unique_ptr; - static make_type make(const bar_settings& bar, tags::action_context& action_ctxt, tray_manager& tray); + static make_type make(const bar_settings& bar, tags::action_context& action_ctxt); explicit renderer(connection& conn, signal_emitter& sig, const config&, const logger& logger, const bar_settings& bar, - background_manager& background_manager, tags::action_context& action_ctxt, tray_manager& tray); + background_manager& background_manager, tags::action_context& action_ctxt); ~renderer(); xcb_window_t window() const; @@ -133,8 +132,6 @@ class renderer : public renderer_interface, bool m_fixedcenter; string m_snapshot_dst; - - tray_manager& m_tray; }; POLYBAR_NS_END diff --git a/include/x11/tray_client.hpp b/include/x11/tray_client.hpp index f1edcb14..f9a4ecdb 100644 --- a/include/x11/tray_client.hpp +++ b/include/x11/tray_client.hpp @@ -30,6 +30,8 @@ class tray_client : public non_copyable_mixin { bool mapped() const; void mapped(bool state); + void hidden(bool state); + xcb_window_t embedder() const; xcb_window_t client() const; @@ -85,6 +87,8 @@ class tray_client : public non_copyable_mixin { // TODO bool m_mapped{false}; + bool m_hidden{false}; + size m_size; }; diff --git a/include/x11/tray_manager.hpp b/include/x11/tray_manager.hpp index 4bf06cb7..1a5d50f0 100644 --- a/include/x11/tray_manager.hpp +++ b/include/x11/tray_manager.hpp @@ -23,9 +23,6 @@ #define SYSTEM_TRAY_BEGIN_MESSAGE 1 #define SYSTEM_TRAY_CANCEL_MESSAGE 2 -#define TRAY_WM_NAME "Polybar tray window" -#define TRAY_WM_CLASS "tray\0Polybar" - #define TRAY_PLACEHOLDER "" POLYBAR_NS @@ -38,29 +35,19 @@ using std::atomic; class connection; class bg_slice; -enum class tray_postition { NONE = 0, LEFT, CENTER, RIGHT, MODULE }; - +// TODO move mutable options into tray_manager class struct tray_settings { - tray_postition tray_position{tray_postition::NONE}; bool running{false}; /** - * Tray window position. - * - * Relative to the inner area of the bar - * - * Specifies the top-left corner for left-aligned trays and tray modules. - * For center-aligned, it's the top-center point and for right aligned, it's the top-right point. + * Specifies the top-left corner of the tray area relative to inner area of the bar. */ position pos{0, 0}; - /** - * Tray offset in pixels applied to pos. - */ - position offset{0, 0}; - /** * Current dimensions of the tray window. + * + * TODO setting almost never used -> refactor */ size win_size{0, 0}; @@ -80,17 +67,21 @@ struct tray_settings { unsigned spacing{0U}; rgba background{}; rgba foreground{}; - bool detached{false}; - xcb_window_t bar_window; + /** + * Window ID of tray selection owner. + * + * Matches the bar window + */ + xcb_window_t selection_owner{XCB_NONE}; }; class tray_manager : public xpp::event::sink, - public signal_receiver { + public signal_receiver { public: using make_type = unique_ptr; static make_type make(const bar_settings& bar_opts); @@ -99,6 +90,7 @@ class tray_manager ~tray_manager(); + // TODO only expose necessary information (e.g. running) const tray_settings settings() const; void setup(const string& tray_module_name); @@ -106,7 +98,6 @@ class tray_manager void activate_delayed(chrono::duration delay = 1s); void deactivate(bool clear_selection = true); void reconfigure(); - void reconfigure_bg(); protected: void reconfigure_window(); @@ -115,8 +106,6 @@ class tray_manager void redraw_window(); void query_atom(); - void create_window(); - void set_wm_hints(); void set_tray_colors(); void acquire_selection(); @@ -129,7 +118,7 @@ class tray_manager /** * Final x-position of the tray window relative to the very top-left bar window. */ - int calculate_x(unsigned width) const; + int calculate_x() const; /** * Final y-position of the tray window relative to the very top-left bar window. @@ -162,7 +151,6 @@ class tray_manager void handle(const evt::unmap_notify& evt) override; bool on(const signals::ui::visibility_change& evt) override; - bool on(const signals::ui::dim_window& evt) override; bool on(const signals::ui::update_background& evt) override; bool on(const signals::ui_tray::tray_pos_change& evt) override; bool on(const signals::ui_tray::tray_visibility& evt) override; @@ -177,7 +165,6 @@ class tray_manager const bar_settings& m_bar_opts; xcb_atom_t m_atom{0}; - xcb_window_t m_tray{0}; xcb_window_t m_othermanager{0}; atomic m_activated{false}; @@ -187,6 +174,7 @@ class tray_manager thread m_delaythread; + // TODO try to remove mutex mutable mutex m_mtx{}; bool m_firstactivation{true}; diff --git a/src/components/bar.cpp b/src/components/bar.cpp index fa122fc5..220fcb5a 100644 --- a/src/components/bar.cpp +++ b/src/components/bar.cpp @@ -388,8 +388,8 @@ void bar::parse(string&& data, bool force) { auto rect = m_opts.inner_area(); - // TODO don't shrink the rect but somehow tell renderer to only use part of the rectangle for rendering bar content - // (but render background everyhwere) + // TODO use legacy tray implementation +#if 0 if (m_tray && !m_tray->settings().detached && m_tray->settings().num_mapped_clients > 0 && m_tray->settings().tray_position != tray_postition::MODULE) { auto tray_pos = m_tray->settings().tray_position; @@ -401,6 +401,7 @@ void bar::parse(string&& data, bool force) { rect.width -= traywidth; } } +#endif m_log.info("Redrawing bar window"); m_renderer->begin(rect); @@ -877,7 +878,7 @@ void bar::handle(const evt::configure_notify&) { void bar::start(const string& tray_module_name) { m_log.trace("bar: Create renderer"); - m_renderer = renderer::make(m_opts, *m_action_ctxt, *m_tray); + m_renderer = renderer::make(m_opts, *m_action_ctxt); m_opts.x_data.window = m_renderer->window(); m_opts.x_data.visual = m_renderer->visual(); diff --git a/src/components/renderer.cpp b/src/components/renderer.cpp index d7cbcaf3..5f6ce0b6 100644 --- a/src/components/renderer.cpp +++ b/src/components/renderer.cpp @@ -21,7 +21,7 @@ static constexpr double BLOCK_GAP{20.0}; /** * Create instance */ -renderer::make_type renderer::make(const bar_settings& bar, tags::action_context& action_ctxt, tray_manager& tray) { +renderer::make_type renderer::make(const bar_settings& bar, tags::action_context& action_ctxt) { // clang-format off return std::make_unique( connection::make(), @@ -30,8 +30,7 @@ renderer::make_type renderer::make(const bar_settings& bar, tags::action_context logger::make(), forward(bar), background_manager::make(), - action_ctxt, - tray); + action_ctxt); // clang-format on } @@ -39,15 +38,14 @@ renderer::make_type renderer::make(const bar_settings& bar, tags::action_context * Construct renderer instance */ renderer::renderer(connection& conn, signal_emitter& sig, const config& conf, const logger& logger, - const bar_settings& bar, background_manager& background, tags::action_context& action_ctxt, tray_manager& tray) + const bar_settings& bar, background_manager& background, tags::action_context& action_ctxt) : renderer_interface(action_ctxt) , m_connection(conn) , m_sig(sig) , m_conf(conf) , m_log(logger) , m_bar(forward(bar)) - , m_rect(m_bar.inner_area()) - , m_tray(tray) { + , m_rect(m_bar.inner_area()) { m_sig.attach(this); m_log.trace("renderer: Get TrueColor visual"); @@ -378,7 +376,6 @@ void renderer::flush() { m_connection.clear_area(0, m_window, 0, 0, m_bar.size.w, m_bar.size.h); // m_connection.copy_area(m_pixmap, m_window, m_gcontext, 0, 0, 0, 0, m_bar.size.w, m_bar.size.h); m_connection.flush(); - m_tray.reconfigure_bg(); if (!m_snapshot_dst.empty()) { try { diff --git a/src/x11/tray_client.cpp b/src/x11/tray_client.cpp index 1c27dede..89854c2c 100644 --- a/src/x11/tray_client.cpp +++ b/src/x11/tray_client.cpp @@ -136,9 +136,19 @@ bool tray_client::mapped() const { * Set client window mapped state */ void tray_client::mapped(bool state) { + m_log.trace("tray(%s): set mapped: %i", m_connection.id(client()), state); m_mapped = state; } +/** + * Sets the client window's visibility. + * + * Use this to trigger a mapping/unmapping + */ +void tray_client::hidden(bool state) { + m_hidden = state; +} + xcb_window_t tray_client::embedder() const { return m_wrapper; } @@ -181,11 +191,18 @@ void tray_client::ensure_state() const { should_be_mapped = m_xembed.is_mapped(); } - if (!mapped() && should_be_mapped) { + if (m_hidden) { + should_be_mapped = false; + } + + m_log.trace( + "tray(%s): ensure_state (mapped=%i, should_be_mapped=%i)", m_connection.id(client()), mapped(), should_be_mapped); + + if (should_be_mapped) { m_log.trace("tray(%s): Map client", m_connection.id(client())); m_connection.map_window_checked(embedder()); m_connection.map_window_checked(client()); - } else if (mapped() && !should_be_mapped) { + } else { m_log.trace("tray(%s): Unmap client", m_connection.id(client())); m_connection.unmap_window_checked(client()); m_connection.unmap_window_checked(embedder()); diff --git a/src/x11/tray_manager.cpp b/src/x11/tray_manager.cpp index 7de2423e..62167868 100644 --- a/src/x11/tray_manager.cpp +++ b/src/x11/tray_manager.cpp @@ -68,26 +68,9 @@ tray_manager::~tray_manager() { void tray_manager::setup(const string& tray_module_name) { const config& conf = config::make(); auto bs = conf.section(); - string position = conf.get(bs, "tray-position", "none"s); - if (!position.empty() && position != "none" && !tray_module_name.empty()) { - m_log.warn( - "The tray position is manually defined (`tray-position`) and also set by the tray module (%s). `tray-position` " - "will be ignored", - tray_module_name); - } - - if (!tray_module_name.empty()) { - m_opts.tray_position = tray_postition::MODULE; - } else if (position == "left") { - m_opts.tray_position = tray_postition::LEFT; - } else if (position == "right") { - m_opts.tray_position = tray_postition::RIGHT; - } else if (position == "center") { - m_opts.tray_position = tray_postition::CENTER; - } else if (position != "none") { - return m_log.err("Disabling tray manager (reason: Invalid position \"" + position + "\")"); - } else { + // TODO remove check once part of tray module + if (tray_module_name.empty()) { return; } @@ -95,7 +78,6 @@ void tray_manager::setup(const string& tray_module_name) { m_opts.win_size.w = 0; m_opts.win_size.h = inner_area.height; - m_opts.detached = conf.get(bs, "tray-detached", false); unsigned client_height = inner_area.height; auto maxsize = conf.get(bs, "tray-maxsize", 16); @@ -111,50 +93,15 @@ void tray_manager::setup(const string& tray_module_name) { m_opts.client_size.w *= scale; m_opts.win_size.h *= scale; - m_opts.pos.x = [&]() -> int { - switch (m_opts.tray_position) { - case tray_postition::LEFT: - return 0; - case tray_postition::CENTER: - return inner_area.width / 2 - m_opts.client_size.w / 2; - case tray_postition::RIGHT: - return inner_area.width; - default: - return 0; - } - }(); - m_opts.pos.y = 0; - - if (conf.has(bs, "tray-transparent")) { - m_log.warn("tray-transparent is deprecated, the tray always uses pseudo-transparency. Please remove it."); - } - // Set user-defined foreground and background colors. + // TODO maybe remove m_opts.background = conf.get(bs, "tray-background", m_bar_opts.background); m_opts.foreground = conf.get(bs, "tray-foreground", m_bar_opts.foreground); // Add user-defined padding m_opts.spacing += conf.get(bs, "tray-padding", 0); - // Add user-defiend offset - auto offset_x = conf.get(bs, "tray-offset-x", percentage_with_offset{}); - auto offset_y = conf.get(bs, "tray-offset-y", percentage_with_offset{}); - - int max_x; - int max_y; - - if (m_opts.detached) { - max_x = m_bar_opts.monitor->w; - max_y = m_bar_opts.monitor->h; - } else { - max_x = inner_area.width; - max_y = inner_area.height; - } - - m_opts.offset.x = units_utils::percentage_with_offset_to_pixel(offset_x, max_x, m_bar_opts.dpi_x); - m_opts.offset.y = units_utils::percentage_with_offset_to_pixel(offset_y, max_y, m_bar_opts.dpi_y); - - m_opts.bar_window = m_bar_opts.x_data.window; + m_opts.selection_owner = m_bar_opts.x_data.window; // Activate the tray manager query_atom(); @@ -183,8 +130,6 @@ void tray_manager::activate() { m_sig.attach(this); try { - create_window(); - set_wm_hints(); set_tray_colors(); } catch (const exception& err) { m_log.err(err.what()); @@ -234,16 +179,9 @@ void tray_manager::deactivate(bool clear_selection) { m_log.trace("tray: Unembed clients"); m_clients.clear(); - if (m_tray) { - m_log.trace("tray: Destroy window"); - m_connection.destroy_window(m_tray); - m_tray = 0; - } - m_opts.win_size.w = 0; m_opts.num_mapped_clients = 0; m_acquired_selection = false; - m_mapped = false; m_connection.flush(); @@ -254,7 +192,7 @@ void tray_manager::deactivate(bool clear_selection) { * Reconfigure tray */ void tray_manager::reconfigure() { - if (!m_tray) { + if (!m_opts.selection_owner) { return; } else if (m_mtx.try_lock()) { std::unique_lock guard(m_mtx, std::adopt_lock); @@ -269,11 +207,6 @@ void tray_manager::reconfigure() { } catch (const exception& err) { m_log.err("Failed to reconfigure tray window (%s)", err.what()); } - try { - reconfigure_bg(); - } catch (const exception& err) { - m_log.err("Failed to reconfigure tray background (%s)", err.what()); - } m_opts.num_mapped_clients = mapped_clients(); guard.unlock(); @@ -288,37 +221,15 @@ void tray_manager::reconfigure() { * Reconfigure container window */ void tray_manager::reconfigure_window() { - m_log.trace("tray: Reconfigure window (mapped=%i, clients=%i)", static_cast(m_mapped), m_clients.size()); + m_log.trace("tray: Reconfigure window (hidden=%i, clients=%i, mapped_clients=%i)", static_cast(m_hidden), + m_clients.size(), mapped_clients()); - if (!m_tray) { + if (!m_opts.selection_owner) { return; } - bool has_clients = has_mapped_clients(); - if (!has_clients && m_mapped) { - m_log.trace("tray: Reconfigure window / unmap"); - m_connection.unmap_window_checked(m_tray); - } else if (has_clients && !m_mapped && !m_hidden) { - m_log.trace("tray: Reconfigure window / map"); - m_connection.map_window_checked(m_tray); - } - auto width = calculate_w(); m_opts.win_size.w = width; - - if (width > 0) { - auto x = calculate_x(width); - m_log.trace("tray: New window values, width=%d, x=%d", width, x); - - uint32_t mask = 0; - std::array values{}; - xcb_params_configure_window_t params{}; - - XCB_AUX_ADD_PARAM(&mask, ¶ms, width, width); - XCB_AUX_ADD_PARAM(&mask, ¶ms, x, x); - connection::pack_values(mask, ¶ms, values); - m_connection.configure_window_checked(m_tray, mask, values.data()); - } } /** @@ -327,7 +238,7 @@ void tray_manager::reconfigure_window() { void tray_manager::reconfigure_clients() { m_log.trace("tray: Reconfigure clients"); - int x = m_opts.spacing; + int x = calculate_x() + m_opts.spacing; for (auto it = m_clients.rbegin(); it != m_clients.rend(); it++) { try { @@ -344,18 +255,11 @@ void tray_manager::reconfigure_clients() { m_sig.emit(signals::ui_tray::tray_width_change{calculate_w()}); } -/** - * Reconfigure root pixmap - */ -void tray_manager::reconfigure_bg() { - m_connection.clear_area(false, m_tray, 0, 0, m_opts.win_size.w, m_opts.win_size.h); -} - /** * Refresh the bar window by clearing it along with each client window */ void tray_manager::refresh_window() { - if (!m_activated || !m_mapped || !m_mtx.try_lock()) { + if (!m_activated || m_hidden || !m_mtx.try_lock()) { return; } @@ -363,11 +267,6 @@ void tray_manager::refresh_window() { m_log.trace("tray: Refreshing window"); - auto width = calculate_w(); - auto height = calculate_h(); - - m_connection.clear_area(0, m_tray, 0, 0, width, height); - for (auto& client : m_clients) { try { if (client.mapped()) { @@ -380,20 +279,14 @@ void tray_manager::refresh_window() { } m_connection.flush(); - - if (has_mapped_clients()) { - m_opts.win_size.w = width; - } else { - m_opts.win_size.w = 0; - } + m_opts.win_size.w = calculate_w(); } /** * Redraw window */ void tray_manager::redraw_window() { - m_log.info("Redraw tray container (id=%s)", m_connection.id(m_tray)); - reconfigure_bg(); + m_log.info("Redraw tray container"); refresh_window(); } @@ -407,66 +300,6 @@ void tray_manager::query_atom() { m_atom = reply.atom(); } -/** - * Create tray window - */ -void tray_manager::create_window() { - m_log.trace("tray: Create tray window"); - - // clang-format off - auto win = winspec(m_connection) - << cw_size(calculate_w(), calculate_h()) - << cw_pos(calculate_x(calculate_w()), calculate_y()) - << cw_depth(XCB_COPY_FROM_PARENT) - << cw_visual(XCB_COPY_FROM_PARENT) - << cw_params_colormap(XCB_COPY_FROM_PARENT) - << cw_class(XCB_WINDOW_CLASS_INPUT_OUTPUT) - << cw_params_back_pixmap(XCB_BACK_PIXMAP_PARENT_RELATIVE) - << cw_params_backing_store(XCB_BACKING_STORE_WHEN_MAPPED) - << cw_params_event_mask(XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT - |XCB_EVENT_MASK_STRUCTURE_NOTIFY - |XCB_EVENT_MASK_EXPOSURE) - << cw_parent(m_opts.bar_window); - // clang-format on - - m_tray = win << cw_flush(true); - m_log.info("Tray window: %s", m_connection.id(m_tray)); - - const unsigned shadow{0}; - m_connection.change_property(XCB_PROP_MODE_REPLACE, m_tray, _COMPTON_SHADOW, XCB_ATOM_CARDINAL, 32, 1, &shadow); -} - -/** - * Set window WM hints - */ -void tray_manager::set_wm_hints() { - const xcb_visualid_t visual{m_bar_opts.x_data.visual->visual_id}; - const uint32_t orientation{_NET_SYSTEM_TRAY_ORIENTATION_HORZ}; - - m_log.trace("bar: Set window WM_NAME / WM_CLASS"); - icccm_util::set_wm_name(m_connection, m_tray, TRAY_WM_NAME, 19_z, TRAY_WM_CLASS, 12_z); - - m_log.trace("tray: Set window WM_PROTOCOLS"); - icccm_util::set_wm_protocols(m_connection, m_tray, {WM_DELETE_WINDOW, WM_TAKE_FOCUS}); - - m_log.trace("tray: Set window _NET_WM_WINDOW_TYPE"); - ewmh_util::set_wm_window_type(m_tray, {_NET_WM_WINDOW_TYPE_DOCK, _NET_WM_WINDOW_TYPE_NORMAL}); - - m_log.trace("tray: Set window _NET_WM_STATE"); - ewmh_util::set_wm_state(m_tray, {_NET_WM_STATE_SKIP_TASKBAR}); - - m_log.trace("tray: Set window _NET_WM_PID"); - ewmh_util::set_wm_pid(m_tray); - - m_log.trace("tray: Set window _NET_SYSTEM_TRAY_VISUAL"); - xcb_change_property( - m_connection, XCB_PROP_MODE_REPLACE, m_tray, _NET_SYSTEM_TRAY_VISUAL, XCB_ATOM_VISUALID, 32, 1, &visual); - - m_log.trace("tray: Set window _NET_SYSTEM_TRAY_ORIENTATION"); - xcb_change_property(m_connection, XCB_PROP_MODE_REPLACE, m_tray, _NET_SYSTEM_TRAY_ORIENTATION, - _NET_SYSTEM_TRAY_ORIENTATION, 32, 1, &orientation); -} - /** * Set color atom used by clients when determing icon theme */ @@ -489,7 +322,7 @@ void tray_manager::set_tray_colors() { }; m_connection.change_property( - XCB_PROP_MODE_REPLACE, m_tray, _NET_SYSTEM_TRAY_COLORS, XCB_ATOM_CARDINAL, 32, 12, colors); + XCB_PROP_MODE_REPLACE, m_opts.selection_owner, _NET_SYSTEM_TRAY_COLORS, XCB_ATOM_CARDINAL, 32, 12, colors); } /** @@ -505,16 +338,16 @@ void tray_manager::acquire_selection() { return; } - if (owner == m_tray) { + if (owner == m_opts.selection_owner) { m_log.trace("tray: Already managing the systray selection"); m_acquired_selection = true; } else if ((m_othermanager = owner) != XCB_NONE) { m_log.warn("Systray selection already managed (window=%s)", m_connection.id(owner)); track_selection_owner(m_othermanager); } else { - m_log.trace("tray: Change selection owner to %s", m_connection.id(m_tray)); - m_connection.set_selection_owner_checked(m_tray, m_atom, XCB_CURRENT_TIME); - if (m_connection.get_selection_owner_unchecked(m_atom)->owner != m_tray) { + m_log.trace("tray: Change selection owner to %s", m_connection.id(m_opts.selection_owner)); + m_connection.set_selection_owner_checked(m_opts.selection_owner, m_atom, XCB_CURRENT_TIME); + if (m_connection.get_selection_owner_unchecked(m_atom)->owner != m_opts.selection_owner) { throw application_error("Failed to get control of the systray selection"); } m_acquired_selection = true; @@ -530,7 +363,7 @@ void tray_manager::notify_clients() { auto message = m_connection.make_client_message(MANAGER, m_connection.root()); message.data.data32[0] = XCB_CURRENT_TIME; message.data.data32[1] = m_atom; - message.data.data32[2] = m_tray; + message.data.data32[2] = m_opts.selection_owner; m_connection.send_client_message(message, m_connection.root()); } } @@ -568,7 +401,7 @@ void tray_manager::process_docking_request(xcb_window_t win) { m_log.info("Processing docking request from '%s' (%s)", ewmh_util::get_wm_name(win), m_connection.id(win)); try { - tray_client client(m_log, m_connection, m_tray, win, m_opts.client_size); + tray_client client(m_log, m_connection, m_opts.selection_owner, win, m_opts.client_size); try { client.query_xembed(); @@ -604,18 +437,12 @@ void tray_manager::process_docking_request(xcb_window_t win) { /** * Calculate x position of tray window */ -int tray_manager::calculate_x(unsigned width) const { - auto x = m_bar_opts.inner_area(false).x + m_opts.pos.x + m_opts.offset.x; - if (m_opts.tray_position == tray_postition::RIGHT) { - x -= ((m_opts.client_size.w + m_opts.spacing) * m_clients.size() + m_opts.spacing); - } else if (m_opts.tray_position == tray_postition::CENTER) { - x -= (width / 2) - (m_opts.client_size.w / 2); - } - return x; +int tray_manager::calculate_x() const { + return m_bar_opts.inner_area(false).x + m_opts.pos.x; } int tray_manager::calculate_y() const { - return m_bar_opts.inner_area(false).y + m_opts.pos.y + m_opts.offset.y; + return m_bar_opts.inner_area(false).y + m_opts.pos.y; } unsigned tray_manager::calculate_w() const { @@ -695,20 +522,21 @@ bool tray_manager::has_mapped_clients() const { } bool tray_manager::change_visibility(bool visible) { - bool has_clients = has_mapped_clients(); + if (!m_activated || m_hidden == !visible) { + return false; + } - m_log.trace("tray: visibility_change (state=%i, activated=%i, mapped=%i, hidden=%i)", visible, - static_cast(m_activated), static_cast(m_mapped), static_cast(m_hidden)); + m_log.trace("tray: visibility_change (state=%i, activated=%i, hidden=%i)", visible, static_cast(m_activated), + static_cast(m_hidden)); m_hidden = !visible; - if (!m_activated) { - return false; - } else if (!m_hidden && !m_mapped && has_clients) { - m_connection.map_window(m_tray); - } else if ((!has_clients || m_hidden) && m_mapped) { - m_connection.unmap_window(m_tray); - } else if (m_mapped && !m_hidden && has_clients) { + for (auto& client : m_clients) { + client.hidden(m_hidden); + client.ensure_state(); + } + + if (!m_hidden) { redraw_window(); } @@ -742,9 +570,9 @@ void tray_manager::handle(const evt::visibility_notify& evt) { void tray_manager::handle(const evt::client_message& evt) { if (!m_activated) { return; - } else if (evt->type == WM_PROTOCOLS && evt->data.data32[0] == WM_DELETE_WINDOW && evt->window == m_tray) { + } else if (evt->type == WM_PROTOCOLS && evt->data.data32[0] == WM_DELETE_WINDOW && + evt->window == m_opts.selection_owner) { m_log.notice("Received WM_DELETE"); - m_tray = 0; deactivate(); } else if (evt->type == _NET_SYSTEM_TRAY_OPCODE && evt->format == 32) { m_log.trace("tray: Received client_message"); @@ -802,7 +630,7 @@ void tray_manager::handle(const evt::selection_clear& evt) { return; } else if (evt->selection != m_atom) { return; - } else if (evt->owner != m_tray) { + } else if (evt->owner != m_opts.selection_owner) { return; } @@ -882,9 +710,7 @@ void tray_manager::handle(const evt::reparent_notify& evt) { * Event callback : XCB_DESTROY_NOTIFY */ void tray_manager::handle(const evt::destroy_notify& evt) { - if (m_activated && evt->window == m_tray) { - deactivate(); - } else if (!m_activated && evt->window == m_othermanager) { + if (!m_activated && evt->window == m_othermanager) { m_log.info("Systray selection unmanaged... re-activating"); activate(); } else if (m_activated && is_embedded(evt->window)) { @@ -898,7 +724,7 @@ void tray_manager::handle(const evt::destroy_notify& evt) { * Event callback : XCB_MAP_NOTIFY */ void tray_manager::handle(const evt::map_notify& evt) { - if (m_activated && evt->window == m_tray) { + 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; @@ -917,7 +743,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 && evt->window == m_tray) { + 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; @@ -937,14 +763,6 @@ bool tray_manager::on(const signals::ui::visibility_change& evt) { return change_visibility(evt.cast()); } -bool tray_manager::on(const signals::ui::dim_window& evt) { - if (m_activated) { - ewmh_util::set_wm_window_opacity(m_tray, evt.cast() * 0xFFFFFFFF); - } - // let the event bubble - return false; -} - // TODO maybe remove signal bool tray_manager::on(const signals::ui::update_background&) { redraw_window(); @@ -961,11 +779,7 @@ bool tray_manager::on(const signals::ui_tray::tray_pos_change& evt) { } bool tray_manager::on(const signals::ui_tray::tray_visibility& evt) { - if (evt.cast() == m_hidden && m_opts.tray_position == tray_postition::MODULE) { - return change_visibility(evt.cast()); - } else { - return true; - } + return change_visibility(evt.cast()); } POLYBAR_NS_END