restack: Add ewmh restacking strategy
Positions the bar window above the _NET_SUPPORTING_WM_CHECK window The generic restacking strategy now first tries the ewmh strategy, the the bottom strategy.
This commit is contained in:
parent
b11a2ff653
commit
4f9f07eefd
@ -11,8 +11,10 @@ namespace restack_util {
|
|||||||
using params = std::pair<xcb_window_t, xcb_stack_mode_t>;
|
using params = std::pair<xcb_window_t, xcb_stack_mode_t>;
|
||||||
|
|
||||||
void restack_relative(connection& conn, xcb_window_t win, xcb_window_t sibling, xcb_stack_mode_t stack_mode);
|
void restack_relative(connection& conn, xcb_window_t win, xcb_window_t sibling, xcb_stack_mode_t stack_mode);
|
||||||
|
string stack_mode_to_string(xcb_stack_mode_t mode);
|
||||||
bool are_siblings(connection& conn, xcb_window_t win, xcb_window_t sibling);
|
bool are_siblings(connection& conn, xcb_window_t win, xcb_window_t sibling);
|
||||||
params get_bottom_params(connection& conn, xcb_window_t bar_window);
|
params get_bottom_params(connection& conn, xcb_window_t bar_window);
|
||||||
|
params get_ewmh_params(connection& conn);
|
||||||
params get_generic_params(connection& conn, xcb_window_t bar_window);
|
params get_generic_params(connection& conn, xcb_window_t bar_window);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,6 +53,9 @@ namespace ewmh_util {
|
|||||||
void set_wm_window_opacity(xcb_window_t win, unsigned long int values);
|
void set_wm_window_opacity(xcb_window_t win, unsigned long int values);
|
||||||
|
|
||||||
vector<xcb_window_t> get_client_list(int screen = 0);
|
vector<xcb_window_t> get_client_list(int screen = 0);
|
||||||
|
|
||||||
|
xcb_window_t get_supporting_wm_check(xcb_window_t win);
|
||||||
|
xcb_window_t get_ewmh_meta_window(xcb_window_t root);
|
||||||
} // namespace ewmh_util
|
} // namespace ewmh_util
|
||||||
|
|
||||||
POLYBAR_NS_END
|
POLYBAR_NS_END
|
||||||
|
@ -501,7 +501,9 @@ void bar::restack_window() {
|
|||||||
xcb_stack_mode_t stack_mode = XCB_STACK_MODE_ABOVE;
|
xcb_stack_mode_t stack_mode = XCB_STACK_MODE_ABOVE;
|
||||||
|
|
||||||
if (wm_restack == "generic") {
|
if (wm_restack == "generic") {
|
||||||
std::tie(restack_sibling, stack_mode) = restack_util::get_bottom_params(m_connection, bar_window);
|
std::tie(restack_sibling, stack_mode) = restack_util::get_generic_params(m_connection, bar_window);
|
||||||
|
} else if (wm_restack == "ewmh") {
|
||||||
|
std::tie(restack_sibling, stack_mode) = restack_util::get_ewmh_params(m_connection);
|
||||||
} else if (wm_restack == "bottom") {
|
} else if (wm_restack == "bottom") {
|
||||||
std::tie(restack_sibling, stack_mode) = restack_util::get_bottom_params(m_connection, bar_window);
|
std::tie(restack_sibling, stack_mode) = restack_util::get_bottom_params(m_connection, bar_window);
|
||||||
} else if (wm_restack == "bspwm") {
|
} else if (wm_restack == "bspwm") {
|
||||||
@ -520,6 +522,8 @@ void bar::restack_window() {
|
|||||||
|
|
||||||
if (restack_sibling != XCB_NONE) {
|
if (restack_sibling != XCB_NONE) {
|
||||||
try {
|
try {
|
||||||
|
m_log.info("bar: Restacking bar window relative to %s with stacking mode %s", m_connection.id(restack_sibling),
|
||||||
|
restack_util::stack_mode_to_string(stack_mode));
|
||||||
restack_util::restack_relative(m_connection, bar_window, restack_sibling, stack_mode);
|
restack_util::restack_relative(m_connection, bar_window, restack_sibling, stack_mode);
|
||||||
m_log.info("Successfully restacked bar window");
|
m_log.info("Successfully restacked bar window");
|
||||||
} catch (const exception& err) {
|
} catch (const exception& err) {
|
||||||
|
@ -22,6 +22,23 @@ void restack_relative(connection& conn, xcb_window_t win, xcb_window_t sibling,
|
|||||||
conn.configure_window_checked(win, value_mask, value_list.data());
|
conn.configure_window_checked(win, value_mask, value_list.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string stack_mode_to_string(xcb_stack_mode_t mode) {
|
||||||
|
switch (mode) {
|
||||||
|
case XCB_STACK_MODE_ABOVE:
|
||||||
|
return "ABOVE";
|
||||||
|
case XCB_STACK_MODE_BELOW:
|
||||||
|
return "BELOW";
|
||||||
|
case XCB_STACK_MODE_TOP_IF:
|
||||||
|
return "TOP_IF";
|
||||||
|
case XCB_STACK_MODE_BOTTOM_IF:
|
||||||
|
return "BOTTOM_IF";
|
||||||
|
case XCB_STACK_MODE_OPPOSITE:
|
||||||
|
return "OPPOSITE";
|
||||||
|
}
|
||||||
|
|
||||||
|
return "UNKNOWN";
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return true iff the two given windows are sibings (are different windows and have same parent).
|
* @return true iff the two given windows are sibings (are different windows and have same parent).
|
||||||
*/
|
*/
|
||||||
@ -40,7 +57,7 @@ bool are_siblings(connection& conn, xcb_window_t win, xcb_window_t sibling) {
|
|||||||
*
|
*
|
||||||
* Moves the bar window to the bottom of the window stack
|
* Moves the bar window to the bottom of the window stack
|
||||||
*/
|
*/
|
||||||
std::pair<xcb_window_t, xcb_stack_mode_t> get_bottom_params(connection& conn, xcb_window_t bar_window) {
|
params get_bottom_params(connection& conn, xcb_window_t bar_window) {
|
||||||
auto children = conn.query_tree(conn.root()).children();
|
auto children = conn.query_tree(conn.root()).children();
|
||||||
if (children.begin() != children.end() && *children.begin() != bar_window) {
|
if (children.begin() != children.end() && *children.begin() != bar_window) {
|
||||||
return {*children.begin(), XCB_STACK_MODE_BELOW};
|
return {*children.begin(), XCB_STACK_MODE_BELOW};
|
||||||
@ -49,19 +66,42 @@ std::pair<xcb_window_t, xcb_stack_mode_t> get_bottom_params(connection& conn, xc
|
|||||||
return NONE_PARAMS;
|
return NONE_PARAMS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* EWMH restack strategy.
|
||||||
|
*
|
||||||
|
* Moves the bar window above the WM meta window (_NET_SUPPORTING_WM_CHECK).
|
||||||
|
* This window is generally towards the bottom of the window stack, but still above other windows that could interfere.
|
||||||
|
*
|
||||||
|
* @see ewmh_util::get_ewmh_meta_window
|
||||||
|
*/
|
||||||
|
params get_ewmh_params(connection& conn) {
|
||||||
|
if (auto meta_window = ewmh_util::get_ewmh_meta_window(conn.root())) {
|
||||||
|
return {meta_window, XCB_STACK_MODE_ABOVE};
|
||||||
|
}
|
||||||
|
|
||||||
|
return NONE_PARAMS;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generic restack stratgey.
|
* Generic restack stratgey.
|
||||||
*
|
*
|
||||||
* Tries to provide the best WM-agnostic restacking.
|
* Tries to provide the best WM-agnostic restacking.
|
||||||
*
|
*
|
||||||
* Currently tries to the following stratgies in order:
|
* Currently tries to the following stratgies in order:
|
||||||
|
* * ewmh
|
||||||
* * bottom
|
* * bottom
|
||||||
*/
|
*/
|
||||||
std::pair<xcb_window_t, xcb_stack_mode_t> get_generic_params(connection& conn, xcb_window_t bar_window) {
|
params get_generic_params(connection& conn, xcb_window_t bar_window) {
|
||||||
auto [sibling, mode] = get_bottom_params(conn, bar_window);
|
auto ewmh_params = get_ewmh_params(conn);
|
||||||
|
|
||||||
if (are_siblings(conn, bar_window, sibling)) {
|
if (are_siblings(conn, bar_window, ewmh_params.first)) {
|
||||||
return {sibling, mode};
|
return ewmh_params;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto bottom_params = get_bottom_params(conn, bar_window);
|
||||||
|
|
||||||
|
if (are_siblings(conn, bar_window, bottom_params.first)) {
|
||||||
|
return bottom_params;
|
||||||
}
|
}
|
||||||
|
|
||||||
return NONE_PARAMS;
|
return NONE_PARAMS;
|
||||||
|
373
src/x11/ewmh.cpp
373
src/x11/ewmh.cpp
@ -11,188 +11,221 @@ POLYBAR_NS
|
|||||||
|
|
||||||
namespace ewmh_util {
|
namespace ewmh_util {
|
||||||
|
|
||||||
ewmh_connection::ewmh_connection() {
|
ewmh_connection::ewmh_connection() {
|
||||||
xcb_ewmh_init_atoms_replies(&c, xcb_ewmh_init_atoms(connection::make(), &c), nullptr);
|
xcb_ewmh_init_atoms_replies(&c, xcb_ewmh_init_atoms(connection::make(), &c), nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
ewmh_connection::~ewmh_connection() {
|
ewmh_connection::~ewmh_connection() {
|
||||||
xcb_ewmh_connection_wipe(&c);
|
xcb_ewmh_connection_wipe(&c);
|
||||||
}
|
}
|
||||||
|
|
||||||
xcb_ewmh_connection_t* ewmh_connection::operator->() {
|
xcb_ewmh_connection_t* ewmh_connection::operator->() {
|
||||||
return &c;
|
return &c;
|
||||||
}
|
}
|
||||||
|
|
||||||
ewmh_connection::operator xcb_ewmh_connection_t*() {
|
ewmh_connection::operator xcb_ewmh_connection_t*() {
|
||||||
return &c;
|
return &c;
|
||||||
}
|
}
|
||||||
|
|
||||||
ewmh_connection& initialize() {
|
ewmh_connection& initialize() {
|
||||||
static ewmh_connection c;
|
static ewmh_connection c;
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool supports(xcb_atom_t atom, int screen) {
|
bool supports(xcb_atom_t atom, int screen) {
|
||||||
auto& conn = initialize();
|
auto& conn = initialize();
|
||||||
xcb_ewmh_get_atoms_reply_t reply{};
|
xcb_ewmh_get_atoms_reply_t reply{};
|
||||||
if (xcb_ewmh_get_supported_reply(conn, xcb_ewmh_get_supported(conn, screen), &reply, nullptr)) {
|
if (xcb_ewmh_get_supported_reply(conn, xcb_ewmh_get_supported(conn, screen), &reply, nullptr)) {
|
||||||
for (size_t n = 0; n < reply.atoms_len; n++) {
|
for (size_t n = 0; n < reply.atoms_len; n++) {
|
||||||
if (reply.atoms[n] == atom) {
|
if (reply.atoms[n] == atom) {
|
||||||
xcb_ewmh_get_atoms_reply_wipe(&reply);
|
xcb_ewmh_get_atoms_reply_wipe(&reply);
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
}
|
|
||||||
xcb_ewmh_get_atoms_reply_wipe(&reply);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
string get_wm_name(xcb_window_t win) {
|
|
||||||
auto& conn = initialize();
|
|
||||||
xcb_ewmh_get_utf8_strings_reply_t utf8_reply{};
|
|
||||||
if (xcb_ewmh_get_wm_name_reply(conn, xcb_ewmh_get_wm_name(conn, win), &utf8_reply, nullptr)) {
|
|
||||||
return get_reply_string(&utf8_reply);
|
|
||||||
}
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
string get_visible_name(xcb_window_t win) {
|
|
||||||
auto& conn = initialize();
|
|
||||||
xcb_ewmh_get_utf8_strings_reply_t utf8_reply{};
|
|
||||||
if (xcb_ewmh_get_wm_visible_name_reply(conn, xcb_ewmh_get_wm_visible_name(conn, win), &utf8_reply, nullptr)) {
|
|
||||||
return get_reply_string(&utf8_reply);
|
|
||||||
}
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
string get_icon_name(xcb_window_t win) {
|
|
||||||
auto& conn = initialize();
|
|
||||||
xcb_ewmh_get_utf8_strings_reply_t utf8_reply{};
|
|
||||||
if (xcb_ewmh_get_wm_icon_name_reply(conn, xcb_ewmh_get_wm_icon_name(conn, win), &utf8_reply, nullptr)) {
|
|
||||||
return get_reply_string(&utf8_reply);
|
|
||||||
}
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
string get_reply_string(xcb_ewmh_get_utf8_strings_reply_t* reply) {
|
|
||||||
string str;
|
|
||||||
if (reply) {
|
|
||||||
str = string(reply->strings, reply->strings_len);
|
|
||||||
xcb_ewmh_get_utf8_strings_reply_wipe(reply);
|
|
||||||
}
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int get_current_desktop(int screen) {
|
|
||||||
auto& conn = initialize();
|
|
||||||
unsigned int desktop = XCB_NONE;
|
|
||||||
xcb_ewmh_get_current_desktop_reply(conn, xcb_ewmh_get_current_desktop(conn, screen), &desktop, nullptr);
|
|
||||||
return desktop;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int get_number_of_desktops(int screen) {
|
|
||||||
auto& conn = initialize();
|
|
||||||
unsigned int desktops = XCB_NONE;
|
|
||||||
xcb_ewmh_get_number_of_desktops_reply(conn, xcb_ewmh_get_number_of_desktops(conn, screen), &desktops, nullptr);
|
|
||||||
return desktops;
|
|
||||||
}
|
|
||||||
|
|
||||||
vector<position> get_desktop_viewports(int screen) {
|
|
||||||
auto& conn = initialize();
|
|
||||||
vector<position> viewports;
|
|
||||||
xcb_ewmh_get_desktop_viewport_reply_t reply{};
|
|
||||||
if (xcb_ewmh_get_desktop_viewport_reply(conn, xcb_ewmh_get_desktop_viewport(conn, screen), &reply, nullptr)) {
|
|
||||||
for (size_t n = 0; n < reply.desktop_viewport_len; n++) {
|
|
||||||
viewports.emplace_back(position{
|
|
||||||
static_cast<short int>(reply.desktop_viewport[n].x), static_cast<short int>(reply.desktop_viewport[n].y)});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return viewports;
|
xcb_ewmh_get_atoms_reply_wipe(&reply);
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
vector<string> get_desktop_names(int screen) {
|
string get_wm_name(xcb_window_t win) {
|
||||||
auto& conn = initialize();
|
auto& conn = initialize();
|
||||||
xcb_ewmh_get_utf8_strings_reply_t reply{};
|
xcb_ewmh_get_utf8_strings_reply_t utf8_reply{};
|
||||||
if (xcb_ewmh_get_desktop_names_reply(conn, xcb_ewmh_get_desktop_names(conn, screen), &reply, nullptr)) {
|
if (xcb_ewmh_get_wm_name_reply(conn, xcb_ewmh_get_wm_name(conn, win), &utf8_reply, nullptr)) {
|
||||||
return string_util::split(string(reply.strings, reply.strings_len), '\0');
|
return get_reply_string(&utf8_reply);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
string get_visible_name(xcb_window_t win) {
|
||||||
|
auto& conn = initialize();
|
||||||
|
xcb_ewmh_get_utf8_strings_reply_t utf8_reply{};
|
||||||
|
if (xcb_ewmh_get_wm_visible_name_reply(conn, xcb_ewmh_get_wm_visible_name(conn, win), &utf8_reply, nullptr)) {
|
||||||
|
return get_reply_string(&utf8_reply);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
string get_icon_name(xcb_window_t win) {
|
||||||
|
auto& conn = initialize();
|
||||||
|
xcb_ewmh_get_utf8_strings_reply_t utf8_reply{};
|
||||||
|
if (xcb_ewmh_get_wm_icon_name_reply(conn, xcb_ewmh_get_wm_icon_name(conn, win), &utf8_reply, nullptr)) {
|
||||||
|
return get_reply_string(&utf8_reply);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
string get_reply_string(xcb_ewmh_get_utf8_strings_reply_t* reply) {
|
||||||
|
string str;
|
||||||
|
if (reply) {
|
||||||
|
str = string(reply->strings, reply->strings_len);
|
||||||
|
xcb_ewmh_get_utf8_strings_reply_wipe(reply);
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int get_current_desktop(int screen) {
|
||||||
|
auto& conn = initialize();
|
||||||
|
unsigned int desktop = XCB_NONE;
|
||||||
|
xcb_ewmh_get_current_desktop_reply(conn, xcb_ewmh_get_current_desktop(conn, screen), &desktop, nullptr);
|
||||||
|
return desktop;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int get_number_of_desktops(int screen) {
|
||||||
|
auto& conn = initialize();
|
||||||
|
unsigned int desktops = XCB_NONE;
|
||||||
|
xcb_ewmh_get_number_of_desktops_reply(conn, xcb_ewmh_get_number_of_desktops(conn, screen), &desktops, nullptr);
|
||||||
|
return desktops;
|
||||||
|
}
|
||||||
|
|
||||||
|
vector<position> get_desktop_viewports(int screen) {
|
||||||
|
auto& conn = initialize();
|
||||||
|
vector<position> viewports;
|
||||||
|
xcb_ewmh_get_desktop_viewport_reply_t reply{};
|
||||||
|
if (xcb_ewmh_get_desktop_viewport_reply(conn, xcb_ewmh_get_desktop_viewport(conn, screen), &reply, nullptr)) {
|
||||||
|
for (size_t n = 0; n < reply.desktop_viewport_len; n++) {
|
||||||
|
viewports.emplace_back(position{
|
||||||
|
static_cast<short int>(reply.desktop_viewport[n].x), static_cast<short int>(reply.desktop_viewport[n].y)});
|
||||||
}
|
}
|
||||||
return {};
|
}
|
||||||
|
return viewports;
|
||||||
|
}
|
||||||
|
|
||||||
|
vector<string> get_desktop_names(int screen) {
|
||||||
|
auto& conn = initialize();
|
||||||
|
xcb_ewmh_get_utf8_strings_reply_t reply{};
|
||||||
|
if (xcb_ewmh_get_desktop_names_reply(conn, xcb_ewmh_get_desktop_names(conn, screen), &reply, nullptr)) {
|
||||||
|
return string_util::split(string(reply.strings, reply.strings_len), '\0');
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
xcb_window_t get_active_window(int screen) {
|
||||||
|
auto& conn = initialize();
|
||||||
|
unsigned int win = XCB_NONE;
|
||||||
|
xcb_ewmh_get_active_window_reply(conn, xcb_ewmh_get_active_window(conn, screen), &win, nullptr);
|
||||||
|
return win;
|
||||||
|
}
|
||||||
|
|
||||||
|
void change_current_desktop(unsigned int desktop) {
|
||||||
|
auto& conn = initialize();
|
||||||
|
xcb_ewmh_request_change_current_desktop(conn, 0, desktop, XCB_CURRENT_TIME);
|
||||||
|
xcb_flush(conn->connection);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int get_desktop_from_window(xcb_window_t window) {
|
||||||
|
auto& conn = initialize();
|
||||||
|
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();
|
||||||
|
xcb_ewmh_set_wm_window_type(conn, win, types.size(), types.data());
|
||||||
|
xcb_flush(conn->connection);
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_wm_state(xcb_window_t win, vector<xcb_atom_t> states) {
|
||||||
|
auto& conn = initialize();
|
||||||
|
xcb_ewmh_set_wm_state(conn, win, states.size(), states.data());
|
||||||
|
xcb_flush(conn->connection);
|
||||||
|
}
|
||||||
|
|
||||||
|
vector<xcb_atom_t> get_wm_state(xcb_window_t win) {
|
||||||
|
auto& conn = initialize();
|
||||||
|
xcb_ewmh_get_atoms_reply_t reply;
|
||||||
|
if (xcb_ewmh_get_wm_state_reply(conn, xcb_ewmh_get_wm_state(conn, win), &reply, nullptr)) {
|
||||||
|
return {reply.atoms, reply.atoms + reply.atoms_len};
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_wm_pid(xcb_window_t win) {
|
||||||
|
auto& conn = initialize();
|
||||||
|
xcb_ewmh_set_wm_pid(conn, win, getpid());
|
||||||
|
xcb_flush(conn->connection);
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_wm_pid(xcb_window_t win, unsigned int pid) {
|
||||||
|
auto& conn = initialize();
|
||||||
|
xcb_ewmh_set_wm_pid(conn, win, pid);
|
||||||
|
xcb_flush(conn->connection);
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_wm_desktop(xcb_window_t win, unsigned int desktop) {
|
||||||
|
auto& conn = initialize();
|
||||||
|
xcb_ewmh_set_wm_desktop(conn, win, desktop);
|
||||||
|
xcb_flush(conn->connection);
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_wm_window_opacity(xcb_window_t win, unsigned long int values) {
|
||||||
|
auto& conn = initialize();
|
||||||
|
xcb_change_property(
|
||||||
|
conn->connection, XCB_PROP_MODE_REPLACE, win, _NET_WM_WINDOW_OPACITY, XCB_ATOM_CARDINAL, 32, 1, &values);
|
||||||
|
xcb_flush(conn->connection);
|
||||||
|
}
|
||||||
|
|
||||||
|
vector<xcb_window_t> get_client_list(int screen) {
|
||||||
|
auto& conn = initialize();
|
||||||
|
xcb_ewmh_get_windows_reply_t reply;
|
||||||
|
if (xcb_ewmh_get_client_list_reply(conn, xcb_ewmh_get_client_list(conn, screen), &reply, nullptr)) {
|
||||||
|
return {reply.windows, reply.windows + reply.windows_len};
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the _NET_SUPPORTING_WM_CHECK atom on the given window
|
||||||
|
*
|
||||||
|
* @return The _NET_SUPPORTING_WM_CHECK window id or XCB_NONE in case of an error
|
||||||
|
*/
|
||||||
|
xcb_window_t get_supporting_wm_check(xcb_window_t win) {
|
||||||
|
auto& conn = initialize();
|
||||||
|
xcb_window_t result{};
|
||||||
|
if (xcb_ewmh_get_supporting_wm_check_reply(conn, xcb_ewmh_get_supporting_wm_check(conn, win), &result, nullptr)) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
return XCB_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Searches for the meta window spawned by the WM to indicate a compliant WM is active.
|
||||||
|
*
|
||||||
|
* The window has the following properties:
|
||||||
|
* * It's pointed to by the root window's _NET_SUPPORTING_WM_CHECK atom
|
||||||
|
* * Its own _NET_SUPPORTING_WM_CHECK atom is set and points to itself
|
||||||
|
*
|
||||||
|
* @return The meta window id or XCB_NONE if it wasn't found
|
||||||
|
*/
|
||||||
|
xcb_window_t get_ewmh_meta_window(xcb_window_t root) {
|
||||||
|
xcb_window_t wm_meta_window = ewmh_util::get_supporting_wm_check(root);
|
||||||
|
|
||||||
|
if (wm_meta_window != XCB_NONE && ewmh_util::get_supporting_wm_check(wm_meta_window) == wm_meta_window) {
|
||||||
|
return wm_meta_window;
|
||||||
}
|
}
|
||||||
|
|
||||||
xcb_window_t get_active_window(int screen) {
|
return XCB_NONE;
|
||||||
auto& conn = initialize();
|
}
|
||||||
unsigned int win = XCB_NONE;
|
|
||||||
xcb_ewmh_get_active_window_reply(conn, xcb_ewmh_get_active_window(conn, screen), &win, nullptr);
|
|
||||||
return win;
|
|
||||||
}
|
|
||||||
|
|
||||||
void change_current_desktop(unsigned int desktop) {
|
|
||||||
auto& conn = initialize();
|
|
||||||
xcb_ewmh_request_change_current_desktop(conn, 0, desktop, XCB_CURRENT_TIME);
|
|
||||||
xcb_flush(conn->connection);
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int get_desktop_from_window(xcb_window_t window) {
|
|
||||||
auto& conn = initialize();
|
|
||||||
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();
|
|
||||||
xcb_ewmh_set_wm_window_type(conn, win, types.size(), types.data());
|
|
||||||
xcb_flush(conn->connection);
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_wm_state(xcb_window_t win, vector<xcb_atom_t> states) {
|
|
||||||
auto& conn = initialize();
|
|
||||||
xcb_ewmh_set_wm_state(conn, win, states.size(), states.data());
|
|
||||||
xcb_flush(conn->connection);
|
|
||||||
}
|
|
||||||
|
|
||||||
vector<xcb_atom_t> get_wm_state(xcb_window_t win) {
|
|
||||||
auto& conn = initialize();
|
|
||||||
xcb_ewmh_get_atoms_reply_t reply;
|
|
||||||
if (xcb_ewmh_get_wm_state_reply(conn, xcb_ewmh_get_wm_state(conn, win), &reply, nullptr)) {
|
|
||||||
return {reply.atoms, reply.atoms + reply.atoms_len};
|
|
||||||
}
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_wm_pid(xcb_window_t win) {
|
|
||||||
auto& conn = initialize();
|
|
||||||
xcb_ewmh_set_wm_pid(conn, win, getpid());
|
|
||||||
xcb_flush(conn->connection);
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_wm_pid(xcb_window_t win, unsigned int pid) {
|
|
||||||
auto& conn = initialize();
|
|
||||||
xcb_ewmh_set_wm_pid(conn, win, pid);
|
|
||||||
xcb_flush(conn->connection);
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_wm_desktop(xcb_window_t win, unsigned int desktop) {
|
|
||||||
auto& conn = initialize();
|
|
||||||
xcb_ewmh_set_wm_desktop(conn, win, desktop);
|
|
||||||
xcb_flush(conn->connection);
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_wm_window_opacity(xcb_window_t win, unsigned long int values) {
|
|
||||||
auto& conn = initialize();
|
|
||||||
xcb_change_property(
|
|
||||||
conn->connection, XCB_PROP_MODE_REPLACE, win, _NET_WM_WINDOW_OPACITY, XCB_ATOM_CARDINAL, 32, 1, &values);
|
|
||||||
xcb_flush(conn->connection);
|
|
||||||
}
|
|
||||||
|
|
||||||
vector<xcb_window_t> get_client_list(int screen) {
|
|
||||||
auto& conn = initialize();
|
|
||||||
xcb_ewmh_get_windows_reply_t reply;
|
|
||||||
if (xcb_ewmh_get_client_list_reply(conn, xcb_ewmh_get_client_list(conn, screen), &reply, nullptr)) {
|
|
||||||
return {reply.windows, reply.windows + reply.windows_len};
|
|
||||||
}
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
} // namespace ewmh_util
|
} // namespace ewmh_util
|
||||||
|
|
||||||
POLYBAR_NS_END
|
POLYBAR_NS_END
|
||||||
|
Loading…
Reference in New Issue
Block a user