From 4221da71bf152b1381480e3d4a49a938ede2ba38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benno=20F=C3=BCnfst=C3=BCck?= Date: Sun, 12 Aug 2018 17:23:32 +0200 Subject: [PATCH] fix(renderer): render transparent blocks correctly This reverts some behaviour differences introduced by the pseudo-transparency implementation. The new implementation is much closer to the non-pseudo-transparent case and thus keeps original behaviour. For the new method we simply fill the bar with the background image fetched from the root window if in pseudo-transparent mode, otherwise we do nothing. This means that everything will work as in the fully-transparent mode. --- src/components/parser.cpp | 2 +- src/components/renderer.cpp | 38 +++++++++++++++++-------------------- 2 files changed, 18 insertions(+), 22 deletions(-) diff --git a/src/components/parser.cpp b/src/components/parser.cpp index 48b9cb12..c5231928 100644 --- a/src/components/parser.cpp +++ b/src/components/parser.cpp @@ -77,7 +77,7 @@ void parser::codeblock(string&& data, const bar_settings& bar) { switch (tag) { case 'B': - m_sig.emit(change_background{parse_color(value, 0x0)}); + m_sig.emit(change_background{parse_color(value, bar.background)}); break; case 'F': diff --git a/src/components/renderer.cpp b/src/components/renderer.cpp index 72de6666..1522660a 100644 --- a/src/components/renderer.cpp +++ b/src/components/renderer.cpp @@ -214,7 +214,7 @@ void renderer::begin(xcb_rectangle_t rect) { m_align = alignment::NONE; // Reset colors - m_bg = 0x0; + m_bg = m_bar.background; m_fg = m_bar.foreground; m_ul = m_bar.underline.color; m_ol = m_bar.overline.color; @@ -223,11 +223,6 @@ void renderer::begin(xcb_rectangle_t rect) { m_context->save(); m_context->clear(); - // Draw the background as base layer so that everything - // else is drawn on top of it - fill_background(); - - // Create corner mask if (m_bar.radius && m_cornermask == nullptr) { m_context->save(); @@ -245,6 +240,16 @@ void renderer::begin(xcb_rectangle_t rect) { m_context->restore(); } + // if using pseudo-transparency, fill the background with the root window's contents + // otherwise, we simply use a fully transparent base layer + if(m_pseudo_transparency) { + auto root_bg = m_background.get_surface(); + if(root_bg != nullptr) { + m_log.trace_x("renderer: root background"); + *m_context << *root_bg; + m_context->paint(); + } + } fill_borders(); // clang-format off @@ -275,6 +280,10 @@ void renderer::end() { // so that it can be masked with the corner pattern m_context->push(); + // Draw the background on the new layer to make up for + // the areas not covered by the alignment blocks + fill_background(); + for (auto&& b : m_blocks) { flush(b.first); } @@ -505,21 +514,6 @@ void renderer::fill_background() { m_context->save(); *m_context << m_comp_bg; - // if using pseudo-transparency, fill the background with the root window's contents - // otherwise, we simply use a fully transparent base layer - if(m_pseudo_transparency) { - auto root_bg = m_background.get_surface(); - if(root_bg != nullptr) { - m_log.trace_x("renderer: root background"); - *m_context << *root_bg; - } - } else { - *m_context << (unsigned int)0; - } - - m_context->paint(); - *m_context << CAIRO_OPERATOR_OVER; - if (!m_bar.background_steps.empty()) { m_log.trace_x("renderer: gradient background (steps=%lu)", m_bar.background_steps.size()); *m_context << cairo::linear_gradient{0.0, 0.0 + m_rect.y, 0.0, 0.0 + m_rect.height, m_bar.background_steps}; @@ -743,6 +737,8 @@ bool renderer::on(const signals::parser::change_alignment& evt) { m_blocks[m_align].y = 0.0; m_context->push(); m_log.trace_x("renderer: push(%i)", static_cast(m_align)); + + fill_background(); } return true; }