feat(xworkspaces): add urgent desktop detection
This commit is contained in:
parent
bd8e748399
commit
44f12c6065
@ -66,6 +66,7 @@ namespace modules {
|
||||
void rebuild_clientlist();
|
||||
void rebuild_desktops();
|
||||
void rebuild_desktop_states();
|
||||
void set_desktop_urgent(xcb_window_t window);
|
||||
|
||||
bool input(string&& cmd);
|
||||
|
||||
|
@ -8,7 +8,7 @@ struct cached_atom {
|
||||
xcb_atom_t* atom;
|
||||
};
|
||||
|
||||
extern cached_atom ATOMS[35];
|
||||
extern cached_atom ATOMS[36];
|
||||
|
||||
extern xcb_atom_t _NET_SUPPORTED;
|
||||
extern xcb_atom_t _NET_CURRENT_DESKTOP;
|
||||
@ -45,3 +45,4 @@ extern xcb_atom_t _XSETROOT_ID;
|
||||
extern xcb_atom_t ESETROOT_PMAP_ID;
|
||||
extern xcb_atom_t _COMPTON_SHADOW;
|
||||
extern xcb_atom_t _NET_WM_WINDOW_OPACITY;
|
||||
extern xcb_atom_t WM_HINTS;
|
||||
|
@ -27,6 +27,7 @@ namespace ewmh_util {
|
||||
xcb_window_t get_active_window(int screen = 0);
|
||||
|
||||
void change_current_desktop(unsigned int desktop);
|
||||
unsigned int get_desktop_from_window(xcb_window_t window);
|
||||
|
||||
void set_wm_window_type(xcb_window_t win, vector<xcb_atom_t> types);
|
||||
|
||||
|
@ -12,6 +12,7 @@ namespace icccm_util {
|
||||
|
||||
void set_wm_name(xcb_connection_t* c, xcb_window_t w, const char* wmname, size_t l, const char* wmclass, size_t l2);
|
||||
void set_wm_protocols(xcb_connection_t* c, xcb_window_t w, vector<xcb_atom_t> flags);
|
||||
bool get_wm_urgency(xcb_connection_t* c, xcb_window_t w);
|
||||
}
|
||||
|
||||
POLYBAR_NS_END
|
||||
|
@ -104,6 +104,10 @@ namespace modules {
|
||||
} else if (evt->atom == m_ewmh->_NET_CURRENT_DESKTOP) {
|
||||
m_current_desktop = ewmh_util::get_current_desktop();
|
||||
rebuild_desktop_states();
|
||||
} else if (evt->atom == WM_HINTS) {
|
||||
if (icccm_util::get_wm_urgency(m_connection, evt->window)) {
|
||||
set_desktop_urgent(evt->window);
|
||||
}
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
@ -133,6 +137,8 @@ namespace modules {
|
||||
std::set_difference(
|
||||
clients.begin(), clients.end(), m_clientlist.begin(), m_clientlist.end(), back_inserter(diff));
|
||||
for (auto&& win : diff) {
|
||||
// listen for wm_hint (urgency) changes
|
||||
m_connection.ensure_event_mask(win, XCB_EVENT_MASK_PROPERTY_CHANGE);
|
||||
// track window
|
||||
m_clientlist.emplace_back(win);
|
||||
}
|
||||
@ -215,6 +221,31 @@ namespace modules {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Find window and set corresponding desktop to urgent
|
||||
*/
|
||||
void xworkspaces_module::set_desktop_urgent(xcb_window_t window) {
|
||||
auto desk = ewmh_util::get_desktop_from_window(window);
|
||||
if(desk == m_current_desktop)
|
||||
// ignore if current desktop is urgent
|
||||
return;
|
||||
for (auto&& v : m_viewports) {
|
||||
for (auto&& d : v->desktops) {
|
||||
if (d->index == desk && d->state != desktop_state::URGENT) {
|
||||
d->state = desktop_state::URGENT;
|
||||
|
||||
d->label = m_labels.at(d->state)->clone();
|
||||
d->label->reset_tokens();
|
||||
d->label->replace_token("%index%", to_string(d->index - d->offset + 1));
|
||||
d->label->replace_token("%name%", m_desktop_names[d->index]);
|
||||
d->label->replace_token("%icon%", m_icons->get(m_desktop_names[d->index], DEFAULT_ICON)->get());
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch and parse data
|
||||
*/
|
||||
|
@ -38,9 +38,10 @@ xcb_atom_t _XSETROOT_ID;
|
||||
xcb_atom_t ESETROOT_PMAP_ID;
|
||||
xcb_atom_t _COMPTON_SHADOW;
|
||||
xcb_atom_t _NET_WM_WINDOW_OPACITY;
|
||||
xcb_atom_t WM_HINTS;
|
||||
|
||||
// clang-format off
|
||||
cached_atom ATOMS[35] = {
|
||||
cached_atom ATOMS[36] = {
|
||||
{"_NET_SUPPORTED", sizeof("_NET_SUPPORTED") - 1, &_NET_SUPPORTED},
|
||||
{"_NET_CURRENT_DESKTOP", sizeof("_NET_CURRENT_DESKTOP") - 1, &_NET_CURRENT_DESKTOP},
|
||||
{"_NET_ACTIVE_WINDOW", sizeof("_NET_ACTIVE_WINDOW") - 1, &_NET_ACTIVE_WINDOW},
|
||||
@ -76,5 +77,6 @@ cached_atom ATOMS[35] = {
|
||||
{"ESETROOT_PMAP_ID", sizeof("ESETROOT_PMAP_ID") - 1, &ESETROOT_PMAP_ID},
|
||||
{"_COMPTON_SHADOW", sizeof("_COMPTON_SHADOW") - 1, &_COMPTON_SHADOW},
|
||||
{"_NET_WM_WINDOW_OPACITY", sizeof("_NET_WM_WINDOW_OPACITY") - 1, &_NET_WM_WINDOW_OPACITY},
|
||||
{"WM_HINTS", sizeof("WM_HINTS") - 1, &WM_HINTS},
|
||||
};
|
||||
// clang-format on
|
||||
|
@ -112,6 +112,13 @@ namespace ewmh_util {
|
||||
xcb_flush(conn->connection);
|
||||
}
|
||||
|
||||
unsigned int get_desktop_from_window(xcb_window_t window) {
|
||||
auto conn = initialize().get();
|
||||
unsigned int desktop = XCB_NONE;
|
||||
xcb_ewmh_get_wm_desktop_reply(conn, xcb_ewmh_get_wm_desktop(conn, window), &desktop, nullptr);
|
||||
return desktop;
|
||||
}
|
||||
|
||||
void set_wm_window_type(xcb_window_t win, vector<xcb_atom_t> types) {
|
||||
auto conn = initialize().get();
|
||||
xcb_ewmh_set_wm_window_type(conn, win, types.size(), types.data());
|
||||
|
@ -29,6 +29,15 @@ namespace icccm_util {
|
||||
void set_wm_protocols(xcb_connection_t* c, xcb_window_t w, vector<xcb_atom_t> flags) {
|
||||
xcb_icccm_set_wm_protocols(c, w, WM_PROTOCOLS, flags.size(), flags.data());
|
||||
}
|
||||
|
||||
bool get_wm_urgency(xcb_connection_t* c, xcb_window_t w) {
|
||||
xcb_icccm_wm_hints_t hints;
|
||||
if (xcb_icccm_get_wm_hints_reply(c, xcb_icccm_get_wm_hints(c, w), &hints, NULL)) {
|
||||
if(xcb_icccm_wm_hints_get_urgency(&hints) == XCB_ICCCM_WM_HINT_X_URGENCY)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
POLYBAR_NS_END
|
||||
|
Loading…
Reference in New Issue
Block a user