1
0
Fork 0
mirror of https://github.com/Zedfrigg/ironbar.git synced 2025-07-02 11:11:04 +02:00

feat(ipc): commands for opening/closing popups

Also includes some refactoring around related GTK helper code
This commit is contained in:
Jake Stanger 2023-07-16 18:57:00 +01:00
parent c582bc3390
commit b7ee794bfc
No known key found for this signature in database
GPG key ID: C51FC8F9CB0BEA61
30 changed files with 747 additions and 345 deletions

View file

@ -1,5 +1,35 @@
#![doc = include_str!("../README.md")]
use std::cell::{Cell, RefCell};
use std::env;
use std::future::Future;
use std::path::PathBuf;
use std::process::exit;
use std::rc::Rc;
use std::sync::mpsc;
use cfg_if::cfg_if;
#[cfg(feature = "cli")]
use clap::Parser;
use color_eyre::eyre::Result;
use color_eyre::Report;
use dirs::config_dir;
use gtk::gdk::Display;
use gtk::prelude::*;
use gtk::Application;
use tokio::runtime::Handle;
use tokio::task::{block_in_place, spawn_blocking};
use tracing::{debug, error, info, warn};
use universal_config::ConfigLoader;
use clients::wayland;
use crate::bar::create_bar;
use crate::config::{Config, MonitorConfig};
use crate::error::ExitCode;
use crate::global_state::GlobalState;
use crate::style::load_css;
mod bar;
mod bridge_channel;
#[cfg(feature = "cli")]
@ -9,6 +39,7 @@ mod config;
mod desktop_file;
mod dynamic_value;
mod error;
mod global_state;
mod gtk_helpers;
mod image;
#[cfg(feature = "ipc")]
@ -23,33 +54,6 @@ mod script;
mod style;
mod unique_id;
use crate::bar::create_bar;
use crate::config::{Config, MonitorConfig};
use crate::style::load_css;
use cfg_if::cfg_if;
#[cfg(feature = "cli")]
use clap::Parser;
use color_eyre::eyre::Result;
use color_eyre::Report;
use dirs::config_dir;
use gtk::gdk::Display;
use gtk::prelude::*;
use gtk::Application;
use std::cell::Cell;
use std::env;
use std::future::Future;
use std::path::PathBuf;
use std::process::exit;
use std::rc::Rc;
use std::sync::mpsc;
use tokio::runtime::Handle;
use tokio::task::{block_in_place, spawn_blocking};
use crate::error::ExitCode;
use clients::wayland;
use tracing::{debug, error, info, warn};
use universal_config::ConfigLoader;
const GTK_APP_ID: &str = "dev.jstanger.ironbar";
const VERSION: &str = env!("CARGO_PKG_VERSION");
@ -57,32 +61,34 @@ const VERSION: &str = env!("CARGO_PKG_VERSION");
async fn main() {
let _guard = logging::install_logging();
let global_state = Rc::new(RefCell::new(GlobalState::new()));
cfg_if! {
if #[cfg(feature = "cli")] {
run_with_args().await;
run_with_args(global_state).await;
} else {
start_ironbar();
start_ironbar(global_state);
}
}
}
#[cfg(feature = "cli")]
async fn run_with_args() {
async fn run_with_args(global_state: Rc<RefCell<GlobalState>>) {
let args = cli::Args::parse();
match args.command {
Some(command) => {
let ipc = ipc::Ipc::new();
let ipc = ipc::Ipc::new(global_state);
match ipc.send(command).await {
Ok(res) => cli::handle_response(res),
Err(err) => error!("{err:?}"),
};
}
None => start_ironbar(),
None => start_ironbar(global_state),
}
}
fn start_ironbar() {
fn start_ironbar(global_state: Rc<RefCell<GlobalState>>) {
info!("Ironbar version {}", VERSION);
info!("Starting application");
@ -101,12 +107,12 @@ fn start_ironbar() {
cfg_if! {
if #[cfg(feature = "ipc")] {
let ipc = ipc::Ipc::new();
let ipc = ipc::Ipc::new(global_state.clone());
ipc.start(app);
}
}
load_interface(app);
load_interface(app, &global_state);
let style_path = env::var("IRONBAR_CSS").ok().map_or_else(
|| {
@ -128,13 +134,15 @@ fn start_ironbar() {
let (tx, rx) = mpsc::channel();
#[cfg(feature = "ipc")]
let ipc_path = ipc.path().to_path_buf();
spawn_blocking(move || {
rx.recv().expect("to receive from channel");
info!("Shutting down");
#[cfg(feature = "ipc")]
ipc.shutdown();
ipc::Ipc::shutdown(ipc_path);
exit(0);
});
@ -149,7 +157,7 @@ fn start_ironbar() {
}
/// Loads the Ironbar config and interface.
pub fn load_interface(app: &Application) {
pub fn load_interface(app: &Application, global_state: &Rc<RefCell<GlobalState>>) {
let display = Display::default().map_or_else(
|| {
let report = Report::msg("Failed to get default GTK display");
@ -180,12 +188,12 @@ pub fn load_interface(app: &Application) {
let variable_manager = ironvar::get_variable_manager();
for (k, v) in ironvars {
if write_lock!(variable_manager).set(k.clone(), v).is_err() {
tracing::warn!("Ignoring invalid ironvar: '{k}'");
warn!("Ignoring invalid ironvar: '{k}'");
}
}
}
if let Err(err) = create_bars(app, &display, &config) {
if let Err(err) = create_bars(app, &display, &config, global_state) {
error!("{:?}", err);
exit(ExitCode::CreateBars as i32);
}
@ -194,7 +202,12 @@ pub fn load_interface(app: &Application) {
}
/// Creates each of the bars across each of the (configured) outputs.
fn create_bars(app: &Application, display: &Display, config: &Config) -> Result<()> {
fn create_bars(
app: &Application,
display: &Display,
config: &Config,
global_state: &Rc<RefCell<GlobalState>>,
) -> Result<()> {
let wl = wayland::get_client();
let outputs = lock!(wl).get_outputs();
@ -216,19 +229,19 @@ fn create_bars(app: &Application, display: &Display, config: &Config) -> Result<
config.monitors.as_ref().map_or_else(
|| {
info!("Creating bar on '{}'", monitor_name);
create_bar(app, &monitor, monitor_name, config.clone())
create_bar(app, &monitor, monitor_name, config.clone(), global_state)
},
|config| {
let config = config.get(monitor_name);
match &config {
Some(MonitorConfig::Single(config)) => {
info!("Creating bar on '{}'", monitor_name);
create_bar(app, &monitor, monitor_name, config.clone())
create_bar(app, &monitor, monitor_name, config.clone(), global_state)
}
Some(MonitorConfig::Multiple(configs)) => {
for config in configs {
info!("Creating bar on '{}'", monitor_name);
create_bar(app, &monitor, monitor_name, config.clone())?;
create_bar(app, &monitor, monitor_name, config.clone(), global_state)?;
}
Ok(())