diff --git a/Cargo.lock b/Cargo.lock index f0d52ae..56ae9a1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -456,9 +456,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.4" +version = "4.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bc066a67923782aa8515dbaea16946c5bcc5addbd668bb80af688e53e548a0" +checksum = "5db83dced34638ad474f39f250d7fea9598bdd239eaced1bdf45d597da0f433f" dependencies = [ "clap_builder", "clap_derive", @@ -466,9 +466,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.2" +version = "4.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4" +checksum = "f7e204572485eb3fbf28f871612191521df159bc3e15a9f5064c66dba3a8c05f" dependencies = [ "anstream", "anstyle", @@ -478,9 +478,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.4" +version = "4.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "528131438037fd55894f62d6e9f068b8f45ac57ffa77517819645d10aed04f64" +checksum = "c780290ccf4fb26629baa7a1081e68ced113f1d3ec302fa5948f1c381ebf06c6" dependencies = [ "heck 0.5.0", "proc-macro2", @@ -897,9 +897,9 @@ checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" [[package]] name = "form_urlencoded" -version = "1.1.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" dependencies = [ "percent-encoding", ] @@ -1452,6 +1452,23 @@ dependencies = [ "want", ] +[[package]] +name = "hyper-rustls" +version = "0.27.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ee4be2c948921a1a5320b629c4193916ed787a7f7f293fd3f7f5a6c9de74155" +dependencies = [ + "futures-util", + "http", + "hyper", + "hyper-util", + "rustls", + "rustls-pki-types", + "tokio", + "tokio-rustls", + "tower-service", +] + [[package]] name = "hyper-tls" version = "0.6.0" @@ -1548,9 +1565,9 @@ checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" [[package]] name = "idna" -version = "0.3.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" dependencies = [ "unicode-bidi", "unicode-normalization", @@ -1882,9 +1899,9 @@ dependencies = [ [[package]] name = "mlua" -version = "0.9.8" +version = "0.9.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e340c022072f3208a4105458286f4985ba5355bfe243c3073afe45cbe9ecf491" +checksum = "d111deb18a9c9bd33e1541309f4742523bfab01d276bfa9a27519f6de9c11dc7" dependencies = [ "bstr", "mlua-sys", @@ -1895,9 +1912,9 @@ dependencies = [ [[package]] name = "mlua-sys" -version = "0.6.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5552e7e4e22ada0463dfdeee6caf6dc057a189fdc83136408a8f950a5e5c5540" +checksum = "a088ed0723df7567f569ba018c5d48c23c501f3878b190b04144dfa5ebfa8abc" dependencies = [ "cc", "cfg-if", @@ -2210,9 +2227,9 @@ checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" [[package]] name = "percent-encoding" -version = "2.2.0" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pest" @@ -2497,9 +2514,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.10.4" +version = "1.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" +checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f" dependencies = [ "aho-corasick", "memchr", @@ -2541,9 +2558,9 @@ checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" [[package]] name = "reqwest" -version = "0.12.4" +version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "566cafdd92868e0939d3fb961bd0dc25fcfaaed179291093b3d43e6b3150ea10" +checksum = "c7d6d2a27d57148378eb5e111173f4276ad26340ecc5c49a4a2152167a2d6a37" dependencies = [ "base64 0.22.0", "bytes", @@ -2554,6 +2571,7 @@ dependencies = [ "http-body", "http-body-util", "hyper", + "hyper-rustls", "hyper-tls", "hyper-util", "ipnet", @@ -2579,6 +2597,20 @@ dependencies = [ "winreg", ] +[[package]] +name = "ring" +version = "0.17.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9babe80d5c16becf6594aa32ad2be8fe08498e7ae60b77de8df700e67f191d7e" +dependencies = [ + "cc", + "getrandom", + "libc", + "spin", + "untrusted", + "windows-sys 0.48.0", +] + [[package]] name = "ron" version = "0.8.1" @@ -2599,9 +2631,9 @@ checksum = "d4a36c42d1873f9a77c53bde094f9664d9891bc604a45b4798fd2c389ed12e5b" [[package]] name = "rustc-hash" -version = "1.1.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" +checksum = "583034fd73374156e66797ed8e5b0d5690409c9226b22d87cb7f19821c05d152" [[package]] name = "rustc_version" @@ -2639,6 +2671,19 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "rustls" +version = "0.23.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebbbdb961df0ad3f2652da8f3fdc4b36122f568f968f45ad3316f26c025c677b" +dependencies = [ + "once_cell", + "rustls-pki-types", + "rustls-webpki", + "subtle", + "zeroize", +] + [[package]] name = "rustls-pemfile" version = "2.1.2" @@ -2655,6 +2700,17 @@ version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ecd36cc4259e3e4514335c4a138c6b43171a8d61d8f5c9348f9fc7529416f247" +[[package]] +name = "rustls-webpki" +version = "0.102.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3bce581c0dd41bce533ce695a1437fa16a7ab5ac3ccfa99fe1a620a7885eabf" +dependencies = [ + "ring", + "rustls-pki-types", + "untrusted", +] + [[package]] name = "ryu" version = "1.0.13" @@ -2941,6 +2997,12 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" + [[package]] name = "static_assertions" version = "1.1.0" @@ -2968,6 +3030,12 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5ee073c9e4cd00e28217186dbe12796d692868f432bf2e97ee73bed0c56dfa01" +[[package]] +name = "subtle" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d0208408ba0c3df17ed26eb06992cb1a1268d41b2c0e12e65203fbe3972cee5" + [[package]] name = "swayipc-async" version = "2.0.1" @@ -3028,9 +3096,9 @@ dependencies = [ [[package]] name = "sync_wrapper" -version = "0.1.2" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" +checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394" [[package]] name = "synom" @@ -3207,6 +3275,17 @@ dependencies = [ "tokio", ] +[[package]] +name = "tokio-rustls" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4" +dependencies = [ + "rustls", + "rustls-pki-types", + "tokio", +] + [[package]] name = "tokio-util" version = "0.7.7" @@ -3487,6 +3566,12 @@ version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861" +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + [[package]] name = "upower_dbus" version = "0.3.2" @@ -3500,9 +3585,9 @@ dependencies = [ [[package]] name = "url" -version = "2.3.1" +version = "2.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643" +checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" dependencies = [ "form_urlencoded", "idna", @@ -3517,9 +3602,9 @@ checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" [[package]] name = "uuid" -version = "1.8.0" +version = "1.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a183cf7feeba97b4dd1c0d46788634f6221d87fa961b305bed08c851829efcc0" +checksum = "5de17fd2f7da591098415cff336e12965a28061ddace43b59cb3c430179c9439" dependencies = [ "getrandom", ] @@ -4144,6 +4229,12 @@ dependencies = [ "zvariant", ] +[[package]] +name = "zeroize" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" + [[package]] name = "zvariant" version = "3.15.0" diff --git a/Cargo.toml b/Cargo.toml index e13e3c5..a29150b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -111,29 +111,29 @@ wayland-protocols-wlr = { version = "0.2.0", features = ["client"] } smithay-client-toolkit = { version = "0.18.1", default-features = false, features = [ "calloop", ] } -universal-config = { version = "0.5.0", default_features = false } +universal-config = { version = "0.5.0", default-features = false } ctrlc = "3.4.2" cfg-if = "1.0.0" # cli -clap = { version = "4.5.4", optional = true, features = ["derive"] } +clap = { version = "4.5.7", optional = true, features = ["derive"] } # ipc serde_json = { version = "1.0.117", optional = true } # http -reqwest = { version = "0.12.4", default_features = false, features = ["default-tls", "http2"], optional = true } +reqwest = { version = "0.12.5", default-features = false, features = ["default-tls", "http2"], optional = true } # cairo lua-src = { version = "546.0.2", optional = true } -mlua = { version = "0.9.8", optional = true, features = ["luajit"] } +mlua = { version = "0.9.9", optional = true, features = ["luajit"] } cairo-rs = { version = "0.18.5", optional = true, features = ["png"] } # clipboard nix = { version = "0.29.0", optional = true, features = ["event", "fs"] } # clock -chrono = { version = "0.4.38", optional = true, default_features = false, features = ["clock", "unstable-locales"] } +chrono = { version = "0.4.38", optional = true, default-features = false, features = ["clock", "unstable-locales"] } # music mpd-utils = { version = "0.2.1", optional = true } @@ -161,7 +161,7 @@ futures-util = { version = "0.3.30", optional = true } # shared futures-lite = { version = "2.3.0", optional = true } # networkmanager, upower, workspaces -regex = { version = "1.10.4", default-features = false, features = [ +regex = { version = "1.10.5", default-features = false, features = [ "std", ], optional = true } # music, sys_info zbus = { version = "3.15.2", default-features = false, features = ["tokio"], optional = true } # networkmanager, notifications, upower diff --git a/README.md b/README.md index 67809c3..a529e1b 100644 --- a/README.md +++ b/README.md @@ -136,6 +136,15 @@ A flake is included with the repo which can be used with Home Manager. CI builds are automatically cached by Garnix. You can use their binary cache by following the steps [here](https://garnix.io/docs/caching). +### Fedora + +[fedora package](https://copr.fedorainfracloud.org/coprs/victorvintorez/tilingtools/packages/) + +``` sh +dnf copr enable victorvintorez/tilingtools +dnf install ironbar +``` + ### Void Linux [void package](https://github.com/void-linux/void-packages/tree/master/srcpkgs/ironbar) diff --git a/docs/Configuration guide.md b/docs/Configuration guide.md index b52c2e2..25e1b22 100644 --- a/docs/Configuration guide.md +++ b/docs/Configuration guide.md @@ -295,23 +295,25 @@ The following table lists each of the top-level bar config options: The following table lists each of the bar-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. | -| `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. | +| 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. | +| `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 | +| `layer` | `background` or `bottom` or `top` or `overlay` | `top` | The layer-shell layer to place the bar on. | +| `exclusive_zone` | `boolean` | `true` unless `start_hidden` is enabled. | Whether the bar should reserve an exclusive zone around it. | +| `popup_gap` | `integer` | `5` | The gap between the bar and popup window. | +| `icon_theme` | `string` | `null` | Name of the GTK icon theme to use. Leave blank to use default. | +| `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/docs/Controlling Ironbar.md b/docs/Controlling Ironbar.md index 9eb3613..3edfdcc 100644 --- a/docs/Controlling Ironbar.md +++ b/docs/Controlling Ironbar.md @@ -289,6 +289,18 @@ Gets the popup's current visibility state. } ``` +#### `set_exclusive` + +Sets whether the bar reserves an exclusive zone. + +```json +{ + "command": "bar", + "subcommand": "set_exclusive", + "exclusive": true +} +``` + ## Responses ### `ok` diff --git a/src/bar.rs b/src/bar.rs index 99f4b04..2e9e7d2 100644 --- a/src/bar.rs +++ b/src/bar.rs @@ -120,27 +120,28 @@ impl Bar { self.name, self.monitor_name ); - self.setup_layer_shell( - &self.window, - true, - config.anchor_to_edges, - config.margin, - monitor, - ); - let start_hidden = config .start_hidden .unwrap_or_else(|| config.autohide.is_some()); + self.setup_layer_shell( + &self.window, + config.exclusive_zone.unwrap_or(!start_hidden), + config.anchor_to_edges, + config.margin, + config.layer, + monitor, + ); + 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, + gtk_layer_shell::Layer::Top, monitor, ); @@ -166,43 +167,46 @@ impl Bar { exclusive_zone: bool, anchor_to_edges: bool, margin: MarginConfig, + layer: gtk_layer_shell::Layer, monitor: &Monitor, ) { + use gtk_layer_shell::Edge; + let position = self.position; win.init_layer_shell(); win.set_monitor(monitor); - win.set_layer(gtk_layer_shell::Layer::Top); + win.set_layer(layer); win.set_namespace(env!("CARGO_PKG_NAME")); if exclusive_zone { win.auto_exclusive_zone_enable(); } - win.set_layer_shell_margin(gtk_layer_shell::Edge::Top, margin.top); - win.set_layer_shell_margin(gtk_layer_shell::Edge::Bottom, margin.bottom); - win.set_layer_shell_margin(gtk_layer_shell::Edge::Left, margin.left); - win.set_layer_shell_margin(gtk_layer_shell::Edge::Right, margin.right); + win.set_layer_shell_margin(Edge::Top, margin.top); + win.set_layer_shell_margin(Edge::Bottom, margin.bottom); + win.set_layer_shell_margin(Edge::Left, margin.left); + win.set_layer_shell_margin(Edge::Right, margin.right); let bar_orientation = position.orientation(); win.set_anchor( - gtk_layer_shell::Edge::Top, + Edge::Top, position == BarPosition::Top || (bar_orientation == Orientation::Vertical && anchor_to_edges), ); win.set_anchor( - gtk_layer_shell::Edge::Bottom, + Edge::Bottom, position == BarPosition::Bottom || (bar_orientation == Orientation::Vertical && anchor_to_edges), ); win.set_anchor( - gtk_layer_shell::Edge::Left, + Edge::Left, position == BarPosition::Left || (bar_orientation == Orientation::Horizontal && anchor_to_edges), ); win.set_anchor( - gtk_layer_shell::Edge::Right, + Edge::Right, position == BarPosition::Right || (bar_orientation == Orientation::Horizontal && anchor_to_edges), ); @@ -329,6 +333,14 @@ impl Bar { pub fn set_visible(&self, visible: bool) { self.window.set_visible(visible) } + + pub fn set_exclusive(&self, exclusive: bool) { + if exclusive { + self.window.auto_exclusive_zone_enable(); + } else { + self.window.set_exclusive_zone(0); + } + } } /// Creates a `gtk::Box` container to place widgets inside. diff --git a/src/clients/swaync/mod.rs b/src/clients/swaync/mod.rs index 173cf73..495040b 100644 --- a/src/clients/swaync/mod.rs +++ b/src/clients/swaync/mod.rs @@ -14,7 +14,7 @@ pub struct Event { pub count: u32, pub dnd: bool, pub cc_open: bool, - pub inhibited: bool, + // pub inhibited: bool, } type GetSubscribeData = (bool, bool, u32, bool); @@ -22,12 +22,12 @@ type GetSubscribeData = (bool, bool, u32, bool); /// Converts the data returned from /// `get_subscribe_data` into an event for convenience. impl From for Event { - fn from((dnd, cc_open, count, inhibited): (bool, bool, u32, bool)) -> Self { + fn from((dnd, cc_open, count, _inhibited): (bool, bool, u32, bool)) -> Self { Self { count, dnd, cc_open, - inhibited, + // inhibited, } } } diff --git a/src/clients/wayland/mod.rs b/src/clients/wayland/mod.rs index 8c7fcb8..ca7c367 100644 --- a/src/clients/wayland/mod.rs +++ b/src/clients/wayland/mod.rs @@ -2,8 +2,9 @@ mod macros; mod wl_output; mod wl_seat; -use crate::error::ERR_CHANNEL_RECV; +use crate::error::{ExitCode, ERR_CHANNEL_RECV}; use crate::{arc_mut, lock, register_client, send, spawn, spawn_blocking}; +use std::process::exit; use std::sync::{Arc, Mutex}; use calloop_channel::Event::Msg; @@ -305,6 +306,8 @@ impl Environment { "{:?}", Report::new(err).wrap_err("Failed to dispatch pending wayland events") ); + + exit(ExitCode::WaylandDispatchError as i32) } } } diff --git a/src/config/impl.rs b/src/config/impl.rs index a5b01b8..3c722c3 100644 --- a/src/config/impl.rs +++ b/src/config/impl.rs @@ -35,6 +35,37 @@ impl<'de> Deserialize<'de> for MonitorConfig { } } +pub fn deserialize_layer<'de, D>(deserializer: D) -> Result +where + D: serde::Deserializer<'de>, +{ + use gtk_layer_shell::Layer; + + let value = Option::::deserialize(deserializer)?; + value + .map(|v| match v.as_str() { + "background" => Ok(Layer::Background), + "bottom" => Ok(Layer::Bottom), + "top" => Ok(Layer::Top), + "overlay" => Ok(Layer::Overlay), + _ => Err(serde::de::Error::custom("invalid value for orientation")), + }) + .unwrap_or(Ok(Layer::Top)) +} + +#[cfg(feature = "schema")] +pub fn schema_layer(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + use schemars::JsonSchema; + let mut schema: schemars::schema::SchemaObject = ::json_schema(gen).into(); + schema.enum_values = Some(vec![ + "background".into(), + "bottom".into(), + "top".into(), + "overlay".into(), + ]); + schema.into() +} + impl BarPosition { /// Gets the orientation the bar and widgets should use /// based on this position. diff --git a/src/config/mod.rs b/src/config/mod.rs index a2cd553..12b7164 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -222,6 +222,36 @@ pub struct BarConfig { #[serde(default)] pub margin: MarginConfig, + /// The layer-shell layer to place the bar on. + /// + /// Taken from the + /// [wlr_layer_shell](https://wayland.app/protocols/wlr-layer-shell-unstable-v1#zwlr_layer_shell_v1:enum:layer) definition: + /// + /// > These values indicate which layers a surface can be rendered in. + /// > They are ordered by z depth, bottom-most first. + /// > Traditional shell surfaces will typically be rendered between the bottom and top layers. + /// > Fullscreen shell surfaces are typically rendered at the top layer. + /// > Multiple surfaces can share a single layer, and ordering within a single layer is undefined. + /// + /// **Valid options**: `background`, `bottom`, `top`, `overlay` + ///
+ /// **Default**: `top` + #[serde( + default = "default_layer", + deserialize_with = "r#impl::deserialize_layer" + )] + #[cfg_attr(feature = "schema", schemars(schema_with = "r#impl::schema_layer"))] + pub layer: gtk_layer_shell::Layer, + + /// Whether the bar should reserve an exclusive zone around it. + /// + /// When true, this prevents windows from rendering in the same space + /// as the bar, causing them to shift. + /// + /// **Default**: `true` unless `start_hidden` is set. + #[serde(default)] + pub exclusive_zone: Option, + /// The size of the gap in pixels /// between the bar and the popup window. /// @@ -288,9 +318,11 @@ impl Default for BarConfig { Self { position: BarPosition::default(), - height: default_bar_height(), margin: MarginConfig::default(), name: None, + layer: default_layer(), + exclusive_zone: None, + height: default_bar_height(), start_hidden: None, autohide: None, icon_theme: None, @@ -346,6 +378,10 @@ pub struct Config { pub monitors: Option>, } +const fn default_layer() -> gtk_layer_shell::Layer { + gtk_layer_shell::Layer::Top +} + const fn default_bar_height() -> i32 { 42 } diff --git a/src/error.rs b/src/error.rs index 66f30cd..a55fa12 100644 --- a/src/error.rs +++ b/src/error.rs @@ -3,6 +3,7 @@ pub enum ExitCode { GtkDisplay = 1, CreateBars = 2, IpcResponseError = 3, + WaylandDispatchError = 4, } pub const ERR_MUTEX_LOCK: &str = "Failed to get lock on Mutex"; diff --git a/src/ipc/commands.rs b/src/ipc/commands.rs index 668519e..93b183e 100644 --- a/src/ipc/commands.rs +++ b/src/ipc/commands.rs @@ -118,4 +118,15 @@ pub enum BarCommandType { }, /// Get the popup's current visibility state. GetPopupVisible, + + // == Exclusivity == \\ + /// Set whether the bar reserves an exclusive zone. + SetExclusive { + #[clap( + num_args(1), + require_equals(true), + action = ArgAction::Set, + )] + exclusive: bool, + }, } diff --git a/src/ipc/server/bar.rs b/src/ipc/server/bar.rs index b4861c5..3bd3b8c 100644 --- a/src/ipc/server/bar.rs +++ b/src/ipc/server/bar.rs @@ -43,6 +43,11 @@ pub fn handle_command(command: BarCommand, ironbar: &Rc) -> Response { GetPopupVisible => Response::OkValue { value: bar.popup().visible().to_string(), }, + SetExclusive { exclusive } => { + bar.set_exclusive(exclusive); + + Response::Ok + } } }