Use individual wrapper window for each tray client
This commit is contained in:
parent
9544130b9c
commit
3711e999ba
@ -34,11 +34,15 @@ 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);
|
||||||
|
|
||||||
#ifdef DEBUG_LOGGER // {{{
|
#ifdef DEBUG_LOGGER // {{{
|
||||||
template <typename... Args>
|
template <typename... Args>
|
||||||
void trace(const string& message, Args&&... args) const {
|
void trace(const string& message, Args&&... args) const {
|
||||||
output(loglevel::TRACE, message, std::forward<Args>(args)...);
|
output(loglevel::TRACE, message, std::forward<Args>(args)...);
|
||||||
@ -57,7 +61,7 @@ class logger {
|
|||||||
void trace(Args&&...) const {}
|
void trace(Args&&...) const {}
|
||||||
template <typename... Args>
|
template <typename... Args>
|
||||||
void trace_x(Args&&...) const {}
|
void trace_x(Args&&...) const {}
|
||||||
#endif // }}}
|
#endif // }}}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Output an info message
|
* Output an info message
|
||||||
@ -118,21 +122,21 @@ class logger {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(__clang__) // {{{
|
#if defined(__clang__) // {{{
|
||||||
#pragma clang diagnostic push
|
#pragma clang diagnostic push
|
||||||
#pragma clang diagnostic ignored "-Wformat-security"
|
#pragma clang diagnostic ignored "-Wformat-security"
|
||||||
#elif defined(__GNUC__)
|
#elif defined(__GNUC__)
|
||||||
#pragma GCC diagnostic push
|
#pragma GCC diagnostic push
|
||||||
#pragma GCC diagnostic ignored "-Wformat-security"
|
#pragma GCC diagnostic ignored "-Wformat-security"
|
||||||
#endif // }}}
|
#endif // }}}
|
||||||
|
|
||||||
dprintf(m_fd, (m_prefixes.at(level) + format + m_suffixes.at(level) + "\n").c_str(), convert(values)...);
|
dprintf(m_fd, (m_prefixes.at(level) + format + m_suffixes.at(level) + "\n").c_str(), convert(values)...);
|
||||||
|
|
||||||
#if defined(__clang__) // {{{
|
#if defined(__clang__) // {{{
|
||||||
#pragma clang diagnostic pop
|
#pragma clang diagnostic pop
|
||||||
#elif defined(__GNUC__)
|
#elif defined(__GNUC__)
|
||||||
#pragma GCC diagnostic pop
|
#pragma GCC diagnostic pop
|
||||||
#endif // }}}
|
#endif // }}}
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -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;
|
||||||
|
@ -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
|
||||||
|
@ -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).
|
||||||
@ -34,28 +34,28 @@ POLYBAR_NS
|
|||||||
namespace xembed {
|
namespace xembed {
|
||||||
|
|
||||||
class info {
|
class info {
|
||||||
public:
|
public:
|
||||||
void set(uint32_t* data);
|
void set(uint32_t* data);
|
||||||
|
|
||||||
uint32_t get_version() const;
|
uint32_t get_version() const;
|
||||||
uint32_t get_flags() const;
|
uint32_t get_flags() const;
|
||||||
|
|
||||||
bool is_mapped() const;
|
bool is_mapped() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
uint32_t version;
|
uint32_t version;
|
||||||
uint32_t flags;
|
uint32_t flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
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
|
||||||
|
|
||||||
POLYBAR_NS_END
|
POLYBAR_NS_END
|
||||||
|
@ -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) {
|
||||||
|
@ -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*>(¬ify));
|
m_connection.send_event_checked(false, m_client, mask, reinterpret_cast<const char*>(¬ify));
|
||||||
}
|
}
|
||||||
|
|
||||||
POLYBAR_NS_END
|
POLYBAR_NS_END
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user