Closed sebastianst closed 5 years ago
It might worth checking if your bar font supports emojis as well.
It does, I use emojis for my keyboard layout indicator and the CPU symbol. I use
bar {
font pango:DejaVu Sans Mono, FontAwesome 10
...
Running i3status-rust
in a terminal doesn't print the emojis, but escaped slashes and hex codes, so you see \\x0f\\x9f\\x8d\\x8d
where the ssid is. Which means, i3status-rs
already internally converts the emojis into multi byte hex codes.
It would probably also just print weird boxed glyphs otherwise...
I found out the reason. The SSID is queried by calling iw
, which returns the ssid with all unicode chars as escaped hex codes, see https://github.com/greshake/i3status-rust/blob/192274fe392f9658ca824d57166c7a2a801840b1/src/blocks/net.rs#L101
The good news is, this line also has nmcli -g general.connection device show {}
as a backup should the first call fail and nmcli returns the SSID as is.
I propose to change the order of commands to nmcli ... || iw ...
because it is better anyways to first query nmcli
instead of iw | grep | sed
. Also note here that the grep | sed
call could be combined into a single sed call. I also think that this parsing should rather be done in rust using regexp than calling sh -c 'iw | grep | sed'
;)
nmcli is part of NetworkManager, though, which most i3 (and thus i3status-rust) users don't even install on their machines.
I spent the last hour trying to find a clean linux way of obtaining the ESSID of the currently connected network, but unfortunately, there are no good news.
The ESSID attribute is neither exposed to /proc/net/
nor to /sys/class/net
filesystems. Additionally, due to Linux' history of wifi interfaces, we won't ever be able to get a generic way of obtaining this information.
The iw
tool links against the nl80211
kernel library and is probably the most widespread choice.
Assuming we don't want to link that library ourselves, we probably should simply parse the iw
output (which is discouraged since the iw
authors don't consider its output stable).
The source of the printing C function is very simple, so we only need to take care of non-utf-8 sequences:
util.c:332
void print_ssid_escaped(const uint8_t len, const uint8_t *data)
{
int i;
for (i = 0; i < len; i++) {
if (isprint(data[i]) && data[i] != ' ' && data[i] != '\\')
printf("%c", data[i]);
else if (data[i] == ' ' &&
(i != 0 && i != len -1))
printf(" ");
else
printf("\\x%.2x", data[i]);
}
}
We could check if the command nmcli
is available and only use it then. (All people I know who use i3 on their laptop do use nm because of the dynamic networking situation with a laptop ;)
Another, probably nicer, option could be to listen to wpa_supplicant DBUS events so we don't even have to poll the SSID but get it delivered when it changes.
The lack of a native way to get the ESSID was a major source of irritation when I did the implementation, and I’d be very glad to be rid of the shell-out-to-iw-or-nmcli approach.
Since we’re increasingly using D-Bus I like the idea of using it here as well — does anyone know how widespread the wpa_supplicant interface is?
Alternatively, we could look at what other bars are doing here.
ps. One thing to keep in mind on this topic is that the ESSID is in no way required to be UTF-8. We’ll likely end up doing lossy conversion on the Rust side, but I don’t know how emojis will fare in that conversion.
Since WEP networks aren't common any more, people seem to be forced to either use wpa_supplicant or iwd, which seems to be supposed to replace wpa_supplicant, though didn't use it yet.
NetworkManager requires wpa_supplicant by the way.
I checked how py3status
and i3status
do it. i3status
natively gets the ssid somehow but the code looked quite convoluted and I couldn't be bothered to fully understand how ;)
py3status
also just calls iw
, parses its output in python and decodes the escaped unicode, see
https://github.com/ultrabug/py3status/commit/cdf34b93673fbdc3722a6bb42e0b97c242b3bfc7 where unicode support was introduced.
i3status
links against the nl80211 library I mentioned above.
@atheriel @greshake Is this something we want? Linking to C libraries? There's not yet a rust binding to nl80211 and I'm not sure I'ld want to maintain one. Additionally, we would need research a bit about how stable across kernels it is.
€: nl80211
what about dbus subscription, so changes are only pushed on change, not polled?
@jheyens We're not dying to maintain bindings, no. I'd strongly prefer going to the D-Bus route proposed by @sebastianst in the long term.
It would also be possible to resolve this specific issue by looking for \x
sequences and translating them to the appropriate UTF-8.
I'm going to close this in favour of #308, although if anyone wants to take on parsing \x
sequences with the existing code I will happily accept such a PR in the meantime.
I'm sometimes connected to a wireless network with emojis in its name. Those are not shown in the title, but their hex code, including
\x
. Like so\x0f0\x9f\x8d\x8d
. It would be great if i3status-rs would just forward unicode chars to i3bar. Thanks!