Skip to content

Conversation

@patrick96
Copy link
Member

@patrick96 patrick96 commented Jun 24, 2019

When a monitor is connected which is automatically mirrored polybar can crash when the monitor name it is currently running gets removed in get_monitors (see #1191).

This also adds a new commandline argument -M --list-all-monitors that also lists cloned monitors. I couldn't change the behavior of -m since some people rely on polybar -m to display polybar on all monitors.

I have not tested this yet but I will once I get some time at home.

This also fixes the bugged clone removal code.

Fixes #1191
Fixes #1794

Premature optimization that tried to cache monitors but the cache did
not take into account the parameter values.

The call `get_monitors(..., ..., false, true);` would get all connected
and unconncected monitors a subsequent call
`get_monitors(..., ..., true, false);` would get back the same list of
monitors even though it requested only connected monitors.

Additionally `get_monitors` is never called periodically so the
optimization really didn't help much.
@codecov
Copy link

codecov bot commented Jun 24, 2019

Codecov Report

Merging #1823 into master will increase coverage by 0.06%.
The diff coverage is 0%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #1823      +/-   ##
==========================================
+ Coverage   23.39%   23.46%   +0.06%     
==========================================
  Files          50       50              
  Lines        2086     2080       -6     
==========================================
  Hits          488      488              
+ Misses       1598     1592       -6
Flag Coverage Δ
#unittests 23.46% <0%> (+0.06%) ⬆️
Impacted Files Coverage Δ
include/x11/extensions/randr.hpp 0% <ø> (ø) ⬆️
src/x11/extensions/randr.cpp 1.03% <0%> (+0.06%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 43556b5...dc45743. Read the comment docs.

Copy link
Member

@Lomadriel Lomadriel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code seems okay for me however I can't test for now (I just sold my secondary monitor since I'm moving soon)

Works the same as -m but doesn't purge cloned monitors
Removing monitors is not really necessary when selecting the monitor
where to render the bar or choosing the backlight. Since both monitors
occupy the same coordinates rendering can be done on both and it's
better to give people felxibility for the backlight.

Fixes polybar#1191
@Lomadriel
Copy link
Member

As suspected in your comment: #1794 (comment)
The code that removes the clone is bugged.

const auto remove_monitor = [&](const monitor_t& monitor) {
monitors.erase(find(monitors.begin(), monitors.end(), monitor));
};

When the erase is called, some iterators are invalidated.
for (auto m = monitors.rbegin(); m != monitors.rend(); m++) {
if ((*m)->w == 0) {
remove_monitor(*m);
continue;
}

The iterator m is invalidated so it's undefined behavior to use it, even for doing something like m++.
See https://en.cppreference.com/w/cpp/container/vector (section "Iterator invalidation") for more information.
If you want I can fix that this weekend but feels free to do it if you can do it before. 😉

@patrick96
Copy link
Member Author

@Lomadriel I already started working on a fix, the whole thing is a mess anyway, maybe I can clean it up a little.

Because of how monitors are removed inside the loop and depending on the
monitor order a cloned monitor may be assigned a width of 0 but is never
actually removed resulting in polybar saying the bar is out of bounds

Fixes polybar#1794
@patrick96
Copy link
Member Author

Was able to clean up a little. The get_monitors method will be changed again anyway once we fix #1437 and correctly support xrandr's new monitor concept (which we don't really do right now).

@patrick96 patrick96 marked this pull request as ready for review June 24, 2019 22:28
@patrick96 patrick96 requested a review from Lomadriel June 26, 2019 11:25
@Lomadriel
Copy link
Member

Lomadriel commented Jun 26, 2019

sort(monitors.begin(), monitors.end(), [](monitor_t& m1, monitor_t& m2) -> bool {
if (m1->x < m2->x || m1->y + m1->h <= m2->y) {
return true;
}
if (m1->x > m2->x || m1->y + m1->h > m2->y) {
return -1;
}
return false;
});

Maybe we should also fix this sort, It seems to be a "C comparator" copy/paste that haven't been adapted for std::sort.

EDIT:
Moreover this comparator is totally broken. For example if you have:
m1 {.x=10, .y = 10, .h = 0}
m2{.x=11, .y = 9, .h = 2}
You have m1 < m2 and m2 < m1, so the final order in the vector depends on the order before the execution of the sort function.
Moreover I don't understand why there is a y + h for the monitor 1 but not for the monitor 2. 😕

Copy link
Member

@NBonaparte NBonaparte left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I found some typos. I'll investigate more of the functionality soon.

@NBonaparte
Copy link
Member

@Lomadriel also why does it return -1 in the second case?

@Lomadriel
Copy link
Member

Lomadriel commented Jun 26, 2019

@Lomadriel also why does it return -1 in the second case?

For me, it is just because originally it was a C comparator like strcmp. Anyway I don't know why the monitors are sorted by their size, I don't see the reason. I tried to figure what should be the comparator but I can't find anything :/

@mjhough
Copy link

mjhough commented Jun 27, 2019

I was having the issue described in #1191. For me, this prevents polybar from crashing, but when I plug in my monitor this is what happens:

  1. Plug in monitor, automatically in non-scaled mirroring mode. Polybar is on both monitors.
  2. Run xrandr code (below) so that monitors are displayed side by side and the 1080p one is scaled.
    xrandr --output eDP-1 --primary --mode 2560x1440 --pos 3072x288 --rotate normal --output DP-1 --off --output DP-2 --off --output HDMI-1 --mode 1920x1080 --pos 0x0 --rotate normal --scale 1.6x1.6

After step 2, I have polybar on my external monitor, even though in my config I have it set to eDP-1 (my laptop monitor). Killing polybar and starting it again brings it back to the correct screen.

@patrick96
Copy link
Member Author

Maybe we should also fix this sort, It seems to be a "C comparator" copy/paste that haven't been adapted for std::sort.

@Lomadriel looking through the git history it seems jaagr copied over the sorting method from lemonbar to be consistent, I doubt that we still need this especially since we are now displaying on the primary monitor by default.

@NBonaparte Thanks for the review. I agree the wording could use some work, I'll look it over again.

@patrick96
Copy link
Member Author

@mjhough I think you are experiencing this because polybar uses the monitor position to make sure the bar is displayed on that monitor. In your case your bar is positioned at 0x0 and when you reconfigure your monitors, your bar stays at 0x0 and your main monitor moves to 3072x288. We recommend setting screenchange-reload = true in the [settings] section.

@mjhough
Copy link

mjhough commented Jun 28, 2019

@mjhough I think you are experiencing this because polybar uses the monitor position to make sure the bar is displayed on that monitor. In your case your bar is positioned at 0x0 and when you reconfigure your monitors, your bar stays at 0x0 and your main monitor moves to 3072x288. We recommend setting screenchange-reload = true in the [settings] section.

It seems I do have screenchange-reload = true in the [settings] section.

@patrick96
Copy link
Member Author

@mjhough Indeed, this seems like an oversight in the code. Polybar doesn't reload if monitor positions change, only when the dimensions change. I will fix this

The lambda returns the wrong values and sorting isn't really necessary
Before it would only reload if the size changed and even that was
reliable since the method relied on the order of the monitor list.

Now if the monitor list differs in any way (pos, dimension, primary,
output, name) a reload is issued
@patrick96 patrick96 requested a review from NBonaparte June 30, 2019 13:35
@patrick96
Copy link
Member Author

I have now adapted the screenchange handling code to compare the monitor lists more thouroughly and reload if anything changed.

Copy link
Member

@NBonaparte NBonaparte left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had trouble replicating #1191 as I still get both monitors listed even when using a clone. I assume it's working for that use case.

However, when I set monitor = <cloned monitor name>, it correctly displays but emits a restacking error on bspwm. Apparently it still uses the cloned monitor as m_opts.monitor, which fails in bspwm_util::restack_to_root().

Copy link
Member

@Lomadriel Lomadriel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Works well on i3wm.

Copy link
Member

@Lomadriel Lomadriel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Checked with upscale (nvidia drivers) #1437 is also fixed.
Good job !

EDIT: Polybar is reloaded when I change the scale factor and it seems to be at the right place every times.

@patrick96
Copy link
Member Author

Checked with upscale (nvidia drivers) #1437 is also fixed.

Were you able to reproduce the issue? Amazing! I thought we needed to rewrite much of the monitor handling code.

@NBonaparte what exactly is the restacking error? I'm unable to reproduce this.

@Lomadriel
Copy link
Member

Lomadriel commented Aug 6, 2019

Were you able to reproduce the issue? Amazing! I thought we needed to rewrite much of the monitor handling code.

The issue is fixed because we reload polybar when a monitor change ;)

EDIT:
#1437 wasn't the issue I ‎thought of

@patrick96
Copy link
Member Author

patrick96 commented Aug 6, 2019

I think #1437 happened even if polybar is restarted.

#1437 wasn't the issue I ‎thought of

What was the issue you thought of?

@Lomadriel
Copy link
Member

What was the issue you thought of?

When I was modifying my resolution, polybar wasn't reloading and so was misplaced/out of the screen, etc...

@patrick96
Copy link
Member Author

Ah, I see.

@NBonaparte
Copy link
Member

@patrick96 just tested this again, I'm only getting one monitor with --list-monitors which is expected, but I still get the restacking error: error: Failed to restack bar window.

I have two monitors, HDMI-0 and DP-1, with bspwm. For testing I set DP-1 to be a clone of HDMI-0 (xrandr --output DP-1 --same-as HDMI-0) and in the config I set monitor = DP-1.

@patrick96
Copy link
Member Author

@NBonaparte I still can't reproduce this. The bspwm restacking mechanic doesn't rely on the monitor name. It searches for a bspwm root window with the exact same coordinates as the monitor that polybar is displayed on, so this patch changes nothing about this behavior. On my machine bspwm has one root window per monitor, even if they are cloned.

I am going to merge this, if you want could you share the output of xwininfo -root -tree and polybar -M when this happens?

@patrick96 patrick96 merged commit ecbe77b into polybar:master Apr 21, 2020
@patrick96 patrick96 deleted the issue/1191 branch April 21, 2020 21:59
patrick96 added a commit that referenced this pull request Nov 29, 2020
Breaking Changes:

* The new config parser imposes some restrictions on which characters can be
  used in section and key names. Users shouldn't be affected by this unless they
  use one of the following characters in any section or key name: `"'=;#[](){}:.$\%`
  Please consult [`man 5 polybar`](https://polybar.readthedocs.io/en/latest/man/polybar.5.html) for a full reference of the new config rules.
* `internal/temperature`: The first and last ramp element are now only used for
  `base-temperature` and below and `warn-temperature` and above respectively.
  This only slightly changes the ranges for which the different ramp levels are
  responsible for.
  (#2197)

Changelog

**Deprecations**

* `[settings]`: `throttle-input-for` has been removed. It wasn't a useful option
  and could cause certain actions (e.g. click commands) to be ignored. (#2117)

* All action names used by modules to handle click and scroll events are
  depercated (#1907).  This change mainly affects users of the menu module.
  Please read the [documentation](https://polybar.readthedocs.io/en/latest/user/actions.html) for instructions on how to migrate.

**New Config Options**

The `include-directory` key can be used the same as `include-file` and includes
all regular files in the given directory.

In labels:

* `label-NAME-minlen`, `label-NAME-alignment` can be used to pad labels with
  spaces to the right (alignment set to `left`), left (alignment set to
  `right`), and both sides (alignment set to `center`).

In `internal/backlight`:

* `enable-scroll` enables changing the brightness through scrolling.

In `internal/github`:

* `format-offline` is used when the module cannot connect to the server.
* `label-offline` can be used in `format-offline`.
* `api-url` can be used to connect to a custom github enterprise instance

In `internal/pulseaudio`:

* `click-right` and `click-middle` can be used to execute commands when
  right/middle clicking.
* `%decibels%` token can be used in `label-volume` and `label-muted` to show the
  volume in decibels.

**Changes To The Build System**

* Allow users to specify python executable when building. (polybar/xpp#27,
  #2125)
* The i3ipcpp submodule no longer rebuilds jsoncpp and just uses whatever
  version is available. (#2015, polybar/i3ipcpp#9)

**Features**

* New commandline argument: `-M` / `--list-all-monitors`.
    Will display all available monitors (even cloned ones).
* New log level: `notice`.
    Used as the default and is used for non-warning messages the user should
    nevertheless be aware of. (#2027)
* config:
    * New config parser (#1377)
    * `include-directory` key (#2196), see #1946
    * Add error message when an entire section is missing. (#2195)
    * `-minlen` and `-alignment` properties for labels. (#1546)
    * Make the `seperator` key in the bar section a label. (#1918)
    * Better color validation. (#1290)
* timer modules: Schedule module updates to be aligned with the update interval.
  For example, the date module now updates on the minute instead of in the
  middle of a minute if the interval is set to 60 seconds. (#2123), see #2064
* `custom/menu`: Multiple menu modules per bar (#1907)
* `internal/backlight`: Support for changing the brightness through scrolling.
  This may require additional changes to the system running polybar. (#1957)
* `internal/github`:
    * `format-offline` for when the module cannot connect to the server (#1825),
    see #1815
    * Support for github enterprise instances. (#1841), see #1812
* `internal/network`: Support `Gbit/s` for `%linkspeed%` token. (#2055)
* `internal/pulseaudio`:
    * `click-right` and `click-middle` keys (#1941)
    * `%decibels%` token (#1894), see #1886
* `internal/xworkspaces`: Proper implementation for `label-occupied`. (#822),
  see #874, #1444, #1033

**Fixes**

* Polybar not executing commands that produce output. (#1680), see #916
* Polybar froze until click commands finished executing (#2248)
* Polybar not properly working with mirrored monitors. (#1823), see #1192 and
  #1794
* Unstable animation framerate (#1683), see #568
* Multiple modules of the same type caused click events not to be delivered to
  the rigth one (#1907), see #1172
* config:
    * Seemingly unrelated error messages when BOM character appears in config.
    (#2166), see #2075
    * Fall back to next possible config location if config file doesn't exist
      (except if `--config` was used). (#2026), see #2016
* iconset: `fuzzy-match` chose first match, even if exact match was available.
  (#2042), see #2041
* `custom/menu`: Spacing issue (#1656)
* `internal/alsa`: Volume didn't go over 100% (#2184), see #2173
* `internal/backlight`: Use amdgpu workaround for all devices starting with
  `amdgpu_bl`. (#2122)
* `internal/battery`: Battery not marked as full if over `full-at` percent.
  (#2019), see #1622
* `internal/cpu`: More accurate cpu load calculation. (#1955)
* `internal/github`: Outdated GitHub API authentication. (#2029), see #2002
* `internal/memory`: Use the correct size prefixes (#2211), see #2023
* `internal/network`:
    * Wrong up- and downspeed values for non-integer intervals. (#2219)
    * tun/tap interfaces didn't query their IP addresses. (#1990), see #1986
    * Don't crash module if linkspeed cannot be queried. (#1772), see #1211
* `internal/temperature`:
    * `format-warn` was not used if the temperature was *exactly*
      `warn-temperature`. (#1897)
* `internal/xworkspaces`:
    * Multi-monitor issue (#1929), see #1764, #1849
    * Module sometimes showed too many workspaces (#1984), see #1983
* build:
    * xpp submodule doesn't work with python 3.9 (polybar/xpp#26)
    * CMake 3.17+ developer warnings (#2089, polybar/xpp#24, polybar/xpp#25)
    * gtest compilation failure (#1993), see google/googletest#2678
    * Compilation issue in GCC 6. (#1953)
@patrick96 patrick96 mentioned this pull request Nov 29, 2020
28 tasks
patrick96 added a commit that referenced this pull request Dec 1, 2020
Breaking Changes:

* The new config parser imposes some restrictions on which characters can be
  used in section and key names. Users shouldn't be affected by, this unless
  they use one of the following characters in any section or key name: `"'=;#[](){}:.$\%`
  Please consult [`man 5 polybar`](https://polybar.readthedocs.io/en/latest/man/polybar.5.html) for a full reference of the new config rules.
* `internal/temperature`: The first and last ramp element are now only used for
  `base-temperature` and below and `warn-temperature` and above respectively.
  This only slightly changes the ranges for which the different ramp levels are
  responsible for.
  (#2197)

Changelog

**Deprecations**

* `[settings]`: `throttle-input-for` has been removed. It wasn't a useful option
  and could cause certain actions (e.g. click commands) to be ignored. (#2117)

* All action names used by modules to handle click and scroll events are
  deprecated (#1907). This change mainly affects users of the menu module.
  Please read the [documentation](https://polybar.readthedocs.io/en/latest/user/actions.html) for instructions on how to migrate.

**New Config Options**

The `include-directory` key can be used the same as `include-file` and includes
all regular files in the given directory.

In labels:

* `label-NAME-minlen`, `label-NAME-alignment` can be used to pad labels with
  spaces to the right (alignment set to `left`), left (alignment set to
  `right`), and both sides (alignment set to `center`).

In `internal/backlight`:

* `enable-scroll` enables changing the brightness through scrolling.

In `internal/github`:

* `format-offline` is used when the module cannot connect to the server.
* `label-offline` can be used in `format-offline`.
* `api-url` can be used to connect to a custom github enterprise instance

In `internal/pulseaudio`:

* `click-right` and `click-middle` can be used to execute commands when
  right/middle clicking.
* `%decibels%` token can be used in `label-volume` and `label-muted` to show the
  volume in decibels.

**Changes To The Build System**

* Allow users to specify python executable when building. (polybar/xpp#27,
  #2125)
* The i3ipcpp submodule no longer rebuilds jsoncpp and just uses whatever
  version is available. (#2015, polybar/i3ipcpp#9)

**Features**

* New commandline argument: `-M` / `--list-all-monitors`.
    Will display all available monitors (even cloned ones).
* New log level: `notice`.
    Used as the default and is used for non-warning messages the user should
    nevertheless be aware of. (#2027)
* config:
    * New config parser (#1377)
    * `include-directory` key (#2196), see #1946
    * Add error message when an entire section is missing. (#2195)
    * `-minlen` and `-alignment` properties for labels. (#1546)
    * Make the `seperator` key in the bar section a label. (#1918)
    * Better color validation. (#1290)
* timer modules: Schedule module updates to be aligned with the update interval.
  For example, the date module now updates on the minute instead of in the
  middle of a minute if the interval is set to 60 seconds. (#2123), see #2064
* `custom/menu`: Multiple menu modules per bar (#1907)
* `internal/backlight`: Support for changing the brightness through scrolling.
  This may require additional changes to the system running polybar. (#1957)
* `internal/github`:
    * `format-offline` for when the module cannot connect to the server (#1825),
    see #1815
    * Support for github enterprise instances. (#1841), see #1812
* `internal/network`: Support `Gbit/s` for `%linkspeed%` token. (#2055)
* `internal/pulseaudio`:
    * `click-right` and `click-middle` keys (#1941)
    * `%decibels%` token (#1894), see #1886
* `internal/xworkspaces`: Proper implementation for `label-occupied`. (#822),
  see #874, #1444, #1033

**Fixes**

* Polybar not executing commands that produce output. (#1680), see #916
* Polybar froze until click commands finished executing (#2248)
* Polybar not properly working with mirrored monitors. (#1823), see #1192 and
  #1794
* Unstable animation framerate (#1683), see #568
* Multiple modules of the same type caused click events not to be delivered to
  the rigth one (#1907), see #1172
* config:
    * Seemingly unrelated error messages when BOM character appears in config.
    (#2166), see #2075
    * Fall back to next possible config location if config file doesn't exist
      (except if `--config` was used). (#2026), see #2016
* iconset: `fuzzy-match` chose first match, even if exact match was available.
  (#2042), see #2041
* `custom/menu`: Spacing issue (#1656)
* `internal/alsa`: Volume didn't go over 100% (#2184), see #2173
* `internal/backlight`: Use amdgpu workaround for all devices starting with
  `amdgpu_bl`. (#2122)
* `internal/battery`: Battery not marked as full if over `full-at` percent.
  (#2019), see #1622
* `internal/cpu`: More accurate cpu load calculation. (#1955)
* `internal/github`: Outdated GitHub API authentication. (#2029), see #2002
* `internal/memory`: Use the correct size prefixes (#2211), see #2023
* `internal/network`:
    * Wrong up- and downspeed values for non-integer intervals. (#2219)
    * tun/tap interfaces didn't query their IP addresses. (#1990), see #1986
    * Don't crash module if linkspeed cannot be queried. (#1772), see #1211
* `internal/temperature`:
    * `format-warn` was not used if the temperature was *exactly*
      `warn-temperature`. (#1897)
* `internal/xworkspaces`:
    * Multi-monitor issue (#1929), see #1764, #1849
    * Module sometimes showed too many workspaces (#1984), see #1983
* build:
    * xpp submodule doesn't work with python 3.9 (polybar/xpp#26)
    * CMake 3.17+ developer warnings (#2089, polybar/xpp#24, polybar/xpp#25)
    * gtest compilation failure (#1993), see google/googletest#2678
    * Compilation issue in GCC 6. (#1953)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Polybar doesn't recognize VGA monitor width, causes error to launch Can't find monitor when running two displays in mirrored mode

4 participants