From efbd8e394f52d38ba23845c369ab7afc74b60536 Mon Sep 17 00:00:00 2001
From: Patrick Ziegler
Date: Wed, 27 Apr 2022 21:09:59 +0200
Subject: [PATCH] fix(bar): Update struts when hiding (#2702)
When the bar is hidden, the struts should be 0 so that WMs can resize
their windows and not leave a gap.
Ref #2701
---
CHANGELOG.md | 1 +
src/components/bar.cpp | 71 ++++++++++++++++++++++--------------------
src/x11/window.cpp | 6 ++--
3 files changed, 43 insertions(+), 35 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 05f97753..c3ee2e7b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- `internal/battery`: `poll-interval` not working ([`#2649`](https://github.com/polybar/polybar/issues/2649), [`#2677`](https://github.com/polybar/polybar/pull/2677))
- ipc: Polybar failing to open IPC channel after another user already ran polybar, if `XDG_RUNTIME_DIR` is not set ([`#2683`](https://github.com/polybar/polybar/issues/2683), [`#2684`](https://github.com/polybar/polybar/pull/2684))
- No overlines/underlines being drawn when using offsets ([`#2685`](https://github.com/polybar/polybar/pull/2685))
+- Update struts (`_NET_WM_STRUT_PARTIAL`) when hiding the bar ([`#2702`](https://github.com/polybar/polybar/pull/2702))
## [3.6.2] - 2022-04-03
### Fixed
diff --git a/src/components/bar.cpp b/src/components/bar.cpp
index b2efa93c..7a08f67a 100644
--- a/src/components/bar.cpp
+++ b/src/components/bar.cpp
@@ -440,10 +440,11 @@ void bar::hide() {
try {
m_log.info("Hiding bar window");
+ m_visible = false;
+ reconfigure_struts();
m_sig.emit(visibility_change{false});
m_connection.unmap_window_checked(m_opts.window);
m_connection.flush();
- m_visible = false;
} catch (const exception& err) {
m_log.err("Failed to unmap bar window (err=%s", err.what());
}
@@ -556,42 +557,46 @@ void bar::reconfigure_pos() {
* Reconfigure window strut values
*/
void bar::reconfigure_struts() {
- auto geom = m_connection.get_geometry(m_screen->root());
- int h = m_opts.size.h + m_opts.offset.y;
+ window win{m_connection, m_opts.window};
+ if (m_visible) {
+ auto geom = m_connection.get_geometry(m_screen->root());
+ int h = m_opts.size.h + m_opts.offset.y;
- // Apply user-defined margins
- if (m_opts.bottom) {
- h += m_opts.strut.top;
- } else {
- h += m_opts.strut.bottom;
- }
-
- h = std::max(h, 0);
-
- int correction = 0;
-
- // Only apply correction if any space is requested
- if (h > 0) {
- /*
- * Strut coordinates have to be relative to root window and not any monitor.
- * If any monitor is not aligned at the top or bottom
- */
+ // Apply user-defined margins
if (m_opts.bottom) {
- /*
- * For bottom-algined bars, the correction is the number of pixels between
- * the root window's bottom edge and the monitor's bottom edge
- */
- correction = geom->height - (m_opts.monitor->y + m_opts.monitor->h);
+ h += m_opts.strut.top;
} else {
- // For top-aligned bars, we simply add the monitor's y-position
- correction = m_opts.monitor->y;
+ h += m_opts.strut.bottom;
}
- correction = std::max(correction, 0);
- }
+ h = std::max(h, 0);
- window win{m_connection, m_opts.window};
- win.reconfigure_struts(m_opts.size.w, h + correction, m_opts.pos.x, m_opts.bottom);
+ int correction = 0;
+
+ // Only apply correction if any space is requested
+ if (h > 0) {
+ /*
+ * Strut coordinates have to be relative to root window and not any monitor.
+ * If any monitor is not aligned at the top or bottom
+ */
+ if (m_opts.bottom) {
+ /*
+ * For bottom-algined bars, the correction is the number of pixels between
+ * the root window's bottom edge and the monitor's bottom edge
+ */
+ correction = geom->height - (m_opts.monitor->y + m_opts.monitor->h);
+ } else {
+ // For top-aligned bars, we simply add the monitor's y-position
+ correction = m_opts.monitor->y;
+ }
+
+ correction = std::max(correction, 0);
+ }
+ win.reconfigure_struts(m_opts.size.w, h + correction, m_opts.pos.x, m_opts.bottom);
+ } else {
+ // Set struts to 0 for invisible bars
+ win.reconfigure_struts(0, 0, 0, m_opts.bottom);
+ }
}
/**
@@ -634,6 +639,8 @@ void bar::broadcast_visibility() {
}
void bar::map_window() {
+ m_visible = true;
+
/**
* First reconfigures the window so that WMs that discard some information
* when unmapping have the correct window properties (geometry etc).
@@ -648,8 +655,6 @@ void bar::map_window() {
* mapping. Additionally updating the window position after mapping seems to fix that.
*/
reconfigure_pos();
-
- m_visible = true;
}
void bar::trigger_click(mousebtn btn, int pos) {
diff --git a/src/x11/window.cpp b/src/x11/window.cpp
index 0c31505a..601cc003 100644
--- a/src/x11/window.cpp
+++ b/src/x11/window.cpp
@@ -57,14 +57,16 @@ window window::reconfigure_pos(short int x, short int y) {
window window::reconfigure_struts(uint32_t w, uint32_t strut, uint32_t x, bool bottom) {
std::array values{};
+ uint32_t end_x = std::max(0, x + w - 1);
+
if (bottom) {
values[to_integral(strut::BOTTOM)] = strut;
values[to_integral(strut::BOTTOM_START_X)] = x;
- values[to_integral(strut::BOTTOM_END_X)] = x + w - 1;
+ values[to_integral(strut::BOTTOM_END_X)] = end_x;
} else {
values[to_integral(strut::TOP)] = strut;
values[to_integral(strut::TOP_START_X)] = x;
- values[to_integral(strut::TOP_END_X)] = x + w - 1;
+ values[to_integral(strut::TOP_END_X)] = end_x;
}
connection().change_property_checked(