restack: Add bottom restacking strategy
For now this is the same as the generic one
This commit is contained in:
parent
59acb4150b
commit
b11a2ff653
@ -8,7 +8,12 @@
|
||||
POLYBAR_NS
|
||||
|
||||
namespace restack_util {
|
||||
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);
|
||||
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_generic_params(connection& conn, xcb_window_t bar_window);
|
||||
}
|
||||
|
||||
POLYBAR_NS_END
|
||||
|
@ -480,8 +480,11 @@ void bar::toggle() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Move the bar window above defined sibling
|
||||
* in the X window stack
|
||||
* Move the bar window above/below defined sibling in the X window stack.
|
||||
*
|
||||
* How the sibling is determined depends on the wm-restack setting.
|
||||
*
|
||||
* This is meant to resolve polybar appearing above other windows (especially in fullscreen).
|
||||
*/
|
||||
void bar::restack_window() {
|
||||
string wm_restack;
|
||||
@ -492,15 +495,15 @@ void bar::restack_window() {
|
||||
return;
|
||||
}
|
||||
|
||||
xcb_window_t bar_window = m_opts.x_data.window;
|
||||
|
||||
xcb_window_t restack_sibling = XCB_NONE;
|
||||
xcb_stack_mode_t stack_mode = XCB_STACK_MODE_ABOVE;
|
||||
|
||||
if (wm_restack == "generic") {
|
||||
auto children = m_connection.query_tree(m_connection.root()).children();
|
||||
if (children.begin() != children.end() && *children.begin() != m_opts.x_data.window) {
|
||||
restack_sibling = *children.begin();
|
||||
stack_mode = XCB_STACK_MODE_BELOW;
|
||||
}
|
||||
std::tie(restack_sibling, stack_mode) = restack_util::get_bottom_params(m_connection, bar_window);
|
||||
} else if (wm_restack == "bottom") {
|
||||
std::tie(restack_sibling, stack_mode) = restack_util::get_bottom_params(m_connection, bar_window);
|
||||
} else if (wm_restack == "bspwm") {
|
||||
restack_sibling = bspwm_util::get_restack_sibling(m_connection, m_opts.monitor);
|
||||
#if ENABLE_I3
|
||||
@ -517,13 +520,13 @@ void bar::restack_window() {
|
||||
|
||||
if (restack_sibling != XCB_NONE) {
|
||||
try {
|
||||
restack_util::restack_relative(m_connection, m_opts.x_data.window, restack_sibling, stack_mode);
|
||||
restack_util::restack_relative(m_connection, bar_window, restack_sibling, stack_mode);
|
||||
m_log.info("Successfully restacked bar window");
|
||||
} catch (const exception& err) {
|
||||
m_log.err("Failed to restack bar window (err=%s)", err.what());
|
||||
}
|
||||
} else if (!wm_restack.empty()) {
|
||||
m_log.err("Failed to restack bar window");
|
||||
m_log.err("Failed to restack bar window: No suitable sibling window for restacking was found");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -36,10 +36,7 @@ vector<xcb_window_t> root_windows(connection& conn) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Restack given window relative to the bspwm root window
|
||||
* for the given monitor.
|
||||
*
|
||||
* Fixes the issue with always-on-top window's
|
||||
* Returns window against which to restack.
|
||||
*/
|
||||
xcb_window_t get_restack_sibling(connection& conn, const monitor_t& mon) {
|
||||
for (auto&& root : root_windows(conn)) {
|
||||
|
@ -66,10 +66,7 @@ namespace i3_util {
|
||||
}
|
||||
|
||||
/**
|
||||
* Restack given window relative to the i3 root window
|
||||
* defined for the given monitor
|
||||
*
|
||||
* Fixes the issue with always-on-top window's
|
||||
* Returns window against which to restack.
|
||||
*/
|
||||
xcb_window_t get_restack_sibling(connection& conn) {
|
||||
return root_window(conn);
|
||||
|
@ -3,21 +3,69 @@
|
||||
POLYBAR_NS
|
||||
|
||||
namespace restack_util {
|
||||
/**
|
||||
* Restacks the given window relative to a given sibling with some stack order (above, below)
|
||||
*
|
||||
* Both windows need to be siblings (have the same parent window).
|
||||
*
|
||||
* @param win The window to restack
|
||||
* @param sibling The window relative to which restacking happens
|
||||
* @param stack_mode The restacking mode (above, below)
|
||||
* @throw Some xpp error if restacking fails
|
||||
*/
|
||||
void restack_relative(connection& conn, xcb_window_t win, xcb_window_t sibling, xcb_stack_mode_t stack_mode) {
|
||||
const unsigned int value_mask = XCB_CONFIG_WINDOW_SIBLING | XCB_CONFIG_WINDOW_STACK_MODE;
|
||||
const std::array<uint32_t, 2> value_list = {sibling, stack_mode};
|
||||
conn.configure_window_checked(win, value_mask, value_list.data());
|
||||
}
|
||||
|
||||
static constexpr params NONE_PARAMS = {XCB_NONE, XCB_STACK_MODE_ABOVE};
|
||||
|
||||
/**
|
||||
* Restacks the given window relative to a given sibling with some stack order (above, below)
|
||||
*
|
||||
* Both windows need to be siblings (have the same parent window).
|
||||
*
|
||||
* @param win The window to restack
|
||||
* @param sibling The window relative to which restacking happens
|
||||
* @param stack_mode The restacking mode (above, below)
|
||||
* @throw Some xpp error if restacking fails
|
||||
*/
|
||||
void restack_relative(connection& conn, xcb_window_t win, xcb_window_t sibling, xcb_stack_mode_t stack_mode) {
|
||||
const unsigned int value_mask = XCB_CONFIG_WINDOW_SIBLING | XCB_CONFIG_WINDOW_STACK_MODE;
|
||||
const std::array<uint32_t, 2> value_list = {sibling, stack_mode};
|
||||
conn.configure_window_checked(win, value_mask, value_list.data());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true iff the two given windows are sibings (are different windows and have same parent).
|
||||
*/
|
||||
bool are_siblings(connection& conn, xcb_window_t win, xcb_window_t sibling) {
|
||||
if (win == XCB_NONE || sibling == XCB_NONE || win == sibling) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto win_tree = conn.query_tree(win);
|
||||
auto sibling_tree = conn.query_tree(sibling);
|
||||
return win_tree->parent == sibling_tree->parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* "bottom" restack strategy.
|
||||
*
|
||||
* 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) {
|
||||
auto children = conn.query_tree(conn.root()).children();
|
||||
if (children.begin() != children.end() && *children.begin() != bar_window) {
|
||||
return {*children.begin(), XCB_STACK_MODE_BELOW};
|
||||
}
|
||||
|
||||
return NONE_PARAMS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic restack stratgey.
|
||||
*
|
||||
* Tries to provide the best WM-agnostic restacking.
|
||||
*
|
||||
* Currently tries to the following stratgies in order:
|
||||
* * bottom
|
||||
*/
|
||||
std::pair<xcb_window_t, xcb_stack_mode_t> get_generic_params(connection& conn, xcb_window_t bar_window) {
|
||||
auto [sibling, mode] = get_bottom_params(conn, bar_window);
|
||||
|
||||
if (are_siblings(conn, bar_window, sibling)) {
|
||||
return {sibling, mode};
|
||||
}
|
||||
|
||||
return NONE_PARAMS;
|
||||
}
|
||||
} // namespace restack_util
|
||||
|
||||
POLYBAR_NS_END
|
||||
|
Loading…
Reference in New Issue
Block a user