From 9b1afe73696106dda3da194edb8e6124f210d8a5 Mon Sep 17 00:00:00 2001 From: patrick96 Date: Wed, 16 Mar 2022 22:13:46 +0100 Subject: [PATCH] Cleanup selection of visual for bar window --- include/components/renderer.hpp | 2 +- include/x11/connection.hpp | 4 +- src/components/renderer.cpp | 64 +++++++++++++---------------- src/x11/background_manager.cpp | 72 ++++++++++++++++----------------- src/x11/connection.cpp | 33 +++------------ src/x11/tray_manager.cpp | 3 +- 6 files changed, 73 insertions(+), 105 deletions(-) diff --git a/include/components/renderer.hpp b/include/components/renderer.hpp index 500c7f08..79b339d9 100644 --- a/include/components/renderer.hpp +++ b/include/components/renderer.hpp @@ -102,7 +102,7 @@ class renderer : public renderer_interface, const bar_settings& m_bar; std::shared_ptr m_background; - int m_depth{32}; + int m_depth{-1}; xcb_window_t m_window; xcb_colormap_t m_colormap; xcb_visualtype_t* m_visual; diff --git a/include/x11/connection.hpp b/include/x11/connection.hpp index 7030dd00..542b842d 100644 --- a/include/x11/connection.hpp +++ b/include/x11/connection.hpp @@ -123,8 +123,8 @@ class connection : public detail::connection_base(bar)) , m_rect(m_bar.inner_area()) { m_sig.attach(this); - m_log.trace("renderer: Get TrueColor visual"); - { - if ((m_visual = m_connection.visual_type(m_connection.screen(), 32)) == nullptr) { - m_log.err("No 32-bit TrueColor visual found..."); - if ((m_visual = m_connection.visual_type(m_connection.screen(), 24)) == nullptr) { - m_log.err("No 24-bit TrueColor visual found..."); - } else { - m_depth = 24; - } - } - if (m_visual == nullptr) { - throw application_error("No matching TrueColor"); - } + m_log.trace("renderer: Get TrueColor visual"); + if ((m_visual = m_connection.visual_type(XCB_VISUAL_CLASS_TRUE_COLOR, 32)) != nullptr) { + m_depth = 32; + } else if ((m_visual = m_connection.visual_type(XCB_VISUAL_CLASS_TRUE_COLOR, 24)) != nullptr) { + m_depth = 24; + } else { + throw application_error("Could not find a 24 or 32-bit TrueColor visual"); } + m_log.info("renderer: Using %d-bit visual", m_depth); + m_log.trace("renderer: Allocate colormap"); - { - m_colormap = m_connection.generate_id(); - m_connection.create_colormap(XCB_COLORMAP_ALLOC_NONE, m_colormap, m_connection.screen()->root, m_visual->visual_id); - } + m_colormap = m_connection.generate_id(); + m_connection.create_colormap(XCB_COLORMAP_ALLOC_NONE, m_colormap, m_connection.screen()->root, m_visual->visual_id); m_log.trace("renderer: Allocate output window"); - { - // clang-format off - m_window = winspec(m_connection) - << cw_size(m_bar.size) - << cw_pos(m_bar.pos) - << cw_depth(m_depth) - << cw_visual(m_visual->visual_id) - << cw_class(XCB_WINDOW_CLASS_INPUT_OUTPUT) - << cw_params_back_pixel(0) - << cw_params_border_pixel(0) - << cw_params_backing_store(XCB_BACKING_STORE_WHEN_MAPPED) - << cw_params_colormap(m_colormap) - << cw_params_event_mask(XCB_EVENT_MASK_PROPERTY_CHANGE - |XCB_EVENT_MASK_EXPOSURE - |XCB_EVENT_MASK_BUTTON_PRESS) - << cw_params_override_redirect(m_bar.override_redirect) - << cw_flush(true); - // clang-format on - } + // clang-format off + m_window = winspec(m_connection) + << cw_size(m_bar.size) + << cw_pos(m_bar.pos) + << cw_depth(m_depth) + << cw_visual(m_visual->visual_id) + << cw_class(XCB_WINDOW_CLASS_INPUT_OUTPUT) + << cw_params_back_pixel(0) + << cw_params_border_pixel(0) + << cw_params_backing_store(XCB_BACKING_STORE_WHEN_MAPPED) + << cw_params_colormap(m_colormap) + << cw_params_event_mask(XCB_EVENT_MASK_PROPERTY_CHANGE + |XCB_EVENT_MASK_EXPOSURE + |XCB_EVENT_MASK_BUTTON_PRESS) + << cw_params_override_redirect(m_bar.override_redirect) + << cw_flush(true); + // clang-format on m_log.trace("renderer: Allocate window pixmaps"); { diff --git a/src/x11/background_manager.cpp b/src/x11/background_manager.cpp index baf8f8c1..73256db0 100644 --- a/src/x11/background_manager.cpp +++ b/src/x11/background_manager.cpp @@ -1,13 +1,14 @@ -#include "cairo/surface.hpp" +#include "x11/background_manager.hpp" + #include "cairo/context.hpp" -#include "events/signal.hpp" +#include "cairo/surface.hpp" #include "components/config.hpp" #include "components/logger.hpp" -#include "x11/atoms.hpp" -#include "x11/connection.hpp" -#include "x11/background_manager.hpp" +#include "events/signal.hpp" #include "utils/factory.hpp" #include "utils/math.hpp" +#include "x11/atoms.hpp" +#include "x11/connection.hpp" POLYBAR_NS @@ -15,11 +16,8 @@ background_manager& background_manager::make() { return *factory_util::singleton(connection::make(), signal_emitter::make(), logger::make()); } -background_manager::background_manager( - connection& conn, signal_emitter& sig, const logger& log) - : m_connection(conn) - , m_sig(sig) - , m_log(log) { +background_manager::background_manager(connection& conn, signal_emitter& sig, const logger& log) + : m_connection(conn), m_sig(sig), m_log(log) { m_sig.attach(this); } @@ -34,7 +32,7 @@ std::shared_ptr background_manager::observe(xcb_rectangle_t rect, xcb_ auto slice = std::shared_ptr(new bg_slice(m_connection, m_log, rect, window, m_visual)); // make sure that we receive a notification when the background changes - if(!m_attached) { + if (!m_attached) { m_connection.ensure_event_mask(m_connection.root(), XCB_EVENT_MASK_PROPERTY_CHANGE); m_connection.flush(); m_connection.attach_sink(this, SINK_PRIORITY_SCREEN); @@ -52,18 +50,17 @@ std::shared_ptr background_manager::observe(xcb_rectangle_t rect, xcb_ } void background_manager::deactivate() { - if(m_attached) { + if (m_attached) { m_connection.detach_sink(this, SINK_PRIORITY_SCREEN); m_attached = false; } free_resources(); } - void background_manager::activate() { - if(!m_visual) { + if (!m_visual) { m_log.trace("background_manager: Finding root visual"); - m_visual = m_connection.visual_type_for_id(m_connection.screen(), m_connection.screen()->root_visual); + m_visual = m_connection.visual_type_for_id(m_connection.screen()->root_visual); m_log.trace("background_manager: Got root visual with depth %d", m_connection.screen()->root_depth); } } @@ -83,14 +80,15 @@ void background_manager::fetch_root_pixmap() { if (!m_connection.root_pixmap(&pixmap, &pixmap_depth, &pixmap_geom)) { return m_log.warn("background_manager: Failed to get root pixmap, default to black (is there a wallpaper?)"); }; - m_log.trace("background_manager: root pixmap (%d:%d) %dx%d+%d+%d", pixmap, pixmap_depth, - pixmap_geom.width, pixmap_geom.height, pixmap_geom.x, pixmap_geom.y); + m_log.trace("background_manager: root pixmap (%d:%d) %dx%d+%d+%d", pixmap, pixmap_depth, pixmap_geom.width, + pixmap_geom.height, pixmap_geom.x, pixmap_geom.y); if (pixmap_depth == 1 && pixmap_geom.width == 1 && pixmap_geom.height == 1) { - return m_log.err("background_manager: Cannot find root pixmap, try a different tool to set the desktop background"); + return m_log.err( + "background_manager: Cannot find root pixmap, try a different tool to set the desktop background"); } - for (auto it = m_slices.begin(); it != m_slices.end(); ) { + for (auto it = m_slices.begin(); it != m_slices.end();) { auto slice = it->lock(); if (!slice) { it = m_slices.erase(it); @@ -98,12 +96,15 @@ void background_manager::fetch_root_pixmap() { } // fill the slice - auto translated = m_connection.translate_coordinates(slice->m_window, m_connection.screen()->root, slice->m_rect.x, slice->m_rect.y); + auto translated = m_connection.translate_coordinates( + slice->m_window, m_connection.screen()->root, slice->m_rect.x, slice->m_rect.y); auto src_x = math_util::cap(translated->dst_x, pixmap_geom.x, int16_t(pixmap_geom.x + pixmap_geom.width)); auto src_y = math_util::cap(translated->dst_y, pixmap_geom.y, int16_t(pixmap_geom.y + pixmap_geom.height)); auto w = math_util::cap(slice->m_rect.width, uint16_t(0), uint16_t(pixmap_geom.width - (src_x - pixmap_geom.x))); - auto h = math_util::cap(slice->m_rect.height, uint16_t(0), uint16_t(pixmap_geom.height - (src_y - pixmap_geom.y))); - m_log.trace("background_manager: Copying from root pixmap (%d:%d) %dx%d+%d+%d", pixmap, pixmap_depth, w, h, src_x, src_y); + auto h = + math_util::cap(slice->m_rect.height, uint16_t(0), uint16_t(pixmap_geom.height - (src_y - pixmap_geom.y))); + m_log.trace( + "background_manager: Copying from root pixmap (%d:%d) %dx%d+%d+%d", pixmap, pixmap_depth, w, h, src_x, src_y); m_connection.copy_area_checked(pixmap, slice->m_pixmap, slice->m_gcontext, src_x, src_y, 0, 0, w, h); it++; @@ -115,16 +116,15 @@ void background_manager::fetch_root_pixmap() { deactivate(); } - } catch(const exception& err) { + } catch (const exception& err) { m_log.err("background_manager: Failed to copy slice of root pixmap (%s)", err.what()); throw; } - } void background_manager::handle(const evt::property_notify& evt) { // if there are no slices to observe, don't do anything - if(m_slices.empty()) { + if (m_slices.empty()) { return; } @@ -136,7 +136,7 @@ void background_manager::handle(const evt::property_notify& evt) { bool background_manager::on(const signals::ui::update_geometry&) { // if there are no slices to observe, don't do anything - if(m_slices.empty()) { + if (m_slices.empty()) { return false; } @@ -145,14 +145,12 @@ bool background_manager::on(const signals::ui::update_geometry&) { return false; } - -bg_slice::bg_slice(connection& conn, const logger& log, xcb_rectangle_t rect, xcb_window_t window, xcb_visualtype_t* visual) - : m_connection(conn) - , m_rect(rect) - , m_window(window) { +bg_slice::bg_slice( + connection& conn, const logger& log, xcb_rectangle_t rect, xcb_window_t window, xcb_visualtype_t* visual) + : m_connection(conn), m_rect(rect), m_window(window) { try { allocate_resources(log, visual); - } catch(...) { + } catch (...) { free_resources(); throw; } @@ -163,13 +161,13 @@ bg_slice::~bg_slice() { } void bg_slice::allocate_resources(const logger& log, xcb_visualtype_t* visual) { - if(m_pixmap == XCB_NONE) { + if (m_pixmap == XCB_NONE) { log.trace("background_manager: Allocating pixmap"); m_pixmap = m_connection.generate_id(); m_connection.create_pixmap(m_connection.screen()->root_depth, m_pixmap, m_window, m_rect.width, m_rect.height); } - if(m_gcontext == XCB_NONE) { + if (m_gcontext == XCB_NONE) { log.trace("background_manager: Allocating graphics context"); auto black_pixel = m_connection.screen()->black_pixel; uint32_t mask = 0; @@ -183,7 +181,7 @@ void bg_slice::allocate_resources(const logger& log, xcb_visualtype_t* visual) { m_connection.create_gc(m_gcontext, m_pixmap, mask, value_list.data()); } - if(!m_surface) { + if (!m_surface) { log.trace("background_manager: Allocating cairo surface"); m_surface = make_unique(m_connection, m_pixmap, visual, m_rect.width, m_rect.height); } @@ -196,12 +194,12 @@ void bg_slice::allocate_resources(const logger& log, xcb_visualtype_t* visual) { void bg_slice::free_resources() { m_surface.reset(); - if(m_pixmap != XCB_NONE) { + if (m_pixmap != XCB_NONE) { m_connection.free_pixmap(m_pixmap); m_pixmap = XCB_NONE; } - if(m_gcontext != XCB_NONE) { + if (m_gcontext != XCB_NONE) { m_connection.free_gc(m_gcontext); m_gcontext = XCB_NONE; } diff --git a/src/x11/connection.cpp b/src/x11/connection.cpp index 82482b93..0680b09b 100644 --- a/src/x11/connection.cpp +++ b/src/x11/connection.cpp @@ -81,6 +81,8 @@ string connection::id(xcb_window_t w) const { /** * Get pointer to the default xcb screen + * + * TODO remove realloc param. Create explicit realloc function */ xcb_screen_t* connection::screen(bool realloc) { if (m_screen == nullptr || realloc) { @@ -139,35 +141,12 @@ void connection::send_client_message( * Try to get a visual type for the given screen that * matches the given depth */ -xcb_visualtype_t* connection::visual_type(xcb_screen_t* screen, int match_depth) { - xcb_depth_iterator_t depth_iter = xcb_screen_allowed_depths_iterator(screen); - if (depth_iter.data) { - for (; depth_iter.rem; xcb_depth_next(&depth_iter)) { - if (match_depth == 0 || match_depth == depth_iter.data->depth) { - for (auto it = xcb_depth_visuals_iterator(depth_iter.data); it.rem; xcb_visualtype_next(&it)) { - return it.data; - } - } - } - if (match_depth > 0) { - return visual_type(screen, 0); - } - } - return nullptr; +xcb_visualtype_t* connection::visual_type(xcb_visual_class_t class_, int match_depth) { + return xcb_aux_find_visual_by_attrs(screen(), class_, match_depth); } -xcb_visualtype_t* connection::visual_type_for_id(xcb_screen_t* screen, xcb_visualid_t visual_id) { - xcb_depth_iterator_t depth_iter = xcb_screen_allowed_depths_iterator(screen); - if (depth_iter.data) { - for (; depth_iter.rem; xcb_depth_next(&depth_iter)) { - for (auto it = xcb_depth_visuals_iterator(depth_iter.data); it.rem; xcb_visualtype_next(&it)) { - if (it.data->visual_id == visual_id) { - return it.data; - } - } - } - } - return nullptr; +xcb_visualtype_t* connection::visual_type_for_id(xcb_visualid_t visual_id) { + return xcb_aux_find_visual_by_id(screen(), visual_id); } /** diff --git a/src/x11/tray_manager.cpp b/src/x11/tray_manager.cpp index 664160c1..31080cc0 100644 --- a/src/x11/tray_manager.cpp +++ b/src/x11/tray_manager.cpp @@ -548,8 +548,7 @@ void tray_manager::create_bg() { } if (!m_surface) { - xcb_visualtype_t* visual = - m_connection.visual_type_for_id(m_connection.screen(), m_connection.screen()->root_visual); + xcb_visualtype_t* visual = m_connection.visual_type_for_id(m_connection.screen()->root_visual); if (!visual) { return m_log.err("Failed to get root visual for tray background"); }