1
0
Fork 0
forked from wry/wry

config: add xwayland client criteria

This commit is contained in:
Julian Orth 2025-05-03 12:55:22 +02:00
parent a952e658da
commit bdabb7bbdd
13 changed files with 47 additions and 1 deletions

View file

@ -84,6 +84,7 @@ pub enum ClientCriterionIpc {
Sandboxed, Sandboxed,
Uid(i32), Uid(i32),
Pid(i32), Pid(i32),
IsXwayland,
} }
#[derive(Serialize, Deserialize, Clone, Debug, Hash, Eq, PartialEq)] #[derive(Serialize, Deserialize, Clone, Debug, Hash, Eq, PartialEq)]

View file

@ -1544,6 +1544,7 @@ impl ConfigClient {
ClientCriterion::Sandboxed => ClientCriterionIpc::Sandboxed, ClientCriterion::Sandboxed => ClientCriterionIpc::Sandboxed,
ClientCriterion::Uid(p) => ClientCriterionIpc::Uid(p), ClientCriterion::Uid(p) => ClientCriterionIpc::Uid(p),
ClientCriterion::Pid(p) => ClientCriterionIpc::Pid(p), ClientCriterion::Pid(p) => ClientCriterionIpc::Pid(p),
ClientCriterion::IsXwayland => ClientCriterionIpc::IsXwayland,
}; };
let res = self.send_with_response(&ClientMessage::CreateClientMatcher { criterion }); let res = self.send_with_response(&ClientMessage::CreateClientMatcher { criterion });
get_response!( get_response!(

View file

@ -81,6 +81,8 @@ pub enum ClientCriterion<'a> {
Uid(i32), Uid(i32),
/// Matches the process ID of the client. /// Matches the process ID of the client.
Pid(i32), Pid(i32),
/// Matches if the client is Xwayland.
IsXwayland,
} }
impl ClientCriterion<'_> { impl ClientCriterion<'_> {

View file

@ -1887,6 +1887,7 @@ impl ConfigProxyHandler {
ClientCriterionIpc::Sandboxed => mgr.sandboxed(), ClientCriterionIpc::Sandboxed => mgr.sandboxed(),
ClientCriterionIpc::Uid(p) => mgr.uid(*p), ClientCriterionIpc::Uid(p) => mgr.uid(*p),
ClientCriterionIpc::Pid(p) => mgr.pid(*p), ClientCriterionIpc::Pid(p) => mgr.pid(*p),
ClientCriterionIpc::IsXwayland => mgr.is_xwayland(),
}; };
let cached = Rc::new(CachedCriterion { let cached = Rc::new(CachedCriterion {
crit: criterion.clone(), crit: criterion.clone(),

View file

@ -7,6 +7,7 @@ use {
CritDestroyListener, CritLiteralOrRegex, CritMatcherId, CritMatcherIds, CritMgrExt, CritDestroyListener, CritLiteralOrRegex, CritMatcherId, CritMatcherIds, CritMgrExt,
CritUpstreamNode, FixedRootMatcher, RootMatcherMap, CritUpstreamNode, FixedRootMatcher, RootMatcherMap,
clm::clm_matchers::{ clm::clm_matchers::{
clmm_is_xwayland::ClmMatchIsXwayland,
clmm_pid::ClmMatchPid, clmm_pid::ClmMatchPid,
clmm_sandboxed::ClmMatchSandboxed, clmm_sandboxed::ClmMatchSandboxed,
clmm_string::{ clmm_string::{
@ -44,6 +45,7 @@ pub struct ClMatcherManager {
leaf_events: Rc<AsyncQueue<CritLeafEvent<Rc<Client>>>>, leaf_events: Rc<AsyncQueue<CritLeafEvent<Rc<Client>>>>,
constant: ClmFixedRootMatcher<CritMatchConstant<Rc<Client>>>, constant: ClmFixedRootMatcher<CritMatchConstant<Rc<Client>>>,
sandboxed: ClmFixedRootMatcher<ClmMatchSandboxed>, sandboxed: ClmFixedRootMatcher<ClmMatchSandboxed>,
is_xwayland: ClmFixedRootMatcher<ClmMatchIsXwayland>,
matchers: Rc<RootMatchers>, matchers: Rc<RootMatchers>,
} }
@ -96,6 +98,7 @@ impl ClMatcherManager {
Self { Self {
constant: CritMatchConstant::create(&matchers, ids), constant: CritMatchConstant::create(&matchers, ids),
sandboxed: bool!(ClmMatchSandboxed), sandboxed: bool!(ClmMatchSandboxed),
is_xwayland: bool!(ClmMatchIsXwayland),
changes: Default::default(), changes: Default::default(),
leaf_events: Default::default(), leaf_events: Default::default(),
ids: ids.clone(), ids: ids.clone(),
@ -158,6 +161,7 @@ impl ClMatcherManager {
unconditional!(uid); unconditional!(uid);
unconditional!(pid); unconditional!(pid);
fixed!(sandboxed); fixed!(sandboxed);
fixed!(is_xwayland);
self.constant[true].handle(data); self.constant[true].handle(data);
} }
} }
@ -185,6 +189,10 @@ impl ClMatcherManager {
pub fn pid(&self, pid: i32) -> Rc<ClmUpstreamNode> { pub fn pid(&self, pid: i32) -> Rc<ClmUpstreamNode> {
self.root(ClmMatchPid(pid as _)) self.root(ClmMatchPid(pid as _))
} }
pub fn is_xwayland(&self) -> Rc<ClmUpstreamNode> {
self.is_xwayland[true].clone()
}
} }
impl CritTarget for Rc<Client> { impl CritTarget for Rc<Client> {

View file

@ -17,6 +17,7 @@ macro_rules! fixed_root_criterion {
}; };
} }
pub mod clmm_is_xwayland;
pub mod clmm_pid; pub mod clmm_pid;
pub mod clmm_sandboxed; pub mod clmm_sandboxed;
pub mod clmm_string; pub mod clmm_string;

View file

@ -0,0 +1,14 @@
use {
crate::{client::Client, criteria::crit_graph::CritFixedRootCriterion},
std::rc::Rc,
};
pub struct ClmMatchIsXwayland(pub bool);
fixed_root_criterion!(ClmMatchIsXwayland, is_xwayland);
impl CritFixedRootCriterion<Rc<Client>> for ClmMatchIsXwayland {
fn matches(&self, data: &Rc<Client>) -> bool {
data.is_xwayland
}
}

View file

@ -234,6 +234,7 @@ pub struct ClientMatch {
pub sandboxed: Option<bool>, pub sandboxed: Option<bool>,
pub uid: Option<i32>, pub uid: Option<i32>,
pub pid: Option<i32>, pub pid: Option<i32>,
pub is_xwayland: Option<bool>,
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]

View file

@ -49,7 +49,7 @@ impl Parser for ClientMatchParser<'_> {
sandbox_app_id, sandbox_app_id,
sandbox_app_id_regex, sandbox_app_id_regex,
), ),
(sandbox_instance_id, sandbox_instance_id_regex, uid, pid), (sandbox_instance_id, sandbox_instance_id_regex, uid, pid, is_xwayland),
) = ext.extract(( ) = ext.extract((
( (
opt(str("name")), opt(str("name")),
@ -68,6 +68,7 @@ impl Parser for ClientMatchParser<'_> {
opt(str("sandbox-instance-id-regex")), opt(str("sandbox-instance-id-regex")),
opt(s32("uid")), opt(s32("uid")),
opt(s32("pid")), opt(s32("pid")),
opt(bol("is-xwayland")),
), ),
))?; ))?;
let mut not = None; let mut not = None;
@ -110,6 +111,7 @@ impl Parser for ClientMatchParser<'_> {
sandboxed: sandboxed.despan(), sandboxed: sandboxed.despan(),
uid: uid.despan(), uid: uid.despan(),
pid: pid.despan(), pid: pid.despan(),
is_xwayland: is_xwayland.despan(),
}) })
} }
} }

