config: add just-mapped window criteria
This commit is contained in:
parent
e36ccd560c
commit
5f1268cada
16 changed files with 95 additions and 4 deletions
|
|
@ -116,6 +116,7 @@ pub enum WindowCriterionIpc {
|
||||||
Urgent,
|
Urgent,
|
||||||
SeatFocus(Seat),
|
SeatFocus(Seat),
|
||||||
Fullscreen,
|
Fullscreen,
|
||||||
|
JustMapped,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Clone, Debug, Hash, Eq, PartialEq)]
|
#[derive(Serialize, Deserialize, Clone, Debug, Hash, Eq, PartialEq)]
|
||||||
|
|
|
||||||
|
|
@ -1662,6 +1662,7 @@ impl ConfigClient {
|
||||||
WindowCriterion::Urgent => WindowCriterionIpc::Urgent,
|
WindowCriterion::Urgent => WindowCriterionIpc::Urgent,
|
||||||
WindowCriterion::Focus(seat) => WindowCriterionIpc::SeatFocus(seat),
|
WindowCriterion::Focus(seat) => WindowCriterionIpc::SeatFocus(seat),
|
||||||
WindowCriterion::Fullscreen => WindowCriterionIpc::Fullscreen,
|
WindowCriterion::Fullscreen => WindowCriterionIpc::Fullscreen,
|
||||||
|
WindowCriterion::JustMapped => WindowCriterionIpc::JustMapped,
|
||||||
};
|
};
|
||||||
let res = self.send_with_response(&ClientMessage::CreateWindowMatcher { criterion });
|
let res = self.send_with_response(&ClientMessage::CreateWindowMatcher { criterion });
|
||||||
get_response!(
|
get_response!(
|
||||||
|
|
|
||||||
|
|
@ -255,6 +255,11 @@ pub enum WindowCriterion<'a> {
|
||||||
Focus(Seat),
|
Focus(Seat),
|
||||||
/// Matches if the window is fullscreen.
|
/// Matches if the window is fullscreen.
|
||||||
Fullscreen,
|
Fullscreen,
|
||||||
|
/// Matches if the window has/hasn't just been mapped.
|
||||||
|
///
|
||||||
|
/// This is true for one iteration of the compositor's main loop immediately after the
|
||||||
|
/// window has been mapped.
|
||||||
|
JustMapped,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WindowCriterion<'_> {
|
impl WindowCriterion<'_> {
|
||||||
|
|
|
||||||
|
|
@ -105,7 +105,6 @@ impl AsyncEngine {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
self.now.take();
|
self.now.take();
|
||||||
self.iteration.fetch_add(1);
|
|
||||||
let mut phase = 0;
|
let mut phase = 0;
|
||||||
while phase < NUM_PHASES {
|
while phase < NUM_PHASES {
|
||||||
self.queues[phase].swap(&mut *stash);
|
self.queues[phase].swap(&mut *stash);
|
||||||
|
|
@ -121,6 +120,7 @@ impl AsyncEngine {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
self.iteration.fetch_add(1);
|
||||||
self.yields.swap(&mut *yield_stash);
|
self.yields.swap(&mut *yield_stash);
|
||||||
while let Some(waker) = yield_stash.pop_front() {
|
while let Some(waker) = yield_stash.pop_front() {
|
||||||
waker.wake();
|
waker.wake();
|
||||||
|
|
@ -153,7 +153,7 @@ impl AsyncEngine {
|
||||||
self.yields.push(waker);
|
self.yields.push(waker);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn iteration(&self) -> u64 {
|
pub fn iteration(&self) -> u64 {
|
||||||
self.iteration.get()
|
self.iteration.get()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,9 @@ use {
|
||||||
criteria::{
|
criteria::{
|
||||||
CritMatcherIds,
|
CritMatcherIds,
|
||||||
clm::{ClMatcherManager, handle_cl_changes, handle_cl_leaf_events},
|
clm::{ClMatcherManager, handle_cl_changes, handle_cl_leaf_events},
|
||||||
tlm::{TlMatcherManager, handle_tl_changes, handle_tl_leaf_events},
|
tlm::{
|
||||||
|
TlMatcherManager, handle_tl_changes, handle_tl_just_mapped, handle_tl_leaf_events,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
damage::{DamageVisualizer, visualize_damage},
|
damage::{DamageVisualizer, visualize_damage},
|
||||||
dbus::Dbus,
|
dbus::Dbus,
|
||||||
|
|
@ -484,6 +486,11 @@ fn start_global_event_handlers(
|
||||||
"tl matcher leaf events",
|
"tl matcher leaf events",
|
||||||
handle_tl_leaf_events(state.clone()),
|
handle_tl_leaf_events(state.clone()),
|
||||||
),
|
),
|
||||||
|
eng.spawn2(
|
||||||
|
"tl matcher just mapped",
|
||||||
|
Phase::Layout,
|
||||||
|
handle_tl_just_mapped(state.clone()),
|
||||||
|
),
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2002,6 +2002,7 @@ impl ConfigProxyHandler {
|
||||||
WindowCriterionIpc::Urgent => mgr.urgent(),
|
WindowCriterionIpc::Urgent => mgr.urgent(),
|
||||||
WindowCriterionIpc::SeatFocus(seat) => mgr.seat_focus(&*self.get_seat(*seat)?),
|
WindowCriterionIpc::SeatFocus(seat) => mgr.seat_focus(&*self.get_seat(*seat)?),
|
||||||
WindowCriterionIpc::Fullscreen => mgr.fullscreen(),
|
WindowCriterionIpc::Fullscreen => mgr.fullscreen(),
|
||||||
|
WindowCriterionIpc::JustMapped => mgr.just_mapped(),
|
||||||
};
|
};
|
||||||
let cached = Rc::new(CachedCriterion {
|
let cached = Rc::new(CachedCriterion {
|
||||||
crit: criterion.clone(),
|
crit: criterion.clone(),
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ use {
|
||||||
tlmm_client::TlmMatchClient,
|
tlmm_client::TlmMatchClient,
|
||||||
tlmm_floating::TlmMatchFloating,
|
tlmm_floating::TlmMatchFloating,
|
||||||
tlmm_fullscreen::TlmMatchFullscreen,
|
tlmm_fullscreen::TlmMatchFullscreen,
|
||||||
|
tlmm_just_mapped::TlmMatchJustMapped,
|
||||||
tlmm_kind::TlmMatchKind,
|
tlmm_kind::TlmMatchKind,
|
||||||
tlmm_seat_focus::TlmMatchSeatFocus,
|
tlmm_seat_focus::TlmMatchSeatFocus,
|
||||||
tlmm_string::{TlmMatchAppId, TlmMatchTitle},
|
tlmm_string::{TlmMatchAppId, TlmMatchTitle},
|
||||||
|
|
@ -49,6 +50,7 @@ bitflags! {
|
||||||
TL_CHANGED_URGENT = 1 << 6,
|
TL_CHANGED_URGENT = 1 << 6,
|
||||||
TL_CHANGED_SEAT_FOCI = 1 << 7,
|
TL_CHANGED_SEAT_FOCI = 1 << 7,
|
||||||
TL_CHANGED_FULLSCREEN = 1 << 8,
|
TL_CHANGED_FULLSCREEN = 1 << 8,
|
||||||
|
TL_CHANGED_JUST_MAPPED = 1 << 9,
|
||||||
}
|
}
|
||||||
|
|
||||||
type TlmFixedRootMatcher<T> = FixedRootMatcher<ToplevelData, T>;
|
type TlmFixedRootMatcher<T> = FixedRootMatcher<ToplevelData, T>;
|
||||||
|
|
@ -57,11 +59,13 @@ pub struct TlMatcherManager {
|
||||||
ids: Rc<CritMatcherIds>,
|
ids: Rc<CritMatcherIds>,
|
||||||
changes: AsyncQueue<Rc<dyn ToplevelNode>>,
|
changes: AsyncQueue<Rc<dyn ToplevelNode>>,
|
||||||
leaf_events: Rc<AsyncQueue<CritLeafEvent<ToplevelData>>>,
|
leaf_events: Rc<AsyncQueue<CritLeafEvent<ToplevelData>>>,
|
||||||
|
handle_just_mapped: AsyncQueue<Rc<dyn ToplevelNode>>,
|
||||||
constant: TlmFixedRootMatcher<CritMatchConstant<ToplevelData>>,
|
constant: TlmFixedRootMatcher<CritMatchConstant<ToplevelData>>,
|
||||||
floating: TlmFixedRootMatcher<TlmMatchFloating>,
|
floating: TlmFixedRootMatcher<TlmMatchFloating>,
|
||||||
visible: TlmFixedRootMatcher<TlmMatchVisible>,
|
visible: TlmFixedRootMatcher<TlmMatchVisible>,
|
||||||
urgent: TlmFixedRootMatcher<TlmMatchUrgent>,
|
urgent: TlmFixedRootMatcher<TlmMatchUrgent>,
|
||||||
fullscreen: TlmFixedRootMatcher<TlmMatchFullscreen>,
|
fullscreen: TlmFixedRootMatcher<TlmMatchFullscreen>,
|
||||||
|
just_mapped: TlmFixedRootMatcher<TlmMatchJustMapped>,
|
||||||
matchers: Rc<RootMatchers>,
|
matchers: Rc<RootMatchers>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -94,6 +98,16 @@ pub async fn handle_tl_leaf_events(state: Rc<State>) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn handle_tl_just_mapped(state: Rc<State>) {
|
||||||
|
let mgr = &state.tl_matcher_manager;
|
||||||
|
loop {
|
||||||
|
let tl = mgr.handle_just_mapped.pop().await;
|
||||||
|
let data = tl.tl_data();
|
||||||
|
data.just_mapped_scheduled.set(false);
|
||||||
|
data.property_changed(TL_CHANGED_JUST_MAPPED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub type TlmUpstreamNode = dyn CritUpstreamNode<ToplevelData>;
|
pub type TlmUpstreamNode = dyn CritUpstreamNode<ToplevelData>;
|
||||||
pub type TlmLeafMatcher = CritLeafMatcher<ToplevelData>;
|
pub type TlmLeafMatcher = CritLeafMatcher<ToplevelData>;
|
||||||
|
|
||||||
|
|
@ -117,16 +131,19 @@ impl TlMatcherManager {
|
||||||
visible: bool!(TlmMatchVisible),
|
visible: bool!(TlmMatchVisible),
|
||||||
urgent: bool!(TlmMatchUrgent),
|
urgent: bool!(TlmMatchUrgent),
|
||||||
fullscreen: bool!(TlmMatchFullscreen),
|
fullscreen: bool!(TlmMatchFullscreen),
|
||||||
|
just_mapped: bool!(TlmMatchJustMapped),
|
||||||
changes: Default::default(),
|
changes: Default::default(),
|
||||||
leaf_events: Default::default(),
|
leaf_events: Default::default(),
|
||||||
ids: ids.clone(),
|
ids: ids.clone(),
|
||||||
matchers,
|
matchers,
|
||||||
|
handle_just_mapped: Default::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn clear(&self) {
|
pub fn clear(&self) {
|
||||||
self.changes.clear();
|
self.changes.clear();
|
||||||
self.leaf_events.clear();
|
self.leaf_events.clear();
|
||||||
|
self.handle_just_mapped.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn rematch_all(&self, state: &Rc<State>) {
|
pub fn rematch_all(&self, state: &Rc<State>) {
|
||||||
|
|
@ -192,6 +209,7 @@ impl TlMatcherManager {
|
||||||
fixed_conditional!(TL_CHANGED_VISIBLE, visible);
|
fixed_conditional!(TL_CHANGED_VISIBLE, visible);
|
||||||
fixed_conditional!(TL_CHANGED_URGENT, urgent);
|
fixed_conditional!(TL_CHANGED_URGENT, urgent);
|
||||||
fixed_conditional!(TL_CHANGED_FULLSCREEN, fullscreen);
|
fixed_conditional!(TL_CHANGED_FULLSCREEN, fullscreen);
|
||||||
|
fixed_conditional!(TL_CHANGED_JUST_MAPPED, just_mapped);
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -263,6 +281,14 @@ impl TlMatcherManager {
|
||||||
fixed_conditional!(TL_CHANGED_VISIBLE, visible);
|
fixed_conditional!(TL_CHANGED_VISIBLE, visible);
|
||||||
fixed_conditional!(TL_CHANGED_URGENT, urgent);
|
fixed_conditional!(TL_CHANGED_URGENT, urgent);
|
||||||
fixed_conditional!(TL_CHANGED_FULLSCREEN, fullscreen);
|
fixed_conditional!(TL_CHANGED_FULLSCREEN, fullscreen);
|
||||||
|
fixed_conditional!(TL_CHANGED_JUST_MAPPED, just_mapped);
|
||||||
|
if changed.contains(TL_CHANGED_JUST_MAPPED)
|
||||||
|
&& data.just_mapped()
|
||||||
|
&& (self.just_mapped[false].has_downstream() || self.just_mapped[true].has_downstream())
|
||||||
|
&& !data.just_mapped_scheduled.replace(true)
|
||||||
|
{
|
||||||
|
self.handle_just_mapped.push(node);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn title(&self, string: CritLiteralOrRegex) -> Rc<TlmUpstreamNode> {
|
pub fn title(&self, string: CritLiteralOrRegex) -> Rc<TlmUpstreamNode> {
|
||||||
|
|
@ -297,6 +323,10 @@ impl TlMatcherManager {
|
||||||
self.urgent[true].clone()
|
self.urgent[true].clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn just_mapped(&self) -> Rc<TlmUpstreamNode> {
|
||||||
|
self.just_mapped[true].clone()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn seat_focus(&self, seat: &WlSeatGlobal) -> Rc<TlmUpstreamNode> {
|
pub fn seat_focus(&self, seat: &WlSeatGlobal) -> Rc<TlmUpstreamNode> {
|
||||||
self.root(TlmMatchSeatFocus::new(seat.id()))
|
self.root(TlmMatchSeatFocus::new(seat.id()))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ macro_rules! fixed_root_criterion {
|
||||||
pub mod tlmm_client;
|
pub mod tlmm_client;
|
||||||
pub mod tlmm_floating;
|
pub mod tlmm_floating;
|
||||||
pub mod tlmm_fullscreen;
|
pub mod tlmm_fullscreen;
|
||||||
|
pub mod tlmm_just_mapped;
|
||||||
pub mod tlmm_kind;
|
pub mod tlmm_kind;
|
||||||
pub mod tlmm_seat_focus;
|
pub mod tlmm_seat_focus;
|
||||||
pub mod tlmm_string;
|
pub mod tlmm_string;
|
||||||
|
|
|
||||||
11
src/criteria/tlm/tlm_matchers/tlmm_just_mapped.rs
Normal file
11
src/criteria/tlm/tlm_matchers/tlmm_just_mapped.rs
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
use crate::{criteria::crit_graph::CritFixedRootCriterion, tree::ToplevelData};
|
||||||
|
|
||||||
|
pub struct TlmMatchJustMapped(pub bool);
|
||||||
|
|
||||||
|
fixed_root_criterion!(TlmMatchJustMapped, just_mapped);
|
||||||
|
|
||||||
|
impl CritFixedRootCriterion<ToplevelData> for TlmMatchJustMapped {
|
||||||
|
fn matches(&self, data: &ToplevelData) -> bool {
|
||||||
|
data.just_mapped()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -103,6 +103,7 @@ impl<T: ToplevelNodeBase> ToplevelNode for T {
|
||||||
let data = self.tl_data();
|
let data = self.tl_data();
|
||||||
let parent_was_none = data.parent.set(Some(parent.clone())).is_none();
|
let parent_was_none = data.parent.set(Some(parent.clone())).is_none();
|
||||||
if parent_was_none {
|
if parent_was_none {
|
||||||
|
data.mapped_during_iteration.set(data.state.eng.iteration());
|
||||||
data.property_changed(TL_CHANGED_NEW);
|
data.property_changed(TL_CHANGED_NEW);
|
||||||
}
|
}
|
||||||
let was_floating = data.is_floating.get();
|
let was_floating = data.is_floating.get();
|
||||||
|
|
@ -308,6 +309,7 @@ pub struct ToplevelData {
|
||||||
pub workspace: CloneCell<Option<Rc<WorkspaceNode>>>,
|
pub workspace: CloneCell<Option<Rc<WorkspaceNode>>>,
|
||||||
pub title: RefCell<String>,
|
pub title: RefCell<String>,
|
||||||
pub parent: CloneCell<Option<Rc<dyn ContainingNode>>>,
|
pub parent: CloneCell<Option<Rc<dyn ContainingNode>>>,
|
||||||
|
pub mapped_during_iteration: Cell<u64>,
|
||||||
pub pos: Cell<Rect>,
|
pub pos: Cell<Rect>,
|
||||||
pub desired_extents: Cell<Rect>,
|
pub desired_extents: Cell<Rect>,
|
||||||
pub seat_state: NodeSeatState,
|
pub seat_state: NodeSeatState,
|
||||||
|
|
@ -325,6 +327,7 @@ pub struct ToplevelData {
|
||||||
pub slf: Weak<dyn ToplevelNode>,
|
pub slf: Weak<dyn ToplevelNode>,
|
||||||
pub destroyed: CopyHashMap<CritMatcherId, Weak<dyn CritDestroyListener<ToplevelData>>>,
|
pub destroyed: CopyHashMap<CritMatcherId, Weak<dyn CritDestroyListener<ToplevelData>>>,
|
||||||
pub changed_properties: Cell<TlMatcherChange>,
|
pub changed_properties: Cell<TlMatcherChange>,
|
||||||
|
pub just_mapped_scheduled: Cell<bool>,
|
||||||
pub seat_foci: CopyHashMap<SeatId, ()>,
|
pub seat_foci: CopyHashMap<SeatId, ()>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -357,6 +360,7 @@ impl ToplevelData {
|
||||||
workspace: Default::default(),
|
workspace: Default::default(),
|
||||||
title: RefCell::new(title),
|
title: RefCell::new(title),
|
||||||
parent: Default::default(),
|
parent: Default::default(),
|
||||||
|
mapped_during_iteration: Cell::new(0),
|
||||||
pos: Default::default(),
|
pos: Default::default(),
|
||||||
desired_extents: Default::default(),
|
desired_extents: Default::default(),
|
||||||
seat_state: Default::default(),
|
seat_state: Default::default(),
|
||||||
|
|
@ -372,6 +376,7 @@ impl ToplevelData {
|
||||||
slf: slf.clone(),
|
slf: slf.clone(),
|
||||||
destroyed: Default::default(),
|
destroyed: Default::default(),
|
||||||
changed_properties: Default::default(),
|
changed_properties: Default::default(),
|
||||||
|
just_mapped_scheduled: Cell::new(false),
|
||||||
seat_foci: Default::default(),
|
seat_foci: Default::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -696,6 +701,10 @@ impl ToplevelData {
|
||||||
};
|
};
|
||||||
(0, 0)
|
(0, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn just_mapped(&self) -> bool {
|
||||||
|
self.mapped_during_iteration.get() == self.state.eng.iteration()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for ToplevelData {
|
impl Drop for ToplevelData {
|
||||||
|
|
|
||||||
|
|
@ -264,6 +264,7 @@ pub struct WindowMatch {
|
||||||
pub urgent: Option<bool>,
|
pub urgent: Option<bool>,
|
||||||
pub focused: Option<bool>,
|
pub focused: Option<bool>,
|
||||||
pub fullscreen: Option<bool>,
|
pub fullscreen: Option<bool>,
|
||||||
|
pub just_mapped: Option<bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,7 @@ impl Parser for WindowMatchParser<'_> {
|
||||||
title,
|
title,
|
||||||
title_regex,
|
title_regex,
|
||||||
),
|
),
|
||||||
(app_id, app_id_regex, floating, visible, urgent, focused, fullscreen),
|
(app_id, app_id_regex, floating, visible, urgent, focused, fullscreen, just_mapped),
|
||||||
) = ext.extract((
|
) = ext.extract((
|
||||||
(
|
(
|
||||||
opt(str("name")),
|
opt(str("name")),
|
||||||
|
|
@ -77,6 +77,7 @@ impl Parser for WindowMatchParser<'_> {
|
||||||
opt(bol("urgent")),
|
opt(bol("urgent")),
|
||||||
opt(bol("focused")),
|
opt(bol("focused")),
|
||||||
opt(bol("fullscreen")),
|
opt(bol("fullscreen")),
|
||||||
|
opt(bol("just-mapped")),
|
||||||
),
|
),
|
||||||
))?;
|
))?;
|
||||||
let mut not = None;
|
let mut not = None;
|
||||||
|
|
@ -127,6 +128,7 @@ impl Parser for WindowMatchParser<'_> {
|
||||||
urgent: urgent.despan(),
|
urgent: urgent.despan(),
|
||||||
focused: focused.despan(),
|
focused: focused.despan(),
|
||||||
fullscreen: fullscreen.despan(),
|
fullscreen: fullscreen.despan(),
|
||||||
|
just_mapped: just_mapped.despan(),
|
||||||
types,
|
types,
|
||||||
client,
|
client,
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -262,6 +262,7 @@ impl Rule for WindowRule {
|
||||||
bool!(Visible, visible);
|
bool!(Visible, visible);
|
||||||
bool!(Urgent, urgent);
|
bool!(Urgent, urgent);
|
||||||
bool!(Fullscreen, fullscreen);
|
bool!(Fullscreen, fullscreen);
|
||||||
|
bool!(JustMapped, just_mapped);
|
||||||
if let Some(value) = match_.focused {
|
if let Some(value) = match_.focused {
|
||||||
let crit = WindowCriterion::Focus(state.persistent.seat);
|
let crit = WindowCriterion::Focus(state.persistent.seat);
|
||||||
let matcher = match value {
|
let matcher = match value {
|
||||||
|
|
|
||||||
|
|
@ -1815,6 +1815,10 @@
|
||||||
"fullscreen": {
|
"fullscreen": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"description": "Matches if the window is/isn't fullscreen."
|
"description": "Matches if the window is/isn't fullscreen."
|
||||||
|
},
|
||||||
|
"just-mapped": {
|
||||||
|
"type": "boolean",
|
||||||
|
"description": "Matches if the window has/hasn't just been mapped.\n\nThis is true for one iteration of the compositor's main loop immediately after the\nwindow has been mapped.\n"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"required": []
|
"required": []
|
||||||
|
|
|
||||||
|
|
@ -4064,6 +4064,15 @@ The table has the following fields:
|
||||||
|
|
||||||
The value of this field should be a boolean.
|
The value of this field should be a boolean.
|
||||||
|
|
||||||
|
- `just-mapped` (optional):
|
||||||
|
|
||||||
|
Matches if the window has/hasn't just been mapped.
|
||||||
|
|
||||||
|
This is true for one iteration of the compositor's main loop immediately after the
|
||||||
|
window has been mapped.
|
||||||
|
|
||||||
|
The value of this field should be a boolean.
|
||||||
|
|
||||||
|
|
||||||
<a name="types-WindowMatchExactly"></a>
|
<a name="types-WindowMatchExactly"></a>
|
||||||
### `WindowMatchExactly`
|
### `WindowMatchExactly`
|
||||||
|
|
|
||||||
|
|
@ -3503,6 +3503,14 @@ WindowMatch:
|
||||||
kind: boolean
|
kind: boolean
|
||||||
required: false
|
required: false
|
||||||
description: Matches if the window is/isn't fullscreen.
|
description: Matches if the window is/isn't fullscreen.
|
||||||
|
just-mapped:
|
||||||
|
kind: boolean
|
||||||
|
required: false
|
||||||
|
description: |
|
||||||
|
Matches if the window has/hasn't just been mapped.
|
||||||
|
|
||||||
|
This is true for one iteration of the compositor's main loop immediately after the
|
||||||
|
window has been mapped.
|
||||||
|
|
||||||
|
|
||||||
WindowMatchExactly:
|
WindowMatchExactly:
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue