config: add WM_CLASS window criteria
This commit is contained in:
parent
6d3d4dcabb
commit
faa0b27ef8
15 changed files with 159 additions and 10 deletions
|
|
@ -1991,6 +1991,8 @@ impl ConfigProxyHandler {
|
|||
WindowCriterionStringField::Title => mgr.title(needle),
|
||||
WindowCriterionStringField::AppId => mgr.app_id(needle),
|
||||
WindowCriterionStringField::Tag => mgr.tag(needle),
|
||||
WindowCriterionStringField::XClass => mgr.class(needle),
|
||||
WindowCriterionStringField::XInstance => mgr.instance(needle),
|
||||
}
|
||||
}
|
||||
WindowCriterionIpc::Types(t) => mgr.kind(*t),
|
||||
|
|
|
|||
|
|
@ -18,7 +18,9 @@ use {
|
|||
tlmm_just_mapped::TlmMatchJustMapped,
|
||||
tlmm_kind::TlmMatchKind,
|
||||
tlmm_seat_focus::TlmMatchSeatFocus,
|
||||
tlmm_string::{TlmMatchAppId, TlmMatchTag, TlmMatchTitle},
|
||||
tlmm_string::{
|
||||
TlmMatchAppId, TlmMatchClass, TlmMatchInstance, TlmMatchTag, TlmMatchTitle,
|
||||
},
|
||||
tlmm_urgent::TlmMatchUrgent,
|
||||
tlmm_visible::TlmMatchVisible,
|
||||
},
|
||||
|
|
@ -52,6 +54,7 @@ bitflags! {
|
|||
TL_CHANGED_FULLSCREEN = 1 << 8,
|
||||
TL_CHANGED_JUST_MAPPED = 1 << 9,
|
||||
TL_CHANGED_TAG = 1 << 10,
|
||||
TL_CHANGED_CLASS_INST = 1 << 11,
|
||||
}
|
||||
|
||||
type TlmFixedRootMatcher<T> = FixedRootMatcher<ToplevelData, T>;
|
||||
|
|
@ -80,6 +83,8 @@ pub struct RootMatchers {
|
|||
tag: TlmRootMatcherMap<TlmMatchTag>,
|
||||
app_id: TlmRootMatcherMap<TlmMatchAppId>,
|
||||
seat_foci: TlmRootMatcherMap<TlmMatchSeatFocus>,
|
||||
class: TlmRootMatcherMap<TlmMatchClass>,
|
||||
instance: TlmRootMatcherMap<TlmMatchInstance>,
|
||||
}
|
||||
|
||||
pub async fn handle_tl_changes(state: Rc<State>) {
|
||||
|
|
@ -208,6 +213,8 @@ impl TlMatcherManager {
|
|||
conditional!(TL_CHANGED_APP_ID, app_id);
|
||||
conditional!(TL_CHANGED_SEAT_FOCI, seat_foci);
|
||||
conditional!(TL_CHANGED_TAG, tag);
|
||||
conditional!(TL_CHANGED_CLASS_INST, class);
|
||||
conditional!(TL_CHANGED_CLASS_INST, instance);
|
||||
fixed_conditional!(TL_CHANGED_FLOATING, floating);
|
||||
fixed_conditional!(TL_CHANGED_VISIBLE, visible);
|
||||
fixed_conditional!(TL_CHANGED_URGENT, urgent);
|
||||
|
|
@ -281,6 +288,8 @@ impl TlMatcherManager {
|
|||
conditional!(TL_CHANGED_APP_ID, app_id);
|
||||
conditional!(TL_CHANGED_SEAT_FOCI, seat_foci);
|
||||
conditional!(TL_CHANGED_TAG, tag);
|
||||
conditional!(TL_CHANGED_CLASS_INST, class);
|
||||
conditional!(TL_CHANGED_CLASS_INST, instance);
|
||||
fixed_conditional!(TL_CHANGED_FLOATING, floating);
|
||||
fixed_conditional!(TL_CHANGED_VISIBLE, visible);
|
||||
fixed_conditional!(TL_CHANGED_URGENT, urgent);
|
||||
|
|
@ -338,6 +347,14 @@ impl TlMatcherManager {
|
|||
pub fn seat_focus(&self, seat: &WlSeatGlobal) -> Rc<TlmUpstreamNode> {
|
||||
self.root(TlmMatchSeatFocus::new(seat.id()))
|
||||
}
|
||||
|
||||
pub fn class(&self, string: CritLiteralOrRegex) -> Rc<TlmUpstreamNode> {
|
||||
self.root(TlmMatchClass::new(string))
|
||||
}
|
||||
|
||||
pub fn instance(&self, string: CritLiteralOrRegex) -> Rc<TlmUpstreamNode> {
|
||||
self.root(TlmMatchInstance::new(string))
|
||||
}
|
||||
}
|
||||
|
||||
impl CritTarget for ToplevelData {
|
||||
|
|
|
|||
|
|
@ -11,10 +11,14 @@ pub type TlmMatchString<T> = CritMatchString<ToplevelData, T>;
|
|||
pub type TlmMatchTitle = TlmMatchString<TitleAccess>;
|
||||
pub type TlmMatchAppId = TlmMatchString<AppIdAccess>;
|
||||
pub type TlmMatchTag = TlmMatchString<TagAccess>;
|
||||
pub type TlmMatchClass = TlmMatchString<ClassAccess>;
|
||||
pub type TlmMatchInstance = TlmMatchString<InstanceAccess>;
|
||||
|
||||
pub struct TitleAccess;
|
||||
pub struct AppIdAccess;
|
||||
pub struct TagAccess;
|
||||
pub struct ClassAccess;
|
||||
pub struct InstanceAccess;
|
||||
|
||||
impl StringAccess<ToplevelData> for TitleAccess {
|
||||
fn with_string(data: &ToplevelData, f: impl FnOnce(&str) -> bool) -> bool {
|
||||
|
|
@ -48,3 +52,29 @@ impl StringAccess<ToplevelData> for TagAccess {
|
|||
&roots.tag
|
||||
}
|
||||
}
|
||||
|
||||
impl StringAccess<ToplevelData> for ClassAccess {
|
||||
fn with_string(data: &ToplevelData, f: impl FnOnce(&str) -> bool) -> bool {
|
||||
if let ToplevelType::XWindow(data) = &data.kind {
|
||||
return f(&data.info.class.borrow().as_deref().unwrap_or_default());
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
fn nodes(roots: &RootMatchers) -> &TlmRootMatcherMap<TlmMatchString<Self>> {
|
||||
&roots.class
|
||||
}
|
||||
}
|
||||
|
||||
impl StringAccess<ToplevelData> for InstanceAccess {
|
||||
fn with_string(data: &ToplevelData, f: impl FnOnce(&str) -> bool) -> bool {
|
||||
if let ToplevelType::XWindow(data) = &data.kind {
|
||||
return f(&data.info.instance.borrow().as_deref().unwrap_or_default());
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
fn nodes(roots: &RootMatchers) -> &TlmRootMatcherMap<TlmMatchString<Self>> {
|
||||
&roots.instance
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -90,8 +90,8 @@ pub struct XwindowInfo {
|
|||
pub override_redirect: Cell<bool>,
|
||||
pub extents: Cell<Rect>,
|
||||
pub pending_extents: Cell<Rect>,
|
||||
pub instance: RefCell<Option<BString>>,
|
||||
pub class: RefCell<Option<BString>>,
|
||||
pub instance: RefCell<Option<String>>,
|
||||
pub class: RefCell<Option<String>>,
|
||||
pub title: RefCell<Option<String>>,
|
||||
pub role: RefCell<Option<BString>>,
|
||||
pub protocols: CopyHashMap<u32, ()>,
|
||||
|
|
@ -211,7 +211,7 @@ impl Xwindow {
|
|||
&data.state,
|
||||
data.info.title.borrow_mut().clone().unwrap_or_default(),
|
||||
Some(surface.client.clone()),
|
||||
ToplevelType::XWindow,
|
||||
ToplevelType::XWindow(data.clone()),
|
||||
id,
|
||||
weak,
|
||||
);
|
||||
|
|
|
|||
|
|
@ -16,7 +16,10 @@ use {
|
|||
jay_screencast::JayScreencast,
|
||||
jay_toplevel::JayToplevel,
|
||||
wl_seat::{NodeSeatState, SeatId, collect_kb_foci, collect_kb_foci2},
|
||||
wl_surface::{WlSurface, xdg_surface::xdg_toplevel::XdgToplevelToplevelData},
|
||||
wl_surface::{
|
||||
WlSurface, x_surface::xwindow::XwindowData,
|
||||
xdg_surface::xdg_toplevel::XdgToplevelToplevelData,
|
||||
},
|
||||
},
|
||||
rect::Rect,
|
||||
state::State,
|
||||
|
|
@ -273,12 +276,11 @@ impl ToplevelOpt {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum ToplevelType {
|
||||
Container,
|
||||
Placeholder,
|
||||
XdgToplevel(Rc<XdgToplevelToplevelData>),
|
||||
XWindow,
|
||||
XWindow(Rc<XwindowData>),
|
||||
}
|
||||
|
||||
impl ToplevelType {
|
||||
|
|
@ -287,7 +289,7 @@ impl ToplevelType {
|
|||
ToplevelType::Container => window::CONTAINER,
|
||||
ToplevelType::Placeholder => window::PLACEHOLDER,
|
||||
ToplevelType::XdgToplevel { .. } => window::XDG_TOPLEVEL,
|
||||
ToplevelType::XWindow => window::X_WINDOW,
|
||||
ToplevelType::XWindow { .. } => window::X_WINDOW,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ use {
|
|||
crate::{
|
||||
async_engine::SpawnedFuture,
|
||||
client::Client,
|
||||
criteria::tlm::TL_CHANGED_CLASS_INST,
|
||||
ifs::{
|
||||
ipc::{
|
||||
DataOfferId, DataSourceId, DynDataOffer, DynDataSource, IpcLocation, IpcVtable,
|
||||
|
|
@ -1116,6 +1117,11 @@ impl Wm {
|
|||
|
||||
async fn load_window_wm_class(&self, data: &Rc<XwindowData>) {
|
||||
let mut buf = vec![];
|
||||
let property_changed = || {
|
||||
if let Some(window) = data.window.get() {
|
||||
window.toplevel_data.property_changed(TL_CHANGED_CLASS_INST);
|
||||
}
|
||||
};
|
||||
match self
|
||||
.c
|
||||
.get_property::<u8>(data.window_id, ATOM_WM_CLASS, 0, &mut buf)
|
||||
|
|
@ -1130,6 +1136,7 @@ impl Wm {
|
|||
Err(XconError::PropertyUnavailable) => {
|
||||
data.info.instance.borrow_mut().take();
|
||||
data.info.class.borrow_mut().take();
|
||||
property_changed();
|
||||
return;
|
||||
}
|
||||
Err(e) => {
|
||||
|
|
@ -1138,8 +1145,10 @@ impl Wm {
|
|||
}
|
||||
}
|
||||
let mut iter = buf.split(|c| *c == 0);
|
||||
*data.info.instance.borrow_mut() = Some(iter.next().unwrap_or(&[]).to_vec().into());
|
||||
*data.info.class.borrow_mut() = Some(iter.next().unwrap_or(&[]).to_vec().into());
|
||||
let mut map = || Some(iter.next().unwrap_or(&[]).to_str_lossy().into_owned());
|
||||
*data.info.instance.borrow_mut() = map();
|
||||
*data.info.class.borrow_mut() = map();
|
||||
property_changed();
|
||||
}
|
||||
|
||||
async fn load_window_wm_name2(&self, data: &Rc<XwindowData>, prop: u32, name: &str) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue