2022-08-14 14:30:13 +01:00
mod bar ;
mod collection ;
mod config ;
2022-08-14 20:40:11 +01:00
mod icon ;
2022-08-21 23:36:07 +01:00
mod logging ;
2022-08-14 14:30:13 +01:00
mod modules ;
mod popup ;
mod style ;
2022-08-14 20:40:11 +01:00
mod sway ;
2022-08-14 14:30:13 +01:00
use crate ::bar ::create_bar ;
2022-08-15 17:06:42 +01:00
use crate ::config ::{ Config , MonitorConfig } ;
2022-08-14 14:30:13 +01:00
use crate ::style ::load_css ;
2022-08-25 21:53:42 +01:00
use crate ::sway ::{ get_client , SwayOutput } ;
2022-08-21 23:36:07 +01:00
use color_eyre ::eyre ::Result ;
use color_eyre ::Report ;
2022-08-14 14:30:13 +01:00
use dirs ::config_dir ;
2022-08-21 23:36:07 +01:00
use gtk ::gdk ::Display ;
2022-08-14 14:30:13 +01:00
use gtk ::prelude ::* ;
2022-08-21 23:36:07 +01:00
use gtk ::Application ;
2022-08-14 16:23:41 +01:00
use ksway ::IpcCommand ;
2022-08-21 23:36:07 +01:00
use std ::env ;
use std ::process ::exit ;
use crate ::logging ::install_tracing ;
use tracing ::{ debug , error , info } ;
const VERSION : & str = env! ( " CARGO_PKG_VERSION " ) ;
2022-08-14 14:30:13 +01:00
#[ tokio::main ]
2022-08-21 23:36:07 +01:00
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 " ) ;
2022-08-14 14:30:13 +01:00
let app = Application ::builder ( )
2022-08-21 23:36:07 +01:00
. application_id ( " dev.jstanger.ironbar " )
2022-08-14 14:30:13 +01:00
. build ( ) ;
2022-08-14 16:23:41 +01:00
app . connect_activate ( move | app | {
2022-08-21 23:36:07 +01:00
let display = match Display ::default ( ) {
Some ( display ) = > display ,
None = > {
let report = Report ::msg ( " Failed to get default GTK display " ) ;
error! ( " {:?} " , report ) ;
exit ( 1 )
}
} ;
let config = match Config ::load ( ) {
Ok ( config ) = > config ,
Err ( err ) = > {
error! ( " {:?} " , err ) ;
Config ::default ( )
}
} ;
debug! ( " Loaded config file " ) ;
if let Err ( err ) = create_bars ( app , & display , & config ) {
error! ( " {:?} " , err ) ;
exit ( 2 ) ;
2022-08-14 14:30:13 +01:00
}
2022-08-21 23:36:07 +01:00
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 ) ;
}
} ;
2022-08-14 14:30:13 +01:00
if style_path . exists ( ) {
load_css ( style_path ) ;
2022-08-21 23:36:07 +01:00
debug! ( " Loaded CSS watcher file " ) ;
2022-08-14 14:30:13 +01:00
}
} ) ;
2022-08-22 23:08:41 +01:00
// Ignore CLI args
// Some are provided by swaybar_config but not currently supported
app . run_with_args ( & Vec ::< & str > ::new ( ) ) ;
2022-08-21 23:36:07 +01:00
Ok ( ( ) )
}
fn create_bars ( app : & Application , display : & Display , config : & Config ) -> Result < ( ) > {
2022-08-25 21:53:42 +01:00
let outputs = {
let sway = get_client ( ) ;
let mut sway = sway . lock ( ) . expect ( " Failed to get lock on Sway IPC client " ) ;
let outputs = sway . ipc ( IpcCommand ::GetOutputs ) ;
2022-08-21 23:36:07 +01:00
2022-08-25 21:53:42 +01:00
match outputs {
Ok ( outputs ) = > Ok ( outputs ) ,
Err ( err ) = > Err ( err ) ,
}
2022-08-21 23:36:07 +01:00
} ? ;
let outputs = serde_json ::from_slice ::< Vec < SwayOutput > > ( & outputs ) ? ;
2022-08-25 21:53:57 +01:00
debug! ( " Received {} outputs from Sway IPC " , outputs . len ( ) ) ;
2022-08-21 23:36:07 +01:00
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 ;
2022-08-25 21:53:57 +01:00
info! ( " Creating bar on '{}' " , monitor_name ) ;
2022-08-21 23:36:07 +01:00
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 ( ( ) )
2022-08-14 14:30:13 +01:00
}