diff --git a/CHANGELOG.md b/CHANGELOG.md index fbc6c7e7..f93a74ad 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ All notable changes to eww will be listed here, starting at changes since versio - Add `substring` function to simplexpr - Add `--duration` flag to `eww open` - Add support for referring to monitor with `` +- Add support for multiple matchers in `monitor` field ## [0.4.0] (04.09.2022) diff --git a/crates/eww/src/app.rs b/crates/eww/src/app.rs index 42b65d01..57cf1b1b 100644 --- a/crates/eww/src/app.rs +++ b/crates/eww/src/app.rs @@ -582,6 +582,14 @@ fn get_monitor_geometry(identifier: Option) -> Result Option { match identifier { + MonitorIdentifier::List(list) => { + for ident in list { + if let Some(monitor) = get_monitor_from_display(display, ident) { + return Some(monitor); + } + } + None + } MonitorIdentifier::Primary => display.primary_monitor(), MonitorIdentifier::Numeric(num) => display.monitor(*num), MonitorIdentifier::Name(name) => { diff --git a/crates/yuck/src/config/monitor.rs b/crates/yuck/src/config/monitor.rs index e023096a..a6432912 100644 --- a/crates/yuck/src/config/monitor.rs +++ b/crates/yuck/src/config/monitor.rs @@ -5,6 +5,7 @@ use serde::{Deserialize, Serialize}; /// The type of the identifier used to select a monitor #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub enum MonitorIdentifier { + List(Vec), Numeric(i32), Name(String), Primary, @@ -19,6 +20,7 @@ impl MonitorIdentifier { impl fmt::Display for MonitorIdentifier { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { + Self::List(l) => write!(f, "[{}]", l.iter().map(|x| x.to_string()).collect::>().join(" ")), Self::Numeric(n) => write!(f, "{}", n), Self::Name(n) => write!(f, "{}", n), Self::Primary => write!(f, ""), diff --git a/crates/yuck/src/config/window_definition.rs b/crates/yuck/src/config/window_definition.rs index afe3fd52..f62ed364 100644 --- a/crates/yuck/src/config/window_definition.rs +++ b/crates/yuck/src/config/window_definition.rs @@ -1,4 +1,4 @@ -use std::fmt::Display; +use std::{fmt::Display, str::FromStr}; use crate::{ config::monitor::MonitorIdentifier, @@ -24,13 +24,22 @@ pub struct WindowDefinition { pub backend_options: BackendWindowOptions, } +impl FromAst for MonitorIdentifier { + fn from_ast(x: Ast) -> DiagResult { + match x { + Ast::Array(_, x) => Ok(Self::List(x.into_iter().map(MonitorIdentifier::from_ast).collect::>()?)), + other => Ok(Self::from_str(&String::from_ast(other)?).unwrap()), + } + } +} + impl FromAstElementContent for WindowDefinition { const ELEMENT_NAME: &'static str = "defwindow"; fn from_tail>(_span: Span, mut iter: AstIterator) -> DiagResult { let (_, name) = iter.expect_symbol()?; let mut attrs = iter.expect_key_values()?; - let monitor = attrs.primitive_optional("monitor")?; + let monitor = attrs.ast_optional::("monitor")?; let resizable = attrs.primitive_optional("resizable")?.unwrap_or(true); let stacking = attrs.primitive_optional("stacking")?.unwrap_or(WindowStacking::Foreground); let geometry = attrs.ast_optional("geometry")?; diff --git a/crates/yuck/src/parser/ast.rs b/crates/yuck/src/parser/ast.rs index d80d208f..5a901299 100644 --- a/crates/yuck/src/parser/ast.rs +++ b/crates/yuck/src/parser/ast.rs @@ -71,6 +71,8 @@ impl Ast { as_func!(AstType::List, as_list as_list_ref> = Ast::List(_, x) => x); + as_func!(AstType::Array, as_array as_array_ref> = Ast::Array(_, x) => x); + pub fn expr_type(&self) -> AstType { match self { Ast::List(..) => AstType::List, diff --git a/docs/src/configuration.md b/docs/src/configuration.md index af7397e8..975099b5 100644 --- a/docs/src/configuration.md +++ b/docs/src/configuration.md @@ -50,10 +50,20 @@ You can now open your first window by running `eww open example`! Glorious! | Property | Description | | ---------: | ------------------------------------------------------------ | -| `monitor` | Which monitor this window should be displayed on. Can be either a number (X11 and Wayland) or an output name (X11 only). | +| `monitor` | Which monitor this window should be displayed on. See below for details.| | `geometry` | Geometry of the window. | +**`monitor`-property** + +This field can be: + +- the string ``, in which case eww tries to identify the primary display (which may fail, especially on wayland) +- an integer, declaring the monitor index +- the name of the monitor +- an array of monitor matchers, such as: `["" "HDMI-A-1" "PHL 345B1C" 0]`. Eww will try to find a match in order, allowing you to specify fallbacks. + + **`geometry`-properties** | Property | Description |