Make tray window a bar subwindow
Currently requires a dirty workaround to prevent tray icons with different depths from crashing
This commit is contained in:
parent
18485d00c2
commit
3244b10ce3
@ -52,12 +52,13 @@ struct tray_settings {
|
|||||||
unsigned int height{0U};
|
unsigned int height{0U};
|
||||||
unsigned int height_fill{0U};
|
unsigned int height_fill{0U};
|
||||||
unsigned int spacing{0U};
|
unsigned int spacing{0U};
|
||||||
unsigned int sibling{0U};
|
|
||||||
rgba background{};
|
rgba background{};
|
||||||
rgba foreground{};
|
rgba foreground{};
|
||||||
bool transparent{false};
|
bool transparent{false};
|
||||||
bool detached{false};
|
bool detached{false};
|
||||||
bool adaptive{false};
|
bool adaptive{false};
|
||||||
|
|
||||||
|
xcb_window_t bar_window;
|
||||||
};
|
};
|
||||||
|
|
||||||
class tray_manager : public xpp::event::sink<evt::expose, evt::visibility_notify, evt::client_message,
|
class tray_manager : public xpp::event::sink<evt::expose, evt::visibility_notify, evt::client_message,
|
||||||
@ -92,7 +93,6 @@ class tray_manager : public xpp::event::sink<evt::expose, evt::visibility_notify
|
|||||||
void query_atom();
|
void query_atom();
|
||||||
void create_window();
|
void create_window();
|
||||||
void create_bg();
|
void create_bg();
|
||||||
void restack_window();
|
|
||||||
void set_wm_hints();
|
void set_wm_hints();
|
||||||
void set_tray_colors();
|
void set_tray_colors();
|
||||||
|
|
||||||
|
@ -110,14 +110,14 @@ void tray_manager::setup() {
|
|||||||
|
|
||||||
m_opts.width_max = m_bar_opts.size.w;
|
m_opts.width_max = m_bar_opts.size.w;
|
||||||
m_opts.width = m_opts.height;
|
m_opts.width = m_opts.height;
|
||||||
m_opts.orig_y = m_bar_opts.pos.y + m_bar_opts.borders.at(edge::TOP).size;
|
m_opts.orig_y = m_bar_opts.borders.at(edge::TOP).size;
|
||||||
|
|
||||||
// Apply user-defined scaling
|
// Apply user-defined scaling
|
||||||
auto scale = conf.get(bs, "tray-scale", 1.0);
|
auto scale = conf.get(bs, "tray-scale", 1.0);
|
||||||
m_opts.width *= scale;
|
m_opts.width *= scale;
|
||||||
m_opts.height_fill *= scale;
|
m_opts.height_fill *= scale;
|
||||||
|
|
||||||
auto inner_area = m_bar_opts.inner_area(true);
|
auto inner_area = m_bar_opts.inner_area();
|
||||||
|
|
||||||
switch (m_opts.align) {
|
switch (m_opts.align) {
|
||||||
case alignment::NONE:
|
case alignment::NONE:
|
||||||
@ -167,8 +167,7 @@ void tray_manager::setup() {
|
|||||||
m_opts.orig_x += units_utils::percentage_with_offset_to_pixel(offset_x, max_x, m_bar_opts.dpi_x);
|
m_opts.orig_x += units_utils::percentage_with_offset_to_pixel(offset_x, max_x, m_bar_opts.dpi_x);
|
||||||
m_opts.orig_y += units_utils::percentage_with_offset_to_pixel(offset_y, max_y, m_bar_opts.dpi_y);
|
m_opts.orig_y += units_utils::percentage_with_offset_to_pixel(offset_y, max_y, m_bar_opts.dpi_y);
|
||||||
|
|
||||||
// Put the tray next to the bar in the window stack
|
m_opts.bar_window = bar_opts.window;
|
||||||
m_opts.sibling = m_bar_opts.window;
|
|
||||||
|
|
||||||
// Activate the tray manager
|
// Activate the tray manager
|
||||||
query_atom();
|
query_atom();
|
||||||
@ -199,7 +198,6 @@ void tray_manager::activate() {
|
|||||||
try {
|
try {
|
||||||
create_window();
|
create_window();
|
||||||
create_bg();
|
create_bg();
|
||||||
restack_window();
|
|
||||||
set_wm_hints();
|
set_wm_hints();
|
||||||
set_tray_colors();
|
set_tray_colors();
|
||||||
} catch (const exception& err) {
|
} catch (const exception& err) {
|
||||||
@ -484,7 +482,8 @@ void tray_manager::create_window() {
|
|||||||
<< cw_params_event_mask(XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT
|
<< cw_params_event_mask(XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT
|
||||||
|XCB_EVENT_MASK_STRUCTURE_NOTIFY
|
|XCB_EVENT_MASK_STRUCTURE_NOTIFY
|
||||||
|XCB_EVENT_MASK_EXPOSURE)
|
|XCB_EVENT_MASK_EXPOSURE)
|
||||||
<< cw_params_override_redirect(true);
|
<< cw_params_override_redirect(true)
|
||||||
|
<< cw_parent(m_opts.bar_window);
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
if (!m_opts.transparent) {
|
if (!m_opts.transparent) {
|
||||||
@ -522,7 +521,8 @@ void tray_manager::create_bg() {
|
|||||||
if (!m_pixmap) {
|
if (!m_pixmap) {
|
||||||
try {
|
try {
|
||||||
m_pixmap = m_connection.generate_id();
|
m_pixmap = m_connection.generate_id();
|
||||||
m_connection.create_pixmap_checked(m_connection.screen()->root_depth, m_pixmap, m_tray, w, h);
|
// TODO get depth from bar window
|
||||||
|
m_connection.create_pixmap_checked(32, m_pixmap, m_tray, w, h);
|
||||||
} catch (const exception& err) {
|
} catch (const exception& err) {
|
||||||
return m_log.err("Failed to create pixmap for tray background (err: %s)", err.what());
|
return m_log.err("Failed to create pixmap for tray background (err: %s)", err.what());
|
||||||
}
|
}
|
||||||
@ -565,32 +565,6 @@ void tray_manager::create_bg() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Put tray window above the defined sibling in the window stack
|
|
||||||
*/
|
|
||||||
void tray_manager::restack_window() {
|
|
||||||
if (m_opts.sibling == XCB_NONE) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
m_log.trace("tray: Restacking tray window");
|
|
||||||
|
|
||||||
unsigned int mask = 0;
|
|
||||||
unsigned int values[7];
|
|
||||||
xcb_params_configure_window_t params{};
|
|
||||||
|
|
||||||
XCB_AUX_ADD_PARAM(&mask, ¶ms, sibling, m_opts.sibling);
|
|
||||||
XCB_AUX_ADD_PARAM(&mask, ¶ms, stack_mode, XCB_STACK_MODE_ABOVE);
|
|
||||||
|
|
||||||
connection::pack_values(mask, ¶ms, values);
|
|
||||||
m_connection.configure_window_checked(m_tray, mask, values);
|
|
||||||
} catch (const exception& err) {
|
|
||||||
auto id = m_connection.id(m_opts.sibling);
|
|
||||||
m_log.err("tray: Failed to put tray above %s in the stack (%s)", id, err.what());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set window WM hints
|
* Set window WM hints
|
||||||
*/
|
*/
|
||||||
@ -752,6 +726,9 @@ void tray_manager::process_docking_request(xcb_window_t win) {
|
|||||||
m_log.trace("tray: Add client window to the save set");
|
m_log.trace("tray: Add client window to the save set");
|
||||||
m_connection.change_save_set_checked(XCB_SET_MODE_INSERT, client->window());
|
m_connection.change_save_set_checked(XCB_SET_MODE_INSERT, client->window());
|
||||||
|
|
||||||
|
// TODO properly support tray icon backgrounds
|
||||||
|
auto p = XCB_BACK_PIXMAP_NONE;
|
||||||
|
m_connection.change_window_attributes_checked(client->window(), XCB_CW_BACK_PIXMAP, &p);
|
||||||
m_log.trace("tray: Reparent client");
|
m_log.trace("tray: Reparent client");
|
||||||
m_connection.reparent_window_checked(
|
m_connection.reparent_window_checked(
|
||||||
client->window(), m_tray, calculate_client_x(client->window()), calculate_client_y());
|
client->window(), m_tray, calculate_client_x(client->window()), calculate_client_y());
|
||||||
|
Loading…
Reference in New Issue
Block a user