From 061fe83b2f36339796e90d053e59592b3243fc73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benno=20F=C3=BCnfst=C3=BCck?= Date: Thu, 5 Jul 2018 21:06:05 +0200 Subject: [PATCH] feat(background_manager): option to disable pseudo-transparency This adds a new config option to select between pseudo transparency and real transparency. --- doc/config.cmake | 1 + include/x11/background_manager.hpp | 4 +++- src/x11/background_manager.cpp | 31 +++++++++++++++++++++++++----- 3 files changed, 30 insertions(+), 6 deletions(-) diff --git a/doc/config.cmake b/doc/config.cmake index ed865628..bb9fe0f2 100644 --- a/doc/config.cmake +++ b/doc/config.cmake @@ -414,6 +414,7 @@ screenchange-reload = true ;compositing-background = screen ;compositing-foreground = source ;compositing-border = over +;pseudo-transparency = false [global/wm] margin-top = 5 diff --git a/include/x11/background_manager.hpp b/include/x11/background_manager.hpp index 33d5a36f..adcdddad 100644 --- a/include/x11/background_manager.hpp +++ b/include/x11/background_manager.hpp @@ -47,9 +47,11 @@ class background_manager : public signal_receiver m_surface; bool m_attached{false}; + bool m_pseudo_transparency{false}; - void allocate_resources(); + void allocate_resources(bool use_root_depth); void free_resources(); + void make_transparent_pixmap(); void fetch_root_pixmap(); }; diff --git a/src/x11/background_manager.cpp b/src/x11/background_manager.cpp index f5521f02..1b2d4981 100644 --- a/src/x11/background_manager.cpp +++ b/src/x11/background_manager.cpp @@ -1,5 +1,7 @@ #include "cairo/surface.hpp" +#include "cairo/context.hpp" #include "events/signal.hpp" +#include "components/config.hpp" #include "components/logger.hpp" #include "x11/atoms.hpp" #include "x11/connection.hpp" @@ -19,6 +21,7 @@ background_manager::background_manager( , m_sig(sig) , m_log(log) { m_sig.attach(this); + m_pseudo_transparency = config::make().get("settings", "pseudo-transparency", false); } background_manager::~background_manager() { @@ -40,7 +43,7 @@ void background_manager::activate(xcb_window_t window, xcb_rectangle_t rect) { free_resources(); // make sure that we receive a notification when the background changes - if(!m_attached) { + if(!m_attached && m_pseudo_transparency) { m_connection.ensure_event_mask(m_connection.root(), XCB_EVENT_MASK_PROPERTY_CHANGE); m_connection.flush(); m_connection.attach_sink(this, SINK_PRIORITY_SCREEN); @@ -48,7 +51,11 @@ void background_manager::activate(xcb_window_t window, xcb_rectangle_t rect) { m_window = window; m_rect = rect; - fetch_root_pixmap(); + if(m_pseudo_transparency) { + fetch_root_pixmap(); + } else { + make_transparent_pixmap(); + } } void background_manager::deactivate() { @@ -56,7 +63,7 @@ void background_manager::deactivate() { } -void background_manager::allocate_resources() { +void background_manager::allocate_resources(bool use_root_depth) { 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); @@ -66,7 +73,8 @@ void background_manager::allocate_resources() { if(m_pixmap == XCB_NONE) { m_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); + auto depth = use_root_depth ? m_connection.screen()->root_depth : 32; + m_connection.create_pixmap(depth, m_pixmap, m_window, m_rect.width, m_rect.height); } if(m_gcontext == XCB_NONE) { @@ -104,8 +112,17 @@ void background_manager::free_resources() { } } +void background_manager::make_transparent_pixmap() { + allocate_resources(false); + + m_log.trace("background_manager: Using transparent background pixmap"); + auto context = cairo::context(*m_surface, m_log); + context << (unsigned int)0; +} + void background_manager::fetch_root_pixmap() { - allocate_resources(); + allocate_resources(true); + m_log.trace("background_manager: Fetching pixmap"); int pixmap_depth; @@ -135,6 +152,8 @@ void background_manager::fetch_root_pixmap() { } void background_manager::handle(const evt::property_notify& evt) { + if(!m_pseudo_transparency) return; + // if region that we should observe is empty, don't do anything if(m_rect.width == 0 || m_rect.height == 0) return; @@ -145,6 +164,8 @@ void background_manager::handle(const evt::property_notify& evt) { } bool background_manager::on(const signals::ui::update_geometry&) { + if(!m_pseudo_transparency) return false; + fetch_root_pixmap(); m_sig.emit(signals::ui::update_background()); return false;