diff --git a/include/components/renderer.hpp b/include/components/renderer.hpp index 31dae136..fbbb01a3 100644 --- a/include/components/renderer.hpp +++ b/include/components/renderer.hpp @@ -12,6 +12,7 @@ #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 @@ -46,10 +47,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); + static make_type make(const bar_settings& bar, tags::action_context& action_ctxt, tray_manager& tray); 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); + background_manager& background_manager, tags::action_context& action_ctxt, tray_manager& tray); ~renderer(); xcb_window_t window() const; @@ -132,6 +133,8 @@ 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_manager.hpp b/include/x11/tray_manager.hpp index f8a475ad..9807fca2 100644 --- a/include/x11/tray_manager.hpp +++ b/include/x11/tray_manager.hpp @@ -109,11 +109,11 @@ class tray_manager : public xpp::event::sink delay = 1s); void deactivate(bool clear_selection = true); void reconfigure(); + void reconfigure_bg(); protected: void reconfigure_window(); void reconfigure_clients(); - void reconfigure_bg(); void refresh_window(); void redraw_window(); diff --git a/src/components/bar.cpp b/src/components/bar.cpp index db08916a..c79b059d 100644 --- a/src/components/bar.cpp +++ b/src/components/bar.cpp @@ -878,7 +878,7 @@ void bar::handle(const evt::configure_notify&) { void bar::start() { m_log.trace("bar: Create renderer"); - m_renderer = renderer::make(m_opts, *m_action_ctxt); + m_renderer = renderer::make(m_opts, *m_action_ctxt, *m_tray); 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 4982da28..ea8ffe1a 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) { +renderer::make_type renderer::make(const bar_settings& bar, tags::action_context& action_ctxt, tray_manager& tray) { // clang-format off return std::make_unique( connection::make(), @@ -30,7 +30,8 @@ renderer::make_type renderer::make(const bar_settings& bar, tags::action_context logger::make(), forward(bar), background_manager::make(), - action_ctxt); + action_ctxt, + tray); // clang-format on } @@ -38,14 +39,15 @@ 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) + const bar_settings& bar, background_manager& background, tags::action_context& action_ctxt, tray_manager& tray) : 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_rect(m_bar.inner_area()) + , m_tray(tray) { m_sig.attach(this); m_log.trace("renderer: Get TrueColor visual"); @@ -86,6 +88,15 @@ renderer::renderer(connection& conn, signal_emitter& sig, const config& conf, co { m_pixmap = m_connection.generate_id(); m_connection.create_pixmap(m_depth, m_pixmap, m_window, m_bar.size.w, m_bar.size.h); + + // TODO + uint32_t configure_mask = 0; + std::array configure_values{}; + xcb_params_cw_t configure_params{}; + + XCB_AUX_ADD_PARAM(&configure_mask, &configure_params, back_pixmap, m_pixmap); + connection::pack_values(configure_mask, &configure_params, configure_values); + m_connection.change_window_attributes_checked(m_window, configure_mask, configure_values.data()); } m_log.trace("renderer: Allocate graphic contexts"); @@ -364,8 +375,10 @@ void renderer::flush() { highlight_clickable_areas(); m_surface->flush(); - m_connection.copy_area(m_pixmap, m_window, m_gcontext, 0, 0, 0, 0, m_bar.size.w, m_bar.size.h); + 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 d2f89af8..a5ffaee4 100644 --- a/src/x11/tray_client.cpp +++ b/src/x11/tray_client.cpp @@ -34,7 +34,8 @@ tray_client::tray_client(const logger& log, connection& conn, xcb_window_t tray, << cw_parent(tray) << cw_class(XCB_WINDOW_CLASS_INPUT_OUTPUT) // TODO add proper pixmap - << cw_params_back_pixmap(XCB_PIXMAP_NONE) + // << cw_params_back_pixmap(XCB_PIXMAP_NONE) + << cw_params_back_pixel(0x00ff00) // The X server requires the border pixel to be defined if the depth doesn't match the parent window << cw_params_border_pixel(conn.screen()->black_pixel) << cw_params_backing_store(XCB_BACKING_STORE_WHEN_MAPPED) @@ -92,6 +93,11 @@ void tray_client::update_client_attributes() const { XCB_AUX_ADD_PARAM( &configure_mask, &configure_params, event_mask, XCB_EVENT_MASK_PROPERTY_CHANGE | XCB_EVENT_MASK_STRUCTURE_NOTIFY); + // TODO + XCB_AUX_ADD_PARAM(&configure_mask, &configure_params, back_pixel, 0xff0000ff); + // TODO + XCB_AUX_ADD_PARAM(&configure_mask, &configure_params, back_pixmap, XCB_PIXMAP_NONE); + connection::pack_values(configure_mask, &configure_params, configure_values); m_log.trace("tray(%s): Update client window", m_connection.id(client())); diff --git a/src/x11/tray_manager.cpp b/src/x11/tray_manager.cpp index 0af6955e..0e2206cf 100644 --- a/src/x11/tray_manager.cpp +++ b/src/x11/tray_manager.cpp @@ -377,6 +377,24 @@ void tray_manager::reconfigure_clients() { * 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); + for (const auto& client : m_clients) { + m_connection.clear_area_checked(false, client.embedder(), 0, 0, client.width(), client.height()); + xcb_visibility_notify_event_t visibility_event; + visibility_event.response_type = XCB_VISIBILITY_NOTIFY; + visibility_event.window = client.client(); + visibility_event.state = XCB_VISIBILITY_FULLY_OBSCURED; + + m_connection.send_event( + true, client.client(), XCB_EVENT_MASK_NO_EVENT, reinterpret_cast(&visibility_event)); + m_connection.flush(); + visibility_event.state = XCB_VISIBILITY_UNOBSCURED; + m_connection.send_event( + true, client.client(), XCB_EVENT_MASK_NO_EVENT, reinterpret_cast(&visibility_event)); + m_connection.flush(); + + client.clear_window(); + } if (!m_opts.transparent || m_clients.empty() || !m_mapped) { return; }; @@ -394,7 +412,6 @@ void tray_manager::reconfigure_bg() { m_context->clear(); *m_context << CAIRO_OPERATOR_SOURCE << *m_surface; - cairo_set_source_surface(*m_context, *surface, 0, 0); m_context->paint(); *m_context << CAIRO_OPERATOR_OVER << m_opts.background; m_context->paint(); @@ -479,6 +496,7 @@ void tray_manager::create_window() { << 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 @@ -486,10 +504,10 @@ void tray_manager::create_window() { << cw_parent(m_opts.bar_window); // clang-format on - if (!m_opts.transparent) { - win << cw_params_back_pixel(m_opts.background); - win << cw_params_border_pixel(m_opts.background); - } + // if (!m_opts.transparent) { + // win << cw_params_back_pixel(m_opts.background); + // win << cw_params_border_pixel(m_opts.background); + // } m_tray = win << cw_flush(true); m_log.info("Tray window: %s", m_connection.id(m_tray)); @@ -560,7 +578,8 @@ void tray_manager::create_bg() { } try { - m_connection.change_window_attributes_checked(m_tray, XCB_CW_BACK_PIXMAP, &m_pixmap); + // TODO + // m_connection.change_window_attributes_checked(m_tray, XCB_CW_BACK_PIXMAP, &m_pixmap); } catch (const exception& err) { m_log.err("Failed to set tray window back pixmap (%s)", err.what()); } @@ -1085,6 +1104,7 @@ bool tray_manager::on(const signals::ui::dim_window& evt) { return false; } +// TODO maybe remove signal bool tray_manager::on(const signals::ui::update_background&) { redraw_window();