mirror of
				https://github.com/Zedfrigg/ironbar.git
				synced 2025-10-30 21:21:55 +01:00 
			
		
		
		
	feat: logging support and proper error handling
This commit is contained in:
		
					parent
					
						
							
								917838c98c
							
						
					
				
			
			
				commit
				
					
						ab8f7ecfc8
					
				
			
		
					 28 changed files with 1056 additions and 388 deletions
				
			
		
							
								
								
									
										153
									
								
								src/main.rs
									
										
									
									
									
								
							
							
						
						
									
										153
									
								
								src/main.rs
									
										
									
									
									
								
							|  | @ -2,6 +2,7 @@ mod bar; | |||
| mod collection; | ||||
| mod config; | ||||
| mod icon; | ||||
| mod logging; | ||||
| mod modules; | ||||
| mod popup; | ||||
| mod style; | ||||
|  | @ -10,74 +11,128 @@ mod sway; | |||
| use crate::bar::create_bar; | ||||
| use crate::config::{Config, MonitorConfig}; | ||||
| use crate::style::load_css; | ||||
| use crate::sway::SwayOutput; | ||||
| use crate::sway::{get_client_error, SwayOutput}; | ||||
| use color_eyre::eyre::Result; | ||||
| use color_eyre::Report; | ||||
| use dirs::config_dir; | ||||
| use gtk::gdk::Display; | ||||
| use gtk::prelude::*; | ||||
| use gtk::{gdk, Application}; | ||||
| use gtk::Application; | ||||
| use ksway::client::Client; | ||||
| use ksway::IpcCommand; | ||||
| use std::env; | ||||
| use std::process::exit; | ||||
| 
 | ||||
| use crate::logging::install_tracing; | ||||
| use tracing::{debug, error, info}; | ||||
| 
 | ||||
| const VERSION: &str = env!("CARGO_PKG_VERSION"); | ||||
| 
 | ||||
