#include #include #include "utils/memory.hpp" #include "x11/connection.hpp" #include "x11/tray_client.hpp" #include "x11/xembed.hpp" #include "x11/xutils.hpp" POLYBAR_NS tray_client::tray_client(connection& conn, xcb_window_t win, uint16_t w, uint16_t h) : m_connection(conn), m_window(win), m_width(w), m_height(h) { m_xembed = memory_util::make_malloc_ptr(); m_xembed->version = XEMBED_VERSION; m_xembed->flags = XEMBED_MAPPED; } tray_client::~tray_client() { xembed::unembed(m_connection, window(), m_connection.root()); } uint16_t tray_client::width() const { return m_width; } uint16_t tray_client::height() const { return m_height; } void tray_client::clear_window() const { try { m_connection.clear_area_checked(1, window(), 0, 0, width(), height()); } catch (const xpp::x::error::window& err) { // ignore } } /** * Match given window against client window */ bool tray_client::match(const xcb_window_t& win) const { return win == m_window; } /** * Get client window mapped state */ bool tray_client::mapped() const { return m_mapped; } /** * Set client window mapped state */ void tray_client::mapped(bool state) { m_mapped = state; } /** * Get client window */ xcb_window_t tray_client::window() const { return m_window; } /** * Get xembed data pointer */ xembed_data* tray_client::xembed() const { return m_xembed.get(); } /** * Make sure that the window mapping state is correct */ void tray_client::ensure_state() const { if (!mapped() && ((xembed()->flags & XEMBED_MAPPED) == XEMBED_MAPPED)) { m_connection.map_window_checked(window()); } else if (mapped() && ((xembed()->flags & XEMBED_MAPPED) != XEMBED_MAPPED)) { m_connection.unmap_window_checked(window()); } } /** * Configure window size */ void tray_client::reconfigure(int16_t x, int16_t y) const { uint32_t configure_mask = 0; uint32_t configure_values[7]; xcb_params_configure_window_t configure_params{}; XCB_AUX_ADD_PARAM(&configure_mask, &configure_params, width, m_width); XCB_AUX_ADD_PARAM(&configure_mask, &configure_params, height, m_height); XCB_AUX_ADD_PARAM(&configure_mask, &configure_params, x, x); XCB_AUX_ADD_PARAM(&configure_mask, &configure_params, y, y); xutils::pack_values(configure_mask, &configure_params, configure_values); m_connection.configure_window_checked(window(), configure_mask, configure_values); } /** * Respond to client resize requests */ void tray_client::configure_notify(int16_t x, int16_t y) const { auto notify = memory_util::make_malloc_ptr(); notify->response_type = XCB_CONFIGURE_NOTIFY; notify->event = m_window; notify->window = m_window; notify->override_redirect = false; notify->above_sibling = 0; notify->x = x; notify->y = y; notify->width = m_width; notify->height = m_height; notify->border_width = 0; uint32_t mask{XCB_EVENT_MASK_STRUCTURE_NOTIFY}; m_connection.send_event_checked(false, m_window, mask, reinterpret_cast(notify.get())); } POLYBAR_NS_END