I3status-rust: net: support switching between ethernet and wireless

Created on 22 Oct 2020  路  14Comments  路  Source: greshake/i3status-rust

This block works fine for my wireless device:

[[block]]
block = "net"
device = "wlan0"
speed_up = true
interval = 2

However, when I connect ethernet and disable wifi, as expected the block then does nothing. It would be nice to instead see the traffic for the wired device, in my case ens8u2.

Here are two ideas to potentially solve this:

1) Default to using the device for the first default route in ip route; most setups will only have one such device. If the wrong one is detected, the user can always specify one via device = "...".

2) Allow using a list of fallback devices, where the first one with non-zero traffic is used. In my case, I could use something like devices = ["wlan0", "ens8u2"].

Both options would require extra work, but I see no alternative if we want to automatically switch over between two devices.

discussion

Most helpful comment

Interesting. The blurb for #102 says

Automatic hiding of graphs/throughput info for inactive networks (which can be turned off with hide_inactive = false)

so that was initially only intended to hide the graph, not the block. But judging by the code it appears to have hidden the entire block anyway:

https://github.com/greshake/i3status-rust/blob/8978ee6a7375deef8cec99237fb4e3c2b8587576/src/blocks/net.rs#L397-L401

PR #344 then was probably the culprit: This code looks like it was intended to be hide_missing OR hide_hidden, but because both are inverted it's actually a hide_missing AND hide_hidden for the else clause:

https://github.com/greshake/i3status-rust/blob/2bb498fba6e4cae9a2aa7b5b6856f27999d96167/src/blocks/net.rs#L512-L516

And that being said, both seem to only be used if self.active == false so i don't know why the second one was needed in the first place?

Edit: #344 actually adds another check (whether the device exists) but it does not differentiate between the 2 cases, both nonexistent and inactive devices are set as self.active = false and therefore can't be displayed in 2 different ways.

So the solution would be to add a self.missing flag to differentiate between those. I should be doing something else right now but i'll give it a go

All 14 comments

How about defining two blocks in your config and using allow_missing and hide_missing?

I thought about that, but that takes up more space. Right now, the "empty" wlan0 net block contains two icons: the wireless signal icon, and an "x" presumably to say that the device isn't enabled.

Perhaps option 3 is to make the block be omitted when the input (device) is disabled.

IIRC isn't that what hide_missing does? (hiding the block when the device can't be found)

Perhaps. I have to admit that the docs don't clarify the difference between missing and inactive, and the code in net.rs seems to use both in the same way as far as I can see.

I tried both, and I still see the wlan0 widget:

$ grep -C3 wlan0 .config/i3status-rust/config.toml 

[[block]]
block = "net"
device = "wlan0"
speed_up = true
interval = 2
hide_inactive = true
$ ip l | grep wlan0
4: wlan0: <BROADCAST,MULTICAST> mtu 1500 qdisc noqueue state DOWN mode DORMANT group default qlen 1000

I completely reloaded sway after changing the config each time, so that fully restarts i3status-rust. I did add the wired net block, which now shows up.

If this worked I'd be fine with it :)

I actually use both hide_missing = true + hide_inactive = true on each interface for your exact purpose, only showing those interfaces that i'm connected to.

Only issue is with alternating color schemes (see #349) but that's less important

@mvdan You need both hide_inactive and hide_missing in your config for it to hide the block

Oh, that's not what I gathered from https://github.com/greshake/i3status-rust/blob/master/blocks.md#net then. Why would they be separate options, if they appear to do nothing on their own?

It's true, i found this confusing as well. IMO it should mean:

missing implies that the interface has been disabled entirely. Think a VPN that is not running.

inactive implies that the interface is available, but not connected. Think wifi not found / ethernet not connected.

But in reality it seems neither work on their own - both my disabled and my disconnected interfaces are only hidden when both options are true. Is this a bug @ammgws?

We should at least clarify this in the docs

Can't look into it atm but they were added by the PRs in the order below. Perhaps reading through the discussions may shed some light on the intended behaviour if the code itself isn't clear enough:

This PR added hide_inactive: https://github.com/greshake/i3status-rust/pull/102

This PR added hide_missing: https://github.com/greshake/i3status-rust/pull/344

This one added documentation for hide_missing and hide_inactive: https://github.com/greshake/i3status-rust/pull/476

Interesting. The blurb for #102 says

Automatic hiding of graphs/throughput info for inactive networks (which can be turned off with hide_inactive = false)

so that was initially only intended to hide the graph, not the block. But judging by the code it appears to have hidden the entire block anyway:

https://github.com/greshake/i3status-rust/blob/8978ee6a7375deef8cec99237fb4e3c2b8587576/src/blocks/net.rs#L397-L401

PR #344 then was probably the culprit: This code looks like it was intended to be hide_missing OR hide_hidden, but because both are inverted it's actually a hide_missing AND hide_hidden for the else clause:

https://github.com/greshake/i3status-rust/blob/2bb498fba6e4cae9a2aa7b5b6856f27999d96167/src/blocks/net.rs#L512-L516

And that being said, both seem to only be used if self.active == false so i don't know why the second one was needed in the first place?

Edit: #344 actually adds another check (whether the device exists) but it does not differentiate between the 2 cases, both nonexistent and inactive devices are set as self.active = false and therefore can't be displayed in 2 different ways.

So the solution would be to add a self.missing flag to differentiate between those. I should be doing something else right now but i'll give it a go

Looks like that first one should have been

if self.active {
...
 } else if self.hide_inactive { 
     vec![&self.network] 
 } else { 
     vec![] 
 } 

in order for it to only show the basic info widget and not the graph widgets.

Although now those widgets have been replaced by the format string..

hide_inactive_graphs would have been a better name

No the first one was correct i think. I'm currently debugging and will make a PR right after

Alright it's in #897, feel free to have a look

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ellsclytn picture ellsclytn  路  6Comments

boi4 picture boi4  路  3Comments

greshake picture greshake  路  6Comments

Nukesor picture Nukesor  路  5Comments

Thra11 picture Thra11  路  6Comments