diff --git a/docs/Configuration guide.md b/docs/Configuration guide.md index 66e7ecd..3c7355d 100644 --- a/docs/Configuration guide.md +++ b/docs/Configuration guide.md @@ -267,22 +267,24 @@ Check [here](config) for an example config file for a fully configured bar in ea The following table lists each of the top-level bar config options: -| Name | Type | Default | Description | -|--------------------|----------------------------------------|-----------|-----------------------------------------------------------------------------------------------------------------| -| `name` | `string` | `bar-` | A unique identifier for the bar, used for controlling it over IPC. If not set, uses a generated integer suffix. | -| `position` | `top` or `bottom` or `left` or `right` | `bottom` | The bar's position on screen. | -| `anchor_to_edges` | `boolean` | `false` | Whether to anchor the bar to the edges of the screen. Setting to false centres the bar. | -| `height` | `integer` | `42` | The bar's height in pixels. | -| `popup_gap` | `integer` | `5` | The gap between the bar and popup window. | -| `margin.top` | `integer` | `0` | The margin on the top of the bar | -| `margin.bottom` | `integer` | `0` | The margin on the bottom of the bar | -| `margin.left` | `integer` | `0` | The margin on the left of the bar | -| `margin.right` | `integer` | `0` | The margin on the right of the bar | -| `icon_theme` | `string` | `null` | Name of the GTK icon theme to use. Leave blank to use default. | -| `ironvar_defaults` | `Map` | `{}` | Map of [ironvar](ironvars) keys against their default values. | -| `start` | `Module[]` | `[]` | Array of left or top modules. | -| `center` | `Module[]` | `[]` | Array of center modules. | -| `end` | `Module[]` | `[]` | Array of right or bottom modules. | +| Name | Type | Default | Description | +|--------------------|----------------------------------------|--------------------------------------|----------------------------------------------------------------------------------------------------------------------------| +| `name` | `string` | `bar-` | A unique identifier for the bar, used for controlling it over IPC. If not set, uses a generated integer suffix. | +| `position` | `top` or `bottom` or `left` or `right` | `bottom` | The bar's position on screen. | +| `anchor_to_edges` | `boolean` | `false` | Whether to anchor the bar to the edges of the screen. Setting to false centres the bar. | +| `height` | `integer` | `42` | The bar's height in pixels. | +| `popup_gap` | `integer` | `5` | The gap between the bar and popup window. | +| `margin.top` | `integer` | `0` | The margin on the top of the bar | +| `margin.bottom` | `integer` | `0` | The margin on the bottom of the bar | +| `margin.left` | `integer` | `0` | The margin on the left of the bar | +| `margin.right` | `integer` | `0` | The margin on the right of the bar | +| `icon_theme` | `string` | `null` | Name of the GTK icon theme to use. Leave blank to use default. | +| `ironvar_defaults` | `Map` | `{}` | Map of [ironvar](ironvars) keys against their default values. | +| `start_hidden` | `boolean` | `false`, or `true` if `autohide` set | Whether the bar should be hidden when the application starts. Enabled by default when `autohide` is set. | +| `autohide` | `integer` | `null` | The duration in milliseconds before the bar is hidden after the cursor leaves. Leave unset to disable auto-hide behaviour. | +| `start` | `Module[]` | `[]` | Array of left or top modules. | +| `center` | `Module[]` | `[]` | Array of center modules. | +| `end` | `Module[]` | `[]` | Array of right or bottom modules. | ### 3.2 Module-level options diff --git a/src/bar.rs b/src/bar.rs index 57cd3f9..67a2910 100644 --- a/src/bar.rs +++ b/src/bar.rs @@ -7,9 +7,10 @@ use crate::{Config, Ironbar}; use color_eyre::Result; use gtk::gdk::Monitor; use gtk::prelude::*; -use gtk::{Application, ApplicationWindow, IconTheme, Orientation}; +use gtk::{Application, ApplicationWindow, IconTheme, Orientation, Window, WindowType}; use std::cell::RefCell; use std::rc::Rc; +use std::time::Duration; use tracing::{debug, info}; #[derive(Debug, Clone)] @@ -37,7 +38,11 @@ pub struct Bar { impl Bar { pub fn new(app: &Application, monitor_name: String, config: Config) -> Self { - let window = ApplicationWindow::builder().application(app).build(); + let window = ApplicationWindow::builder() + .application(app) + .type_(WindowType::Toplevel) + .build(); + let name = config .name .clone() @@ -108,11 +113,36 @@ impl Bar { self.name, self.monitor_name ); - self.setup_layer_shell(config.anchor_to_edges, config.margin, monitor); + self.setup_layer_shell( + &self.window, + true, + config.anchor_to_edges, + config.margin, + monitor, + ); + + let start_hidden = config.start_hidden.unwrap_or(config.autohide.is_some()); + + if let Some(autohide) = config.autohide { + let hotspot_window = Window::new(WindowType::Toplevel); + + Self::setup_autohide(&self.window, &hotspot_window, autohide); + self.setup_layer_shell( + &hotspot_window, + false, + config.anchor_to_edges, + config.margin, + monitor, + ); + + if start_hidden { + hotspot_window.show(); + } + } let load_result = self.load_modules(config, monitor)?; - self.show(); + self.show(!start_hidden); self.inner = Inner::Loaded { popup: load_result.popup, @@ -121,16 +151,25 @@ impl Bar { } /// Sets up GTK layer shell for a provided application window. - fn setup_layer_shell(&self, anchor_to_edges: bool, margin: MarginConfig, monitor: &Monitor) { - let win = &self.window; + fn setup_layer_shell( + &self, + win: &impl IsA, + exclusive_zone: bool, + anchor_to_edges: bool, + margin: MarginConfig, + monitor: &Monitor, + ) { let position = self.position; gtk_layer_shell::init_for_window(win); gtk_layer_shell::set_monitor(win, monitor); gtk_layer_shell::set_layer(win, gtk_layer_shell::Layer::Top); - gtk_layer_shell::auto_exclusive_zone_enable(win); gtk_layer_shell::set_namespace(win, env!("CARGO_PKG_NAME")); + if exclusive_zone { + gtk_layer_shell::auto_exclusive_zone_enable(win); + } + gtk_layer_shell::set_margin(win, gtk_layer_shell::Edge::Top, margin.top); gtk_layer_shell::set_margin(win, gtk_layer_shell::Edge::Bottom, margin.bottom); gtk_layer_shell::set_margin(win, gtk_layer_shell::Edge::Left, margin.left); @@ -164,6 +203,40 @@ impl Bar { ); } + fn setup_autohide(window: &ApplicationWindow, hotspot_window: &Window, timeout: u64) { + hotspot_window.hide(); + + hotspot_window.set_opacity(0.0); + hotspot_window.set_decorated(false); + hotspot_window.set_size_request(0, 1); + + { + let hotspot_window = hotspot_window.clone(); + + window.connect_leave_notify_event(move |win, _| { + let win = win.clone(); + let hotspot_window = hotspot_window.clone(); + + glib::timeout_add_local_once(Duration::from_millis(timeout), move || { + win.hide(); + hotspot_window.show(); + }); + Inhibit(false) + }); + } + + { + let win = window.clone(); + + hotspot_window.connect_enter_notify_event(move |hotspot_win, _| { + hotspot_win.hide(); + win.show(); + + Inhibit(false) + }); + } + } + /// Loads the configured modules onto a bar. fn load_modules(&self, config: Config, monitor: &Monitor) -> Result { let icon_theme = IconTheme::new(); @@ -210,7 +283,7 @@ impl Bar { Ok(result) } - fn show(&self) { + fn show(&self, include_window: bool) { debug!("Showing bar: {}", self.name); // show each box but do not use `show_all`. @@ -219,7 +292,10 @@ impl Bar { self.center.show(); self.end.show(); self.content.show(); - self.window.show(); + + if include_window { + self.window.show(); + } } pub fn name(&self) -> &str { diff --git a/src/config/mod.rs b/src/config/mod.rs index cfb0485..357fb2c 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -99,6 +99,11 @@ pub struct Config { pub popup_gap: i32, pub name: Option, + #[serde(default)] + pub start_hidden: Option, + #[serde(default)] + pub autohide: Option, + /// GTK icon theme to use. pub icon_theme: Option, @@ -127,6 +132,8 @@ impl Default for Config { height: default_bar_height(), margin: MarginConfig::default(), name: None, + start_hidden: None, + autohide: None, popup_gap: default_popup_gap(), icon_theme: None, ironvar_defaults: None, diff --git a/src/main.rs b/src/main.rs index 5d3747d..83b6771 100644 --- a/src/main.rs +++ b/src/main.rs @@ -21,7 +21,6 @@ use glib::PropertySet; use gtk::gdk::Display; use gtk::prelude::*; use gtk::Application; -use lazy_static::lazy_static; use tokio::runtime::Handle; use tokio::task::{block_in_place, spawn_blocking}; use tracing::{debug, error, info, warn}; @@ -93,7 +92,7 @@ async fn run_with_args() { static COUNTER: AtomicUsize = AtomicUsize::new(1); #[cfg(feature = "ipc")] -lazy_static! { +lazy_static::lazy_static! { static ref VARIABLE_MANAGER: Arc> = arc_rw!(VariableManager::new()); }