config: add content-type window criteria
This commit is contained in:
parent
fb5c50467b
commit
4fd70f03e1
22 changed files with 327 additions and 18 deletions
|
|
@ -16,7 +16,10 @@ use {
|
|||
tlm::{TlmLeafMatcher, TlmUpstreamNode},
|
||||
},
|
||||
format::config_formats,
|
||||
ifs::wl_seat::{SeatId, WlSeatGlobal},
|
||||
ifs::{
|
||||
wl_seat::{SeatId, WlSeatGlobal},
|
||||
wp_content_type_v1::ContentTypeExt,
|
||||
},
|
||||
io_uring::TaskResultExt,
|
||||
kbvm::{KbvmError, KbvmMap},
|
||||
output_schedule::map_cursor_hz,
|
||||
|
|
@ -2062,6 +2065,7 @@ impl ConfigProxyHandler {
|
|||
WindowCriterionIpc::Workspace(w) => mgr.workspace(CritLiteralOrRegex::Literal(
|
||||
self.get_workspace(*w)?.to_string(),
|
||||
)),
|
||||
WindowCriterionIpc::ContentTypes(t) => mgr.content_type(*t),
|
||||
};
|
||||
let cached = Rc::new(CachedCriterion {
|
||||
crit: criterion.clone(),
|
||||
|
|
@ -2356,6 +2360,17 @@ impl ConfigProxyHandler {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_get_content_type(&self, window: Window) -> Result<(), CphError> {
|
||||
let kind = self
|
||||
.get_window(window)?
|
||||
.tl_data()
|
||||
.content_type
|
||||
.get()
|
||||
.to_config();
|
||||
self.respond(Response::GetContentType { kind });
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_window_exists(&self, window: Window) {
|
||||
self.respond(Response::WindowExists {
|
||||
exists: self.get_window(window).is_ok(),
|
||||
|
|
@ -2964,6 +2979,9 @@ impl ConfigProxyHandler {
|
|||
ClientMessage::SetMiddleButtonEmulationEnabled { device, enabled } => self
|
||||
.handle_set_middle_button_emulation_enabled(device, enabled)
|
||||
.wrn("set_middle_button_emulation_enabled")?,
|
||||
ClientMessage::GetContentType { window } => self
|
||||
.handle_get_content_type(window)
|
||||
.wrn("get_content_type")?,
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ use {
|
|||
crit_matchers::critm_constant::CritMatchConstant,
|
||||
tlm::tlm_matchers::{
|
||||
tlmm_client::TlmMatchClient,
|
||||
tlmm_content_type::TlmMatchContentType,
|
||||
tlmm_floating::TlmMatchFloating,
|
||||
tlmm_fullscreen::TlmMatchFullscreen,
|
||||
tlmm_just_mapped::TlmMatchJustMapped,
|
||||
|
|
@ -34,7 +35,7 @@ use {
|
|||
toplevel_identifier::ToplevelIdentifier,
|
||||
},
|
||||
},
|
||||
jay_config::window::WindowType,
|
||||
jay_config::window::{ContentType, WindowType},
|
||||
linearize::static_map,
|
||||
std::{
|
||||
marker::PhantomData,
|
||||
|
|
@ -58,6 +59,7 @@ bitflags! {
|
|||
TL_CHANGED_CLASS_INST = 1 << 11,
|
||||
TL_CHANGED_ROLE = 1 << 12,
|
||||
TL_CHANGED_WORKSPACE = 1 << 13,
|
||||
TL_CHANGED_CONTENT_TY = 1 << 14,
|
||||
}
|
||||
|
||||
type TlmFixedRootMatcher<T> = FixedRootMatcher<ToplevelData, T>;
|
||||
|
|
@ -90,6 +92,7 @@ pub struct RootMatchers {
|
|||
instance: TlmRootMatcherMap<TlmMatchInstance>,
|
||||
role: TlmRootMatcherMap<TlmMatchRole>,
|
||||
workspace: TlmRootMatcherMap<TlmMatchWorkspace>,
|
||||
content_ty: TlmRootMatcherMap<TlmMatchContentType>,
|
||||
}
|
||||
|
||||
pub async fn handle_tl_changes(state: Rc<State>) {
|
||||
|
|
@ -222,6 +225,7 @@ impl TlMatcherManager {
|
|||
conditional!(TL_CHANGED_CLASS_INST, instance);
|
||||
conditional!(TL_CHANGED_ROLE, role);
|
||||
conditional!(TL_CHANGED_WORKSPACE, workspace);
|
||||
conditional!(TL_CHANGED_CONTENT_TY, content_ty);
|
||||
fixed_conditional!(TL_CHANGED_FLOATING, floating);
|
||||
fixed_conditional!(TL_CHANGED_VISIBLE, visible);
|
||||
fixed_conditional!(TL_CHANGED_URGENT, urgent);
|
||||
|
|
@ -299,6 +303,7 @@ impl TlMatcherManager {
|
|||
conditional!(TL_CHANGED_CLASS_INST, instance);
|
||||
conditional!(TL_CHANGED_ROLE, role);
|
||||
conditional!(TL_CHANGED_WORKSPACE, workspace);
|
||||
conditional!(TL_CHANGED_CONTENT_TY, content_ty);
|
||||
fixed_conditional!(TL_CHANGED_FLOATING, floating);
|
||||
fixed_conditional!(TL_CHANGED_VISIBLE, visible);
|
||||
fixed_conditional!(TL_CHANGED_URGENT, urgent);
|
||||
|
|
@ -372,6 +377,10 @@ impl TlMatcherManager {
|
|||
pub fn workspace(&self, string: CritLiteralOrRegex) -> Rc<TlmUpstreamNode> {
|
||||
self.root(TlmMatchWorkspace::new(string))
|
||||
}
|
||||
|
||||
pub fn content_type(&self, kind: ContentType) -> Rc<TlmUpstreamNode> {
|
||||
self.root(TlmMatchContentType::new(kind))
|
||||
}
|
||||
}
|
||||
|
||||
impl CritTarget for ToplevelData {
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ macro_rules! fixed_root_criterion {
|
|||
}
|
||||
|
||||
pub mod tlmm_client;
|
||||
pub mod tlmm_content_type;
|
||||
pub mod tlmm_floating;
|
||||
pub mod tlmm_fullscreen;
|
||||
pub mod tlmm_just_mapped;
|
||||
|
|
|
|||
32
src/criteria/tlm/tlm_matchers/tlmm_content_type.rs
Normal file
32
src/criteria/tlm/tlm_matchers/tlmm_content_type.rs
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
use {
|
||||
crate::{
|
||||
criteria::{
|
||||
crit_graph::CritRootCriterion,
|
||||
tlm::{RootMatchers, TlmRootMatcherMap},
|
||||
},
|
||||
ifs::wp_content_type_v1::ContentTypeExt,
|
||||
tree::ToplevelData,
|
||||
utils::bitflags::BitflagsExt,
|
||||
},
|
||||
jay_config::window::ContentType,
|
||||
};
|
||||
|
||||
pub struct TlmMatchContentType {
|
||||
kind: ContentType,
|
||||
}
|
||||
|
||||
impl TlmMatchContentType {
|
||||
pub fn new(kind: ContentType) -> TlmMatchContentType {
|
||||
Self { kind }
|
||||
}
|
||||
}
|
||||
|
||||
impl CritRootCriterion<ToplevelData> for TlmMatchContentType {
|
||||
fn matches(&self, data: &ToplevelData) -> bool {
|
||||
self.kind.0.contains(data.content_type.get().to_config().0)
|
||||
}
|
||||
|
||||
fn nodes(roots: &RootMatchers) -> Option<&TlmRootMatcherMap<Self>> {
|
||||
Some(&roots.content_ty)
|
||||
}
|
||||
}
|
||||
|
|
@ -26,6 +26,9 @@ impl SurfaceExt for XSurface {
|
|||
fn after_apply_commit(self: Rc<Self>) {
|
||||
if let Some(xwindow) = self.xwindow.get() {
|
||||
xwindow.map_status_changed();
|
||||
xwindow
|
||||
.toplevel_data
|
||||
.set_content_type(self.surface.content_type.get());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -217,6 +217,7 @@ impl Xwindow {
|
|||
weak,
|
||||
);
|
||||
tld.pos.set(surface.extents.get());
|
||||
tld.content_type.set(surface.content_type.get());
|
||||
Self {
|
||||
id,
|
||||
data: data.clone(),
|
||||
|
|
|
|||
|
|
@ -146,6 +146,17 @@ impl XdgToplevel {
|
|||
let data = Rc::new(XdgToplevelToplevelData {
|
||||
tag: Default::default(),
|
||||
});
|
||||
let toplevel_data = ToplevelData::new(
|
||||
state,
|
||||
String::new(),
|
||||
Some(surface.surface.client.clone()),
|
||||
ToplevelType::XdgToplevel(data.clone()),
|
||||
node_id,
|
||||
slf,
|
||||
);
|
||||
toplevel_data
|
||||
.content_type
|
||||
.set(surface.surface.content_type.get());
|
||||
Self {
|
||||
id,
|
||||
state: state.clone(),
|
||||
|
|
@ -161,14 +172,7 @@ impl XdgToplevel {
|
|||
max_width: Cell::new(None),
|
||||
max_height: Cell::new(None),
|
||||
tracker: Default::default(),
|
||||
toplevel_data: ToplevelData::new(
|
||||
state,
|
||||
String::new(),
|
||||
Some(surface.surface.client.clone()),
|
||||
ToplevelType::XdgToplevel(data.clone()),
|
||||
node_id,
|
||||
slf,
|
||||
),
|
||||
toplevel_data,
|
||||
drag: Default::default(),
|
||||
is_mapped: Cell::new(false),
|
||||
dialog: Default::default(),
|
||||
|
|
@ -518,6 +522,8 @@ impl XdgToplevel {
|
|||
self.state.tree_changed();
|
||||
self.toplevel_data.broadcast(self.clone());
|
||||
}
|
||||
self.toplevel_data
|
||||
.set_content_type(self.xdg.surface.content_type.get());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,10 @@ use {
|
|||
object::{Object, Version},
|
||||
wire::{WpContentTypeV1Id, wp_content_type_v1::*},
|
||||
},
|
||||
jay_config::window::{
|
||||
ContentType as ConfigContentType, GAME_CONTENT, NO_CONTENT_TYPE, PHOTO_CONTENT,
|
||||
VIDEO_CONTENT,
|
||||
},
|
||||
std::rc::Rc,
|
||||
thiserror::Error,
|
||||
};
|
||||
|
|
@ -22,6 +26,21 @@ pub enum ContentType {
|
|||
Game,
|
||||
}
|
||||
|
||||
pub trait ContentTypeExt {
|
||||
fn to_config(&self) -> ConfigContentType;
|
||||
}
|
||||
|
||||
impl ContentTypeExt for Option<ContentType> {
|
||||
fn to_config(&self) -> ConfigContentType {
|
||||
match self {
|
||||
None => NO_CONTENT_TYPE,
|
||||
Some(ContentType::Photo) => PHOTO_CONTENT,
|
||||
Some(ContentType::Video) => VIDEO_CONTENT,
|
||||
Some(ContentType::Game) => GAME_CONTENT,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct WpContentTypeV1 {
|
||||
pub id: WpContentTypeV1Id,
|
||||
pub client: Rc<Client>,
|
||||
|
|
|
|||
|
|
@ -4,9 +4,9 @@ use {
|
|||
criteria::{
|
||||
CritDestroyListener, CritMatcherId,
|
||||
tlm::{
|
||||
TL_CHANGED_APP_ID, TL_CHANGED_DESTROYED, TL_CHANGED_FLOATING,
|
||||
TL_CHANGED_FULLSCREEN, TL_CHANGED_NEW, TL_CHANGED_TITLE, TL_CHANGED_URGENT,
|
||||
TL_CHANGED_VISIBLE, TL_CHANGED_WORKSPACE, TlMatcherChange,
|
||||
TL_CHANGED_APP_ID, TL_CHANGED_CONTENT_TY, TL_CHANGED_DESTROYED,
|
||||
TL_CHANGED_FLOATING, TL_CHANGED_FULLSCREEN, TL_CHANGED_NEW, TL_CHANGED_TITLE,
|
||||
TL_CHANGED_URGENT, TL_CHANGED_VISIBLE, TL_CHANGED_WORKSPACE, TlMatcherChange,
|
||||
},
|
||||
},
|
||||
ifs::{
|
||||
|
|
@ -20,6 +20,7 @@ use {
|
|||
WlSurface, x_surface::xwindow::XwindowData,
|
||||
xdg_surface::xdg_toplevel::XdgToplevelToplevelData,
|
||||
},
|
||||
wp_content_type_v1::ContentType,
|
||||
zwlr_foreign_toplevel_handle_v1::ZwlrForeignToplevelHandleV1,
|
||||
zwlr_foreign_toplevel_manager_v1::ZwlrForeignToplevelManagerV1,
|
||||
},
|
||||
|
|
@ -371,6 +372,7 @@ pub struct ToplevelData {
|
|||
pub changed_properties: Cell<TlMatcherChange>,
|
||||
pub just_mapped_scheduled: Cell<bool>,
|
||||
pub seat_foci: CopyHashMap<SeatId, ()>,
|
||||
pub content_type: Cell<Option<ContentType>>,
|
||||
}
|
||||
|
||||
impl ToplevelData {
|
||||
|
|
@ -422,6 +424,7 @@ impl ToplevelData {
|
|||
changed_properties: Default::default(),
|
||||
just_mapped_scheduled: Cell::new(false),
|
||||
seat_foci: Default::default(),
|
||||
content_type: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -857,6 +860,12 @@ impl ToplevelData {
|
|||
pub fn just_mapped(&self) -> bool {
|
||||
self.mapped_during_iteration.get() == self.state.eng.iteration()
|
||||
}
|
||||
|
||||
pub fn set_content_type(&self, content_type: Option<ContentType>) {
|
||||
if self.content_type.replace(content_type) != content_type {
|
||||
self.property_changed(TL_CHANGED_CONTENT_TY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for ToplevelData {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue