-----BEGIN PGP SIGNATURE-----

iQEzBAABCAAdFiEEHVeRNS1RoijU3dukUh5eA668oacFAmbAiTEACgkQUh5eA668
 oachJAf9E5UWTESCxwMEUVFOFWgl1ewfbRI9lhfO5OLIFJxkqAhAmcWA/BBcfmry
 ETap5Q/+7y3TkzdrYPxU0J7J0rsZLOnx9XfPuclUY2b9VURa42/Axb+q4MVEeJ/f
 uG1kgRABCtuGnuH/6/C9OwRNMhiUEJeQi3SvoPbwJx2l9jLlRXNmp1R+uN1D446g
 Jki7ws+X1OzcRVs7pZm/o0RYSM1QdDajxxoNXEW0sdmiAhQo2isCXiI402QOymGc
 5vEVAHEFEiCeJy/WpbDhkAD/WIvoLTI24ajPXmHzfd+3SRup2o64VtXnV+uSlK0w
 c+lbTrwIoUmYqSBxonuvcgvgH/OkpA==
 =h+kl
 -----END PGP SIGNATURE-----

Merge tag '3.7.2'
This commit is contained in:
Przemek Grondek 2024-09-18 20:10:54 +02:00
commit b9a719b2b7
18 changed files with 112 additions and 52 deletions

View File

@ -32,20 +32,16 @@ Checks: '
' '
CheckOptions: CheckOptions:
- key: modernize-loop-convert.NamingStyle cppcoreguidelines-avoid-do-while.IgnoreMacros: true
value: lower_case modernize-loop-convert.NamingStyle: lower_case
- key: readability-identifier-naming.ClassCase readability-identifier-naming.ClassCase: lower_case
value: lower_case readability-identifier-naming.ClassConstantCase: UPPER_CASE
- key: readability-identifier-naming.ClassConstantCase readability-identifier-naming.ClassMethodCase: lower_case
value: UPPER_CASE readability-identifier-naming.MemberCase: lower_case
- key: readability-identifier-naming.ClassMethodCase readability-identifier-naming.ProtectedMemberPrefix: 'm_'
value: lower_case readability-identifier-naming.PrivateMemberPrefix: 'm_'
- key: readability-identifier-naming.MemberCase readability-simplify-boolean-expr.SimplifyDeMorgan: false
value: lower_case
- key: readability-identifier-naming.ProtectedMemberPrefix
value: 'm_'
- key: readability-identifier-naming.PrivateMemberPrefix
value: 'm_'
HeaderFilterRegex: '' HeaderFilterRegex: ''
WarningsAsErrors: '' WarningsAsErrors: ''
AnalyzeTemporaryDtors: false AnalyzeTemporaryDtors: false

View File

@ -14,7 +14,7 @@ jobs:
env: env:
COLOR: "ON" COLOR: "ON"
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
with: with:
ref: ${{ github.event.inputs.ref }} ref: ${{ github.event.inputs.ref }}
- name: Install Dependencies - name: Install Dependencies
@ -48,7 +48,7 @@ jobs:
python3-xcbgen \ python3-xcbgen \
libuv1-dev \ libuv1-dev \
xcb-proto xcb-proto
- uses: actions/checkout@v3 - uses: actions/checkout@v4
with: with:
submodules: true submodules: true
ref: ${{ github.event.inputs.ref }} ref: ${{ github.event.inputs.ref }}
@ -115,7 +115,7 @@ jobs:
if [ "$POLYBAR_BUILD_TYPE" = "tests" ]; then if [ "$POLYBAR_BUILD_TYPE" = "tests" ]; then
sudo apt-get install -y lcov sudo apt-get install -y lcov
fi fi
- uses: actions/checkout@v3 - uses: actions/checkout@v4
with: with:
submodules: true submodules: true
ref: ${{ github.event.inputs.ref }} ref: ${{ github.event.inputs.ref }}
@ -144,14 +144,20 @@ jobs:
lcov --remove cov_total.info "${PWD}/build/*" "${PWD}/tests/*" "${PWD}/lib/*" -o cov.info lcov --remove cov_total.info "${PWD}/build/*" "${PWD}/tests/*" "${PWD}/lib/*" -o cov.info
- name: Upload Coverage - name: Upload Coverage
if: ${{ matrix.polybar_build_type == 'tests' }} if: ${{ matrix.polybar_build_type == 'tests' }}
uses: codecov/codecov-action@v3 uses: codecov/codecov-action@v4
with: with:
token: ${{ secrets.CODECOV_TOKEN }}
flags: unittests flags: unittests
# We provide our own coverage files
disable_search: true
# Disable all plugins, we handle all preparations ourselves
plugins: noop
files: ./cov.info files: ./cov.info
fail_ci_if_error: true fail_ci_if_error: true
verbose: true
- name: Upload Logs - name: Upload Logs
if: failure() if: failure()
uses: actions/upload-artifact@v2 uses: actions/upload-artifact@v4
with: with:
name: cmake name: cmake
path: | path: |