| #[tokio::main] | ||||
| async fn main() { | ||||
| async fn main() -> Result<()> { | ||||
|     // Disable backtraces by default
 | ||||
|     if env::var("RUST_LIB_BACKTRACE").is_err() { | ||||
|         env::set_var("RUST_LIB_BACKTRACE", "0"); | ||||
|     } | ||||
| 
 | ||||
|     // keep guard in scope
 | ||||
|     // otherwise file logging drops
 | ||||
|     let _guard = install_tracing()?; | ||||
| 
 | ||||
|     color_eyre::install()?; | ||||
| 
 | ||||
|     info!("Ironbar version {}", VERSION); | ||||
|     info!("Starting application"); | ||||
| 
 | ||||
|     let app = Application::builder() | ||||
|         .application_id("dev.jstanger.waylandbar") | ||||
|         .application_id("dev.jstanger.ironbar") | ||||
|         .build(); | ||||
| 
 | ||||
|     let mut sway_client = Client::connect().expect("Failed to connect to Sway IPC"); | ||||
|     let outputs = sway_client | ||||
|         .ipc(IpcCommand::GetOutputs) | ||||
|         .expect("Failed to get Sway outputs"); | ||||
|     let outputs = serde_json::from_slice::<Vec<SwayOutput>>(&outputs) | ||||
|         .expect("Failed to deserialize outputs message from Sway IPC"); | ||||
| 
 | ||||
|     app.connect_activate(move |app| { | ||||
|         let config = Config::load().unwrap_or_default(); | ||||
|         let display = match Display::default() { | ||||
|             Some(display) => display, | ||||
|             None => { | ||||
|                 let report = Report::msg("Failed to get default GTK display"); | ||||
|                 error!("{:?}", report); | ||||
|                 exit(1) | ||||
|             } | ||||
|         }; | ||||
| 
 | ||||
|         // TODO: Better logging (https://crates.io/crates/tracing)
 | ||||
|         // TODO: error handling (https://crates.io/crates/color-eyre)
 | ||||
|         let config = match Config::load() { | ||||
|             Ok(config) => config, | ||||
|             Err(err) => { | ||||
|                 error!("{:?}", err); | ||||
|                 Config::default() | ||||
|             } | ||||
|         }; | ||||
|         debug!("Loaded config file"); | ||||
| 
 | ||||
|         // TODO: Embedded Deno/lua - build custom modules via script???
 | ||||
| 
 | ||||
|         let display = gdk::Display::default().expect("Failed to get default GDK display"); | ||||
|         let num_monitors = display.n_monitors(); | ||||
| 
 | ||||
|         for i in 0..num_monitors { | ||||
|             let monitor = display.monitor(i).unwrap(); | ||||
|             let monitor_name = &outputs | ||||
|                 .get(i as usize) | ||||
|                 .expect("GTK monitor output differs from Sway's") | ||||
|                 .name; | ||||
| 
 | ||||
|             config.monitors.as_ref().map_or_else( | ||||
|                 || { | ||||
|                     create_bar(app, &monitor, monitor_name, config.clone()); | ||||
|                 }, | ||||
|                 |config| { | ||||
|                     let config = config.get(monitor_name); | ||||
|                     match &config { | ||||
|                         Some(MonitorConfig::Single(config)) => { | ||||
|                             create_bar(app, &monitor, monitor_name, config.clone()); | ||||
|                         } | ||||
|                         Some(MonitorConfig::Multiple(configs)) => { | ||||
|                             for config in configs { | ||||
|                                 create_bar(app, &monitor, monitor_name, config.clone()); | ||||
|                             } | ||||
|                         } | ||||
|                         _ => {} | ||||
|                     } | ||||
|                 }, | ||||
|             ) | ||||
|         if let Err(err) = create_bars(app, &display, &config) { | ||||
|             error!("{:?}", err); | ||||
|             exit(2); | ||||
|         } | ||||
| 
 | ||||
|         let style_path = config_dir() | ||||
|             .expect("Failed to locate user config dir") | ||||
|             .join("ironbar") | ||||
|             .join("style.css"); | ||||
|         debug!("Created bars"); | ||||
| 
 | ||||
|         let style_path = match config_dir() { | ||||
|             Some(dir) => dir.join("ironbar").join("style.css"), | ||||
|             None => { | ||||
|                 let report = Report::msg("Failed to locate user config dir"); | ||||
|                 error!("{:?}", report); | ||||
|                 exit(3); | ||||
|             } | ||||
|         }; | ||||
| 
 | ||||
|         if style_path.exists() { | ||||
|             load_css(style_path); | ||||
|             debug!("Loaded CSS watcher file"); | ||||
|         } | ||||
|     }); | ||||
| 
 | ||||
|     app.run(); | ||||
| 
 | ||||
|     Ok(()) | ||||
| } | ||||
| 
 | ||||
| fn create_bars(app: &Application, display: &Display, config: &Config) -> Result<()> { | ||||
|     let mut sway_client = match Client::connect() { | ||||
|         Ok(client) => Ok(client), | ||||
|         Err(err) => Err(get_client_error(err)), | ||||
|     }?; | ||||
| 
 | ||||
|     let outputs = match sway_client.ipc(IpcCommand::GetOutputs) { | ||||
|         Ok(outputs) => Ok(outputs), | ||||
|         Err(err) => Err(get_client_error(err)), | ||||
|     }?; | ||||
| 
 | ||||
|     let outputs = serde_json::from_slice::<Vec<SwayOutput>>(&outputs)?; | ||||
| 
 | ||||
|     let num_monitors = display.n_monitors(); | ||||
| 
 | ||||
|     for i in 0..num_monitors { | ||||
|         let monitor = display.monitor(i).ok_or_else(|| Report::msg("GTK and Sway are reporting a different number of outputs - this is a severe bug and should never happen"))?; | ||||
|         let monitor_name = &outputs.get(i as usize).ok_or_else(|| Report::msg("GTK and Sway are reporting a different set of outputs - this is a severe bug and should never happen"))?.name; | ||||
| 
 | ||||
|         config.monitors.as_ref().map_or_else( | ||||
|             || create_bar(app, &monitor, monitor_name, config.clone()), | ||||
|             |config| { | ||||
|                 let config = config.get(monitor_name); | ||||
|                 match &config { | ||||
|                     Some(MonitorConfig::Single(config)) => { | ||||
|                         create_bar(app, &monitor, monitor_name, config.clone()) | ||||
|                     } | ||||
|                     Some(MonitorConfig::Multiple(configs)) => { | ||||
|                         for config in configs { | ||||
|                             create_bar(app, &monitor, monitor_name, config.clone())?; | ||||
|                         } | ||||
| 
 | ||||
|                         Ok(()) | ||||
|                     } | ||||
|                     _ => Ok(()), | ||||
|                 } | ||||
|             }, | ||||
|         )?; | ||||
|     } | ||||
| 
 | ||||
|     Ok(()) | ||||
| } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue