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_clientlist();
|
||||||
void rebuild_desktops();
|
void rebuild_desktops();
|
||||||
void rebuild_desktop_states();
|
void rebuild_desktop_states();
|
||||||
|
void set_desktop_urgent(xcb_window_t window);
|
||||||
|
|
||||||
bool input(string&& cmd);
|
bool input(string&& cmd);
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ struct cached_atom {
|
|||||||
xcb_atom_t* 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_SUPPORTED;
|
||||||
extern xcb_atom_t _NET_CURRENT_DESKTOP;
|
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 ESETROOT_PMAP_ID;
|
||||||
extern xcb_atom_t _COMPTON_SHADOW;
|
extern xcb_atom_t _COMPTON_SHADOW;
|
||||||
extern xcb_atom_t _NET_WM_WINDOW_OPACITY;
|
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);
|
xcb_window_t get_active_window(int screen = 0);
|
||||||
|
|
||||||
void change_current_desktop(unsigned int desktop);
|
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);
|
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_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);
|
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
|
POLYBAR_NS_END
|
||||||
|
@ -104,6 +104,10 @@ namespace modules {
|
|||||||
} else if (evt->atom == m_ewmh->_NET_CURRENT_DESKTOP) {
|
} else if (evt->atom == m_ewmh->_NET_CURRENT_DESKTOP) {
|
||||||
m_current_desktop = ewmh_util::get_current_desktop();
|
m_current_desktop = ewmh_util::get_current_desktop();
|
||||||
rebuild_desktop_states();
|
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 {
|
} else {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -133,6 +137,8 @@ namespace modules {
|
|||||||
std::set_difference(
|
std::set_difference(
|
||||||
clients.begin(), clients.end(), m_clientlist.begin(), m_clientlist.end(), back_inserter(diff));
|
clients.begin(), clients.end(), m_clientlist.begin(), m_clientlist.end(), back_inserter(diff));
|
||||||
for (auto&& win : diff) {
|
for (auto&& win : diff) {
|
||||||
|
// listen for wm_hint (urgency) changes
|
||||||
|
m_connection.ensure_event_mask(win, XCB_EVENT_MASK_PROPERTY_CHANGE);
|
||||||
// track window
|
// track window
|
||||||
m_clientlist.emplace_back(win);
|
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
|
* Fetch and parse data
|
||||||
*/
|
*/
|
||||||
|
@ -38,9 +38,10 @@ xcb_atom_t _XSETROOT_ID;
|
|||||||
xcb_atom_t ESETROOT_PMAP_ID;
|
xcb_atom_t ESETROOT_PMAP_ID;
|
||||||
xcb_atom_t _COMPTON_SHADOW;
|
xcb_atom_t _COMPTON_SHADOW;
|
||||||
xcb_atom_t _NET_WM_WINDOW_OPACITY;
|
xcb_atom_t _NET_WM_WINDOW_OPACITY;
|
||||||
|
xcb_atom_t WM_HINTS;
|
||||||
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
cached_atom ATOMS[35] = {
|
cached_atom ATOMS[36] = {
|
||||||
{"_NET_SUPPORTED", sizeof("_NET_SUPPORTED") - 1, &_NET_SUPPORTED},
|
{"_NET_SUPPORTED", sizeof("_NET_SUPPORTED") - 1, &_NET_SUPPORTED},
|
||||||
{"_NET_CURRENT_DESKTOP", sizeof("_NET_CURRENT_DESKTOP") - 1, &_NET_CURRENT_DESKTOP},
|
{"_NET_CURRENT_DESKTOP", sizeof("_NET_CURRENT_DESKTOP") - 1, &_NET_CURRENT_DESKTOP},
|
||||||
{"_NET_ACTIVE_WINDOW", sizeof("_NET_ACTIVE_WINDOW") - 1, &_NET_ACTIVE_WINDOW},
|
{"_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},
|
{"ESETROOT_PMAP_ID", sizeof("ESETROOT_PMAP_ID") - 1, &ESETROOT_PMAP_ID},
|
||||||
{"_COMPTON_SHADOW", sizeof("_COMPTON_SHADOW") - 1, &_COMPTON_SHADOW},
|
{"_COMPTON_SHADOW", sizeof("_COMPTON_SHADOW") - 1, &_COMPTON_SHADOW},
|
||||||
{"_NET_WM_WINDOW_OPACITY", sizeof("_NET_WM_WINDOW_OPACITY") - 1, &_NET_WM_WINDOW_OPACITY},
|
{"_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
|
// clang-format on
|
||||||
|
@ -112,6 +112,13 @@ namespace ewmh_util {
|
|||||||
xcb_flush(conn->connection);
|
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) {
|
void set_wm_window_type(xcb_window_t win, vector<xcb_atom_t> types) {
|
||||||
auto conn = initialize().get();
|
auto conn = initialize().get();
|
||||||
xcb_ewmh_set_wm_window_type(conn, win, types.size(), types.data());
|
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) {
|
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());
|
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
|
POLYBAR_NS_END
|
||||||
|
Loading…
Reference in New Issue
Block a user