fix(tray): Visibility change
This commit is contained in:
parent
a3f2e8aa51
commit
bb0cfcf033
@ -39,6 +39,7 @@ class bar : public xpp::event::sink<evt::button_press, evt::expose, evt::propert
|
|||||||
void reconfigure_pos();
|
void reconfigure_pos();
|
||||||
void reconfigure_struts();
|
void reconfigure_struts();
|
||||||
void reconfigure_wm_hints();
|
void reconfigure_wm_hints();
|
||||||
|
void broadcast_visibility();
|
||||||
|
|
||||||
void handle(const evt::button_press& evt);
|
void handle(const evt::button_press& evt);
|
||||||
void handle(const evt::expose& evt);
|
void handle(const evt::expose& evt);
|
||||||
|
@ -113,6 +113,7 @@ class tray_manager : public xpp::event::sink<evt::expose, evt::visibility_notify
|
|||||||
void reconfigure_clients();
|
void reconfigure_clients();
|
||||||
void reconfigure_bg(bool realloc = false);
|
void reconfigure_bg(bool realloc = false);
|
||||||
void refresh_window();
|
void refresh_window();
|
||||||
|
void redraw_window();
|
||||||
|
|
||||||
void query_atom();
|
void query_atom();
|
||||||
void create_window();
|
void create_window();
|
||||||
|
@ -159,10 +159,12 @@ void bar::bootstrap(bool nodraw) {
|
|||||||
|
|
||||||
restack_window();
|
restack_window();
|
||||||
|
|
||||||
|
m_log.trace("bar: Reconfigure window");
|
||||||
reconfigure_struts();
|
reconfigure_struts();
|
||||||
reconfigure_wm_hints();
|
reconfigure_wm_hints();
|
||||||
|
|
||||||
m_connection.map_window(m_window);
|
m_log.trace("bar: Map window");
|
||||||
|
m_connection.map_window_checked(m_window);
|
||||||
|
|
||||||
// Reconfigure window position after mapping (required by Openbox)
|
// Reconfigure window position after mapping (required by Openbox)
|
||||||
// Required by Openbox
|
// Required by Openbox
|
||||||
@ -341,6 +343,7 @@ void bar::activate_tray() {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
m_tray->activate();
|
m_tray->activate();
|
||||||
|
broadcast_visibility();
|
||||||
} catch (const exception& err) {
|
} catch (const exception& err) {
|
||||||
m_log.err(err.what());
|
m_log.err(err.what());
|
||||||
m_log.err("Failed to activate tray manager, disabling...");
|
m_log.err("Failed to activate tray manager, disabling...");
|
||||||
@ -587,6 +590,29 @@ void bar::reconfigure_wm_hints() {
|
|||||||
wm_util::set_wmpid(m_connection, m_window, getpid());
|
wm_util::set_wmpid(m_connection, m_window, getpid());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Broadcast current map state
|
||||||
|
*/
|
||||||
|
void bar::broadcast_visibility() {
|
||||||
|
if (!g_signals::bar::visibility_change) {
|
||||||
|
return m_log.trace("bar: no callback handler set for bar visibility change");
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
auto attr = m_connection.get_window_attributes(m_window);
|
||||||
|
|
||||||
|
if (attr->map_state == XCB_MAP_STATE_UNVIEWABLE) {
|
||||||
|
g_signals::bar::visibility_change(false);
|
||||||
|
} else if (attr->map_state == XCB_MAP_STATE_UNMAPPED) {
|
||||||
|
g_signals::bar::visibility_change(false);
|
||||||
|
} else {
|
||||||
|
g_signals::bar::visibility_change(true);
|
||||||
|
}
|
||||||
|
} catch (const exception& err) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Event handler for XCB_BUTTON_PRESS events
|
* Event handler for XCB_BUTTON_PRESS events
|
||||||
*
|
*
|
||||||
@ -647,7 +673,7 @@ void bar::handle(const evt::button_press& evt) {
|
|||||||
* Used to redraw the bar
|
* Used to redraw the bar
|
||||||
*/
|
*/
|
||||||
void bar::handle(const evt::expose& evt) {
|
void bar::handle(const evt::expose& evt) {
|
||||||
if (evt->window == m_window) {
|
if (evt->window == m_window && evt->count == 0) {
|
||||||
m_log.trace("bar: Received expose event");
|
m_log.trace("bar: Received expose event");
|
||||||
m_renderer->flush(false);
|
m_renderer->flush(false);
|
||||||
}
|
}
|
||||||
@ -666,30 +692,13 @@ void bar::handle(const evt::expose& evt) {
|
|||||||
* pseudo-transparent background when it changes
|
* pseudo-transparent background when it changes
|
||||||
*/
|
*/
|
||||||
void bar::handle(const evt::property_notify& evt) {
|
void bar::handle(const evt::property_notify& evt) {
|
||||||
#if DEBUG
|
#ifdef VERBOSE_TRACELOG
|
||||||
string atom_name = m_connection.get_atom_name(evt->atom).name();
|
string atom_name = m_connection.get_atom_name(evt->atom).name();
|
||||||
m_log.trace("bar: property_notify(%s)", atom_name);
|
m_log.trace_x("bar: property_notify(%s)", atom_name);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (evt->window == m_window && evt->atom == WM_STATE) {
|
if (evt->window == m_window && evt->atom == WM_STATE) {
|
||||||
if (!g_signals::bar::visibility_change) {
|
broadcast_visibility();
|
||||||
return m_log.trace("bar: no callback handler set for bar visibility change");
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
auto attr = m_connection.get_window_attributes(m_window);
|
|
||||||
if (attr->map_state == XCB_MAP_STATE_VIEWABLE) {
|
|
||||||
g_signals::bar::visibility_change(true);
|
|
||||||
} else if (attr->map_state == XCB_MAP_STATE_UNVIEWABLE) {
|
|
||||||
g_signals::bar::visibility_change(false);
|
|
||||||
} else if (attr->map_state == XCB_MAP_STATE_UNMAPPED) {
|
|
||||||
g_signals::bar::visibility_change(false);
|
|
||||||
} else {
|
|
||||||
g_signals::bar::visibility_change(true);
|
|
||||||
}
|
|
||||||
} catch (const exception& err) {
|
|
||||||
m_log.warn("Failed to emit bar window's visibility change event");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
312
src/x11/tray.cpp
312
src/x11/tray.cpp
@ -55,53 +55,53 @@ tray_client::~tray_client() {
|
|||||||
/**
|
/**
|
||||||
* Match given window against client window
|
* Match given window against 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_window;
|
||||||
} // }}}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get client window mapped state
|
* Get client window mapped state
|
||||||
*/
|
*/
|
||||||
bool tray_client::mapped() const { // {{{
|
bool tray_client::mapped() const {
|
||||||
return m_mapped;
|
return m_mapped;
|
||||||
} // }}}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set client window mapped state
|
* Set client window mapped state
|
||||||
*/
|
*/
|
||||||
void tray_client::mapped(bool state) { // {{{
|
void tray_client::mapped(bool state) {
|
||||||
m_mapped = state;
|
m_mapped = state;
|
||||||
} // }}}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get client window
|
* Get client window
|
||||||
*/
|
*/
|
||||||
xcb_window_t tray_client::window() const { // {{{
|
xcb_window_t tray_client::window() const {
|
||||||
return m_window;
|
return m_window;
|
||||||
} // }}}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get xembed data pointer
|
* Get xembed data pointer
|
||||||
*/
|
*/
|
||||||
xembed_data* tray_client::xembed() const { // {{{
|
xembed_data* tray_client::xembed() const {
|
||||||
return m_xembed.get();
|
return m_xembed.get();
|
||||||
} // }}}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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 {
|
||||||
if (!mapped() && ((xembed()->flags & XEMBED_MAPPED) == XEMBED_MAPPED)) {
|
if (!mapped() && ((xembed()->flags & XEMBED_MAPPED) == XEMBED_MAPPED)) {
|
||||||
m_connection.map_window_checked(window());
|
m_connection.map_window_checked(window());
|
||||||
} else if (mapped() && ((xembed()->flags & XEMBED_MAPPED) != XEMBED_MAPPED)) {
|
} else if (mapped() && ((xembed()->flags & XEMBED_MAPPED) != XEMBED_MAPPED)) {
|
||||||
m_connection.unmap_window_checked(window());
|
m_connection.unmap_window_checked(window());
|
||||||
}
|
}
|
||||||
} // }}}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configure window size
|
* Configure window size
|
||||||
*/
|
*/
|
||||||
void tray_client::reconfigure(int16_t x, int16_t y) const { // {{{
|
void tray_client::reconfigure(int16_t x, int16_t y) const {
|
||||||
uint32_t configure_mask = 0;
|
uint32_t configure_mask = 0;
|
||||||
uint32_t configure_values[7];
|
uint32_t configure_values[7];
|
||||||
xcb_params_configure_window_t configure_params;
|
xcb_params_configure_window_t configure_params;
|
||||||
@ -113,12 +113,12 @@ void tray_client::reconfigure(int16_t x, int16_t y) const { // {{{
|
|||||||
|
|
||||||
xutils::pack_values(configure_mask, &configure_params, configure_values);
|
xutils::pack_values(configure_mask, &configure_params, configure_values);
|
||||||
m_connection.configure_window_checked(window(), configure_mask, configure_values);
|
m_connection.configure_window_checked(window(), configure_mask, configure_values);
|
||||||
} // }}}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Respond to client resize requests
|
* Respond to client resize requests
|
||||||
*/
|
*/
|
||||||
void tray_client::configure_notify(int16_t x, int16_t y) const { // {{{
|
void tray_client::configure_notify(int16_t x, int16_t y) const {
|
||||||
auto notify = memory_util::make_malloc_ptr<xcb_configure_notify_event_t>(32);
|
auto notify = memory_util::make_malloc_ptr<xcb_configure_notify_event_t>(32);
|
||||||
notify->response_type = XCB_CONFIGURE_NOTIFY;
|
notify->response_type = XCB_CONFIGURE_NOTIFY;
|
||||||
notify->event = m_window;
|
notify->event = m_window;
|
||||||
@ -133,7 +133,7 @@ void tray_client::configure_notify(int16_t x, int16_t y) const { // {{{
|
|||||||
|
|
||||||
const char* data = reinterpret_cast<const char*>(notify.get());
|
const char* data = reinterpret_cast<const char*>(notify.get());
|
||||||
m_connection.send_event_checked(false, m_window, XCB_EVENT_MASK_STRUCTURE_NOTIFY, data);
|
m_connection.send_event_checked(false, m_window, XCB_EVENT_MASK_STRUCTURE_NOTIFY, data);
|
||||||
} // }}}
|
}
|
||||||
|
|
||||||
// }}}
|
// }}}
|
||||||
// implementation : tray_manager {{{
|
// implementation : tray_manager {{{
|
||||||
@ -155,25 +155,25 @@ tray_manager::~tray_manager() {
|
|||||||
/**
|
/**
|
||||||
* Get the settings container
|
* Get the settings container
|
||||||
*/
|
*/
|
||||||
const tray_settings tray_manager::settings() const { // {{{
|
const tray_settings tray_manager::settings() const {
|
||||||
return m_opts;
|
return m_opts;
|
||||||
} // }}}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize data
|
* Initialize data
|
||||||
*/
|
*/
|
||||||
void tray_manager::bootstrap(tray_settings settings) { // {{{
|
void tray_manager::bootstrap(tray_settings settings) {
|
||||||
m_opts = settings;
|
m_opts = settings;
|
||||||
query_atom();
|
query_atom();
|
||||||
|
|
||||||
// Listen for visibility change events on the bar window
|
// Listen for visibility change events on the bar window
|
||||||
g_signals::bar::visibility_change = bind(&tray_manager::bar_visibility_change, this, placeholders::_1);
|
g_signals::bar::visibility_change = bind(&tray_manager::bar_visibility_change, this, placeholders::_1);
|
||||||
} // }}}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Activate systray management
|
* Activate systray management
|
||||||
*/
|
*/
|
||||||
void tray_manager::activate() { // {{{
|
void tray_manager::activate() {
|
||||||
if (m_activated) {
|
if (m_activated) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -207,12 +207,12 @@ void tray_manager::activate() { // {{{
|
|||||||
if (m_othermanager != XCB_NONE && m_othermanager != m_tray) {
|
if (m_othermanager != XCB_NONE && m_othermanager != m_tray) {
|
||||||
notify_clients_delayed();
|
notify_clients_delayed();
|
||||||
}
|
}
|
||||||
} // }}}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deactivate systray management
|
* Deactivate systray management
|
||||||
*/
|
*/
|
||||||
void tray_manager::deactivate(bool clear_selection) { // {{{
|
void tray_manager::deactivate(bool clear_selection) {
|
||||||
if (!m_activated) {
|
if (!m_activated) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -238,15 +238,8 @@ void tray_manager::deactivate(bool clear_selection) { // {{{
|
|||||||
m_clients.clear();
|
m_clients.clear();
|
||||||
|
|
||||||
if (m_tray) {
|
if (m_tray) {
|
||||||
if (m_mapped) {
|
|
||||||
m_log.trace("tray: Unmap window");
|
|
||||||
m_connection.unmap_window(m_tray);
|
|
||||||
m_mapped = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_log.trace("tray: Destroy window");
|
m_log.trace("tray: Destroy window");
|
||||||
m_connection.destroy_window(m_tray);
|
m_connection.destroy_window(m_tray);
|
||||||
m_hidden = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_pixmap) {
|
if (m_pixmap) {
|
||||||
@ -269,21 +262,17 @@ void tray_manager::deactivate(bool clear_selection) { // {{{
|
|||||||
m_opts.configured_h = 0;
|
m_opts.configured_h = 0;
|
||||||
m_opts.configured_slots = 0;
|
m_opts.configured_slots = 0;
|
||||||
m_acquired_selection = false;
|
m_acquired_selection = false;
|
||||||
|
m_mapped = false;
|
||||||
|
m_restacked = false;
|
||||||
|
|
||||||
m_connection.flush();
|
m_connection.flush();
|
||||||
} // }}}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reconfigure tray
|
* Reconfigure tray
|
||||||
*/
|
*/
|
||||||
void tray_manager::reconfigure() { // {{{
|
void tray_manager::reconfigure() {
|
||||||
// Skip if tray window doesn't exist or if it's
|
if (!m_tray || !m_mtx.try_lock()) {
|
||||||
// in pseudo-hidden state
|
|
||||||
if (!m_tray || m_hidden) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!m_mtx.try_lock()) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -307,10 +296,6 @@ 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());
|
||||||
}
|
}
|
||||||
|
|
||||||
refresh_window();
|
|
||||||
|
|
||||||
m_connection.flush();
|
|
||||||
|
|
||||||
m_opts.configured_slots = mapped_clients();
|
m_opts.configured_slots = mapped_clients();
|
||||||
|
|
||||||
// Report status
|
// Report status
|
||||||
@ -321,37 +306,30 @@ void tray_manager::reconfigure() { // {{{
|
|||||||
guard.unlock();
|
guard.unlock();
|
||||||
|
|
||||||
refresh_window();
|
refresh_window();
|
||||||
} // }}}
|
|
||||||
|
m_connection.flush();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reconfigure container window
|
* Reconfigure container window
|
||||||
*/
|
*/
|
||||||
void tray_manager::reconfigure_window() { // {{{
|
void tray_manager::reconfigure_window() {
|
||||||
m_log.trace("tray: Reconfigure window");
|
m_log.trace("tray: Reconfigure window (mapped=%i, clients=%i)", static_cast<bool>(m_mapped), m_clients.size());
|
||||||
|
|
||||||
if (!m_tray) {
|
if (!m_tray || m_hidden) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto clients = mapped_clients();
|
auto clients = mapped_clients();
|
||||||
|
auto mapped = static_cast<bool>(m_mapped);
|
||||||
|
|
||||||
if (!clients && m_mapped) {
|
if (!clients && m_mapped) {
|
||||||
m_log.trace("tray: Reconfigure window / unmap");
|
m_log.trace("tray: Reconfigure window / unmap");
|
||||||
m_mapped = false;
|
|
||||||
m_connection.unmap_window_checked(m_tray);
|
m_connection.unmap_window_checked(m_tray);
|
||||||
} else if (clients && !m_mapped) {
|
} else if (clients && !m_mapped) {
|
||||||
m_log.trace("tray: Reconfigure window / map");
|
m_log.trace("tray: Reconfigure window / map");
|
||||||
m_mapped = true;
|
|
||||||
m_connection.map_window_checked(m_tray);
|
m_connection.map_window_checked(m_tray);
|
||||||
}
|
} else if (!mapped || !clients) {
|
||||||
|
|
||||||
if (!m_mapped) {
|
|
||||||
m_log.trace("tray: Reconfigure window / ignoring unmapped");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!clients) {
|
|
||||||
m_log.trace("tray: Reconfigure window / no clients");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -379,12 +357,12 @@ void tray_manager::reconfigure_window() { // {{{
|
|||||||
|
|
||||||
m_opts.configured_w = width;
|
m_opts.configured_w = width;
|
||||||
m_opts.configured_x = x;
|
m_opts.configured_x = x;
|
||||||
} // }}}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reconfigure clients
|
* Reconfigure clients
|
||||||
*/
|
*/
|
||||||
void tray_manager::reconfigure_clients() { // {{{
|
void tray_manager::reconfigure_clients() {
|
||||||
m_log.trace("tray: Reconfigure clients");
|
m_log.trace("tray: Reconfigure clients");
|
||||||
|
|
||||||
uint32_t x = m_opts.spacing;
|
uint32_t x = m_opts.spacing;
|
||||||
@ -401,14 +379,16 @@ void tray_manager::reconfigure_clients() { // {{{
|
|||||||
remove_client(client, false);
|
remove_client(client, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} // }}}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reconfigure root pixmap
|
* Reconfigure root pixmap
|
||||||
*/
|
*/
|
||||||
void tray_manager::reconfigure_bg(bool realloc) { // {{{
|
void tray_manager::reconfigure_bg(bool realloc) {
|
||||||
if (!m_opts.transparent || m_clients.empty() || !m_mapped) {
|
if (!m_opts.transparent || m_clients.empty() || !m_mapped) {
|
||||||
return;
|
return;
|
||||||
|
} else if (!m_rootpixmap.pixmap) {
|
||||||
|
realloc = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto w = calculate_w();
|
auto w = calculate_w();
|
||||||
@ -420,9 +400,7 @@ void tray_manager::reconfigure_bg(bool realloc) { // {{{
|
|||||||
|
|
||||||
m_log.trace("tray: Reconfigure bg (realloc=%i)", realloc);
|
m_log.trace("tray: Reconfigure bg (realloc=%i)", realloc);
|
||||||
|
|
||||||
if (!m_rootpixmap.pixmap && !get_root_pixmap(m_connection, &m_rootpixmap)) {
|
if (realloc && !get_root_pixmap(m_connection, &m_rootpixmap)) {
|
||||||
return m_log.err("Failed to get root pixmap for tray background (realloc=%i)", realloc);
|
|
||||||
} else if (realloc && !get_root_pixmap(m_connection, &m_rootpixmap)) {
|
|
||||||
return m_log.err("Failed to get root pixmap for tray background (realloc=%i)", realloc);
|
return m_log.err("Failed to get root pixmap for tray background (realloc=%i)", realloc);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -463,19 +441,19 @@ void tray_manager::reconfigure_bg(bool realloc) { // {{{
|
|||||||
}
|
}
|
||||||
|
|
||||||
m_connection.copy_area_checked(m_rootpixmap.pixmap, m_pixmap, m_gc, px, py, 0, 0, w, h);
|
m_connection.copy_area_checked(m_rootpixmap.pixmap, m_pixmap, m_gc, px, py, 0, 0, w, h);
|
||||||
} // }}}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Refresh the bar window by clearing it along with each client window
|
* Refresh the bar window by clearing it along with each client window
|
||||||
*/
|
*/
|
||||||
void tray_manager::refresh_window() { // {{{
|
void tray_manager::refresh_window() {
|
||||||
if (!m_mtx.try_lock()) {
|
if (!m_mtx.try_lock()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::lock_guard<std::mutex> lock(m_mtx, std::adopt_lock);
|
std::lock_guard<std::mutex> lock(m_mtx, std::adopt_lock);
|
||||||
|
|
||||||
if (!m_activated || !m_mapped || m_hidden) {
|
if (!m_activated || !m_mapped) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -495,22 +473,31 @@ void tray_manager::refresh_window() { // {{{
|
|||||||
}
|
}
|
||||||
|
|
||||||
m_connection.flush();
|
m_connection.flush();
|
||||||
} // }}}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Redraw window
|
||||||
|
*/
|
||||||
|
void tray_manager::redraw_window() {
|
||||||
|
m_log.info("Redraw tray container (id=%s)", m_connection.id(m_tray));
|
||||||
|
reconfigure_bg(true);
|
||||||
|
refresh_window();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find the systray selection atom
|
* Find the systray selection atom
|
||||||
*/
|
*/
|
||||||
void tray_manager::query_atom() { // {{{
|
void tray_manager::query_atom() {
|
||||||
m_log.trace("tray: Find systray selection atom for the default screen");
|
m_log.trace("tray: Find systray selection atom for the default screen");
|
||||||
string name{"_NET_SYSTEM_TRAY_S" + to_string(m_connection.default_screen())};
|
string name{"_NET_SYSTEM_TRAY_S" + to_string(m_connection.default_screen())};
|
||||||
auto reply = m_connection.intern_atom(false, name.length(), name.c_str());
|
auto reply = m_connection.intern_atom(false, name.length(), name.c_str());
|
||||||
m_atom = reply.atom();
|
m_atom = reply.atom();
|
||||||
} // }}}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create tray window
|
* Create tray window
|
||||||
*/
|
*/
|
||||||
void tray_manager::create_window() { // {{{
|
void tray_manager::create_window() {
|
||||||
m_log.trace("tray: Create tray window");
|
m_log.trace("tray: Create tray window");
|
||||||
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
@ -532,12 +519,12 @@ void tray_manager::create_window() { // {{{
|
|||||||
m_log.info("Tray window: %s", m_connection.id(m_tray));
|
m_log.info("Tray window: %s", m_connection.id(m_tray));
|
||||||
|
|
||||||
xutils::compton_shadow_exclude(m_connection, m_tray);
|
xutils::compton_shadow_exclude(m_connection, m_tray);
|
||||||
} // }}}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create tray window background components
|
* Create tray window background components
|
||||||
*/
|
*/
|
||||||
void tray_manager::create_bg(bool realloc) { // {{{
|
void tray_manager::create_bg(bool realloc) {
|
||||||
if (!m_opts.transparent) {
|
if (!m_opts.transparent) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -570,12 +557,12 @@ void tray_manager::create_bg(bool realloc) { // {{{
|
|||||||
} catch (const exception& err) {
|
} catch (const exception& err) {
|
||||||
m_log.err("Failed to set tray window back pixmap (%s)", err.what());
|
m_log.err("Failed to set tray window back pixmap (%s)", err.what());
|
||||||
}
|
}
|
||||||
} // }}}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Put tray window above the defined sibling in the window stack
|
* Put tray window above the defined sibling in the window stack
|
||||||
*/
|
*/
|
||||||
void tray_manager::restack_window() { // {{{
|
void tray_manager::restack_window() {
|
||||||
if (!m_opts.sibling) {
|
if (!m_opts.sibling) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -596,12 +583,12 @@ void tray_manager::restack_window() { // {{{
|
|||||||
auto id = m_connection.id(m_opts.sibling);
|
auto id = m_connection.id(m_opts.sibling);
|
||||||
m_log.trace("tray: Failed to put tray above %s in the stack (%s)", id, err.what());
|
m_log.trace("tray: Failed to put tray above %s in the stack (%s)", id, err.what());
|
||||||
}
|
}
|
||||||
} // }}}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set window WM hints
|
* Set window WM hints
|
||||||
*/
|
*/
|
||||||
void tray_manager::set_wmhints() { // {{{
|
void tray_manager::set_wmhints() {
|
||||||
m_log.trace("tray: Set window WM_NAME / WM_CLASS", m_connection.id(m_tray));
|
m_log.trace("tray: Set window WM_NAME / WM_CLASS", m_connection.id(m_tray));
|
||||||
xcb_icccm_set_wm_name(m_connection, m_tray, XCB_ATOM_STRING, 8, 19, TRAY_WM_NAME);
|
xcb_icccm_set_wm_name(m_connection, m_tray, XCB_ATOM_STRING, 8, 19, TRAY_WM_NAME);
|
||||||
xcb_icccm_set_wm_class(m_connection, m_tray, 12, TRAY_WM_CLASS);
|
xcb_icccm_set_wm_class(m_connection, m_tray, 12, TRAY_WM_CLASS);
|
||||||
@ -623,12 +610,12 @@ void tray_manager::set_wmhints() { // {{{
|
|||||||
|
|
||||||
m_log.trace("tray: Set window _NET_SYSTEM_TRAY_VISUAL");
|
m_log.trace("tray: Set window _NET_SYSTEM_TRAY_VISUAL");
|
||||||
wm_util::set_trayvisual(m_connection, m_tray, m_connection.screen()->root_visual);
|
wm_util::set_trayvisual(m_connection, m_tray, m_connection.screen()->root_visual);
|
||||||
} // }}}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set color atom used by clients when determing icon theme
|
* Set color atom used by clients when determing icon theme
|
||||||
*/
|
*/
|
||||||
void tray_manager::set_traycolors() { // {{{
|
void tray_manager::set_traycolors() {
|
||||||
m_log.trace("tray: Set _NET_SYSTEM_TRAY_COLORS to %x", m_opts.background);
|
m_log.trace("tray: Set _NET_SYSTEM_TRAY_COLORS to %x", m_opts.background);
|
||||||
|
|
||||||
auto r = color_util::red_channel(m_opts.background);
|
auto r = color_util::red_channel(m_opts.background);
|
||||||
@ -644,12 +631,12 @@ void tray_manager::set_traycolors() { // {{{
|
|||||||
|
|
||||||
m_connection.change_property(
|
m_connection.change_property(
|
||||||
XCB_PROP_MODE_REPLACE, m_tray, _NET_SYSTEM_TRAY_COLORS, XCB_ATOM_CARDINAL, 32, 12, colors);
|
XCB_PROP_MODE_REPLACE, m_tray, _NET_SYSTEM_TRAY_COLORS, XCB_ATOM_CARDINAL, 32, 12, colors);
|
||||||
} // }}}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Acquire the systray selection
|
* Acquire the systray selection
|
||||||
*/
|
*/
|
||||||
void tray_manager::acquire_selection() { // {{{
|
void tray_manager::acquire_selection() {
|
||||||
xcb_window_t owner{m_connection.get_selection_owner_unchecked(m_atom)->owner};
|
xcb_window_t owner{m_connection.get_selection_owner_unchecked(m_atom)->owner};
|
||||||
|
|
||||||
if (owner == m_tray) {
|
if (owner == m_tray) {
|
||||||
@ -667,12 +654,12 @@ void tray_manager::acquire_selection() { // {{{
|
|||||||
}
|
}
|
||||||
|
|
||||||
m_acquired_selection = false;
|
m_acquired_selection = false;
|
||||||
} // }}}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Notify pending clients about the new systray MANAGER
|
* Notify pending clients about the new systray MANAGER
|
||||||
*/
|
*/
|
||||||
void tray_manager::notify_clients() { // {{{
|
void tray_manager::notify_clients() {
|
||||||
if (m_activated) {
|
if (m_activated) {
|
||||||
m_log.info("Notifying pending tray clients");
|
m_log.info("Notifying pending tray clients");
|
||||||
auto message = m_connection.make_client_message(MANAGER, m_connection.root());
|
auto message = m_connection.make_client_message(MANAGER, m_connection.root());
|
||||||
@ -681,12 +668,12 @@ void tray_manager::notify_clients() { // {{{
|
|||||||
message->data.data32[2] = m_tray;
|
message->data.data32[2] = m_tray;
|
||||||
m_connection.send_client_message(message, m_connection.root());
|
m_connection.send_client_message(message, m_connection.root());
|
||||||
}
|
}
|
||||||
} // }}}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send delayed notification to pending clients
|
* Send delayed notification to pending clients
|
||||||
*/
|
*/
|
||||||
void tray_manager::notify_clients_delayed(chrono::duration<double, std::milli> delay) { // {{{
|
void tray_manager::notify_clients_delayed(chrono::duration<double, std::milli> delay) {
|
||||||
if (m_delaythread.joinable()) {
|
if (m_delaythread.joinable()) {
|
||||||
m_delaythread.join();
|
m_delaythread.join();
|
||||||
}
|
}
|
||||||
@ -696,25 +683,25 @@ void tray_manager::notify_clients_delayed(chrono::duration<double, std::milli> d
|
|||||||
notify_clients();
|
notify_clients();
|
||||||
});
|
});
|
||||||
|
|
||||||
} // }}}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Track changes to the given selection owner
|
* Track changes to the given selection owner
|
||||||
* If it gets destroyed or goes away we can reactivate the tray_manager
|
* If it gets destroyed or goes away we can reactivate the tray_manager
|
||||||
*/
|
*/
|
||||||
void tray_manager::track_selection_owner(xcb_window_t owner) { // {{{
|
void tray_manager::track_selection_owner(xcb_window_t owner) {
|
||||||
if (owner) {
|
if (owner) {
|
||||||
m_log.trace("tray: Listen for events on the new selection window");
|
m_log.trace("tray: Listen for events on the new selection window");
|
||||||
const uint32_t mask{XCB_CW_EVENT_MASK};
|
const uint32_t mask{XCB_CW_EVENT_MASK};
|
||||||
const uint32_t values[]{XCB_EVENT_MASK_STRUCTURE_NOTIFY};
|
const uint32_t values[]{XCB_EVENT_MASK_STRUCTURE_NOTIFY};
|
||||||
m_connection.change_window_attributes(owner, mask, values);
|
m_connection.change_window_attributes(owner, mask, values);
|
||||||
}
|
}
|
||||||
} // }}}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process client docking request
|
* Process client docking request
|
||||||
*/
|
*/
|
||||||
void tray_manager::process_docking_request(xcb_window_t win) { // {{{
|
void tray_manager::process_docking_request(xcb_window_t win) {
|
||||||
auto client = find_client(win);
|
auto client = find_client(win);
|
||||||
|
|
||||||
if (client) {
|
if (client) {
|
||||||
@ -769,37 +756,34 @@ void tray_manager::process_docking_request(xcb_window_t win) { // {{{
|
|||||||
m_log.err("Failed to setup tray client, removing... (%s)", err.what());
|
m_log.err("Failed to setup tray client, removing... (%s)", err.what());
|
||||||
remove_client(client, false);
|
remove_client(client, false);
|
||||||
}
|
}
|
||||||
} // }}}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Signal handler connected to the bar window's visibility change signal.
|
* Signal handler connected to the bar window's visibility change signal.
|
||||||
* This is used as a fallback in case the window restacking fails. It will
|
* This is used as a fallback in case the window restacking fails. It will
|
||||||
* toggle the tray window whenever the visibility of the bar window changes.
|
* toggle the tray window whenever the visibility of the bar window changes.
|
||||||
*/
|
*/
|
||||||
void tray_manager::bar_visibility_change(bool state) { // {{{
|
void tray_manager::bar_visibility_change(bool visible) {
|
||||||
if (!m_activated || m_restacked || m_hidden == !state) {
|
m_log.trace("tray: visibility_change %d", visible);
|
||||||
|
m_hidden = !visible;
|
||||||
|
|
||||||
|
if (!m_activated || m_restacked) {
|
||||||
return;
|
return;
|
||||||
}
|
} else if (!m_hidden && !m_mapped) {
|
||||||
|
|
||||||
m_log.trace("tray: visibility_change %d", state);
|
|
||||||
|
|
||||||
m_hidden = !state;
|
|
||||||
|
|
||||||
if (!m_hidden && !m_mapped) {
|
|
||||||
m_connection.map_window(m_tray);
|
m_connection.map_window(m_tray);
|
||||||
} else if (m_hidden && m_mapped) {
|
} else if (m_hidden && m_mapped) {
|
||||||
m_connection.unmap_window(m_tray);
|
m_connection.unmap_window(m_tray);
|
||||||
} else {
|
} else if (m_mapped && !m_hidden) {
|
||||||
return;
|
redraw_window();
|
||||||
}
|
}
|
||||||
|
|
||||||
m_connection.flush();
|
m_connection.flush();
|
||||||
} // }}}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculate x position of tray window
|
* Calculate x position of tray window
|
||||||
*/
|
*/
|
||||||
int16_t tray_manager::calculate_x(uint16_t width) const { // {{{
|
int16_t tray_manager::calculate_x(uint16_t width) const {
|
||||||
auto x = m_opts.orig_x;
|
auto x = m_opts.orig_x;
|
||||||
|
|
||||||
if (m_opts.align == alignment::RIGHT) {
|
if (m_opts.align == alignment::RIGHT) {
|
||||||
@ -809,19 +793,19 @@ int16_t tray_manager::calculate_x(uint16_t width) const { // {{{
|
|||||||
}
|
}
|
||||||
|
|
||||||
return x;
|
return x;
|
||||||
} // }}}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculate y position of tray window
|
* Calculate y position of tray window
|
||||||
*/
|
*/
|
||||||
int16_t tray_manager::calculate_y() const { // {{{
|
int16_t tray_manager::calculate_y() const {
|
||||||
return m_opts.orig_y;
|
return m_opts.orig_y;
|
||||||
} // }}}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculate width of tray window
|
* Calculate width of tray window
|
||||||
*/
|
*/
|
||||||
uint16_t tray_manager::calculate_w() const { // {{{
|
uint16_t tray_manager::calculate_w() const {
|
||||||
uint16_t width = m_opts.spacing;
|
uint16_t width = m_opts.spacing;
|
||||||
|
|
||||||
for (auto&& client : m_clients) {
|
for (auto&& client : m_clients) {
|
||||||
@ -831,61 +815,61 @@ uint16_t tray_manager::calculate_w() const { // {{{
|
|||||||
}
|
}
|
||||||
|
|
||||||
return width;
|
return width;
|
||||||
} // }}}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculate height of tray window
|
* Calculate height of tray window
|
||||||
*/
|
*/
|
||||||
uint16_t tray_manager::calculate_h() const { // {{{
|
uint16_t tray_manager::calculate_h() const {
|
||||||
return m_opts.height_fill;
|
return m_opts.height_fill;
|
||||||
} // }}}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculate x position of client window
|
* Calculate x position of client window
|
||||||
*/
|
*/
|
||||||
int16_t tray_manager::calculate_client_x(const xcb_window_t& win) { // {{{
|
int16_t tray_manager::calculate_client_x(const xcb_window_t& win) {
|
||||||
for (size_t i = 0; i < m_clients.size(); i++) {
|
for (size_t i = 0; i < m_clients.size(); i++) {
|
||||||
if (m_clients[i]->match(win)) {
|
if (m_clients[i]->match(win)) {
|
||||||
return m_opts.spacing + m_opts.width * i;
|
return m_opts.spacing + m_opts.width * i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return m_opts.spacing;
|
return m_opts.spacing;
|
||||||
} // }}}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculate y position of client window
|
* Calculate y position of client window
|
||||||
*/
|
*/
|
||||||
int16_t tray_manager::calculate_client_y() { // {{{
|
int16_t tray_manager::calculate_client_y() {
|
||||||
return (m_opts.height_fill - m_opts.height) / 2;
|
return (m_opts.height_fill - m_opts.height) / 2;
|
||||||
} // }}}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find tray client by window
|
* Find tray client by window
|
||||||
*/
|
*/
|
||||||
shared_ptr<tray_client> tray_manager::find_client(const xcb_window_t& win) const { // {{{
|
shared_ptr<tray_client> tray_manager::find_client(const xcb_window_t& win) const {
|
||||||
for (auto&& client : m_clients) {
|
for (auto&& client : m_clients) {
|
||||||
if (client->match(win)) {
|
if (client->match(win)) {
|
||||||
return shared_ptr<tray_client>{client.get(), factory_util::null_deleter{}};
|
return shared_ptr<tray_client>{client.get(), factory_util::null_deleter{}};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return {};
|
return {};
|
||||||
} // }}}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Client error handling
|
* Client error handling
|
||||||
*/
|
*/
|
||||||
void tray_manager::remove_client(shared_ptr<tray_client>& client, bool reconfigure) { // {{{
|
void tray_manager::remove_client(shared_ptr<tray_client>& client, bool reconfigure) {
|
||||||
m_clients.erase(std::find(m_clients.begin(), m_clients.end(), client));
|
m_clients.erase(std::find(m_clients.begin(), m_clients.end(), client));
|
||||||
|
|
||||||
if (reconfigure) {
|
if (reconfigure) {
|
||||||
tray_manager::reconfigure();
|
tray_manager::reconfigure();
|
||||||
}
|
}
|
||||||
} // }}}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get number of mapped clients
|
* Get number of mapped clients
|
||||||
*/
|
*/
|
||||||
int tray_manager::mapped_clients() const { // {{{
|
int tray_manager::mapped_clients() const {
|
||||||
int mapped_clients = 0;
|
int mapped_clients = 0;
|
||||||
|
|
||||||
for (auto&& client : m_clients) {
|
for (auto&& client : m_clients) {
|
||||||
@ -895,32 +879,32 @@ int tray_manager::mapped_clients() const { // {{{
|
|||||||
}
|
}
|
||||||
|
|
||||||
return mapped_clients;
|
return mapped_clients;
|
||||||
} // }}}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Event callback : XCB_EXPOSE
|
* Event callback : XCB_EXPOSE
|
||||||
*/
|
*/
|
||||||
void tray_manager::handle(const evt::expose& evt) { // {{{
|
void tray_manager::handle(const evt::expose& evt) {
|
||||||
if (m_activated && !m_clients.empty()) {
|
if (m_activated && !m_clients.empty() && evt->count == 0) {
|
||||||
m_log.trace("tray: Received expose event for %s", m_connection.id(evt->window));
|
|
||||||
reconfigure_window();
|
reconfigure_window();
|
||||||
|
redraw_window();
|
||||||
}
|
}
|
||||||
} // }}}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Event callback : XCB_VISIBILITY_NOTIFY
|
* Event callback : XCB_VISIBILITY_NOTIFY
|
||||||
*/
|
*/
|
||||||
void tray_manager::handle(const evt::visibility_notify& evt) { // {{{
|
void tray_manager::handle(const evt::visibility_notify& evt) {
|
||||||
if (m_activated && !m_clients.empty()) {
|
if (m_activated && !m_clients.empty()) {
|
||||||
m_log.trace("tray: Received visibility_notify for %s", m_connection.id(evt->window));
|
m_log.trace("tray: Received visibility_notify for %s", m_connection.id(evt->window));
|
||||||
reconfigure_window();
|
reconfigure_window();
|
||||||
}
|
}
|
||||||
} // }}}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Event callback : XCB_CLIENT_MESSAGE
|
* Event callback : XCB_CLIENT_MESSAGE
|
||||||
*/
|
*/
|
||||||
void tray_manager::handle(const evt::client_message& evt) { // {{{
|
void tray_manager::handle(const evt::client_message& evt) {
|
||||||
if (!m_activated) {
|
if (!m_activated) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -940,7 +924,7 @@ void tray_manager::handle(const evt::client_message& evt) { // {{{
|
|||||||
process_docking_request(evt->data.data32[2]);
|
process_docking_request(evt->data.data32[2]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} // }}}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Event callback : XCB_CONFIGURE_REQUEST
|
* Event callback : XCB_CONFIGURE_REQUEST
|
||||||
@ -949,7 +933,7 @@ void tray_manager::handle(const evt::client_message& evt) { // {{{
|
|||||||
* wants to reconfigure its window. This is of course nothing we appreciate
|
* wants to reconfigure its window. This is of course nothing we appreciate
|
||||||
* so we return an answer that'll put him in place.
|
* so we return an answer that'll put him in place.
|
||||||
*/
|
*/
|
||||||
void tray_manager::handle(const evt::configure_request& evt) { // {{{
|
void tray_manager::handle(const evt::configure_request& evt) {
|
||||||
if (!m_activated) {
|
if (!m_activated) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -967,12 +951,12 @@ void tray_manager::handle(const evt::configure_request& evt) { // {{{
|
|||||||
m_log.err("Failed to reconfigure tray client, removing... (%s)", err.what());
|
m_log.err("Failed to reconfigure tray client, removing... (%s)", err.what());
|
||||||
remove_client(client);
|
remove_client(client);
|
||||||
}
|
}
|
||||||
} // }}}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see tray_manager::handle(const evt::configure_request&);
|
* @see tray_manager::handle(const evt::configure_request&);
|
||||||
*/
|
*/
|
||||||
void tray_manager::handle(const evt::resize_request& evt) { // {{{
|
void tray_manager::handle(const evt::resize_request& evt) {
|
||||||
if (!m_activated) {
|
if (!m_activated) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -990,12 +974,12 @@ void tray_manager::handle(const evt::resize_request& evt) { // {{{
|
|||||||
m_log.err("Failed to reconfigure tray client, removing... (%s)", err.what());
|
m_log.err("Failed to reconfigure tray client, removing... (%s)", err.what());
|
||||||
remove_client(client);
|
remove_client(client);
|
||||||
}
|
}
|
||||||
} // }}}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Event callback : XCB_SELECTION_CLEAR
|
* Event callback : XCB_SELECTION_CLEAR
|
||||||
*/
|
*/
|
||||||
void tray_manager::handle(const evt::selection_clear& evt) { // {{{
|
void tray_manager::handle(const evt::selection_clear& evt) {
|
||||||
if (!m_activated) {
|
if (!m_activated) {
|
||||||
return;
|
return;
|
||||||
} else if (evt->selection != m_atom) {
|
} else if (evt->selection != m_atom) {
|
||||||
@ -1014,23 +998,20 @@ void tray_manager::handle(const evt::selection_clear& evt) { // {{{
|
|||||||
}
|
}
|
||||||
|
|
||||||
deactivate(false);
|
deactivate(false);
|
||||||
} // }}}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Event callback : XCB_PROPERTY_NOTIFY
|
* Event callback : XCB_PROPERTY_NOTIFY
|
||||||
*/
|
*/
|
||||||
void tray_manager::handle(const evt::property_notify& evt) { // {{{
|
void tray_manager::handle(const evt::property_notify& evt) {
|
||||||
if (!m_activated) {
|
if (!m_activated) {
|
||||||
return;
|
return;
|
||||||
} else if (evt->atom == _XROOTMAP_ID) {
|
} else if (evt->atom == _XROOTMAP_ID) {
|
||||||
reconfigure_bg(true);
|
redraw_window();
|
||||||
refresh_window();
|
|
||||||
} else if (evt->atom == _XSETROOT_ID) {
|
} else if (evt->atom == _XSETROOT_ID) {
|
||||||
reconfigure_bg(true);
|
redraw_window();
|
||||||
refresh_window();
|
|
||||||
} else if (evt->atom == ESETROOT_PMAP_ID) {
|
} else if (evt->atom == ESETROOT_PMAP_ID) {
|
||||||
reconfigure_bg(true);
|
redraw_window();
|
||||||
refresh_window();
|
|
||||||
} else if (evt->atom == _XEMBED_INFO) {
|
} else if (evt->atom == _XEMBED_INFO) {
|
||||||
auto client = find_client(evt->window);
|
auto client = find_client(evt->window);
|
||||||
|
|
||||||
@ -1055,12 +1036,12 @@ void tray_manager::handle(const evt::property_notify& evt) { // {{{
|
|||||||
reconfigure();
|
reconfigure();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} // }}}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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) {
|
if (!m_activated) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1071,12 +1052,12 @@ void tray_manager::handle(const evt::reparent_notify& evt) { // {{{
|
|||||||
m_log.trace("tray: Received reparent_notify for client, remove...");
|
m_log.trace("tray: Received reparent_notify for client, remove...");
|
||||||
remove_client(client);
|
remove_client(client);
|
||||||
}
|
}
|
||||||
} // }}}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Event callback : XCB_DESTROY_NOTIFY
|
* Event callback : XCB_DESTROY_NOTIFY
|
||||||
*/
|
*/
|
||||||
void tray_manager::handle(const evt::destroy_notify& evt) { // {{{
|
void tray_manager::handle(const evt::destroy_notify& evt) {
|
||||||
if (m_activated && evt->window == m_tray) {
|
if (m_activated && evt->window == m_tray) {
|
||||||
deactivate();
|
deactivate();
|
||||||
} else if (!m_activated && evt->window == m_othermanager && evt->window != m_tray) {
|
} else if (!m_activated && evt->window == m_othermanager && evt->window != m_tray) {
|
||||||
@ -1091,22 +1072,21 @@ void tray_manager::handle(const evt::destroy_notify& evt) { // {{{
|
|||||||
remove_client(client);
|
remove_client(client);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} // }}}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Event callback : XCB_MAP_NOTIFY
|
* Event callback : XCB_MAP_NOTIFY
|
||||||
*/
|
*/
|
||||||
void tray_manager::handle(const evt::map_notify& evt) { // {{{
|
void tray_manager::handle(const evt::map_notify& evt) {
|
||||||
if (!m_activated) {
|
if (!m_activated) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (evt->window == m_tray) {
|
if (evt->window == m_tray) {
|
||||||
if (!m_mapped) {
|
m_log.trace("tray: Received map_notify");
|
||||||
m_log.trace("tray: Received map_notify");
|
m_log.trace("tray: Update container mapped flag");
|
||||||
m_log.trace("tray: Update container mapped flag");
|
m_mapped = true;
|
||||||
m_mapped = true;
|
redraw_window();
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
auto client = find_client(evt->window);
|
auto client = find_client(evt->window);
|
||||||
|
|
||||||
@ -1115,33 +1095,27 @@ void tray_manager::handle(const evt::map_notify& evt) { // {{{
|
|||||||
m_log.trace("tray: Set client mapped");
|
m_log.trace("tray: Set client mapped");
|
||||||
client->mapped(true);
|
client->mapped(true);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (mapped_clients() > m_opts.configured_slots) {
|
if (mapped_clients() > m_opts.configured_slots) {
|
||||||
reconfigure();
|
reconfigure();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} // }}}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Event callback : XCB_UNMAP_NOTIFY
|
* Event callback : XCB_UNMAP_NOTIFY
|
||||||
*/
|
*/
|
||||||
void tray_manager::handle(const evt::unmap_notify& evt) { // {{{
|
void tray_manager::handle(const evt::unmap_notify& evt) {
|
||||||
if (!m_activated) {
|
if (!m_activated) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (evt->window == m_tray) {
|
if (evt->window == m_tray) {
|
||||||
m_log.trace("tray: Received unmap_notify");
|
m_log.trace("tray: Received unmap_notify");
|
||||||
|
m_log.trace("tray: Update container mapped flag");
|
||||||
if (m_mapped) {
|
m_mapped = false;
|
||||||
m_log.trace("tray: Update container mapped flag");
|
m_opts.configured_w = 0;
|
||||||
m_mapped = false;
|
m_opts.configured_x = 0;
|
||||||
}
|
|
||||||
|
|
||||||
if (m_mapped && !m_hidden) {
|
|
||||||
m_opts.configured_w = 0;
|
|
||||||
m_opts.configured_x = 0;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
auto client = find_client(evt->window);
|
auto client = find_client(evt->window);
|
||||||
|
|
||||||
@ -1151,7 +1125,7 @@ void tray_manager::handle(const evt::unmap_notify& evt) { // {{{
|
|||||||
client->mapped(true);
|
client->mapped(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} // }}}
|
}
|
||||||
|
|
||||||
// }}}
|
// }}}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user