tray: Disable pseudo-transparency for opaque bgs

This commit is contained in:
patrick96 2023-03-23 23:03:45 +01:00
parent 89f29fa12e
commit 58e0911ac6
No known key found for this signature in database
GPG Key ID: 521E5E03AEBCA1A7
6 changed files with 39 additions and 15 deletions

View File

@ -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;

View File

@ -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<bg_slice> m_bg_slice;
shared_ptr<bg_slice> m_bg_slice{nullptr};
unique_ptr<cairo::context> m_context;
unique_ptr<cairo::xcb_surface> m_surface;
};

View File

@ -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.
*/

View File

@ -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<uint16_t>(m_size.w), static_cast<uint16_t>(m_size.h)};
m_bg_slice = m_background_manager.observe(rect, embedder());

View File

@ -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<client>(
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();

View File

@ -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());