View File

@ -38,7 +38,7 @@ jobs:
} >> "$GITHUB_ENV" } >> "$GITHUB_ENV"
# Checks out the target tag # Checks out the target tag
- uses: actions/checkout@v2 - uses: actions/checkout@v4
with: with:
ref: ${{ env.RELEASE_TAG }} ref: ${{ env.RELEASE_TAG }}
submodules: true submodules: true
@ -55,7 +55,7 @@ jobs:
- name: Get Upload URL - name: Get Upload URL
id: get_upload_url id: get_upload_url
uses: actions/github-script@v3 uses: actions/github-script@v7
with: with:
github-token: ${{ secrets.GITHUB_TOKEN }} github-token: ${{ secrets.GITHUB_TOKEN }}
script: | script: |
@ -83,7 +83,7 @@ jobs:
# Adds a download section to the beginning of the release body # Adds a download section to the beginning of the release body
- name: Update Release Body - name: Update Release Body
uses: actions/github-script@v3 uses: actions/github-script@v7
env: env:
# Existing release body, fetched in the get_upload_url step. # Existing release body, fetched in the get_upload_url step.
RELEASE_BODY: ${{ env.RELEASE_BODY }} RELEASE_BODY: ${{ env.RELEASE_BODY }}

View File

@ -65,6 +65,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- `internal/i3`: module errors when i3 has negative gaps ([`#2888`](https://github.com/polybar/polybar/issues/2888), [`#2889`](https://github.com/polybar/polybar/pull/2889)) - `internal/i3`: module errors when i3 has negative gaps ([`#2888`](https://github.com/polybar/polybar/issues/2888), [`#2889`](https://github.com/polybar/polybar/pull/2889))
- `wm-restack = bspwm`: bar may become unclickable if there are overlapping monitors ([`#2873`](https://github.com/polybar/polybar/issues/2873), [`#2961`](https://github.com/polybar/polybar/pull/2961)) - `wm-restack = bspwm`: bar may become unclickable if there are overlapping monitors ([`#2873`](https://github.com/polybar/polybar/issues/2873), [`#2961`](https://github.com/polybar/polybar/pull/2961))
## [3.7.2] - 2024-08-17
### 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)
- `internal/tray`: Fix crash during restarting, when tray icons were not removed proberly ([`#3111`](https://github.com/polybar/polybar/issues/3111), [`#3112`](https://github.com/polybar/polybar/pull/3112))
- `custom/ipc`: Module would display the literal `%output%` token before the initial hook finished executing ([`#3131`](https://github.com/polybar/polybar/issues/3131), [`#3140`](https://github.com/polybar/polybar/pull/3140))
- renderer: Pseudo-transparency rendering artifacts when wallpaper does not fill entire screen ([`#3096`](https://github.com/polybar/polybar/pull/3096), [`#3041`](https://github.com/polybar/polybar/issues/3041))
## [3.7.1] - 2023-11-27 ## [3.7.1] - 2023-11-27
### Build ### Build
- Fixed missing header when using `libc++` in clang 15 and below - Fixed missing header when using `libc++` in clang 15 and below
@ -313,7 +323,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Fixed ### Fixed
- Empty color values are no longer treated as invalid and no longer produce an error. - Empty color values are no longer treated as invalid and no longer produce an error.
[Unreleased]: https://github.com/polybar/polybar/compare/3.7.1...HEAD [Unreleased]: https://github.com/polybar/polybar/compare/3.7.2...HEAD
[3.7.2]: https://github.com/polybar/polybar/releases/tag/3.7.2
[3.7.1]: https://github.com/polybar/polybar/releases/tag/3.7.1 [3.7.1]: https://github.com/polybar/polybar/releases/tag/3.7.1
[3.7.0]: https://github.com/polybar/polybar/releases/tag/3.7.0 [3.7.0]: https://github.com/polybar/polybar/releases/tag/3.7.0
[3.6.3]: https://github.com/polybar/polybar/releases/tag/3.6.3 [3.6.3]: https://github.com/polybar/polybar/releases/tag/3.6.3

View File

@ -64,6 +64,14 @@ enable-ipc = true
; override-redirect = true ; override-redirect = true
; This module is not active by default (to enable it, add it to one of the
; modules-* list above).
; Please note that only a single tray can exist at any time. If you launch
; multiple bars with this module, only a single one will show it, the others
; will produce a warning. Which bar gets the module is timing dependent and can
; be quite random.
; For more information, see the documentation page for this module:
; https://polybar.readthedocs.io/en/stable/user/modules/tray.html
[module/systray] [module/systray]
type = internal/tray type = internal/tray

View File

@ -4,4 +4,4 @@
sphinx~=7.2.6 sphinx~=7.2.6
sphinx-rtd-theme~=2.0.0rc2 sphinx-rtd-theme~=2.0.0rc2
sphinx-notfound-page~=1.0.0 sphinx-notfound-page~=1.0.0
readthedocs-sphinx-search~=0.3.1 readthedocs-sphinx-search~=0.3.2

View File

@ -15,14 +15,16 @@ the Dropbox application).
Polybar is only responsible for embedding the windows in the bar and Polybar is only responsible for embedding the windows in the bar and
positioning them correctly. positioning them correctly.
.. note:: .. attention::
Only a single instance of this module can be active at the same time (across Only a single instance of this module can be active at the same time (across
all polybar instances). all polybar instances in the same graphical session).
The way the `system tray protocol <systray-spec_>`_ works, at most one tray The way the `system tray protocol <systray-spec_>`_ works, at most one tray
can exist at any time. can exist at any time.
Polybar will produce a warning if additional tray instances are created. Polybar will produce a warning if additional tray instances are created.
This also applies when another tray application (e.g. ``stalonetray``) is
active.
For transparent background colors, the tray will use pseudo-transparency, true For transparent background colors, the tray will use pseudo-transparency, true
transparency is not possible for the tray icons. transparency is not possible for the tray icons.

View File

@ -67,7 +67,12 @@ namespace modules {
brightness_handle m_val; brightness_handle m_val;
brightness_handle m_max; brightness_handle m_max;
int m_percentage = 0; /**
* Initial value set to a negative number so that any value read from the backlight file triggers an update during
* the first read.
* Otherwise, tokens may not be replaced
*/
int m_percentage = -1;
chrono::duration<double> m_interval{}; chrono::duration<double> m_interval{};
chrono::steady_clock::time_point m_lastpoll; chrono::steady_clock::time_point m_lastpoll;

View File

@ -119,7 +119,7 @@ namespace modules {
template <typename Impl> template <typename Impl>
string module<Impl>::contents() { string module<Impl>::contents() {
if (m_changed) { if (m_changed.exchange(false)) {
m_log.info("%s: Rebuilding cache", name()); m_log.info("%s: Rebuilding cache", name());
m_cache = CAST_MOD(Impl)->get_output(); m_cache = CAST_MOD(Impl)->get_output();
// Make sure builder is really empty // Make sure builder is really empty
@ -129,7 +129,6 @@ namespace modules {
m_builder->control(tags::controltag::R); m_builder->control(tags::controltag::R);
m_cache += m_builder->flush(); m_cache += m_builder->flush();
} }
m_changed = false;
} }
return m_cache; return m_cache;
} }

View File

@ -92,6 +92,7 @@ class command<output_policy::REDIRECTED> : private command<output_policy::IGNORE
void tail(std::function<void(string)> cb); void tail(std::function<void(string)> cb);
string readline(); string readline();
bool wait_for_data(int timeout_ms);
int get_stdout(int c); int get_stdout(int c);
int get_stdin(int c); int get_stdin(int c);

View File

@ -155,7 +155,7 @@ script_runner::interval script_runner::run_tail() {
assert(fd != -1); assert(fd != -1);
while (!m_stopping && cmd.is_running() && !io_util::poll(fd, POLLHUP, 0)) { 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()); auto changed = set_output(cmd.readline());
if (changed) { if (changed) {

View File

@ -86,14 +86,6 @@ renderer::renderer(connection& conn, signal_emitter& sig, const config& conf, co
{ {
m_pixmap = m_connection.generate_id(); m_pixmap = m_connection.generate_id();
m_connection.create_pixmap(m_depth, m_pixmap, m_window, m_bar.size.w, m_bar.size.h); m_connection.create_pixmap(m_depth, m_pixmap, m_window, m_bar.size.w, m_bar.size.h);
uint32_t configure_mask = 0;
std::array<uint32_t, 32> configure_values{};
xcb_params_cw_t configure_params{};
XCB_AUX_ADD_PARAM(&configure_mask, &configure_params, back_pixmap, m_pixmap);
connection::pack_values(configure_mask, &configure_params, configure_values);
m_connection.change_window_attributes_checked(m_window, configure_mask, configure_values.data());
} }
m_log.trace("renderer: Allocate graphic contexts"); m_log.trace("renderer: Allocate graphic contexts");
@ -372,8 +364,8 @@ void renderer::flush() {
highlight_clickable_areas(); highlight_clickable_areas();
m_surface->flush(); m_surface->flush();
// Clear entire window so that the new pixmap is shown // Copy pixmap onto the window
m_connection.clear_area(0, m_window, 0, 0, m_bar.size.w, m_bar.size.h); m_connection.copy_area(m_pixmap, m_window, m_gcontext, 0, 0, 0, 0, m_bar.size.w, m_bar.size.h);
m_connection.flush(); m_connection.flush();
if (!m_snapshot_dst.empty()) { if (!m_snapshot_dst.empty()) {

View File

@ -82,14 +82,15 @@ namespace drawtypes {
for (auto&& tok : m_tokens) { for (auto&& tok : m_tokens) {
string repl{replacement}; string repl{replacement};
size_t len = string_util::char_len(repl);
if (token == tok.token) { if (token == tok.token) {
if (tok.max != 0_z && string_util::char_len(repl) > tok.max) { if (tok.max != 0_z && len > tok.max) {
repl = string_util::utf8_truncate(std::move(repl), tok.max) + tok.suffix; repl = string_util::utf8_truncate(std::move(repl), tok.max) + tok.suffix;
} else if (tok.min != 0_z && repl.length() < tok.min) { } else if (tok.min != 0_z && len < tok.min) {
if (tok.rpadding) { if (tok.rpadding) {
repl.append(tok.min - repl.length(), ' '); repl.append(tok.min - len, ' ');
} else { } else {
repl.insert(0_z, tok.min - repl.length(), tok.zpad ? '0' : ' '); repl.insert(0_z, tok.min - len, tok.zpad ? '0' : ' ');
} }
} }

View File

@ -79,6 +79,8 @@ namespace modules {
this->module::start(); this->module::start();
m_mainthread = thread([&] { m_mainthread = thread([&] {
m_log.trace("%s: Thread id = %i", this->name(), concurrency_util::thread_id(this_thread::get_id())); m_log.trace("%s: Thread id = %i", this->name(), concurrency_util::thread_id(this_thread::get_id()));
// Initial update to start with an empty output until the initial hook finishes
update_output();
update(); update();
broadcast(); broadcast();
}); });

View File

@ -201,6 +201,14 @@ string command<output_policy::REDIRECTED>::readline() {
return s; return s;
} }
/**
* Wait until there is data in the output stream or until timeout_ms milliseconds
*/
bool command<output_policy::REDIRECTED>::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 * Get command output channel
*/ */

View File

@ -220,13 +220,34 @@ void bg_slice::copy(xcb_pixmap_t root_pixmap, int depth, xcb_rectangle_t geom, x
ensure_resources(depth, visual); ensure_resources(depth, visual);
assert(m_pixmap); assert(m_pixmap);
// fill the slice auto pixmap_end_x = int16_t(geom.x + geom.width);
auto pixmap_end_y = int16_t(geom.y + geom.height);
auto translated = m_connection.translate_coordinates(m_window, m_connection.screen()->root, m_rect.x, m_rect.y); auto translated = m_connection.translate_coordinates(m_window, m_connection.screen()->root, m_rect.x, m_rect.y);
// Coordinates of the slice in the root pixmap
auto src_x = math_util::cap(translated->dst_x, geom.x, int16_t(geom.x + geom.width)); /*
auto src_y = math_util::cap(translated->dst_y, geom.y, int16_t(geom.y + geom.height)); * If the slice is not fully contained in the root pixmap, we will be missing at least some background pixels. For
* those areas, nothing is copied over and a simple black background is shown.
* This can happen when connecting new monitors without updating the root pixmap.
*/
if (!(translated->dst_x >= geom.x && translated->dst_x + m_rect.width <= pixmap_end_x &&
translated->dst_y >= geom.y && translated->dst_y + m_rect.height <= pixmap_end_y)) {
m_log.err(
"background_manager: Root pixmap does not fully cover transparent areas. "
"Pseudo-transparency may not fully work and instead just show a black background. "
"Make sure you have a wallpaper set on all of your screens");
}
/*
* Coordinates of the slice in the root pixmap. The rectangle is capped so that it is contained in the root pixmap to
* avoid copying areas not covered by the pixmap.
*/
auto src_x = math_util::cap(translated->dst_x, geom.x, pixmap_end_x);
auto src_y = math_util::cap(translated->dst_y, geom.y, pixmap_end_x);
auto w = math_util::cap(m_rect.width, uint16_t(0), uint16_t(geom.width - (src_x - geom.x))); auto w = math_util::cap(m_rect.width, uint16_t(0), uint16_t(geom.width - (src_x - geom.x)));
auto h = math_util::cap(m_rect.height, uint16_t(0), uint16_t(geom.height - (src_y - geom.y))); auto h = math_util::cap(m_rect.height, uint16_t(0), uint16_t(geom.height - (src_y - geom.y)));
// fill the slice
m_log.trace( m_log.trace(
"background_manager: Copying from root pixmap (0x%x:%d) %dx%d+%d+%d", root_pixmap, depth, w, h, src_x, src_y); "background_manager: Copying from root pixmap (0x%x:%d) %dx%d+%d+%d", root_pixmap, depth, w, h, src_x, src_y);
m_connection.copy_area_checked(root_pixmap, m_pixmap, m_gcontext, src_x, src_y, 0, 0, w, h); m_connection.copy_area_checked(root_pixmap, m_pixmap, m_gcontext, src_x, src_y, 0, 0, w, h);
@ -257,12 +278,18 @@ void bg_slice::allocate_resources(xcb_visualtype_t* visual) {
XCB_AUX_ADD_PARAM(&mask, &params, foreground, black_pixel); XCB_AUX_ADD_PARAM(&mask, &params, foreground, black_pixel);
XCB_AUX_ADD_PARAM(&mask, &params, background, black_pixel); XCB_AUX_ADD_PARAM(&mask, &params, background, black_pixel);
XCB_AUX_ADD_PARAM(&mask, &params, graphics_exposures, 0); XCB_AUX_ADD_PARAM(&mask, &params, graphics_exposures, 0);
m_connection.pack_values(mask, &params, value_list); connection::pack_values(mask, &params, value_list);
m_gcontext = m_connection.generate_id(); m_gcontext = m_connection.generate_id();
m_connection.create_gc(m_gcontext, m_pixmap, mask, value_list.data()); m_connection.create_gc(m_gcontext, m_pixmap, mask, value_list.data());
m_log.trace("background_manager: Allocating cairo surface"); m_log.trace("background_manager: Allocating cairo surface");
m_surface = make_unique<cairo::xcb_surface>(m_connection, m_pixmap, visual, m_rect.width, m_rect.height); m_surface = make_unique<cairo::xcb_surface>(m_connection, m_pixmap, visual, m_rect.width, m_rect.height);
/*
* Fill pixmap with black in case it is not fully filled by the root pixmap. Otherwise we may render uninitialized
* memory
*/
m_connection.poly_fill_rectangle(m_pixmap, m_gcontext, 1, &m_rect);
} }
void bg_slice::free_resources() { void bg_slice::free_resources() {

View File

@ -502,7 +502,8 @@ void manager::remove_client(const client& c) {
void manager::remove_client(xcb_window_t win) { void manager::remove_client(xcb_window_t win) {
auto old_size = m_clients.size(); auto old_size = m_clients.size();
m_clients.erase( m_clients.erase(
std::remove_if(m_clients.begin(), m_clients.end(), [win](const auto& client) { return client->match(win); })); std::remove_if(m_clients.begin(), m_clients.end(), [win](const auto& client) { return client->match(win); }),
m_clients.end());
if (old_size != m_clients.size()) { if (old_size != m_clients.size()) {
reconfigure(); reconfigure();
@ -518,7 +519,8 @@ void manager::remove_client(xcb_window_t win) {
*/ */
void manager::clean_clients() { void manager::clean_clients() {
m_clients.erase( m_clients.erase(
std::remove_if(m_clients.begin(), m_clients.end(), [](const auto& client) { return client.get() == nullptr; })); std::remove_if(m_clients.begin(), m_clients.end(), [](const auto& client) { return client.get() == nullptr; }),
m_clients.end());
} }
bool manager::change_visibility(bool visible) { bool manager::change_visibility(bool visible) {

View File

@ -1,4 +1,4 @@
# Polybar version information # Polybar version information
# Update this on every release # Update this on every release
# This is used to create the version string if a git repo is not available # This is used to create the version string if a git repo is not available
3.7.1 3.7.2