feat(render): support pseudo-transparency

This adds pseudo-transparency for the background of the bar and the
background of the systray.
This commit is contained in:
Benno Fünfstück
2017-05-23 21:32:34 +02:00
committed by Patrick Ziegler
parent 654c667698
commit 3de914abca
15 changed files with 315 additions and 86 deletions

View File

@ -7,6 +7,7 @@
#include "utils/file.hpp"
#include "utils/math.hpp"
#include "x11/atoms.hpp"
#include "x11/background_manager.hpp"
#include "x11/connection.hpp"
#include "x11/extensions/all.hpp"
#include "x11/winspec.hpp"
@ -25,7 +26,8 @@ renderer::make_type renderer::make(const bar_settings& bar) {
signal_emitter::make(),
config::make(),
logger::make(),
forward<decltype(bar)>(bar));
forward<decltype(bar)>(bar),
background_manager::make());
// clang-format on
}
@ -33,13 +35,15 @@ renderer::make_type renderer::make(const bar_settings& bar) {
* Construct renderer instance
*/
renderer::renderer(
connection& conn, signal_emitter& sig, const config& conf, const logger& logger, const bar_settings& bar)
connection& conn, signal_emitter& sig, const config& conf, const logger& logger, const bar_settings& bar, background_manager& background)
: m_connection(conn)
, m_sig(sig)
, m_conf(conf)
, m_log(logger)
, m_bar(forward<const bar_settings&>(bar))
, m_background(background)
, m_rect(m_bar.inner_area()) {
m_sig.attach(this);
m_log.trace("renderer: Get TrueColor visual");
{
@ -160,6 +164,9 @@ renderer::renderer(
m_log.info("Loaded font \"%s\" (name=%s, offset=%i, file=%s)", pattern, font->name(), offset, font->file());
*m_context << move(font);
}
m_log.trace("Activate root background manager");
m_background.activate(m_window, m_bar.inner_area(true));
}
m_comp_bg = m_conf.get<cairo_operator_t>("settings", "compositing-background", m_comp_bg);
@ -205,7 +212,7 @@ void renderer::begin(xcb_rectangle_t rect) {
m_align = alignment::NONE;
// Reset colors
m_bg = m_bar.background;
m_bg = 0x0;
m_fg = m_bar.foreground;
m_ul = m_bar.underline.color;
m_ol = m_bar.overline.color;
@ -214,6 +221,11 @@ void renderer::begin(xcb_rectangle_t rect) {
m_context->save();
m_context->clear();
// Draw the background on the new layer to make up for
// the areas not covered by the alignment blocks
fill_background();
// Create corner mask
if (m_bar.radius && m_cornermask == nullptr) {
m_context->save();
@ -261,10 +273,6 @@ 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);
}
@ -495,6 +503,14 @@ void renderer::fill_background() {
m_context->save();
*m_context << m_comp_bg;
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();
*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};
@ -718,8 +734,6 @@ 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<int>(m_align));
fill_background();
}
return true;
}