Moving rfkill to the main event loop had unexpected side-effects.
Notably, the network module mutex can block all the main thread events
for several seconds while the network worker thread is sleeping.
Instead of waiting for the mutex let's hope that the worker thread
succeeds and schedule timer thread wakeup just in case.
Open rfkill device only once per module.
Remove rfkill threads and use `Glib::signal_io` as a more efficient way
to poll the rfkill device.
Handle runtime errors from rfkill and stop polling of the device instead
of crashing waybar.
Kernel 5.11 added one more field to the `struct rfkill_event` and broke
unnecessarily strict check in `rfkill.cpp`. According to `linux/rfkill.h`,
we must accept events at least as large as v1 event size and should be
prepared to get additional fields at the end of a v1 event structure.
Multiple .done events may arrive in batch. In this case libwayland would
queue xdg_output.destroy and dispatch all pending events, triggering
this callback several times for the same output.
Delete xdg_output pointer immediately on the first event and use the
value as a guard for reentering.
At this point we're not awaiting any protocol events and flushing
wayland queue makes little sense. As #1019 shows, it may be even harmful
as an extra roundtrip could process wl_output disappearance and delete
output object right from under our code.
Ignore any further xdg_output events. Name and description are constant
for the lifetime of wl_output in xdg-output-unstable-v1 version 2 and we
don't need other properties.
Fixes#990.
Add additional fields, namely `source_volume` and `source_desc`
Add `tooltip-format`, reverting to default behavior if not specified
Add additional CSS classes, namely `sink-muted` and `source-muted`
Destroy request is not specified for foreign toplevel manager and it
does not prevent the compositor from sending more events.
Libwayland would ignore events to a destroyed objects, but that could
indirectly cause a gap in the sequence of new object ids and trigger
error condition in the library.
With this commit waybar sends a `stop` request to notify the compositor
about the destruction of a toplevel manager. That fixes abnormal
termination of the bar with following errors:
```
(waybar:11791): Gdk-DEBUG: 20:04:19.778: not a valid new object id (4278190088), message toplevel(n)
Gdk-Message: 20:04:19.778: Error reading events from display: Invalid argument
```
This error occurs because of an incorrect assumption that the size of
the list of nodes that contains the focused window is the number of
windows in a workspace.
The windows in a workspace are stored as a tree by Sway, rather than a
list, so the number of windows has to be found by counting the leaves of
a workspace tree.
GDK Wayland backend can emit two events for mouse scroll: one is a
GDK_SCROLL_SMOOTH and the other one is an emulated scroll event with
direction. We only receive emulated events on a window, thus it is not
possible to handle these in a module and stop propagation.
Ignoring emulated events should be safe since those are duplicates of
smooth scroll events anyways.
Fixes#386
Previously we only checked when connecting to the server whether it had
the minimum required version but didn't act accordingly in the various
functions that use the functionality of later versions. If there were a
server in the wild, that actually would not have this functionality,
there would have been a crash. Fix this by checking the version before
using the functionality and gracefully abort it.
There was an update the of the toplevel manager protocol. Unfortunately,
there are no new interesting updates with regard to the taskbar
implementation. Nonetheless, update the protocol xml files to the latest
version so that the implementation is up-to-date.
While being there, also change the debug warning that is shown when
there is a version mismatch between the server and client version of the
protocol.
Speedup battery state update by only updating the battery list when we
get a CREATE/DELETE event in the directory or whenever we do a full
refresh on the interval.
There was one uninitialized value warning and two mismatched-sign
compare warnings. They both appear valid, the first occurring when MPD's
"format-stopped" contains {songPosition} or {queueLength} and the second
occurring when the clock's "timezones" array is more than 2 billion
items long (not likely, I admit). Fix both issues.
This is very useful when writing CSS that affects more than just a
single widget. Pass `-l debug` to enable debug logging and show this
information.
Example output:
[2020-11-30 12:38:51.141] [debug] GTK widget tree:
window#waybar.background.bottom.eDP-1.:dir(ltr)
decoration:dir(ltr)
box.horizontal:dir(ltr)
box.horizontal.modules-left:dir(ltr)
widget:dir(ltr)
box#workspaces.horizontal:dir(ltr)
widget:dir(ltr)
label#mode:dir(ltr)
widget:dir(ltr)
label#window:dir(ltr)
box.horizontal.modules-center:dir(ltr)
box.horizontal.modules-right:dir(ltr)
widget:dir(ltr)
box#tray.horizontal:dir(ltr)
widget:dir(ltr)
label#idle_inhibitor:dir(ltr)
widget:dir(ltr)
label#pulseaudio:dir(ltr)
widget:dir(ltr)
label#network:dir(ltr)
widget:dir(ltr)
label#cpu:dir(ltr)
widget:dir(ltr)
label#memory:dir(ltr)
widget:dir(ltr)
label#temperature:dir(ltr)
widget:dir(ltr)
label#backlight:dir(ltr)
widget:dir(ltr)
label#battery:dir(ltr)
widget:dir(ltr)
label#clock:dir(ltr)
full-at was capped at the value instead of allowing the battery to show
100% when you were at the full-at value. Uncapping makes more sense as
it makes the full-at value the new 100% and the scale goes down from
there. Whereas before the battery would stay at the full-at value until
it went down enough which is unrealistic.
Since we're now clamping at 100% and rounding, mark as full at that
point. Some batteries will stay in charging state for a long time while
stuck at the same charge level. Just mark them as full to not be
confusing.
The energy values are all that's needed to calculate the battery state.
Using other values for the total capacity results in broken results in
some cases. This matches the output of TLP and i3status, while also
being more straightforward.
../src/modules/network.cpp:22:6: error: ‘optional’ in namespace ‘std’ does not name a template type
22 | std::optional<unsigned long long> read_netstat(std::string_view category, std::string_view key) {
| ^~~~~~~~
../src/modules/network.cpp:7:1: note: ‘std::optional’ is defined in header ‘<optional>’; did you forget to ‘#include <optional>’?
6 | #include "util/format.hpp"
+++ |+#include <optional>
7 | #ifdef WANT_RFKILL