mirror of
				https://github.com/Zedfrigg/ironbar.git
				synced 2025-11-03 23:11:54 +01:00 
			
		
		
		
	fix: only update relevant parts of state upon property change
This commit is contained in:
		
					parent
					
						
							
								d56f76f6a8
							
						
					
				
			
			
				commit
				
					
						465d16800a
					
				
			
		
					 1 changed files with 117 additions and 105 deletions
				
			
		| 
						 | 
					@ -35,7 +35,32 @@ struct ClientInner<'l> {
 | 
				
			||||||
    dbus_connection: Connection,
 | 
					    dbus_connection: Connection,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
macro_rules! initialise_path_map {
 | 
					impl Client {
 | 
				
			||||||
 | 
					    fn new() -> Result<Client> {
 | 
				
			||||||
 | 
					        let state = Mutable::new(State {
 | 
				
			||||||
 | 
					            wired: WiredState::Unknown,
 | 
				
			||||||
 | 
					            wifi: WifiState::Unknown,
 | 
				
			||||||
 | 
					            cellular: CellularState::Unknown,
 | 
				
			||||||
 | 
					            vpn: VpnState::Unknown,
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					        let dbus_connection = Connection::system()?;
 | 
				
			||||||
 | 
					        let root_object = {
 | 
				
			||||||
 | 
					            let root_object = DbusProxyBlocking::new(&dbus_connection)?;
 | 
				
			||||||
 | 
					            // Workaround for the fact that zbus (unnecessarily) requires a static lifetime here
 | 
				
			||||||
 | 
					            Box::leak(Box::new(root_object))
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Ok(Client(Arc::new(ClientInner {
 | 
				
			||||||
 | 
					            state,
 | 
				
			||||||
 | 
					            root_object,
 | 
				
			||||||
 | 
					            active_connections: RwLock::new(HashMap::new()),
 | 
				
			||||||
 | 
					            devices: RwLock::new(HashMap::new()),
 | 
				
			||||||
 | 
					            dbus_connection,
 | 
				
			||||||
 | 
					        })))
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fn run(&self) -> Result<()> {
 | 
				
			||||||
 | 
					        macro_rules! initialise_path_map {
 | 
				
			||||||
            (
 | 
					            (
 | 
				
			||||||
                $client:expr,
 | 
					                $client:expr,
 | 
				
			||||||
                $path_map:ident,
 | 
					                $path_map:ident,
 | 
				
			||||||
| 
						 | 
					@ -56,9 +81,9 @@ macro_rules! initialise_path_map {
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                *write_lock!($client.$path_map) = path_map;
 | 
					                *write_lock!($client.$path_map) = path_map;
 | 
				
			||||||
            };
 | 
					            };
 | 
				
			||||||
}
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
macro_rules! spawn_path_list_watcher {
 | 
					        macro_rules! spawn_path_list_watcher {
 | 
				
			||||||
            (
 | 
					            (
 | 
				
			||||||
                $client:expr,
 | 
					                $client:expr,
 | 
				
			||||||
                $property:ident,
 | 
					                $property:ident,
 | 
				
			||||||
| 
						 | 
					@ -105,14 +130,15 @@ macro_rules! spawn_path_list_watcher {
 | 
				
			||||||
                    Ok(())
 | 
					                    Ok(())
 | 
				
			||||||
                });
 | 
					                });
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
}
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
macro_rules! spawn_property_watcher {
 | 
					        macro_rules! spawn_property_watcher {
 | 
				
			||||||
            (
 | 
					            (
 | 
				
			||||||
                $client:expr,
 | 
					                $client:expr,
 | 
				
			||||||
                $path:expr,
 | 
					                $path:expr,
 | 
				
			||||||
                $property_changes:ident,
 | 
					                $property_changes:ident,
 | 
				
			||||||
        $containing_list:ident
 | 
					                $containing_list:ident,
 | 
				
			||||||
 | 
					                |$inner_client:ident| $state_update:expr
 | 
				
			||||||
            ) => {
 | 
					            ) => {
 | 
				
			||||||
                let client = $client.clone();
 | 
					                let client = $client.clone();
 | 
				
			||||||
                let path = $path.clone();
 | 
					                let path = $path.clone();
 | 
				
			||||||
| 
						 | 
					@ -125,51 +151,30 @@ macro_rules! spawn_property_watcher {
 | 
				
			||||||
                        if !read_lock!(client.$containing_list).contains_key(&path) {
 | 
					                        if !read_lock!(client.$containing_list).contains_key(&path) {
 | 
				
			||||||
                            break;
 | 
					                            break;
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                client.state.set(State {
 | 
					                        {
 | 
				
			||||||
                    // TODO: Investigate if there's a sane way to do only the relevant updates
 | 
					                            let $inner_client = &client;
 | 
				
			||||||
                    wired: determine_wired_state(&read_lock!(client.devices))?,
 | 
					                            $state_update;
 | 
				
			||||||
                    wifi: determine_wifi_state(&read_lock!(client.devices))?,
 | 
					                        }
 | 
				
			||||||
                    cellular: determine_cellular_state(&read_lock!(client.devices))?,
 | 
					 | 
				
			||||||
                    vpn: determine_vpn_state(&read_lock!(client.active_connections))?,
 | 
					 | 
				
			||||||
                });
 | 
					 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    Ok(())
 | 
					                    Ok(())
 | 
				
			||||||
                });
 | 
					                });
 | 
				
			||||||
            };
 | 
					            };
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl Client {
 | 
					 | 
				
			||||||
    fn new() -> Result<Client> {
 | 
					 | 
				
			||||||
        let state = Mutable::new(State {
 | 
					 | 
				
			||||||
            wired: WiredState::Unknown,
 | 
					 | 
				
			||||||
            wifi: WifiState::Unknown,
 | 
					 | 
				
			||||||
            cellular: CellularState::Unknown,
 | 
					 | 
				
			||||||
            vpn: VpnState::Unknown,
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
        let dbus_connection = Connection::system()?;
 | 
					 | 
				
			||||||
        let root_object = {
 | 
					 | 
				
			||||||
            let root_object = DbusProxyBlocking::new(&dbus_connection)?;
 | 
					 | 
				
			||||||
            // Workaround for the fact that zbus (unnecessarily) requires a static lifetime here
 | 
					 | 
				
			||||||
            Box::leak(Box::new(root_object))
 | 
					 | 
				
			||||||
        };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        Ok(Client(Arc::new(ClientInner {
 | 
					 | 
				
			||||||
            state,
 | 
					 | 
				
			||||||
            root_object,
 | 
					 | 
				
			||||||
            active_connections: RwLock::new(HashMap::new()),
 | 
					 | 
				
			||||||
            devices: RwLock::new(HashMap::new()),
 | 
					 | 
				
			||||||
            dbus_connection,
 | 
					 | 
				
			||||||
        })))
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn run(&self) -> Result<()> {
 | 
					 | 
				
			||||||
        initialise_path_map!(
 | 
					        initialise_path_map!(
 | 
				
			||||||
            self.0,
 | 
					            self.0,
 | 
				
			||||||
            active_connections,
 | 
					            active_connections,
 | 
				
			||||||
            ActiveConnectionDbusProxyBlocking
 | 
					            ActiveConnectionDbusProxyBlocking
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
        initialise_path_map!(self.0, devices, DeviceDbusProxyBlocking, |path| {
 | 
					        initialise_path_map!(self.0, devices, DeviceDbusProxyBlocking, |path| {
 | 
				
			||||||
            spawn_property_watcher!(self.0, path, receive_state_changed, devices);
 | 
					            spawn_property_watcher!(self.0, path, receive_state_changed, devices, |client| {
 | 
				
			||||||
 | 
					                client.state.set(State {
 | 
				
			||||||
 | 
					                    wired: determine_wired_state(&read_lock!(client.devices))?,
 | 
				
			||||||
 | 
					                    wifi: determine_wifi_state(&read_lock!(client.devices))?,
 | 
				
			||||||
 | 
					                    cellular: determine_cellular_state(&read_lock!(client.devices))?,
 | 
				
			||||||
 | 
					                    vpn: client.state.get_cloned().vpn,
 | 
				
			||||||
 | 
					                });
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
        self.0.state.set(State {
 | 
					        self.0.state.set(State {
 | 
				
			||||||
            wired: determine_wired_state(&read_lock!(self.0.devices))?,
 | 
					            wired: determine_wired_state(&read_lock!(self.0.devices))?,
 | 
				
			||||||
| 
						 | 
					@ -190,7 +195,14 @@ impl Client {
 | 
				
			||||||
            receive_devices_changed,
 | 
					            receive_devices_changed,
 | 
				
			||||||
            DeviceDbusProxyBlocking,
 | 
					            DeviceDbusProxyBlocking,
 | 
				
			||||||
            |client, path| {
 | 
					            |client, path| {
 | 
				
			||||||
                spawn_property_watcher!(client, path, receive_state_changed, devices);
 | 
					                spawn_property_watcher!(client, path, receive_state_changed, devices, |client| {
 | 
				
			||||||
 | 
					                    client.state.set(State {
 | 
				
			||||||
 | 
					                        wired: determine_wired_state(&read_lock!(client.devices))?,
 | 
				
			||||||
 | 
					                        wifi: determine_wifi_state(&read_lock!(client.devices))?,
 | 
				
			||||||
 | 
					                        cellular: determine_cellular_state(&read_lock!(client.devices))?,
 | 
				
			||||||
 | 
					                        vpn: client.state.get_cloned().vpn,
 | 
				
			||||||
 | 
					                    });
 | 
				
			||||||
 | 
					                });
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue