fix(network): open a browser when connection is behind a captive portal

This commit is contained in:
Ashley Wulber 2023-12-12 15:39:44 -05:00 committed by Ashley Wulber
parent 17073628af
commit e6ec592cb0
2 changed files with 42 additions and 10 deletions

View file

@ -21,7 +21,9 @@ use cosmic::{
widget::{button, divider, icon}, widget::{button, divider, icon},
Element, Theme, Element, Theme,
}; };
use cosmic_dbus_networkmanager::interface::enums::{ActiveConnectionState, DeviceState}; use cosmic_dbus_networkmanager::interface::enums::{
ActiveConnectionState, DeviceState, NmConnectivityState,
};
use cosmic_time::{anim, chain, id, once_cell::sync::Lazy, Instant, Timeline}; use cosmic_time::{anim, chain, id, once_cell::sync::Lazy, Instant, Timeline};
use futures::channel::mpsc::UnboundedSender; use futures::channel::mpsc::UnboundedSender;
@ -306,6 +308,20 @@ impl cosmic::Application for CosmicNetworkApplet {
} }
} }
} }
if self.nm_state.connectivity != state.connectivity
&& !matches!(req, NetworkManagerRequest::Reload)
&& matches!(state.connectivity, NmConnectivityState::Portal)
{
// spawn browser
if let Err(err) = std::process::Command::new("xdg-open")
.arg("http://pop.system76.com")
.spawn()
{
log::error!("Failed to open browser: {}", err);
}
}
self.update_nm_state(state); self.update_nm_state(state);
} }
}, },

View file

@ -11,8 +11,8 @@ use cosmic_dbus_networkmanager::{
device::SpecificDevice, device::SpecificDevice,
interface::{ interface::{
active_connection::ActiveConnectionProxy, active_connection::ActiveConnectionProxy,
enums::DeviceType,
enums::{self, ActiveConnectionState}, enums::{self, ActiveConnectionState},
enums::{DeviceType, NmConnectivityState},
}, },
nm::NetworkManager, nm::NetworkManager,
settings::{connection::Settings, NetworkManagerSettings}, settings::{connection::Settings, NetworkManagerSettings},
@ -512,19 +512,33 @@ pub enum NetworkManagerEvent {
ActiveConns(NetworkManagerState), ActiveConns(NetworkManagerState),
} }
#[derive(Debug, Clone, Default)] #[derive(Debug, Clone)]
pub struct NetworkManagerState { pub struct NetworkManagerState {
pub wireless_access_points: Vec<AccessPoint>, pub wireless_access_points: Vec<AccessPoint>,
pub active_conns: Vec<ActiveConnectionInfo>, pub active_conns: Vec<ActiveConnectionInfo>,
pub known_access_points: Vec<AccessPoint>, pub known_access_points: Vec<AccessPoint>,
pub wifi_enabled: bool, pub wifi_enabled: bool,
pub airplane_mode: bool, pub airplane_mode: bool,
pub connectivity: NmConnectivityState,
}
impl Default for NetworkManagerState {
fn default() -> Self {
Self {
wireless_access_points: Vec::new(),
active_conns: Vec::new(),
known_access_points: Vec::new(),
wifi_enabled: false,
airplane_mode: false,
connectivity: NmConnectivityState::Unknown,
}
}
} }
impl NetworkManagerState { impl NetworkManagerState {
pub async fn new(conn: &Connection) -> anyhow::Result<Self> { pub async fn new(conn: &Connection) -> anyhow::Result<Self> {
let network_manager = NetworkManager::new(conn).await?; let network_manager = NetworkManager::new(conn).await?;
let mut _self = Self::default(); let mut self_ = Self::default();
// airplane mode // airplane mode
let airplaine_mode = Command::new("rfkill") let airplaine_mode = Command::new("rfkill")
.arg("list") .arg("list")
@ -532,8 +546,8 @@ impl NetworkManagerState {
.output() .output()
.await?; .await?;
let airplane_mode = std::str::from_utf8(&airplaine_mode.stdout).unwrap_or_default(); let airplane_mode = std::str::from_utf8(&airplaine_mode.stdout).unwrap_or_default();
_self.wifi_enabled = network_manager.wireless_enabled().await.unwrap_or_default(); self_.wifi_enabled = network_manager.wireless_enabled().await.unwrap_or_default();
_self.airplane_mode = airplane_mode.contains("Soft blocked: yes") && !_self.wifi_enabled; self_.airplane_mode = airplane_mode.contains("Soft blocked: yes") && !self_.wifi_enabled;
let s = NetworkManagerSettings::new(conn).await?; let s = NetworkManagerSettings::new(conn).await?;
_ = s.load_connections(&[]).await; _ = s.load_connections(&[]).await;
@ -595,10 +609,12 @@ impl NetworkManagerState {
.cloned() .cloned()
.collect(); .collect();
wireless_access_points.sort_by(|a, b| b.strength.cmp(&a.strength)); wireless_access_points.sort_by(|a, b| b.strength.cmp(&a.strength));
_self.wireless_access_points = wireless_access_points; self_.wireless_access_points = wireless_access_points;
_self.active_conns = active_conns; self_.active_conns = active_conns;
_self.known_access_points = known_access_points; self_.known_access_points = known_access_points;
Ok(_self) self_.connectivity = network_manager.connectivity().await?;
Ok(self_)
} }
#[allow(dead_code)] #[allow(dead_code)]