Skip to content

Commit

Permalink
Allow list of monitor matchers
Browse files Browse the repository at this point in the history
  • Loading branch information
elkowar committed Dec 20, 2023
1 parent 85550cc commit 7340302
Show file tree
Hide file tree
Showing 6 changed files with 35 additions and 3 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 `<primary>`
- Add support for multiple matchers in `monitor` field

## [0.4.0] (04.09.2022)

Expand Down
8 changes: 8 additions & 0 deletions crates/eww/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -582,6 +582,14 @@ fn get_monitor_geometry(identifier: Option<MonitorIdentifier>) -> Result<gdk::Re
/// Outside of x11, only [MonitorIdentifier::Numeric] is supported
pub fn get_monitor_from_display(display: &gdk::Display, identifier: &MonitorIdentifier) -> Option<gdk::Monitor> {
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) => {
Expand Down
2 changes: 2 additions & 0 deletions crates/yuck/src/config/monitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<MonitorIdentifier>),
Numeric(i32),
Name(String),
Primary,
Expand All @@ -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::<Vec<_>>().join(" ")),
Self::Numeric(n) => write!(f, "{}", n),
Self::Name(n) => write!(f, "{}", n),
Self::Primary => write!(f, "<primary>"),
Expand Down
13 changes: 11 additions & 2 deletions crates/yuck/src/config/window_definition.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::fmt::Display;
use std::{fmt::Display, str::FromStr};

use crate::{
config::monitor::MonitorIdentifier,
Expand All @@ -24,13 +24,22 @@ pub struct WindowDefinition {
pub backend_options: BackendWindowOptions,
}

impl FromAst for MonitorIdentifier {
fn from_ast(x: Ast) -> DiagResult<Self> {
match x {
Ast::Array(_, x) => Ok(Self::List(x.into_iter().map(MonitorIdentifier::from_ast).collect::<DiagResult<_>>()?)),
other => Ok(Self::from_str(&String::from_ast(other)?).unwrap()),
}
}
}

impl FromAstElementContent for WindowDefinition {
const ELEMENT_NAME: &'static str = "defwindow";

fn from_tail<I: Iterator<Item = Ast>>(_span: Span, mut iter: AstIterator<I>) -> DiagResult<Self> {
let (_, name) = iter.expect_symbol()?;
let mut attrs = iter.expect_key_values()?;
let monitor = attrs.primitive_optional("monitor")?;
let monitor = attrs.ast_optional::<MonitorIdentifier>("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")?;
Expand Down
2 changes: 2 additions & 0 deletions crates/yuck/src/parser/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ impl Ast {

as_func!(AstType::List, as_list as_list_ref<Vec<Ast>> = Ast::List(_, x) => x);

as_func!(AstType::Array, as_array as_array_ref<Vec<Ast>> = Ast::Array(_, x) => x);

pub fn expr_type(&self) -> AstType {
match self {
Ast::List(..) => AstType::List,
Expand Down
12 changes: 11 additions & 1 deletion docs/src/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 `<primary>`, 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: `["<primary>" "HDMI-A-1" "PHL 345B1C" 0]`. Eww will try to find a match in order, allowing you to specify fallbacks.


**`geometry`-properties**

| Property | Description |
Expand Down

0 comments on commit 7340302

Please sign in to comment.