Fix BadMatch error for wrapper window

The wrapper window must define a border background if the depth doesn't
match the parent window.
This commit is contained in:
patrick96 2022-03-16 18:37:34 +01:00
parent 3711e999ba
commit b8c275d6ac
No known key found for this signature in database
GPG Key ID: 521E5E03AEBCA1A7
2 changed files with 38 additions and 28 deletions

View File

@ -9,33 +9,41 @@
POLYBAR_NS
// TODO create wrapper window
tray_client::tray_client(const logger& log, connection& conn, xcb_window_t tray, xcb_window_t win, size s)
: m_log(log), m_connection(conn), m_client(win), m_size(s) {
auto geom = conn.get_geometry(win);
auto attrs = conn.get_window_attributes(win);
int depth = geom->depth;
xcb_visualid_t visual = attrs->visual;
m_log.trace("tray(%s): depth: %u, width: %u, height: %u, visual: 0x%x", conn.id(win), depth, geom->width, geom->height, visual);
int client_depth = geom->depth;
auto client_visual = attrs->visual;
auto client_colormap = attrs->colormap;
m_log.trace("tray(%s): depth: %u, width: %u, height: %u", conn.id(win), client_depth, geom->width, geom->height);
/*
* Create embedder window for tray icon
*
* The embedder window inherits the depth, visual and color map from the icon window in order for reparenting to
* always work, even if the icon window uses ParentRelative for some of its pixmaps (back pixmap or border pixmap).
*/
// clang-format off
m_wrapper = winspec(conn)
<< cw_size(s.h, s.w)
<< cw_pos(0, 0)
// TODO fix BadMatch error for redshift-gtk window
// << cw_depth(depth)
// << cw_visual(visual)
<< cw_depth(client_depth)
<< cw_visual(client_visual)
<< cw_parent(tray)
<< cw_class(XCB_WINDOW_CLASS_INPUT_OUTPUT)
// TODO add proper pixmap
<< cw_params_back_pixmap(XCB_PIXMAP_NONE)
// << cw_class(XCB_WINDOW_CLASS_INPUT_OUTPUT)
// The X server requires the border pixel to be defined if the depth doesn't match the parent window
<< cw_params_border_pixel(conn.screen()->black_pixel)
<< cw_params_backing_store(XCB_BACKING_STORE_WHEN_MAPPED)
<< cw_params_save_under(true)
<< cw_params_event_mask(XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT
| XCB_EVENT_MASK_PROPERTY_CHANGE
| XCB_EVENT_MASK_STRUCTURE_NOTIFY
| XCB_EVENT_MASK_EXPOSURE)
// << cw_flush(false);
// TODO Make unchecked
<< cw_params_colormap(client_colormap)
<< cw_flush(true);
// clang-format on
}

View File

@ -475,13 +475,14 @@ void tray_manager::create_window() {
auto win = winspec(m_connection)
<< cw_size(calculate_w(), calculate_h())
<< cw_pos(calculate_x(calculate_w()), calculate_y())
<< cw_depth(XCB_COPY_FROM_PARENT)
<< cw_visual(XCB_COPY_FROM_PARENT)
<< cw_params_colormap(XCB_COPY_FROM_PARENT)
<< cw_class(XCB_WINDOW_CLASS_INPUT_OUTPUT)
<< cw_params_backing_store(XCB_BACKING_STORE_WHEN_MAPPED)
<< cw_params_event_mask(XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT
|XCB_EVENT_MASK_STRUCTURE_NOTIFY
|XCB_EVENT_MASK_EXPOSURE)
// TODO
// << cw_params_override_redirect(true)
<< cw_parent(m_opts.bar_window);
// clang-format on
@ -700,22 +701,22 @@ void tray_manager::track_selection_owner(xcb_window_t owner) {
void tray_manager::process_docking_request(xcb_window_t win) {
m_log.info("Processing docking request from '%s' (%s)", ewmh_util::get_wm_name(win), m_connection.id(win));
tray_client client(m_log, m_connection, m_tray, win, m_opts.client_size);
try {
client.query_xembed();
} catch (const xpp::x::error::window& err) {
m_log.err("Failed to query _XEMBED_INFO, removing client... (%s)", err.what());
return;
}
tray_client client(m_log, m_connection, m_tray, win, m_opts.client_size);
m_log.trace("tray: xembed = %s", client.is_xembed_supported() ? "true" : "false");
if (client.is_xembed_supported()) {
m_log.trace("tray: version = 0x%x, flags = 0x%x, XEMBED_MAPPED = %s", client.get_xembed().get_version(),
client.get_xembed().get_flags(), client.get_xembed().is_mapped() ? "true" : "false");
}
try {
client.query_xembed();
} catch (const xpp::x::error::window& err) {
m_log.err("Failed to query _XEMBED_INFO, removing client... (%s)", err.what());
return;
}
m_log.trace("tray: xembed = %s", client.is_xembed_supported() ? "true" : "false");
if (client.is_xembed_supported()) {
m_log.trace("tray: version = 0x%x, flags = 0x%x, XEMBED_MAPPED = %s", client.get_xembed().get_version(),
client.get_xembed().get_flags(), client.get_xembed().is_mapped() ? "true" : "false");
}
try {
const uint32_t mask = XCB_CW_EVENT_MASK;
const uint32_t value = XCB_EVENT_MASK_PROPERTY_CHANGE | XCB_EVENT_MASK_STRUCTURE_NOTIFY;
@ -746,13 +747,13 @@ void tray_manager::process_docking_request(xcb_window_t win) {
m_connection.map_window_checked(client.client());
m_connection.map_window_checked(client.embedder());
}
m_clients.emplace_back(std::move(client));
} catch (const std::exception& err) {
m_log.err("Failed to setup tray client '%s' (%s) removing... (%s)", ewmh_util::get_wm_name(win),
m_connection.id(win), err.what());
return;
}
m_clients.emplace_back(std::move(client));
}
/**
@ -976,7 +977,8 @@ void tray_manager::handle(const evt::property_notify& evt) {
}
// React an wallpaper change, if bar has transparency
if (m_opts.transparent && (evt->atom == _XROOTPMAP_ID || evt->atom == _XSETROOT_ID || evt->atom == ESETROOT_PMAP_ID)) {
if (m_opts.transparent &&
(evt->atom == _XROOTPMAP_ID || evt->atom == _XSETROOT_ID || evt->atom == ESETROOT_PMAP_ID)) {
redraw_window();
return;
}