Use individual wrapper window for each tray client

This commit is contained in:
patrick96 2022-03-07 15:12:42 +01:00
parent 9544130b9c
commit 3711e999ba
No known key found for this signature in database
GPG Key ID: 521E5E03AEBCA1A7
8 changed files with 174 additions and 86 deletions

View File

@ -34,6 +34,10 @@ class logger {
explicit logger(loglevel level); explicit logger(loglevel level);
const logger& operator=(const logger&) const {
return *this;
}
static loglevel parse_verbosity(const string& name, loglevel fallback = loglevel::NONE); static loglevel parse_verbosity(const string& name, loglevel fallback = loglevel::NONE);
void verbosity(loglevel level); void verbosity(loglevel level);

View File

@ -13,7 +13,7 @@ class connection;
class tray_client : public non_copyable_mixin { class tray_client : public non_copyable_mixin {
public: public:
explicit tray_client(connection& conn, xcb_window_t win, size s); explicit tray_client(const logger& log, connection& conn, xcb_window_t tray, xcb_window_t win, size s);
~tray_client(); ~tray_client();
tray_client(tray_client&&); tray_client(tray_client&&);
@ -27,7 +27,8 @@ class tray_client : public non_copyable_mixin {
bool mapped() const; bool mapped() const;
void mapped(bool state); void mapped(bool state);
xcb_window_t window() const; xcb_window_t embedder() const;
xcb_window_t client() const;
void query_xembed(); void query_xembed();
bool is_xembed_supported() const; bool is_xembed_supported() const;
@ -38,8 +39,27 @@ class tray_client : public non_copyable_mixin {
void configure_notify(int x, int y) const; void configure_notify(int x, int y) const;
protected: protected:
const logger& m_log;
connection& m_connection; connection& m_connection;
xcb_window_t m_window{XCB_NONE};
/**
* Embedder window.
*
* The docking client window is reparented to this window.
* This window is itself a child of the main tray window.
*
* This class owns this window and is responsible for creating/destroying it.
*/
xcb_window_t m_wrapper{XCB_NONE};
/**
* Client window.
*
* The window itself is owned by the application providing it.
* This class is responsible for correctly mapping and reparenting it in accordance with the XEMBED protocol.
*/
xcb_window_t m_client{XCB_NONE};
/** /**
* Whether the client window supports XEMBED. * Whether the client window supports XEMBED.
@ -50,9 +70,12 @@ class tray_client : public non_copyable_mixin {
/** /**
* _XEMBED_INFO of the client window * _XEMBED_INFO of the client window
*
* Only valid if m_xembed_supported == true
*/ */
xembed::info m_xembed; xembed::info m_xembed;
// TODO
bool m_mapped{false}; bool m_mapped{false};
size m_size; size m_size;

View File

@ -69,7 +69,7 @@ struct tray_settings {
/** /**
* Number of clients currently mapped. * Number of clients currently mapped.
*/ */
int num_clients{0}; int num_mapped_clients{0};
// This is the width of the bar window // This is the width of the bar window
// TODO directly read from bar_settings // TODO directly read from bar_settings

View File

@ -5,26 +5,26 @@
POLYBAR_NS POLYBAR_NS
#define XEMBED_VERSION 0 static constexpr uint32_t XEMBED_VERSION = 0;
#define XEMBED_MAPPED (1 << 0) static constexpr uint32_t XEMBED_MAPPED = (1 << 0);
#define XEMBED_EMBEDDED_NOTIFY 0 static constexpr uint32_t XEMBED_EMBEDDED_NOTIFY = 0;
#define XEMBED_WINDOW_ACTIVATE 1 static constexpr uint32_t XEMBED_WINDOW_ACTIVATE = 1;
#define XEMBED_WINDOW_DEACTIVATE 2 static constexpr uint32_t XEMBED_WINDOW_DEACTIVATE = 2;
#define XEMBED_REQUEST_FOCUS 3 static constexpr uint32_t XEMBED_REQUEST_FOCUS = 3;
#define XEMBED_FOCUS_IN 3 static constexpr uint32_t XEMBED_FOCUS_IN = 3;
#define XEMBED_FOCUS_OUT 4 static constexpr uint32_t XEMBED_FOCUS_OUT = 4;
#define XEMBED_FOCUS_NEXT 5 static constexpr uint32_t XEMBED_FOCUS_NEXT = 5;
#define XEMBED_FOCUS_PREV 6 static constexpr uint32_t XEMBED_FOCUS_PREV = 6;
#define XEMBED_FOCUS_CURRENT 0 static constexpr uint32_t XEMBED_FOCUS_CURRENT = 0;
#define XEMBED_FOCUS_FIRST 1 static constexpr uint32_t XEMBED_FOCUS_FIRST = 1;
#define XEMBED_FOCUS_LAST 1 static constexpr uint32_t XEMBED_FOCUS_LAST = 2;
/** /**
* Max XEMBED version supported. * Max XEMBED version supported.
*/ */
#define XEMBED_MAX_VERSION UINT32_C(0) static constexpr uint32_t XEMBED_MAX_VERSION = 0;
/** /**
* Implementation of parts of the XEMBED spec (as much as needed to get the tray working). * Implementation of parts of the XEMBED spec (as much as needed to get the tray working).
@ -48,12 +48,12 @@ namespace xembed {
}; };
bool query(connection& conn, xcb_window_t win, info& data); bool query(connection& conn, xcb_window_t win, info& data);
void send_message(connection& conn, xcb_window_t target, long message, long d1, long d2, long d3); void send_message(connection& conn, xcb_window_t target, uint32_t message, uint32_t d1, uint32_t d2, uint32_t d3);
void send_focus_event(connection& conn, xcb_window_t target); void send_focus_event(connection& conn, xcb_window_t target);
void notify_embedded(connection& conn, xcb_window_t win, xcb_window_t embedder, uint32_t version); void notify_embedded(connection& conn, xcb_window_t win, xcb_window_t embedder, uint32_t version);
void notify_activated(connection& conn, xcb_window_t win); void notify_activated(connection& conn, xcb_window_t win);
void notify_deactivated(connection& conn, xcb_window_t win); void notify_deactivated(connection& conn, xcb_window_t win);
void notify_focused(connection& conn, xcb_window_t win, long focus_type); void notify_focused(connection& conn, xcb_window_t win, uint32_t focus_type);
void notify_unfocused(connection& conn, xcb_window_t win); void notify_unfocused(connection& conn, xcb_window_t win);
void unembed(connection& conn, xcb_window_t win, xcb_window_t root); void unembed(connection& conn, xcb_window_t win, xcb_window_t root);
} // namespace xembed } // namespace xembed

View File

@ -61,8 +61,8 @@ bar::make_type bar::make(loop& loop, bool only_initialize_values) {
* TODO: Break out all tray handling * TODO: Break out all tray handling
*/ */
bar::bar(connection& conn, signal_emitter& emitter, const config& config, const logger& logger, loop& loop, bar::bar(connection& conn, signal_emitter& emitter, const config& config, const logger& logger, loop& loop,
unique_ptr<screen>&& screen, unique_ptr<tags::dispatch>&& dispatch, unique_ptr<screen>&& screen, unique_ptr<tags::dispatch>&& dispatch, unique_ptr<tags::action_context>&& action_ctxt,
unique_ptr<tags::action_context>&& action_ctxt, bool only_initialize_values) bool only_initialize_values)
: m_connection(conn) : m_connection(conn)
, m_sig(emitter) , m_sig(emitter)
, m_conf(config) , m_conf(config)
@ -393,7 +393,7 @@ void bar::parse(string&& data, bool force) {
auto rect = m_opts.inner_area(); auto rect = m_opts.inner_area();
if (m_tray && !m_tray->settings().detached && m_tray->settings().num_clients > 0 && !m_tray->settings().adaptive) { if (m_tray && !m_tray->settings().detached && m_tray->settings().num_mapped_clients > 0 && !m_tray->settings().adaptive) {
auto trayalign = m_tray->settings().align; auto trayalign = m_tray->settings().align;
auto traywidth = m_tray->settings().win_size.w; auto traywidth = m_tray->settings().win_size.w;
if (trayalign == alignment::LEFT) { if (trayalign == alignment::LEFT) {

View File

@ -5,24 +5,61 @@
#include "utils/memory.hpp" #include "utils/memory.hpp"
#include "x11/connection.hpp" #include "x11/connection.hpp"
#include "x11/winspec.hpp"
POLYBAR_NS POLYBAR_NS
tray_client::tray_client(connection& conn, xcb_window_t win, size s) : m_connection(conn), m_window(win), m_size(s) {} // 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);
// 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_parent(tray)
// TODO add proper pixmap
<< cw_params_back_pixmap(XCB_PIXMAP_NONE)
// << 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_PROPERTY_CHANGE
| XCB_EVENT_MASK_STRUCTURE_NOTIFY
| XCB_EVENT_MASK_EXPOSURE)
// << cw_flush(false);
// TODO Make unchecked
<< cw_flush(true);
// clang-format on
}
tray_client::~tray_client() { tray_client::~tray_client() {
if (m_window != XCB_NONE) { if (m_client != XCB_NONE) {
xembed::unembed(m_connection, m_window, m_connection.root()); xembed::unembed(m_connection, m_client, m_connection.root());
}
if (m_wrapper != XCB_NONE) {
m_connection.destroy_window(m_wrapper);
} }
} }
tray_client::tray_client(tray_client&& c) : m_connection(c.m_connection), m_size(c.m_size) { tray_client::tray_client(tray_client&& c) : m_log(c.m_log), m_connection(c.m_connection), m_size(c.m_size) {
std::swap(m_window, c.m_window); std::swap(m_wrapper, c.m_wrapper);
std::swap(m_client, c.m_client);
} }
tray_client& tray_client::operator=(tray_client&& c) { tray_client& tray_client::operator=(tray_client&& c) {
m_log = c.m_log;
m_connection = c.m_connection; m_connection = c.m_connection;
std::swap(m_window, c.m_window); std::swap(m_wrapper, c.m_wrapper);
std::swap(m_client, c.m_client);
std::swap(m_size, c.m_size); std::swap(m_size, c.m_size);
return *this; return *this;
} }
@ -36,14 +73,14 @@ unsigned int tray_client::height() const {
} }
void tray_client::clear_window() const { void tray_client::clear_window() const {
m_connection.clear_area_checked(1, window(), 0, 0, width(), height()); m_connection.clear_area_checked(1, client(), 0, 0, width(), height());
} }
/** /**
* Match given window against client window * Is this the client for the given client window
*/ */
bool tray_client::match(const xcb_window_t& win) const { bool tray_client::match(const xcb_window_t& win) const {
return win == m_window; return win == m_client;
} }
/** /**
@ -60,15 +97,16 @@ void tray_client::mapped(bool state) {
m_mapped = state; m_mapped = state;
} }
/** xcb_window_t tray_client::embedder() const {
* Get client window return m_wrapper;
*/ }
xcb_window_t tray_client::window() const {
return m_window; xcb_window_t tray_client::client() const {
return m_client;
} }
void tray_client::query_xembed() { void tray_client::query_xembed() {
m_xembed_supported = xembed::query(m_connection, m_window, m_xembed); m_xembed_supported = xembed::query(m_connection, m_client, m_xembed);
} }
bool tray_client::is_xembed_supported() const { bool tray_client::is_xembed_supported() const {
@ -83,6 +121,7 @@ const xembed::info& tray_client::get_xembed() const {
* Make sure that the window mapping state is correct * Make sure that the window mapping state is correct
*/ */
void tray_client::ensure_state() const { void tray_client::ensure_state() const {
// TODO correctly map/unmap wrapper
bool should_be_mapped = true; bool should_be_mapped = true;
if (is_xembed_supported()) { if (is_xembed_supported()) {
@ -90,9 +129,11 @@ void tray_client::ensure_state() const {
} }
if (!mapped() && should_be_mapped) { if (!mapped() && should_be_mapped) {
m_connection.map_window_checked(window()); m_connection.map_window_checked(embedder());
m_connection.map_window_checked(client());
} else if (mapped() && !should_be_mapped) { } else if (mapped() && !should_be_mapped) {
m_connection.unmap_window_checked(window()); m_connection.unmap_window_checked(embedder());
m_connection.unmap_window_checked(client());
} }
} }
@ -100,6 +141,9 @@ void tray_client::ensure_state() const {
* Configure window size * Configure window size
*/ */
void tray_client::reconfigure(int x, int y) const { void tray_client::reconfigure(int x, int y) const {
m_log.trace("tray(%s): moving to (%d, %d)", m_connection.id(client()), x, y);
// TODO correctly reconfigure wrapper + client
uint32_t configure_mask = 0; uint32_t configure_mask = 0;
std::array<uint32_t, 32> configure_values{}; std::array<uint32_t, 32> configure_values{};
xcb_params_configure_window_t configure_params{}; xcb_params_configure_window_t configure_params{};
@ -109,17 +153,26 @@ void tray_client::reconfigure(int x, int y) const {
XCB_AUX_ADD_PARAM(&configure_mask, &configure_params, x, x); XCB_AUX_ADD_PARAM(&configure_mask, &configure_params, x, x);
XCB_AUX_ADD_PARAM(&configure_mask, &configure_params, y, y); XCB_AUX_ADD_PARAM(&configure_mask, &configure_params, y, y);
connection::pack_values(configure_mask, &configure_params, configure_values); connection::pack_values(configure_mask, &configure_params, configure_values);
m_connection.configure_window_checked(window(), configure_mask, configure_values.data()); m_connection.configure_window_checked(embedder(), configure_mask, configure_values.data());
configure_mask = 0;
XCB_AUX_ADD_PARAM(&configure_mask, &configure_params, width, m_size.w);
XCB_AUX_ADD_PARAM(&configure_mask, &configure_params, height, m_size.h);
XCB_AUX_ADD_PARAM(&configure_mask, &configure_params, x, 0);
XCB_AUX_ADD_PARAM(&configure_mask, &configure_params, y, 0);
connection::pack_values(configure_mask, &configure_params, configure_values);
m_connection.configure_window_checked(client(), configure_mask, configure_values.data());
} }
/** /**
* Respond to client resize requests * Respond to client resize/move requests
*/ */
void tray_client::configure_notify(int x, int y) const { void tray_client::configure_notify(int x, int y) const {
// TODO remove x and y position. The position will always be (0,0)
xcb_configure_notify_event_t notify; xcb_configure_notify_event_t notify;
notify.response_type = XCB_CONFIGURE_NOTIFY; notify.response_type = XCB_CONFIGURE_NOTIFY;
notify.event = m_window; notify.event = m_client;
notify.window = m_window; notify.window = m_client;
notify.override_redirect = false; notify.override_redirect = false;
notify.above_sibling = 0; notify.above_sibling = 0;
notify.x = x; notify.x = x;
@ -129,7 +182,7 @@ void tray_client::configure_notify(int x, int y) const {
notify.border_width = 0; notify.border_width = 0;
unsigned int mask{XCB_EVENT_MASK_STRUCTURE_NOTIFY}; unsigned int mask{XCB_EVENT_MASK_STRUCTURE_NOTIFY};
m_connection.send_event_checked(false, m_window, mask, reinterpret_cast<const char*>(&notify)); m_connection.send_event_checked(false, m_client, mask, reinterpret_cast<const char*>(&notify));
} }
POLYBAR_NS_END POLYBAR_NS_END

View File

@ -265,7 +265,7 @@ void tray_manager::deactivate(bool clear_selection) {
} }
m_opts.win_size.w = 0; m_opts.win_size.w = 0;
m_opts.num_clients = 0; m_opts.num_mapped_clients = 0;
m_acquired_selection = false; m_acquired_selection = false;
m_mapped = false; m_mapped = false;
@ -299,7 +299,7 @@ void tray_manager::reconfigure() {
m_log.err("Failed to reconfigure tray background (%s)", err.what()); m_log.err("Failed to reconfigure tray background (%s)", err.what());
} }
m_opts.num_clients = mapped_clients(); m_opts.num_mapped_clients = mapped_clients();
guard.unlock(); guard.unlock();
refresh_window(); refresh_window();
m_connection.flush(); m_connection.flush();
@ -432,8 +432,8 @@ void tray_manager::refresh_window() {
client.clear_window(); client.clear_window();
} }
} catch (const std::exception& e) { } catch (const std::exception& e) {
m_log.err("Failed to clear tray client %s '%s' (%s)", m_connection.id(client.window()), m_log.err("Failed to clear tray client %s '%s' (%s)", ewmh_util::get_wm_name(client.client()),
ewmh_util::get_wm_name(client.window()), e.what()); m_connection.id(client.client()), e.what());
} }
} }
@ -480,7 +480,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) // TODO
// << cw_params_override_redirect(true)
<< cw_parent(m_opts.bar_window); << cw_parent(m_opts.bar_window);
// clang-format on // clang-format on
@ -699,10 +700,7 @@ void tray_manager::track_selection_owner(xcb_window_t owner) {
void tray_manager::process_docking_request(xcb_window_t win) { 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)); m_log.info("Processing docking request from '%s' (%s)", ewmh_util::get_wm_name(win), m_connection.id(win));
tray_client client(m_connection, win, m_opts.client_size); tray_client client(m_log, m_connection, m_tray, win, m_opts.client_size);
auto geom = m_connection.get_geometry(win);
m_log.trace("tray: depth: %u, width: %u, height: %u", geom->depth, geom->width, geom->height);
try { try {
client.query_xembed(); client.query_xembed();
@ -722,29 +720,31 @@ void tray_manager::process_docking_request(xcb_window_t win) {
const uint32_t value = XCB_EVENT_MASK_PROPERTY_CHANGE | XCB_EVENT_MASK_STRUCTURE_NOTIFY; const uint32_t value = XCB_EVENT_MASK_PROPERTY_CHANGE | XCB_EVENT_MASK_STRUCTURE_NOTIFY;
m_log.trace("tray: Update client window"); m_log.trace("tray: Update client window");
m_connection.change_window_attributes_checked(client.window(), mask, &value); m_connection.change_window_attributes_checked(client.client(), mask, &value);
m_log.trace("tray: Configure client size"); m_log.trace("tray: Configure client size");
client.reconfigure(0, 0); client.reconfigure(0, 0);
// TODO properly support tray icon backgrounds // TODO put this into tray_client class
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.client(), client.embedder(), calculate_client_x(client.client()), calculate_client_y());
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()); // TODO move this into tray_client
m_connection.change_save_set_checked(XCB_SET_MODE_INSERT, client.client());
if (client.is_xembed_supported()) { if (client.is_xembed_supported()) {
m_log.trace("tray: Send embbeded notification to client"); m_log.trace("tray: Send embbeded notification to client");
xembed::notify_embedded(m_connection, client.window(), m_tray, client.get_xembed().get_version()); // TODO move this into tray_client
xembed::notify_embedded(m_connection, client.client(), client.embedder(), client.get_xembed().get_version());
} }
if (!client.is_xembed_supported() || client.get_xembed().is_mapped()) { if (!client.is_xembed_supported() || client.get_xembed().is_mapped()) {
m_log.trace("tray: Map client"); m_log.trace("tray: Map client");
m_connection.map_window_checked(client.window()); // TODO move this into tray_client
m_connection.map_window_checked(client.client());
m_connection.map_window_checked(client.embedder());
} }
} catch (const std::exception& err) { } catch (const std::exception& err) {
m_log.err("Failed to setup tray client '%s' (%s) removing... (%s)", ewmh_util::get_wm_name(win), m_log.err("Failed to setup tray client '%s' (%s) removing... (%s)", ewmh_util::get_wm_name(win),
@ -840,7 +840,7 @@ tray_client* tray_manager::find_client(const xcb_window_t& win) {
* Remove tray client * Remove tray client
*/ */
void tray_manager::remove_client(const tray_client& client, bool reconfigure) { void tray_manager::remove_client(const tray_client& client, bool reconfigure) {
remove_client(client.window(), reconfigure); remove_client(client.client(), reconfigure);
} }
/** /**
@ -993,8 +993,6 @@ void tray_manager::handle(const evt::property_notify& evt) {
m_log.trace("tray: _XEMBED_INFO: %s", m_connection.id(evt->window)); m_log.trace("tray: _XEMBED_INFO: %s", m_connection.id(evt->window));
auto win = client->window();
if (evt->state == XCB_PROPERTY_NEW_VALUE) { if (evt->state == XCB_PROPERTY_NEW_VALUE) {
m_log.trace("tray: _XEMBED_INFO value has changed"); m_log.trace("tray: _XEMBED_INFO value has changed");
} }
@ -1003,7 +1001,7 @@ void tray_manager::handle(const evt::property_notify& evt) {
client->query_xembed(); client->query_xembed();
} catch (const xpp::x::error::window& err) { } catch (const xpp::x::error::window& err) {
m_log.err("Failed to query _XEMBED_INFO, removing client... (%s)", err.what()); m_log.err("Failed to query _XEMBED_INFO, removing client... (%s)", err.what());
remove_client(win, true); remove_client(*client, true);
return; return;
} }
@ -1019,9 +1017,19 @@ void tray_manager::handle(const evt::property_notify& evt) {
* Event callback : XCB_REPARENT_NOTIFY * Event callback : XCB_REPARENT_NOTIFY
*/ */
void tray_manager::handle(const evt::reparent_notify& evt) { void tray_manager::handle(const evt::reparent_notify& evt) {
if (m_activated && is_embedded(evt->window) && evt->parent != m_tray) { if (!m_activated) {
return;
}
auto client = find_client(evt->window);
if (!client) {
return;
}
if (evt->parent != client->embedder()) {
m_log.trace("tray: Received reparent_notify for client, remove..."); m_log.trace("tray: Received reparent_notify for client, remove...");
remove_client(evt->window); remove_client(*client);
} }
} }
@ -1054,7 +1062,7 @@ void tray_manager::handle(const evt::map_notify& evt) {
m_log.trace("tray: Received map_notify"); m_log.trace("tray: Received map_notify");
m_log.trace("tray: Set client mapped"); m_log.trace("tray: Set client mapped");
find_client(evt->window)->mapped(true); find_client(evt->window)->mapped(true);
if (mapped_clients() > m_opts.num_clients) { if (mapped_clients() > m_opts.num_mapped_clients) {
reconfigure(); reconfigure();
} }
} }

View File

@ -48,7 +48,7 @@ namespace xembed {
/** /**
* Send _XEMBED messages * Send _XEMBED messages
*/ */
void send_message(connection& conn, xcb_window_t target, long message, long d1, long d2, long d3) { void send_message(connection& conn, xcb_window_t target, uint32_t message, uint32_t d1, uint32_t d2, uint32_t d3) {
auto msg = conn.make_client_message(_XEMBED, target); auto msg = conn.make_client_message(_XEMBED, target);
msg.data.data32[0] = XCB_CURRENT_TIME; msg.data.data32[0] = XCB_CURRENT_TIME;
msg.data.data32[1] = message; msg.data.data32[1] = message;
@ -92,7 +92,7 @@ namespace xembed {
/** /**
* Send window focused notification * Send window focused notification
*/ */
void notify_focused(connection& conn, xcb_window_t win, long focus_type) { void notify_focused(connection& conn, xcb_window_t win, uint32_t focus_type) {
send_message(conn, win, XEMBED_FOCUS_IN, focus_type, 0, 0); send_message(conn, win, XEMBED_FOCUS_IN, focus_type, 0, 0);
} }