feat: Restack-to-root
Fixes the issue where the bar window is being drawn on top of fullscreen window's
This commit is contained in:
parent
dac5a3c804
commit
e1b6238564
11
README.md
11
README.md
@ -414,6 +414,17 @@ The configuration syntax is based on the `ini` file format.
|
|||||||
; left
|
; left
|
||||||
; right
|
; right
|
||||||
tray-position = right
|
tray-position = right
|
||||||
|
|
||||||
|
; Restack the bar window and put it above the
|
||||||
|
; selected window manager's root
|
||||||
|
;
|
||||||
|
; Fixes the issue where the bar is being drawn
|
||||||
|
; on top of fullscreen window's
|
||||||
|
;
|
||||||
|
; Currently supported WM's:
|
||||||
|
; bspwm
|
||||||
|
; Default: none
|
||||||
|
wm-restack = bspwm
|
||||||
~~~
|
~~~
|
||||||
|
|
||||||
### Modules
|
### Modules
|
||||||
|
@ -30,6 +30,8 @@ modules-right = volume cpu ram clock
|
|||||||
|
|
||||||
tray-position = right
|
tray-position = right
|
||||||
|
|
||||||
|
wm-restack = bspwm
|
||||||
|
|
||||||
[module/label]
|
[module/label]
|
||||||
type = custom/text
|
type = custom/text
|
||||||
content = %{F#f90f59}Example%{F#ff} configuration
|
content = %{F#f90f59}Example%{F#ff} configuration
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
#include "components/x11/window.hpp"
|
#include "components/x11/window.hpp"
|
||||||
#include "components/x11/xlib.hpp"
|
#include "components/x11/xlib.hpp"
|
||||||
#include "components/x11/xutils.hpp"
|
#include "components/x11/xutils.hpp"
|
||||||
|
#include "utils/bspwm.hpp"
|
||||||
#include "utils/math.hpp"
|
#include "utils/math.hpp"
|
||||||
#include "utils/string.hpp"
|
#include "utils/string.hpp"
|
||||||
#include "utils/threading.hpp"
|
#include "utils/threading.hpp"
|
||||||
@ -275,6 +276,23 @@ class bar : public xpp::event::sink<evt::button_press> {
|
|||||||
m_connection.map_window_checked(m_window);
|
m_connection.map_window_checked(m_window);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// Restack window and put it above defined WM's root {{{
|
||||||
|
|
||||||
|
try {
|
||||||
|
auto wm_restack = m_conf.get<string>(bs, "wm-restack");
|
||||||
|
|
||||||
|
if (wm_restack == "bspwm") {
|
||||||
|
if (bspwm_util::restack_above_root(m_connection, m_bar.monitor, m_window))
|
||||||
|
m_log.info("Successfully restacked window above Bspwm root");
|
||||||
|
else
|
||||||
|
m_log.err("Failed to restack bar window above Bspwm root");
|
||||||
|
} else {
|
||||||
|
m_log.warn("Unsupported wm-restack option '%s'", wm_restack);
|
||||||
|
}
|
||||||
|
} catch (const key_error& err) {
|
||||||
|
}
|
||||||
|
|
||||||
// }}}
|
// }}}
|
||||||
// Create graphic contexts {{{
|
// Create graphic contexts {{{
|
||||||
|
|
||||||
|
@ -1,8 +1,12 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <xcb/xcb.h>
|
#include <xcb/xcb.h>
|
||||||
|
#include <xcb/xcb_icccm.h>
|
||||||
|
|
||||||
#include "common.hpp"
|
#include "common.hpp"
|
||||||
|
#include "components/x11/connection.hpp"
|
||||||
|
#include "components/x11/randr.hpp"
|
||||||
|
#include "components/x11/window.hpp"
|
||||||
#include "config.hpp"
|
#include "config.hpp"
|
||||||
#include "utils/socket.hpp"
|
#include "utils/socket.hpp"
|
||||||
#include "utils/string.hpp"
|
#include "utils/string.hpp"
|
||||||
@ -22,6 +26,57 @@ namespace bspwm_util {
|
|||||||
size_t len = 0;
|
size_t len = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all bspwm root windows
|
||||||
|
*/
|
||||||
|
auto root_windows(connection& conn) {
|
||||||
|
vector<xcb_window_t> roots;
|
||||||
|
auto children = conn.query_tree(conn.screen()->root).children();
|
||||||
|
|
||||||
|
for (auto it = children.begin(); it != children.end(); it++) {
|
||||||
|
auto cookie = xcb_icccm_get_wm_class(conn, *it);
|
||||||
|
xcb_icccm_get_wm_class_reply_t reply;
|
||||||
|
|
||||||
|
if (xcb_icccm_get_wm_class_reply(conn, cookie, &reply, nullptr) == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!string_util::compare("Bspwm", reply.class_name) ||
|
||||||
|
!string_util::compare("root", reply.instance_name))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
roots.emplace_back(*it);
|
||||||
|
}
|
||||||
|
|
||||||
|
return roots;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restack given window above the bspwm root window
|
||||||
|
* for the given monitor.
|
||||||
|
*
|
||||||
|
* Fixes the issue with always-on-top window's
|
||||||
|
*/
|
||||||
|
bool restack_above_root(connection& conn, const monitor_t& mon, const xcb_window_t win) {
|
||||||
|
for (auto&& root : root_windows(conn)) {
|
||||||
|
auto geom = conn.get_geometry(root);
|
||||||
|
|
||||||
|
if (mon->x != geom->x || mon->y != geom->y)
|
||||||
|
continue;
|
||||||
|
if (mon->w != geom->width || mon->h != geom->height)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
const uint32_t value_mask = XCB_CONFIG_WINDOW_SIBLING | XCB_CONFIG_WINDOW_STACK_MODE;
|
||||||
|
const uint32_t value_list[2]{root, XCB_STACK_MODE_ABOVE};
|
||||||
|
|
||||||
|
conn.configure_window_checked(win, value_mask, value_list);
|
||||||
|
conn.flush();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get path to the bspwm socket by the following order
|
* Get path to the bspwm socket by the following order
|
||||||
*
|
*
|
||||||
|
Loading…
Reference in New Issue
Block a user