Compare commits

...

14 Commits

Author SHA1 Message Date
b9a719b2b7 -----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'
2024-09-18 20:10:54 +02:00
patrick96
b3af5a3316
Version 3.7.2 2024-08-17 13:19:58 +02:00
patrick96
c0d3d7a3e7 fix(render): Deal with incomplete wallpapers
If the root pixmap does not fully cover the bar window, some
pseudo-transparent areas were filled with unitialized data, causing
pixelation or other rendering artifacts.

Now, ovserved background slices are first filled with black to make sure
this does not happen and they print an error if not the full pixmap can
be filled.

Fixes #3041
2024-08-17 13:13:12 +02:00
patrick96
35638027a8 Update github actions
checkout is bumped from v3 to v4, there shouldn't be any breaking
changes (just bumps the node version)

upload-artifact is bumped from v2 to v4, our use case shouldn't break

github-script is bumped from v3 to v7. I don't see any breaking changes
that should affect us. Again mainly a nodejs version bump
2024-08-04 13:55:04 +02:00
patrick96
6f8db4a3fe ci: Use codecov token
This wasn't required for PRs but for the job that runs on the `master`
branch, the job fails without the token (because it's a protected
branch)
2024-08-04 13:55:04 +02:00
patrick96
52ff00c28d fix(ci): Get Codecov to work again
Mainly updates the plugin
2024-08-01 12:13:30 +02:00
patrick96
4d1758457b fix(ipc): Clear output until initial hook finishes
Before, it just showed '%output%'

