1
0
Fork 0
forked from wry/wry

config: add content-type window criteria

This commit is contained in:
Julian Orth 2025-07-17 11:02:32 +02:00
parent fb5c50467b
commit 4fd70f03e1
22 changed files with 327 additions and 18 deletions

View file

@ -28,7 +28,7 @@ use {
status::MessageFormat,
theme::Color,
video::{ColorSpace, Format, GfxApi, TearingMode, TransferFunction, Transform, VrrMode},
window::{TileState, WindowType},
window::{ContentType, TileState, WindowType},
xwayland::XScalingMode,
},
std::{
@ -277,6 +277,7 @@ pub struct WindowMatch {
pub x_role_regex: Option<String>,
pub workspace: Option<String>,
pub workspace_regex: Option<String>,
pub content_types: Option<ContentType>,
}
#[derive(Debug, Clone)]

View file

@ -15,6 +15,7 @@ pub mod color_management;
pub mod config;
mod connector;
mod connector_match;
mod content_type;
mod drm_device;
mod drm_device_match;
mod env;

View file

@ -0,0 +1,53 @@
use {
crate::{
config::parser::{DataType, ParseResult, Parser, UnexpectedDataType},
toml::{
toml_span::{Span, Spanned, SpannedExt},
toml_value::Value,
},
},
jay_config::window::{
ContentType, GAME_CONTENT, NO_CONTENT_TYPE, PHOTO_CONTENT, VIDEO_CONTENT,
},
thiserror::Error,
};
#[derive(Debug, Error)]
pub enum ContentTypeParserError {
#[error(transparent)]
Expected(#[from] UnexpectedDataType),
#[error("Unknown content type `{}`", .0)]
UnknownContentType(String),
}
pub struct ContentTypeParser;
impl Parser for ContentTypeParser {
type Value = ContentType;
type Error = ContentTypeParserError;
const EXPECTED: &'static [DataType] = &[DataType::Array, DataType::String];
fn parse_string(&mut self, span: Span, string: &str) -> ParseResult<Self> {
let ty = match string {
"none" => NO_CONTENT_TYPE,
"any" => !NO_CONTENT_TYPE,
"photo" => PHOTO_CONTENT,
"video" => VIDEO_CONTENT,
"game" => GAME_CONTENT,
_ => {
return Err(
ContentTypeParserError::UnknownContentType(string.to_owned()).spanned(span),
);
}
};
Ok(ty)
}
fn parse_array(&mut self, _span: Span, array: &[Spanned<Value>]) -> ParseResult<Self> {
let mut ty = ContentType(0);
for el in array {
ty |= el.parse(&mut ContentTypeParser)?;
}
Ok(ty)
}
}

View file

@ -7,6 +7,7 @@ use {
parser::{DataType, ParseResult, Parser, UnexpectedDataType},
parsers::{
client_match::{ClientMatchParser, ClientMatchParserError},
content_type::{ContentTypeParser, ContentTypeParserError},
window_type::{WindowTypeParser, WindowTypeParserError},
},
},
@ -29,6 +30,8 @@ pub enum WindowMatchParserError {
WindowTypes(#[from] WindowTypeParserError),
#[error(transparent)]
ClientMatchParserError(#[from] ClientMatchParserError),
#[error(transparent)]
ContentTypes(#[from] ContentTypeParserError),
}
pub struct WindowMatchParser<'a>(pub &'a Context<'a>);
@ -77,6 +80,7 @@ impl Parser for WindowMatchParser<'_> {
x_role_regex,
workspace,
workspace_regex,
content_types_val,
),
) = ext.extract((
(
@ -111,6 +115,7 @@ impl Parser for WindowMatchParser<'_> {
opt(str("x-role-regex")),
opt(str("workspace")),
opt(str("workspace-regex")),
opt(val("content-types")),
),
))?;
let mut not = None;
@ -144,6 +149,10 @@ impl Parser for WindowMatchParser<'_> {
if let Some(value) = client_val {
client = Some(value.parse_map(&mut ClientMatchParser(self.0))?);
}
let mut content_types = None;
if let Some(value) = content_types_val {
content_types = Some(value.parse_map(&mut ContentTypeParser)?);
}
Ok(WindowMatch {
generic: GenericMatch {
name: name.despan_into(),
@ -174,6 +183,7 @@ impl Parser for WindowMatchParser<'_> {
workspace_regex: workspace_regex.despan_into(),
types,
client,
content_types,
})
}
}

View file

@ -281,6 +281,9 @@ impl Rule for WindowRule {
};
all.push(matcher);
}
if let Some(value) = &match_.content_types {
all.push(m(WindowCriterion::ContentTypes(*value)));
}
Some(())
}