config: add window-rule infrastructure
This commit is contained in:
parent
a6257910bb
commit
59f8acdfde
26 changed files with 1829 additions and 38 deletions
|
|
@ -1,10 +1,13 @@
|
|||
use {
|
||||
crate::{
|
||||
State,
|
||||
config::{ClientMatch, ClientRule, GenericMatch},
|
||||
config::{ClientMatch, ClientRule, GenericMatch, WindowMatch, WindowRule},
|
||||
},
|
||||
ahash::{AHashMap, AHashSet},
|
||||
jay_config::client::{ClientCriterion, ClientMatcher},
|
||||
jay_config::{
|
||||
client::{ClientCriterion, ClientMatcher},
|
||||
window::{WindowCriterion, WindowMatcher},
|
||||
},
|
||||
std::{mem::ManuallyDrop, rc::Rc},
|
||||
};
|
||||
|
||||
|
|
@ -195,6 +198,131 @@ impl Rule for ClientRule {
|
|||
}
|
||||
}
|
||||
|
||||
impl Rule for WindowRule {
|
||||
type Match = WindowMatch;
|
||||
type Matcher = WindowMatcher;
|
||||
type Criterion<'a> = WindowCriterion<'a>;
|
||||
|
||||
const NAME_UPPER: &str = "Window";
|
||||
const NAME_LOWER: &str = "window";
|
||||
|
||||
fn name(&self) -> Option<&str> {
|
||||
self.name.as_deref()
|
||||
}
|
||||
|
||||
fn match_(&self) -> &Self::Match {
|
||||
&self.match_
|
||||
}
|
||||
|
||||
fn generic(m: &Self::Match) -> &GenericMatch<Self::Match> {
|
||||
&m.generic
|
||||
}
|
||||
|
||||
fn map_custom(
|
||||
_state: &Rc<State>,
|
||||
all: &mut Vec<MatcherTemp<Self>>,
|
||||
match_: &Self::Match,
|
||||
) -> Option<()> {
|
||||
let m = |c: WindowCriterion<'_>| MatcherTemp(c.to_matcher());
|
||||
#[expect(unused_macros)]
|
||||
macro_rules! value {
|
||||
($ty:ident, $field:ident) => {
|
||||
if let Some(value) = &match_.$field {
|
||||
all.push(m(WindowCriterion::$ty(value)));
|
||||
}
|
||||
};
|
||||
}
|
||||
#[expect(unused_macros)]
|
||||
macro_rules! bool {
|
||||
($ty:ident, $field:ident) => {
|
||||
if let Some(value) = &match_.$field {
|
||||
let crit = WindowCriterion::$ty;
|
||||
let matcher = match value {
|
||||
false => m(WindowCriterion::Not(&crit)),
|
||||
true => m(crit),
|
||||
};
|
||||
all.push(matcher);
|
||||
}
|
||||
};
|
||||
}
|
||||
if let Some(value) = &match_.types {
|
||||
all.push(m(WindowCriterion::Types(*value)));
|
||||
}
|
||||
Some(())
|
||||
}
|
||||
|
||||
fn create(c: Self::Criterion<'_>) -> Self::Matcher {
|
||||
c.to_matcher()
|
||||
}
|
||||
|
||||
fn destroy(m: Self::Matcher) {
|
||||
m.destroy();
|
||||
}
|
||||
|
||||
fn bind(&self, state: &Rc<State>, matcher: Self::Matcher) {
|
||||
let state = state.clone();
|
||||
macro_rules! latch {
|
||||
($g:ident, $client:ident, $win:ident) => {
|
||||
let g = $g.clone();
|
||||
let state = state.clone();
|
||||
$win.latch(move || {
|
||||
state.with_client($client, true, || {
|
||||
state.with_window(*$win, true, || g());
|
||||
});
|
||||
});
|
||||
};
|
||||
}
|
||||
if let Some(action) = &self.action {
|
||||
let f = action.clone().into_fn(&state);
|
||||
if let Some(action) = &self.latch {
|
||||
let g = action.clone().into_rc_fn(&state);
|
||||
matcher.bind(move |win| {
|
||||
let client = win.client();
|
||||
state.with_client(client, false, || {
|
||||
state.with_window(*win, false, &f);
|
||||
});
|
||||
latch!(g, client, win);
|
||||
});
|
||||
} else {
|
||||
matcher.bind(move |win| {
|
||||
let client = win.client();
|
||||
state.with_client(client, false, || {
|
||||
state.with_window(*win, false, &f);
|
||||
});
|
||||
});
|
||||
}
|
||||
} else {
|
||||
if let Some(action) = &self.latch {
|
||||
let g = action.clone().into_rc_fn(&state);
|
||||
matcher.bind(move |win| {
|
||||
let client = win.client();
|
||||
latch!(g, client, win);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn gen_matcher(m: Self::Matcher) -> Self::Criterion<'static> {
|
||||
WindowCriterion::Matcher(m)
|
||||
}
|
||||
|
||||
fn gen_not<'a, 'b: 'a>(m: &'a Self::Criterion<'b>) -> Self::Criterion<'a> {
|
||||
WindowCriterion::Not(m)
|
||||
}
|
||||
|
||||
fn gen_all<'a, 'b: 'a>(m: &'a [Self::Criterion<'b>]) -> Self::Criterion<'a> {
|
||||
WindowCriterion::All(m)
|
||||
}
|
||||
|
||||
fn gen_any<'a, 'b: 'a>(m: &'a [Self::Criterion<'b>]) -> Self::Criterion<'a> {
|
||||
WindowCriterion::Any(m)
|
||||
}
|
||||
|
||||
fn gen_exactly<'a, 'b: 'a>(n: usize, m: &'a [Self::Criterion<'b>]) -> Self::Criterion<'a> {
|
||||
WindowCriterion::Exactly(n, m)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct RuleMapper<R>
|
||||
where
|
||||
R: Rule,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue