This is a boolean option. When set, “N:” prefixes will be stripped
from the workspaces’ name tag, *after* having been sorted (if the
‘sort’ option is being used).
This makes it useful to arrange the workspaces in a fixed order, by
prefixing the names with a number in the Sway config:
set $ws1 “1:xyz”
set $ws2 “2:abc”
Then, in the yambar config:
i3:
sort: ascending
strip-workspace-numbers: true
Audio CDs are special, in that they don’t (usually) have any data
partitions. They also don’t have a volume label. They just have
tracks.
Before this patch, we ignored all optical mediums that did *not* have
a filesystem (that includes audio CDs).
Now, instead of using the ID_FS_USAGE property to determine whether
there’s media present in the CD-ROM or not, we use the
ID_CDROM_MEDIA. This property is set to ‘1’ for both audio CDs and
data CDs.
Then, we read the ID_CDROM_MEDIA_TRACK_COUNT_AUDIO property to
determine how many audio tracks there are.
If the CD has a filesystem, we treat it as a data CD, and use the
already existing add_partition() function to track it.
If the CD does _not_ have a filesystem, but it _does_ have at least
one audio track, we treat it as an audio CD and use the new
add_audio_cd() function to track it.
This function is almost identical to add_partition(), but instead of
reading the ID_FS_LABEL property, it reads the
ID_CDROM_MEDIA_TRACK_COUNT_AUDIO property and synthesizes a label on
the form “Audio CD - N tracks”.
Finally, a new boolean tag, “audio”, has been added. It is set to true
for audio CD “partitions”, and to false in all other cases.
Set to true for empty (no windows) workspaces.
Mostly useful with persistent workspaces, to be able to differentiate
between invisible non-empty workspaces and actually empty
workspaces (the latter not being possible with non-persistent
workspaces).
This fixes an issue where we sometimes failed to retrieve the SSID; we
sent one initial request before the family ID had been set.
Then, we received the family ID and tried to send another
request. However, if the first request was still in progress, the
second request was never made.
Since the first request lacked the family ID, that response didn’t
contain anything useful.
Without this change yambar can't be installed/used without libmpdclient even for
people who do not use MPD. Let's make this optional.
We could put the optional module summary in the module meson.build but we'd have
to move summary() in main meson.build so that they appear in proper order.
This adds a new ‘poll-interval’ option to the network module. When set
to a non-zero value, the following Wi-Fi stats will be updated:
* Signal strength
* RX+TX bitrate
This cleans up the nl80211 handling quite a bit, and adds initial
support for nl80211 notifications.
* We now join the nl80211 MLME multicast group (done by parsing the
CTRL_ATTR_MCAST_GROUPS attribute in the reply to our
CTRL_CMD_GETFAMILY request). This gives us CONNECT and DISCONNECT
notifications, allowing us to request and reset SSID that way, instead
of detecting the link’s OPER state.
* Before parsing an nl80211 message, verify it’s for us, by looking
for a NL80211_ATTR_IFINDEX attribute in the message (and comparing the
contents with our previously detected ifindex).
This mostly comes down to tracking whether each channel is a playback,
or capture channel, and using the appropriate APIs when dealing with
it.
Some cleanup related to this:
* Add a channel struct, for per-channel data. Previously, our channel
list was just a list of ALSA channel IDs.
* We now store current volume per-channel (but volume min/max is
per-device)
* Muted state is stored per-channel
* Track both the device’s playback and capture volume ranges, as well
as whether the device *has* playback or capture volume.
* Get the playback/capture volume ranges once, during init, instead of
at each update.
* Use struct pointers for the volume/muted channels. This way we don’t
have to iterate all channels and to string comparisons on the name
each time we update our state.
* Bind the foreign-toplevel-manager object *after* the first round of
global objects. This ensures we bind all pre-existing wl-output
objects before binding the toplevel manager. This is important, since
otherwise we wont get any output_enter() events for the initial set of
toplevels.
* Bind xdg-output-manager, to be able to bind xdg-output objects for
each wl-output.
* Add xdg-output-listener to each wl/xdg-output, to be able to get the
outputs’ names.
* Add a list of outputs to each toplevel. The output_enter() event
adds to this list, and output_leave() removes from it.
* Add option ‘all-monitors’. When not set (the default), toplevels are
only included in the generated content if they are mapped on the same
output as the bar itself. When *not* set, all toplevels are always
included in the generated content.
* ‘content’ is a template; the module returns a list of toplevels,
each one instantiated using the content template.
* Each toplevel has 6 tags:
- app-id (string)
- title (string)
- maximized (bool)
- minimized (bool)
- activated (bool)
- fullscreen (bool)
To show the application name and title of the currently active window,
one can do:
- foreign-toplevel:
content:
map:
tag: activated
values:
false: {empty: {}}
true: {string: {text: "{app-id}: {title}"}}
Otherwise we’ll keep adding the same channel(s) over and over again,
for each (successful) connect attempt.
I.e. if you plug and unplug an USB soundcard repeatedly, we’ll keep
extending the channel list each time.
When e.g. a USB soundcard is inserted, we get several CREATE
events. In my experiments, we only succeed in connecting to ALSA after
the last event.
This means, we’ll have several CREATE events that we receive, remove
the watcher, attempt to connect, fail, and then re-add the watcher.
What if that “last” CREATE event occurs while our watcher has been
removed? That’s right, we miss it, and will get stuck waiting forever.
The solution is keep the watcher around.
Now, if we’ve been successfully connected to ALSA for a long time,
chances are we’ve built up events (for other cards, for example). We
don’t want to trigger a storm of re-connect attempts, so drain the
event queue after having been disconnected from ALSA.
There *is* a small race here - if a card is removed and
re-added *very* fast, we _may_ accidentally drain the CREATE event. I
don’t see this happening in reality though.
While waiting for the configured ALSA card to become available, use
inotify and watch for CREATE events on /dev/snd instead of
polling (using a timeout in the poll(3) call).
Note that we don’t know the actual names of the files that (will) be
created. This means:
* Every time we see a CREATE event on /dev/snd, we *try* to connect to
ALSA. If we fail, we go back to watching /dev/snd again.
* ALSA (not yambar) will log an error message each time we fail.
These options allows you to select which channel to use as volume
source, and which channel to use as the source for the muted state.
With this, we can also remove the check for *all* (playback) channels
having the same volume/muted state. And with that, we no longer need
to warn when not all channels have the same volume/muted state.
With this patch, a non-existing ALSA device is no longer considered a
fatal error. Instead, we keep retrying until we succeed.
Furthermore, if we have successfully opened the ALSA device, and it
then disappears, we a) no longer crash, or cause 100% CPU usage, and
b) try to re-connect to the device.
With this, we now handle e.g. USB soundcards being disconnected and
then re-connected. We should also handle pseudo devices, like pipewire
provides ones, when yambar is started before pipewire.
Closes#59Closes#61Closes#86