1 #include "x11/tray_client.hpp"
2
3 #include <xcb/xcb.h>
4 #include <xcb/xcb_aux.h>
5
6 #include "utils/memory.hpp"
7 #include "x11/connection.hpp"
8
9 POLYBAR_NS
10
tray_client(connection & conn,xcb_window_t win,unsigned int w,unsigned int h)11 tray_client::tray_client(connection& conn, xcb_window_t win, unsigned int w, unsigned int h)
12 : m_connection(conn), m_window(win), m_width(w), m_height(h) {}
13
~tray_client()14 tray_client::~tray_client() {
15 xembed::unembed(m_connection, window(), m_connection.root());
16 }
17
width() const18 unsigned int tray_client::width() const {
19 return m_width;
20 }
21
height() const22 unsigned int tray_client::height() const {
23 return m_height;
24 }
25
clear_window() const26 void tray_client::clear_window() const {
27 m_connection.clear_area_checked(1, window(), 0, 0, width(), height());
28 }
29
30 /**
31 * Match given window against client window
32 */
match(const xcb_window_t & win) const33 bool tray_client::match(const xcb_window_t& win) const {
34 return win == m_window;
35 }
36
37 /**
38 * Get client window mapped state
39 */
mapped() const40 bool tray_client::mapped() const {
41 return m_mapped;
42 }
43
44 /**
45 * Set client window mapped state
46 */
mapped(bool state)47 void tray_client::mapped(bool state) {
48 m_mapped = state;
49 }
50
51 /**
52 * Get client window
53 */
window() const54 xcb_window_t tray_client::window() const {
55 return m_window;
56 }
57
query_xembed()58 void tray_client::query_xembed() {
59 m_xembed_supported = xembed::query(m_connection, m_window, m_xembed);
60 }
61
is_xembed_supported() const62 bool tray_client::is_xembed_supported() const {
63 return m_xembed_supported;
64 }
65
get_xembed() const66 const xembed::info& tray_client::get_xembed() const {
67 return m_xembed;
68 }
69
70 /**
71 * Make sure that the window mapping state is correct
72 */
ensure_state() const73 void tray_client::ensure_state() const {
74 bool should_be_mapped = true;
75
76 if (is_xembed_supported()) {
77 should_be_mapped = m_xembed.is_mapped();
78 }
79
80 if (!mapped() && should_be_mapped) {
81 m_connection.map_window_checked(window());
82 } else if (mapped() && !should_be_mapped) {
83 m_connection.unmap_window_checked(window());
84 }
85 }
86
87 /**
88 * Configure window size
89 */
reconfigure(int x,int y) const90 void tray_client::reconfigure(int x, int y) const {
91 unsigned int configure_mask = 0;
92 unsigned int configure_values[7];
93 xcb_params_configure_window_t configure_params{};
94
95 XCB_AUX_ADD_PARAM(&configure_mask, &configure_params, width, m_width);
96 XCB_AUX_ADD_PARAM(&configure_mask, &configure_params, height, m_height);
97 XCB_AUX_ADD_PARAM(&configure_mask, &configure_params, x, x);
98 XCB_AUX_ADD_PARAM(&configure_mask, &configure_params, y, y);
99
100 connection::pack_values(configure_mask, &configure_params, configure_values);
101 m_connection.configure_window_checked(window(), configure_mask, configure_values);
102 }
103
104 /**
105 * Respond to client resize requests
106 */
configure_notify(int x,int y) const107 void tray_client::configure_notify(int x, int y) const {
108 auto notify = memory_util::make_malloc_ptr<xcb_configure_notify_event_t, 32_z>();
109 notify->response_type = XCB_CONFIGURE_NOTIFY;
110 notify->event = m_window;
111 notify->window = m_window;
112 notify->override_redirect = false;
113 notify->above_sibling = 0;
114 notify->x = x;
115 notify->y = y;
116 notify->width = m_width;
117 notify->height = m_height;
118 notify->border_width = 0;
119
120 unsigned int mask{XCB_EVENT_MASK_STRUCTURE_NOTIFY};
121 m_connection.send_event_checked(false, m_window, mask, reinterpret_cast<const char*>(notify.get()));
122 }
123
124 POLYBAR_NS_END
125