Fixes #3131
2024-08-01 11:15:48 +02:00
patrick96
baed54bc76 doc: Improve tray documentation
Unaware users may be confused by why the tray module is not shown in the
default config and if they add it, they may be confused why only one of
their bars shows the module.
2024-08-01 11:09:46 +02:00
Isak05
81ea16931e
fix(script): Receiving multiple lines rapidly only displays first line (#3119)
Fixes #3117
2024-04-28 21:10:12 +02:00
patrick96
ab583b08cd fix(tray): Clients not being removed properly
The vector::erase call needs to be supplied with the end of the range,
otherwise only a single element is removed.

Fixes #3111
2024-04-15 23:43:25 +02:00
patrick96
c8f7dc1c14 fix(i3): Properly render non-full-width windows
Without override-redirect, i3 will not allow you to have a
non-full-width bar. But polybar simply ignores that request and
continues to render the user-requested width instead of the width i3 has
configured the window to be.

With the 3.7 release, we started setting the window's backing pixmap to
the rendering pixmap. In the case above, the pixmap would only be
allocted for the smaller width and when i3 maps the window, it repeats
the backing pixmap to fill the entire window.

At the point where i3 maps the window, the pixmap contains an initial
render of the bar without module content and that render is then
duplicated.

Reverting back to the old approach of simply copying over the pixmap
after each render does not have that problem and the remainder of the
bar is black (or fully transparent with a compositor).

Ideally, polybar would respect the width i3 configures for it, but that
would break many existing setups that rely on non-full-width bars in i3

Fixes #3060
2024-02-18 19:02:30 +01:00
Patrick Ziegler
020699724f
fix(label): Misbehaving min-length tokens with non-ASCII characters (#3090)
* Changed bit count for label to use UTF8 standard

Fixes #3074

* label: Calculate length only once

The length calculation has to traverse the whole string

---------

Co-authored-by: nklloyd <nicholask.lloyd@gmail.com>
2024-02-10 12:51:34 +01:00
Patrick Ziegler
8e04f15ed6
fix(backlight): %backlight% token appearing on the bar (#3081)
* Fix backlight initial value matching the actual brightness level

The initial value is `0`. If the actual brightness is also `0` you see
`%percentage%` token as text, it’s not being replaced. Since
`m_brightness` is an `int` the initial value could be just `-1` since
the actual brightness is never goes below zero. Thus this bug will never
show up again because actual brightness on first render won’t match
the “old” `m_brightness` value.

See also for more detailed explanation of the bug:
https://github.com/polybar/polybar/discussions/3079#discussioncomment-8169932

* Add docs

---------

Co-authored-by: Viacheslav Lotsmanov <lotsmanov89@gmail.com>
2024-01-20 18:09:12 +01:00
patrick96
0ed669f049
fix(doc): Update vulnerable rtd search extension
Ref: https://github.com/readthedocs/readthedocs-sphinx-search/security/advisories/GHSA-xgfm-fjx6-62mj
2024-01-20 17:53:28 +01:00
18 changed files with 112 additions and 52 deletions

View File

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

View File

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

View File

@ -38,7 +38,7 @@ jobs:
} >> "$GITHUB_ENV"
# Checks out the target tag
- uses: actions/checkout@v2
- uses: actions/checkout@v4
with:
ref: ${{ env.RELEASE_TAG }}
submodules: true
@ -55,7 +55,7 @@ jobs:
- name: Get Upload URL
id: get_upload_url
uses: actions/github-script@v3
uses: actions/github-script@v7
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
@ -83,7 +83,7 @@ jobs:
# Adds a download section to the beginning of the release body
- name: Update Release Body
uses: actions/github-script@v3
uses: actions/github-script@v7
env:
# Existing release body, fetched in the get_upload_url step.
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))
- `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
### Build
- 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
- 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.0]: https://github.com/polybar/polybar/releases/tag/3.7.0
[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
; 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]
type = internal/tray

View File

@ -4,4 +4,4 @@
sphinx~=7.2.6
sphinx-rtd-theme~=2.0.0rc2
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
positioning them correctly.
.. note::
.. attention::
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
can exist at any time.
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
transparency is not possible for the tray icons.

View File

@ -67,7 +67,12 @@ namespace modules {
brightness_handle m_val;
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::steady_clock::time_point m_lastpoll;

View File

@ -119,7 +119,7 @@ namespace modules {
template <typename Impl>
string module<Impl>::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;
}

View File

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

View File

@ -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) {

View File

@ -86,14 +86,6 @@ renderer::renderer(connection& conn, signal_emitter& sig, const config& conf, co
{
m_pixmap = m_connection.generate_id();
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");
@ -372,8 +364,8 @@ void renderer::flush() {
highlight_clickable_areas();
m_surface->flush();
// Clear entire window so that the new pixmap is shown
m_connection.clear_area(0, m_window, 0, 0, m_bar.size.w, m_bar.size.h);
// Copy pixmap onto the window
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();
if (!m_snapshot_dst.empty()) {

View File

@ -82,14 +82,15 @@ namespace drawtypes {
for (auto&& tok : m_tokens) {
string repl{replacement};
size_t len = string_util::char_len(repl);
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;
} else if (tok.min != 0_z && repl.length() < tok.min) {
} else if (tok.min != 0_z && len < tok.min) {
if (tok.rpadding) {
repl.append(tok.min - repl.length(), ' ');
repl.append(tok.min - len, ' ');
} 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();
m_mainthread = thread([&] {
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();
broadcast();
});

View File

@ -201,6 +201,14 @@ string command<output_policy::REDIRECTED>::readline() {
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
*/

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);
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);
// 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 h = math_util::cap(m_rect.height, uint16_t(0), uint16_t(geom.height - (src_y - geom.y)));
// fill the slice
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);
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, background, black_pixel);
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_connection.create_gc(m_gcontext, m_pixmap, mask, value_list.data());
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);
/*
* 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() {

View File

@ -502,7 +502,8 @@ void manager::remove_client(const client& c) {
void manager::remove_client(xcb_window_t win) {
auto old_size = m_clients.size();
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()) {
reconfigure();
@ -518,7 +519,8 @@ void manager::remove_client(xcb_window_t win) {
*/
void manager::clean_clients() {
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) {

View File

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