View file

@ -123,6 +123,7 @@ impl Rule for ClientRule {
value!(Uid, uid); value!(Uid, uid);
value!(Pid, pid); value!(Pid, pid);
bool!(Sandboxed, sandboxed); bool!(Sandboxed, sandboxed);
bool!(IsXwayland, is_xwayland);
Some(()) Some(())
} }

View file

@ -567,6 +567,10 @@
"pid": { "pid": {
"type": "integer", "type": "integer",
"description": "Matches the process ID of the client." "description": "Matches the process ID of the client."
},
"is-xwayland": {
"type": "boolean",
"description": "Matches if the client is/isn't Xwayland."
} }
}, },
"required": [] "required": []

View file

@ -887,6 +887,12 @@ The table has the following fields:
The numbers should be integers. The numbers should be integers.
- `is-xwayland` (optional):
Matches if the client is/isn't Xwayland.
The value of this field should be a boolean.
<a name="types-ClientMatchExactly"></a> <a name="types-ClientMatchExactly"></a>
### `ClientMatchExactly` ### `ClientMatchExactly`

View file

@ -3247,6 +3247,10 @@ ClientMatch:
integer_only: true integer_only: true
required: false required: false
description: Matches the process ID of the client. description: Matches the process ID of the client.
is-xwayland:
kind: boolean
required: false
description: Matches if the client is/isn't Xwayland.
ClientMatchExactly: ClientMatchExactly: