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
|
POLYBAR_NS
|
||||||
|
|
||||||
namespace restack_util {
|
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);
|
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
|
POLYBAR_NS_END
|
||||||
|
@ -480,8 +480,11 @@ void bar::toggle() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Move the bar window above defined sibling
|
* Move the bar window above/below defined sibling in the X window stack.
|
||||||
* 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() {
|
void bar::restack_window() {
|
||||||
string wm_restack;
|
string wm_restack;
|
||||||
@ -492,15 +495,15 @@ void bar::restack_window() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
xcb_window_t bar_window = m_opts.x_data.window;
|
||||||
|
|
||||||
xcb_window_t restack_sibling = XCB_NONE;
|
xcb_window_t restack_sibling = XCB_NONE;
|
||||||
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") {
|
||||||
auto children = m_connection.query_tree(m_connection.root()).children();
|
std::tie(restack_sibling, stack_mode) = restack_util::get_bottom_params(m_connection, bar_window);
|
||||||
if (children.begin() != children.end() && *children.begin() != m_opts.x_data.window) {
|
} else if (wm_restack == "bottom") {
|
||||||
restack_sibling = *children.begin();
|
std::tie(restack_sibling, stack_mode) = restack_util::get_bottom_params(m_connection, bar_window);
|
||||||
stack_mode = XCB_STACK_MODE_BELOW;
|
|
||||||
}
|
|
||||||
} else if (wm_restack == "bspwm") {
|
} else if (wm_restack == "bspwm") {
|
||||||
restack_sibling = bspwm_util::get_restack_sibling(m_connection, m_opts.monitor);
|
restack_sibling = bspwm_util::get_restack_sibling(m_connection, m_opts.monitor);
|
||||||
#if ENABLE_I3
|
#if ENABLE_I3
|
||||||
@ -517,13 +520,13 @@ void bar::restack_window() {
|
|||||||
|
|
||||||
if (restack_sibling != XCB_NONE) {
|
if (restack_sibling != XCB_NONE) {
|
||||||
try {
|
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");
|
m_log.info("Successfully restacked bar window");
|
||||||
} catch (const exception& err) {
|
} catch (const exception& err) {
|
||||||
m_log.err("Failed to restack bar window (err=%s)", err.what());
|
m_log.err("Failed to restack bar window (err=%s)", err.what());
|
||||||
}
|
}
|
||||||
} else if (!wm_restack.empty()) {
|
} 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
|
* Returns window against which to restack.
|
||||||
* for the given monitor.
|
|
||||||
*
|
|
||||||
* Fixes the issue with always-on-top window's
|
|
||||||
*/
|
*/
|
||||||
xcb_window_t get_restack_sibling(connection& conn, const monitor_t& mon) {
|
xcb_window_t get_restack_sibling(connection& conn, const monitor_t& mon) {
|
||||||
for (auto&& root : root_windows(conn)) {
|
for (auto&& root : root_windows(conn)) {
|
||||||
|
@ -66,10 +66,7 @@ namespace i3_util {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Restack given window relative to the i3 root window
|
* Returns window against which to restack.
|
||||||
* defined for the given monitor
|
|
||||||
*
|
|
||||||
* Fixes the issue with always-on-top window's
|
|
||||||
*/
|
*/
|
||||||
xcb_window_t get_restack_sibling(connection& conn) {
|
xcb_window_t get_restack_sibling(connection& conn) {
|
||||||
return root_window(conn);
|
return root_window(conn);
|
||||||
|
@ -3,6 +3,9 @@
|
|||||||
POLYBAR_NS
|
POLYBAR_NS
|
||||||
|
|
||||||
namespace restack_util {
|
namespace restack_util {
|
||||||
|
|
||||||
|
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)
|
* Restacks the given window relative to a given sibling with some stack order (above, below)
|
||||||
*
|
*
|
||||||
@ -18,6 +21,51 @@ namespace restack_util {
|
|||||||
const std::array<uint32_t, 2> value_list = {sibling, stack_mode};
|
const std::array<uint32_t, 2> value_list = {sibling, stack_mode};
|
||||||
conn.configure_window_checked(win, value_mask, value_list.data());
|
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
|
POLYBAR_NS_END
|
||||||
|
Loading…
Reference in New Issue
Block a user