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(