From 58e0911ac62c7e9814cbd850bb6506b520d16751 Mon Sep 17 00:00:00 2001
From: patrick96
Date: Thu, 23 Mar 2023 23:03:45 +0100
Subject: [PATCH] tray: Disable pseudo-transparency for opaque bgs
---
include/utils/color.hpp | 1 +
include/x11/tray_client.hpp | 7 ++++---
src/utils/color.cpp | 4 ++++
src/x11/tray_client.cpp | 24 ++++++++++++++----------
src/x11/tray_manager.cpp | 5 +++--
tests/unit_tests/utils/color.cpp | 13 +++++++++++++
6 files changed, 39 insertions(+), 15 deletions(-)
diff --git a/include/utils/color.hpp b/include/utils/color.hpp
index 3961876f..491d48ee 100644
--- a/include/utils/color.hpp
+++ b/include/utils/color.hpp
@@ -37,6 +37,7 @@ class rgba {
uint8_t blue_i() const;
bool has_color() const;
+ bool is_transparent() const;
rgba apply_alpha_to(rgba other) const;
rgba try_apply_alpha_to(rgba other) const;
diff --git a/include/x11/tray_client.hpp b/include/x11/tray_client.hpp
index 2d0dfb9a..97e98924 100644
--- a/include/x11/tray_client.hpp
+++ b/include/x11/tray_client.hpp
@@ -25,7 +25,7 @@ namespace tray {
class client : public non_copyable_mixin, public non_movable_mixin {
public:
explicit client(
- const logger& log, connection& conn, xcb_window_t parent, xcb_window_t win, size s, uint32_t desired_background);
+ const logger& log, connection& conn, xcb_window_t parent, xcb_window_t win, size s, rgba desired_background);
~client();
string name() const;
@@ -124,9 +124,10 @@ class client : public non_copyable_mixin, public non_movable_mixin {
size m_size;
position m_pos{0, 0};
- rgba m_desired_background;
+ const rgba m_desired_background;
+ const bool m_transparent{m_desired_background.is_transparent()};
background_manager& m_background_manager;
- shared_ptr m_bg_slice;
+ shared_ptr m_bg_slice{nullptr};
unique_ptr m_context;
unique_ptr m_surface;
};
diff --git a/src/utils/color.cpp b/src/utils/color.cpp
index bfff83dc..59fa59ae 100644
--- a/src/utils/color.cpp
+++ b/src/utils/color.cpp
@@ -154,6 +154,10 @@ bool rgba::has_color() const {
return m_type != type::NONE;
}
+bool rgba::is_transparent() const {
+ return alpha_i() != 0xFF;
+}
+
/**
* Applies the alpha channel of this color to the given color.
*/
diff --git a/src/x11/tray_client.cpp b/src/x11/tray_client.cpp
index 18438eba..3de60b25 100644
--- a/src/x11/tray_client.cpp
+++ b/src/x11/tray_client.cpp
@@ -33,7 +33,7 @@ namespace tray {
* 3. Use background color
*/
client::client(
- const logger& log, connection& conn, xcb_window_t parent, xcb_window_t win, size s, uint32_t desired_background)
+ const logger& log, connection& conn, xcb_window_t parent, xcb_window_t win, size s, rgba desired_background)
: m_log(log)
, m_connection(conn)
, m_name(ewmh_util::get_wm_name(win))
@@ -350,17 +350,16 @@ void client::configure_notify() const {
void client::update_bg() const {
m_log.trace("%s: Update background", name());
- // Composite background slice with background color.
-
m_context->clear();
- auto root_bg = m_bg_slice->get_surface();
- if (root_bg != nullptr) {
- // TODO the compositing doesn't have to be done if the background color is not transparent.
- // In that case, the bg slice can be completely skipped, we shouldn't event observe the background
- *m_context << CAIRO_OPERATOR_SOURCE << *root_bg;
- m_context->paint();
- *m_context << CAIRO_OPERATOR_OVER;
+ // Composite background slice with background color.
+ if (m_bg_slice) {
+ auto root_bg = m_bg_slice->get_surface();
+ if (root_bg != nullptr) {
+ *m_context << CAIRO_OPERATOR_SOURCE << *root_bg;
+ m_context->paint();
+ *m_context << CAIRO_OPERATOR_OVER;
+ }
}
*m_context << m_desired_background;
m_context->paint();
@@ -372,6 +371,11 @@ void client::update_bg() const {
}
void client::observe_background() {
+ // Opaque backgrounds don't require pseudo-transparency
+ if (!m_transparent) {
+ return;
+ }
+
xcb_rectangle_t rect{0, 0, static_cast(m_size.w), static_cast(m_size.h)};
m_bg_slice = m_background_manager.observe(rect, embedder());
diff --git a/src/x11/tray_manager.cpp b/src/x11/tray_manager.cpp
index b7b0dbf0..d271a0dd 100644
--- a/src/x11/tray_manager.cpp
+++ b/src/x11/tray_manager.cpp
@@ -122,6 +122,7 @@ void manager::activate() {
try {
set_tray_colors();
set_tray_orientation();
+ // TODO
// set_tray_visual();
} catch (const exception& err) {
m_log.err(err.what());
@@ -353,7 +354,7 @@ void manager::set_tray_orientation() {
XCB_ATOM_CARDINAL, 32, 1, &orientation);
}
-// TODO remove
+// TODO remove, we should probably not set a visual at all (or only a 24-bit one)
void manager::set_tray_visual() {
// TODO use bar visual
const uint32_t visualid = m_connection.visual_type(XCB_VISUAL_CLASS_TRUE_COLOR, 32)->visual_id;
@@ -436,7 +437,7 @@ void manager::process_docking_request(xcb_window_t win) {
try {
auto cl = make_unique(
- m_log, m_connection, m_opts.selection_owner, win, m_opts.client_size, m_bar_opts.background.value());
+ m_log, m_connection, m_opts.selection_owner, win, m_opts.client_size, m_opts.background);
try {
cl->query_xembed();
diff --git a/tests/unit_tests/utils/color.cpp b/tests/unit_tests/utils/color.cpp
index 7b62969c..4f693cbc 100644
--- a/tests/unit_tests/utils/color.cpp
+++ b/tests/unit_tests/utils/color.cpp
@@ -88,6 +88,19 @@ TEST(Rgba, hasColor) {
EXPECT_FALSE(v.has_color());
}
+TEST(Rgba, isTransparent) {
+ rgba v(0x1243);
+ EXPECT_FALSE(v.is_transparent());
+
+ v = rgba(0xff1243);
+
+ EXPECT_FALSE(v.is_transparent());
+
+ v = rgba(0xfe1243);
+
+ EXPECT_TRUE(v.is_transparent());
+}
+
TEST(Rgba, channel) {
rgba v{0xCC123456};
EXPECT_EQ(0xCC, v.alpha_i());