Window definitions are parsed fully
This commit is contained in:
parent
dd5078b4be
commit
98cbbff7c9
6 changed files with 216 additions and 78 deletions
123
src/config/backend_window_options.rs
Normal file
123
src/config/backend_window_options.rs
Normal file
|
@ -0,0 +1,123 @@
|
||||||
|
use std::str::FromStr;
|
||||||
|
|
||||||
|
use anyhow::*;
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
enum_parse,
|
||||||
|
error::AstResult,
|
||||||
|
parser::{
|
||||||
|
ast::{Ast, AstIterator, Span},
|
||||||
|
from_ast::FromAstElementContent,
|
||||||
|
},
|
||||||
|
value::NumWithUnit,
|
||||||
|
};
|
||||||
|
|
||||||
|
use super::{attributes::Attributes, window_definition::EnumParseError};
|
||||||
|
|
||||||
|
pub type BackendWindowOptions = X11WindowOptions;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize)]
|
||||||
|
pub struct X11WindowOptions {
|
||||||
|
pub wm_ignore: bool,
|
||||||
|
pub sticky: bool,
|
||||||
|
pub window_type: EwwWindowType,
|
||||||
|
pub struts: StrutDefinition,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl X11WindowOptions {
|
||||||
|
pub fn from_attrs(attrs: &mut Attributes) -> AstResult<Self> {
|
||||||
|
let struts = attrs.ast_optional("reserve")?;
|
||||||
|
let window_type = attrs.primitive_optional("windowtype")?;
|
||||||
|
Ok(X11WindowOptions {
|
||||||
|
wm_ignore: attrs.primitive_optional("wm-ignore")?.unwrap_or(window_type.is_none() && struts.is_none()),
|
||||||
|
window_type: window_type.unwrap_or_default(),
|
||||||
|
sticky: attrs.primitive_optional("sticky")?.unwrap_or(true),
|
||||||
|
struts: struts.unwrap_or_default(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, smart_default::SmartDefault, serde::Serialize)]
|
||||||
|
pub enum EwwWindowType {
|
||||||
|
#[default]
|
||||||
|
Dock,
|
||||||
|
Dialog,
|
||||||
|
Toolbar,
|
||||||
|
Normal,
|
||||||
|
Utility,
|
||||||
|
}
|
||||||
|
impl FromStr for EwwWindowType {
|
||||||
|
type Err = EnumParseError;
|
||||||
|
|
||||||
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
|
enum_parse! { "window type", s,
|
||||||
|
"dock" => Self::Dock,
|
||||||
|
"toolbar" => Self::Toolbar,
|
||||||
|
"dialog" => Self::Dialog,
|
||||||
|
"normal" => Self::Normal,
|
||||||
|
"utility" => Self::Utility,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, Eq, PartialEq, smart_default::SmartDefault, serde::Serialize)]
|
||||||
|
pub enum Side {
|
||||||
|
#[default]
|
||||||
|
Top,
|
||||||
|
Left,
|
||||||
|
Right,
|
||||||
|
Bottom,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::str::FromStr for Side {
|
||||||
|
type Err = EnumParseError;
|
||||||
|
|
||||||
|
fn from_str(s: &str) -> Result<Side, Self::Err> {
|
||||||
|
enum_parse! { "side", s,
|
||||||
|
"l" | "left" => Side::Left,
|
||||||
|
"r" | "right" => Side::Right,
|
||||||
|
"t" | "top" => Side::Top,
|
||||||
|
"b" | "bottom" => Side::Bottom,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Surface definition if the backend for X11 is enable
|
||||||
|
#[derive(Debug, Clone, Copy, Eq, PartialEq, Default, serde::Serialize)]
|
||||||
|
pub struct StrutDefinition {
|
||||||
|
pub side: Side,
|
||||||
|
pub dist: NumWithUnit,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FromAstElementContent for StrutDefinition {
|
||||||
|
fn get_element_name() -> &'static str {
|
||||||
|
"struts"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn from_tail<I: Iterator<Item = Ast>>(span: Span, mut iter: AstIterator<I>) -> AstResult<Self> {
|
||||||
|
let mut attrs = iter.expect_key_values()?;
|
||||||
|
Ok(StrutDefinition { side: attrs.primitive_required("side")?, dist: attrs.primitive_required("distance")? })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize)]
|
||||||
|
pub struct WaylandWindowOptions {
|
||||||
|
pub exclusive: bool,
|
||||||
|
pub focusable: bool,
|
||||||
|
}
|
||||||
|
impl WaylandWindowOptions {
|
||||||
|
pub fn from_attrs(attrs: &mut Attributes) -> AstResult<Self> {
|
||||||
|
Ok(WaylandWindowOptions {
|
||||||
|
exclusive: attrs.primitive_optional("exclusive")?.unwrap_or(false),
|
||||||
|
focusable: attrs.primitive_optional("focusable")?.unwrap_or(false),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize)]
|
||||||
|
pub struct NoBackendWindowOptions;
|
||||||
|
impl NoBackendWindowOptions {
|
||||||
|
pub fn from_attrs(attrs: &mut Attributes) -> Result<Self> {
|
||||||
|
Ok(NoBackendWindowOptions)
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,7 +4,7 @@ use simplexpr::SimplExpr;
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
script_var_definition::ScriptVarDefinition, var_definition::VarDefinition, widget_definition::WidgetDefinition,
|
script_var_definition::ScriptVarDefinition, var_definition::VarDefinition, widget_definition::WidgetDefinition,
|
||||||
widget_use::WidgetUse,
|
widget_use::WidgetUse, window_definition::WindowDefinition,
|
||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
config::script_var_definition::{PollScriptVar, TailScriptVar},
|
config::script_var_definition::{PollScriptVar, TailScriptVar},
|
||||||
|
@ -21,6 +21,7 @@ pub enum TopLevel {
|
||||||
VarDefinition(VarDefinition),
|
VarDefinition(VarDefinition),
|
||||||
ScriptVarDefinition(ScriptVarDefinition),
|
ScriptVarDefinition(ScriptVarDefinition),
|
||||||
WidgetDefinition(WidgetDefinition),
|
WidgetDefinition(WidgetDefinition),
|
||||||
|
WindowDefinition(WindowDefinition),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromAst for TopLevel {
|
impl FromAst for TopLevel {
|
||||||
|
@ -40,6 +41,9 @@ impl FromAst for TopLevel {
|
||||||
x if x == TailScriptVar::get_element_name() => {
|
x if x == TailScriptVar::get_element_name() => {
|
||||||
Self::ScriptVarDefinition(ScriptVarDefinition::Tail(TailScriptVar::from_tail(span, iter)?))
|
Self::ScriptVarDefinition(ScriptVarDefinition::Tail(TailScriptVar::from_tail(span, iter)?))
|
||||||
}
|
}
|
||||||
|
x if x == WindowDefinition::get_element_name() => {
|
||||||
|
Self::WindowDefinition(WindowDefinition::from_tail(span, iter)?)
|
||||||
|
}
|
||||||
x => return Err(AstError::UnknownToplevel(Some(sym_span), x.to_string())),
|
x => return Err(AstError::UnknownToplevel(Some(sym_span), x.to_string())),
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -49,6 +53,7 @@ impl FromAst for TopLevel {
|
||||||
#[derive(Debug, PartialEq, Eq, Clone, serde::Serialize)]
|
#[derive(Debug, PartialEq, Eq, Clone, serde::Serialize)]
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
widget_definitions: HashMap<String, WidgetDefinition>,
|
widget_definitions: HashMap<String, WidgetDefinition>,
|
||||||
|
window_definitions: HashMap<String, WindowDefinition>,
|
||||||
var_definitions: HashMap<VarName, VarDefinition>,
|
var_definitions: HashMap<VarName, VarDefinition>,
|
||||||
script_vars: HashMap<VarName, ScriptVarDefinition>,
|
script_vars: HashMap<VarName, ScriptVarDefinition>,
|
||||||
}
|
}
|
||||||
|
@ -56,8 +61,12 @@ pub struct Config {
|
||||||
impl FromAst for Config {
|
impl FromAst for Config {
|
||||||
fn from_ast(e: Ast) -> AstResult<Self> {
|
fn from_ast(e: Ast) -> AstResult<Self> {
|
||||||
let list = e.as_list()?;
|
let list = e.as_list()?;
|
||||||
let mut config =
|
let mut config = Self {
|
||||||
Self { widget_definitions: HashMap::new(), var_definitions: HashMap::new(), script_vars: HashMap::new() };
|
widget_definitions: HashMap::new(),
|
||||||
|
window_definitions: HashMap::new(),
|
||||||
|
var_definitions: HashMap::new(),
|
||||||
|
script_vars: HashMap::new(),
|
||||||
|
};
|
||||||
for element in list {
|
for element in list {
|
||||||
match TopLevel::from_ast(element)? {
|
match TopLevel::from_ast(element)? {
|
||||||
TopLevel::VarDefinition(x) => {
|
TopLevel::VarDefinition(x) => {
|
||||||
|
@ -69,6 +78,9 @@ impl FromAst for Config {
|
||||||
TopLevel::WidgetDefinition(x) => {
|
TopLevel::WidgetDefinition(x) => {
|
||||||
config.widget_definitions.insert(x.name.clone(), x);
|
config.widget_definitions.insert(x.name.clone(), x);
|
||||||
}
|
}
|
||||||
|
TopLevel::WindowDefinition(x) => {
|
||||||
|
config.window_definitions.insert(x.name.clone(), x);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(config)
|
Ok(config)
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
pub mod attributes;
|
pub mod attributes;
|
||||||
|
pub mod backend_window_options;
|
||||||
mod config;
|
mod config;
|
||||||
pub mod config_parse_error;
|
pub mod config_parse_error;
|
||||||
pub mod script_var_definition;
|
pub mod script_var_definition;
|
||||||
|
|
|
@ -13,9 +13,15 @@ Config(
|
||||||
],
|
],
|
||||||
widget: WidgetUse(
|
widget: WidgetUse(
|
||||||
name: "text",
|
name: "text",
|
||||||
|
attrs: Attributes(
|
||||||
|
span: Span(99, 104, 0),
|
||||||
attrs: {
|
attrs: {
|
||||||
AttrName("text"): Literal(Span(99, 104, 0), DynVal("bla", None)),
|
AttrName("text"): AttrEntry(
|
||||||
|
key_span: Span(99, 104, 0),
|
||||||
|
value: Literal(Span(99, 104, 0), DynVal("bla", None)),
|
||||||
|
),
|
||||||
},
|
},
|
||||||
|
),
|
||||||
children: [],
|
children: [],
|
||||||
span: Span(99, 104, 0),
|
span: Span(99, 104, 0),
|
||||||
),
|
),
|
||||||
|
@ -29,9 +35,15 @@ Config(
|
||||||
],
|
],
|
||||||
widget: WidgetUse(
|
widget: WidgetUse(
|
||||||
name: "text",
|
name: "text",
|
||||||
|
attrs: Attributes(
|
||||||
|
span: Span(44, 51, 0),
|
||||||
attrs: {
|
attrs: {
|
||||||
AttrName("text"): Literal(Span(44, 51, 0), DynVal("heyho", None)),
|
AttrName("text"): AttrEntry(
|
||||||
|
key_span: Span(44, 51, 0),
|
||||||
|
value: Literal(Span(44, 51, 0), DynVal("heyho", None)),
|
||||||
|
),
|
||||||
},
|
},
|
||||||
|
),
|
||||||
children: [],
|
children: [],
|
||||||
span: Span(44, 51, 0),
|
span: Span(44, 51, 0),
|
||||||
),
|
),
|
||||||
|
@ -39,6 +51,51 @@ Config(
|
||||||
args_span: Span(26, 31, 0),
|
args_span: Span(26, 31, 0),
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
window_definitions: {
|
||||||
|
"some-window": WindowDefinition(
|
||||||
|
name: "some-window",
|
||||||
|
geometry: Some(WindowGeometry(
|
||||||
|
anchor_point: AnchorPoint(
|
||||||
|
x: START,
|
||||||
|
y: START,
|
||||||
|
),
|
||||||
|
offset: Coords(
|
||||||
|
x: Pixels(0),
|
||||||
|
y: Pixels(0),
|
||||||
|
),
|
||||||
|
size: Coords(
|
||||||
|
x: Percent(12),
|
||||||
|
y: Pixels(20),
|
||||||
|
),
|
||||||
|
)),
|
||||||
|
stacking: Foreground,
|
||||||
|
monitor_number: Some(12),
|
||||||
|
widget: WidgetUse(
|
||||||
|
name: "foo",
|
||||||
|
attrs: Attributes(
|
||||||
|
span: Span(509, 509, 513),
|
||||||
|
attrs: {
|
||||||
|
AttrName("arg"): AttrEntry(
|
||||||
|
key_span: Span(514, 518, 0),
|
||||||
|
value: Literal(Span(519, 524, 0), DynVal("bla", None)),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
children: [],
|
||||||
|
span: Span(509, 525, 0),
|
||||||
|
),
|
||||||
|
resizable: true,
|
||||||
|
backend_options: X11WindowOptions(
|
||||||
|
wm_ignore: false,
|
||||||
|
sticky: true,
|
||||||
|
window_type: Dock,
|
||||||
|
struts: StrutDefinition(
|
||||||
|
side: Left,
|
||||||
|
dist: Pixels(30),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
},
|
||||||
var_definitions: {
|
var_definitions: {
|
||||||
VarName("some_var"): VarDefinition(
|
VarName("some_var"): VarDefinition(
|
||||||
name: VarName("some_var"),
|
name: VarName("some_var"),
|
||||||
|
|
|
@ -18,6 +18,13 @@ fn test_config() {
|
||||||
(defvar some_var "bla")
|
(defvar some_var "bla")
|
||||||
(defpollvar stuff :interval "12s" "date")
|
(defpollvar stuff :interval "12s" "date")
|
||||||
(deftailvar stuff "tail -f stuff")
|
(deftailvar stuff "tail -f stuff")
|
||||||
|
(defwindow some-window
|
||||||
|
:stacking "fg"
|
||||||
|
:monitor 12
|
||||||
|
:resizable true
|
||||||
|
:geometry (geometry :width "12%" :height "20px")
|
||||||
|
:reserve (struts :side "left" :distance "30px")
|
||||||
|
(foo :arg "bla"))
|
||||||
"#;
|
"#;
|
||||||
|
|
||||||
let lexer = Lexer::new(0, input.to_string());
|
let lexer = Lexer::new(0, input.to_string());
|
||||||
|
|
|
@ -12,20 +12,20 @@ use crate::{
|
||||||
value::{AttrName, NumWithUnit, VarName},
|
value::{AttrName, NumWithUnit, VarName},
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{widget_use::WidgetUse, window_geometry::WindowGeometry};
|
use super::{backend_window_options::BackendWindowOptions, widget_use::WidgetUse, window_geometry::WindowGeometry};
|
||||||
|
|
||||||
#[derive(Debug, Clone, serde::Serialize)]
|
#[derive(Debug, Clone, serde::Serialize, PartialEq, Eq)]
|
||||||
pub struct EwwWindowDefinition {
|
pub struct WindowDefinition {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub geometry: Option<WindowGeometry>,
|
pub geometry: Option<WindowGeometry>,
|
||||||
pub stacking: WindowStacking,
|
pub stacking: WindowStacking,
|
||||||
pub monitor_number: Option<i32>,
|
pub monitor_number: Option<i32>,
|
||||||
pub widget: WidgetUse,
|
pub widget: WidgetUse,
|
||||||
pub resizable: bool,
|
pub resizable: bool,
|
||||||
// pub backend_options: BackendWindowOptions,
|
pub backend_options: BackendWindowOptions,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromAstElementContent for EwwWindowDefinition {
|
impl FromAstElementContent for WindowDefinition {
|
||||||
fn get_element_name() -> &'static str {
|
fn get_element_name() -> &'static str {
|
||||||
"defwindow"
|
"defwindow"
|
||||||
}
|
}
|
||||||
|
@ -37,8 +37,9 @@ impl FromAstElementContent for EwwWindowDefinition {
|
||||||
let resizable = attrs.primitive_optional("resizable")?.unwrap_or(true);
|
let resizable = attrs.primitive_optional("resizable")?.unwrap_or(true);
|
||||||
let stacking = attrs.primitive_optional("stacking")?.unwrap_or(WindowStacking::Foreground);
|
let stacking = attrs.primitive_optional("stacking")?.unwrap_or(WindowStacking::Foreground);
|
||||||
let geometry = attrs.ast_optional("geometry")?;
|
let geometry = attrs.ast_optional("geometry")?;
|
||||||
|
let backend_options = BackendWindowOptions::from_attrs(&mut attrs)?;
|
||||||
let widget = iter.expect_any()?;
|
let widget = iter.expect_any()?;
|
||||||
Ok(Self { name, monitor_number, resizable, widget, stacking, geometry })
|
Ok(Self { name, monitor_number, resizable, widget, stacking, geometry, backend_options })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,69 +77,6 @@ macro_rules! enum_parse {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, smart_default::SmartDefault)]
|
|
||||||
pub enum EwwWindowType {
|
|
||||||
#[default]
|
|
||||||
Dock,
|
|
||||||
Dialog,
|
|
||||||
Toolbar,
|
|
||||||
Normal,
|
|
||||||
Utility,
|
|
||||||
}
|
|
||||||
impl FromStr for EwwWindowType {
|
|
||||||
type Err = EnumParseError;
|
|
||||||
|
|
||||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
|
||||||
enum_parse! { "window type", s,
|
|
||||||
"dock" => Self::Dock,
|
|
||||||
"toolbar" => Self::Toolbar,
|
|
||||||
"dialog" => Self::Dialog,
|
|
||||||
"normal" => Self::Normal,
|
|
||||||
"utility" => Self::Utility,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, Eq, PartialEq, smart_default::SmartDefault)]
|
|
||||||
pub enum Side {
|
|
||||||
#[default]
|
|
||||||
Top,
|
|
||||||
Left,
|
|
||||||
Right,
|
|
||||||
Bottom,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl std::str::FromStr for Side {
|
|
||||||
type Err = EnumParseError;
|
|
||||||
|
|
||||||
fn from_str(s: &str) -> Result<Side, Self::Err> {
|
|
||||||
enum_parse! { "side", s,
|
|
||||||
"l" | "left" => Side::Left,
|
|
||||||
"r" | "right" => Side::Right,
|
|
||||||
"t" | "top" => Side::Top,
|
|
||||||
"b" | "bottom" => Side::Bottom,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Surface definition if the backend for X11 is enable
|
|
||||||
#[derive(Debug, Clone, Copy, Eq, PartialEq, Default)]
|
|
||||||
pub struct StrutDefinition {
|
|
||||||
pub side: Side,
|
|
||||||
pub dist: NumWithUnit,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl FromAstElementContent for StrutDefinition {
|
|
||||||
fn get_element_name() -> &'static str {
|
|
||||||
"struts"
|
|
||||||
}
|
|
||||||
|
|
||||||
fn from_tail<I: Iterator<Item = Ast>>(span: Span, mut iter: AstIterator<I>) -> AstResult<Self> {
|
|
||||||
let mut attrs = iter.expect_key_values()?;
|
|
||||||
Ok(StrutDefinition { side: attrs.primitive_required("side")?, dist: attrs.primitive_required("distance")? })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, derive_more::Display, smart_default::SmartDefault, serde::Serialize)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, derive_more::Display, smart_default::SmartDefault, serde::Serialize)]
|
||||||
pub enum WindowStacking {
|
pub enum WindowStacking {
|
||||||
#[default]
|
#[default]
|
||||||
|
|
Loading…
Add table
Reference in a new issue