From 81ea16931e10770d0f9ac7090a44455d8cc86a1f Mon Sep 17 00:00:00 2001 From: Isak05 <51046377+Isak05@users.noreply.github.com> Date: Sun, 28 Apr 2024 21:10:12 +0200 Subject: [PATCH] fix(script): Receiving multiple lines rapidly only displays first line (#3119) Fixes #3117 --- CHANGELOG.md | 1 + include/modules/meta/base.inl | 3 +-- include/utils/command.hpp | 1 + src/adapters/script_runner.cpp | 2 +- src/utils/command.cpp | 8 ++++++++ 5 files changed, 12 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b85e9cfa..b3aff186 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] ### Fixed +- `custom/script`: When a script with `tail = true` received multiple lines quickly, only the first would get displayed ([`#3117`](https://github.com/polybar/polybar/issues/3117), [`#3119`](https://github.com/polybar/polybar/pull/3119)) by [@Isak05](https://github.com/Isak05) - Token min-length calculations would behave differently when non-ASCII characters appear in the token ([`#3074`](https://github.com/polybar/polybar/issues/3074), [`#3087`](https://github.com/polybar/polybar/pull/3087)) by [@nklloyd](https://github.com/nklloyd) - i3: Fix duplicated rendering for non-full-width bars ([`#3091`](https://github.com/polybar/polybar/pull/3091), [`#3060`](https://github.com/polybar/polybar/issues/3060)) - `internal/backlight`: Module could display the literal `%percentage%` token if the backlight reports a value of 0 at startup ([`#3081`](https://github.com/polybar/polybar/pull/3081)) by [@unclechu](https://github.com/unclechu) diff --git a/include/modules/meta/base.inl b/include/modules/meta/base.inl index f80c7782..8a647d45 100644 --- a/include/modules/meta/base.inl +++ b/include/modules/meta/base.inl @@ -119,7 +119,7 @@ namespace modules { template string module::contents() { - if (m_changed) { + if (m_changed.exchange(false)) { m_log.info("%s: Rebuilding cache", name()); m_cache = CAST_MOD(Impl)->get_output(); // Make sure builder is really empty @@ -129,7 +129,6 @@ namespace modules { m_builder->control(tags::controltag::R); m_cache += m_builder->flush(); } - m_changed = false; } return m_cache; } diff --git a/include/utils/command.hpp b/include/utils/command.hpp index 322984c8..919ba86a 100644 --- a/include/utils/command.hpp +++ b/include/utils/command.hpp @@ -92,6 +92,7 @@ class command : private command cb); string readline(); + bool wait_for_data(int timeout_ms); int get_stdout(int c); int get_stdin(int c); diff --git a/src/adapters/script_runner.cpp b/src/adapters/script_runner.cpp index c7ffb26a..5cfe68a3 100644 --- a/src/adapters/script_runner.cpp +++ b/src/adapters/script_runner.cpp @@ -155,7 +155,7 @@ script_runner::interval script_runner::run_tail() { assert(fd != -1); while (!m_stopping && cmd.is_running() && !io_util::poll(fd, POLLHUP, 0)) { - if (io_util::poll_read(fd, 250)) { + if (cmd.wait_for_data(250)) { auto changed = set_output(cmd.readline()); if (changed) { diff --git a/src/utils/command.cpp b/src/utils/command.cpp index a4571215..a0b57569 100644 --- a/src/utils/command.cpp +++ b/src/utils/command.cpp @@ -201,6 +201,14 @@ string command::readline() { return s; } +/** + * Wait until there is data in the output stream or until timeout_ms milliseconds + */ +bool command::wait_for_data(int timeout_ms) { + return (m_stdout_reader && m_stdout_reader->rdbuf()->in_avail() > 0) || + io_util::poll_read(get_stdout(PIPE_READ), timeout_ms); +} + /** * Get command output channel */