1
0
Fork 0
forked from wry/wry

create event system

This commit is contained in:
atagen 2026-04-07 16:13:45 +10:00
parent 21819e27d2
commit 18a0c78657
9 changed files with 65 additions and 5 deletions

View file

@ -68,7 +68,7 @@ use {
clone3::ensure_reaper, clone3::ensure_reaper,
clonecell::CloneCell, clonecell::CloneCell,
errorfmt::ErrorFmt, errorfmt::ErrorFmt,
event_listener::handle_lazy_event_sources, event_listener::{handle_lazy_event_sources, handle_post_layout_event_sources},
fdcloser::FdCloser, fdcloser::FdCloser,
nice::{did_elevate_scheduler, elevate_scheduler}, nice::{did_elevate_scheduler, elevate_scheduler},
numcell::NumCell, numcell::NumCell,
@ -393,6 +393,7 @@ fn start_compositor2(
supports_presentation_feedback: Default::default(), supports_presentation_feedback: Default::default(),
eventfd_cache, eventfd_cache,
lazy_event_sources: Default::default(), lazy_event_sources: Default::default(),
post_layout_event_sources: Default::default(),
bo_drop_queue: Rc::new(ObjectDropQueue::new(&ring)), bo_drop_queue: Rc::new(ObjectDropQueue::new(&ring)),
virtual_outputs: Default::default(), virtual_outputs: Default::default(),
clean_logs_older_than: Default::default(), clean_logs_older_than: Default::default(),
@ -602,6 +603,11 @@ fn start_global_event_handlers(state: &Rc<State>) -> Vec<SpawnedFuture<()>> {
"lazy event sources", "lazy event sources",
handle_lazy_event_sources(state.clone()), handle_lazy_event_sources(state.clone()),
), ),
eng.spawn2(
"post layout event sources",
Phase::PostLayout,
handle_post_layout_event_sources(state.clone()),
),
eng.spawn( eng.spawn(
"warp mouse to focus", "warp mouse to focus",
handle_warp_mouse_to_focus(state.clone()), handle_warp_mouse_to_focus(state.clone()),
@ -799,6 +805,7 @@ fn create_dummy_output(state: &Rc<State>) {
pinned: Default::default(), pinned: Default::default(),
tearing: Default::default(), tearing: Default::default(),
active_zwlr_gamma_control: Default::default(), active_zwlr_gamma_control: Default::default(),
workspace_switched: state.lazy_event_sources.create_source(),
}); });
let dummy_workspace = WorkspaceNode::new(&dummy_output, "dummy", true); let dummy_workspace = WorkspaceNode::new(&dummy_output, "dummy", true);
dummy_workspace.may_capture.set(false); dummy_workspace.may_capture.set(false);

View file

@ -536,6 +536,7 @@ impl XdgToplevel {
} }
} }
self.state.tree_changed(); self.state.tree_changed();
self.toplevel_data.unmapped_source.trigger();
} else { } else {
self.map(self.parent.get().as_deref(), pos); self.map(self.parent.get().as_deref(), pos);
self.extents_changed(); self.extents_changed();
@ -550,6 +551,7 @@ impl XdgToplevel {
// } // }
// } // }
self.state.tree_changed(); self.state.tree_changed();
self.toplevel_data.mapped_source.trigger();
self.toplevel_data.broadcast(self.clone()); self.toplevel_data.broadcast(self.clone());
} }
self.toplevel_data self.toplevel_data

View file

@ -298,6 +298,7 @@ pub struct State {
pub supports_presentation_feedback: Cell<bool>, pub supports_presentation_feedback: Cell<bool>,
pub eventfd_cache: Rc<EventfdCache>, pub eventfd_cache: Rc<EventfdCache>,
pub lazy_event_sources: Rc<LazyEventSources>, pub lazy_event_sources: Rc<LazyEventSources>,
pub post_layout_event_sources: Rc<LazyEventSources>,
pub bo_drop_queue: Rc<ObjectDropQueue<Rc<dyn BufferObject>>>, pub bo_drop_queue: Rc<ObjectDropQueue<Rc<dyn BufferObject>>>,
pub virtual_outputs: VirtualOutputs, pub virtual_outputs: VirtualOutputs,
pub clean_logs_older_than: Cell<Option<SystemTime>>, pub clean_logs_older_than: Cell<Option<SystemTime>>,
@ -936,6 +937,7 @@ impl State {
if !output.is_dummy { if !output.is_dummy {
output.schedule_update_render_data(); output.schedule_update_render_data();
self.tree_changed(); self.tree_changed();
output.workspace_switched.trigger();
} }
} }
@ -1169,6 +1171,7 @@ impl State {
self.wait_for_syncobj.clear(); self.wait_for_syncobj.clear();
self.xdg_surface_configure_events.clear(); self.xdg_surface_configure_events.clear();
self.lazy_event_sources.clear(); self.lazy_event_sources.clear();
self.post_layout_event_sources.clear();
self.bo_drop_queue.kill(); self.bo_drop_queue.kill();
self.virtual_outputs.clear(); self.virtual_outputs.clear();
} }

View file

@ -233,6 +233,7 @@ impl ConnectorHandler {
pinned: Default::default(), pinned: Default::default(),
tearing: Default::default(), tearing: Default::default(),
active_zwlr_gamma_control: Default::default(), active_zwlr_gamma_control: Default::default(),
workspace_switched: self.state.lazy_event_sources.create_source(),
}); });
on.update_visible(); on.update_visible();
on.update_rects(); on.update_rects();

View file

@ -29,6 +29,7 @@ use {
clonecell::CloneCell, clonecell::CloneCell,
double_click_state::DoubleClickState, double_click_state::DoubleClickState,
errorfmt::ErrorFmt, errorfmt::ErrorFmt,
event_listener::LazyEventSource,
hash_map_ext::HashMapExt, hash_map_ext::HashMapExt,
linkedlist::{LinkedList, LinkedNode, NodeRef}, linkedlist::{LinkedList, LinkedNode, NodeRef},
numcell::NumCell, numcell::NumCell,
@ -140,6 +141,10 @@ pub struct ContainerNode {
attention_requests: ThresholdCounter, attention_requests: ThresholdCounter,
pending_layout_damage: Cell<bool>, pending_layout_damage: Cell<bool>,
layout_damage_timeout: Cell<Option<SpawnedFuture<()>>>, layout_damage_timeout: Cell<Option<SpawnedFuture<()>>>,
pub layout_complete: Rc<LazyEventSource>,
pub child_added: Rc<LazyEventSource>,
pub child_removed: Rc<LazyEventSource>,
pub all_children_resized: Rc<LazyEventSource>,
} }
impl Debug for ContainerNode { impl Debug for ContainerNode {
@ -258,6 +263,10 @@ impl ContainerNode {
attention_requests: Default::default(), attention_requests: Default::default(),
pending_layout_damage: Cell::new(false), pending_layout_damage: Cell::new(false),
layout_damage_timeout: Cell::new(None), layout_damage_timeout: Cell::new(None),
layout_complete: state.post_layout_event_sources.create_source(),
child_added: state.lazy_event_sources.create_source(),
child_removed: state.lazy_event_sources.create_source(),
all_children_resized: state.post_layout_event_sources.create_source(),
}); });
child.tl_set_parent(slf.clone()); child.tl_set_parent(slf.clone());
slf.pull_child_properties(&child_node_ref); slf.pull_child_properties(&child_node_ref);
@ -368,6 +377,7 @@ impl ContainerNode {
// log::info!("add_child"); // log::info!("add_child");
self.schedule_layout(); self.schedule_layout();
self.cancel_seat_ops(); self.cancel_seat_ops();
self.child_added.trigger();
} }
fn cancel_seat_ops(&self) { fn cancel_seat_ops(&self) {
@ -461,6 +471,22 @@ impl ContainerNode {
} }
} }
fn all_children_match_body(&self) -> bool {
if let Some(mono) = self.mono_child.get() {
let body = self.mono_body.get();
let content = mono.content.get();
return content.width() == body.width() && content.height() == body.height();
}
for child in self.children.iter() {
let body = child.body.get();
let content = child.content.get();
if content.width() != body.width() || content.height() != body.height() {
return false;
}
}
true
}
fn perform_layout(self: &Rc<Self>) { fn perform_layout(self: &Rc<Self>) {
if self.num_children.get() == 0 { if self.num_children.get() == 0 {
return; return;
@ -475,6 +501,7 @@ impl ContainerNode {
// log::info!("perform_layout"); // log::info!("perform_layout");
self.schedule_render_titles(); self.schedule_render_titles();
self.schedule_compute_render_positions(); self.schedule_compute_render_positions();
self.layout_complete.trigger();
if self.pending_layout_damage.get() { if self.pending_layout_damage.get() {
let slf = self.clone(); let slf = self.clone();
let timeout = self.state.eng.spawn("layout damage timeout", async move { let timeout = self.state.eng.spawn("layout damage timeout", async move {
@ -1832,6 +1859,9 @@ impl Node for ContainerNode {
if let Some(node) = cn.get(&child.node_id()) { if let Some(node) = cn.get(&child.node_id()) {
self.update_child_size(node, width, height); self.update_child_size(node, width, height);
} }
if self.pending_layout_damage.get() && self.all_children_match_body() {
self.all_children_resized.trigger();
}
self.flush_layout_damage(); self.flush_layout_damage();
} }
@ -2115,6 +2145,7 @@ impl ContainingNode for ContainerNode {
// log::info!("cnode_remove_child2"); // log::info!("cnode_remove_child2");
self.schedule_layout(); self.schedule_layout();
self.cancel_seat_ops(); self.cancel_seat_ops();
self.child_removed.trigger();
} }
fn cnode_accepts_child(&self, _node: &dyn Node) -> bool { fn cnode_accepts_child(&self, _node: &dyn Node) -> bool {

View file

@ -20,8 +20,8 @@ use {
}, },
utils::{ utils::{
asyncevent::AsyncEvent, clonecell::CloneCell, double_click_state::DoubleClickState, asyncevent::AsyncEvent, clonecell::CloneCell, double_click_state::DoubleClickState,
errorfmt::ErrorFmt, linkedlist::LinkedNode, on_drop_event::OnDropEvent, errorfmt::ErrorFmt, event_listener::LazyEventSource, linkedlist::LinkedNode,
smallmap::SmallMapMut, on_drop_event::OnDropEvent, smallmap::SmallMapMut,
}, },
}, },
ahash::AHashMap, ahash::AHashMap,
@ -56,6 +56,7 @@ pub struct FloatNode {
pub title_textures: RefCell<SmallMapMut<Scale, TextTexture, 2>>, pub title_textures: RefCell<SmallMapMut<Scale, TextTexture, 2>>,
cursors: RefCell<AHashMap<CursorType, CursorState>>, cursors: RefCell<AHashMap<CursorType, CursorState>>,
pub attention_requested: Cell<bool>, pub attention_requested: Cell<bool>,
pub layout_complete: Rc<LazyEventSource>,
} }
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
@ -136,6 +137,7 @@ impl FloatNode {
title_textures: Default::default(), title_textures: Default::default(),
cursors: Default::default(), cursors: Default::default(),
attention_requested: Cell::new(false), attention_requested: Cell::new(false),
layout_complete: state.post_layout_event_sources.create_source(),
}); });
floater.pull_child_properties(); floater.pull_child_properties();
*floater.display_link.borrow_mut() = Some(state.root.stacked.add_last(floater.clone())); *floater.display_link.borrow_mut() = Some(state.root.stacked.add_last(floater.clone()));
@ -190,6 +192,7 @@ impl FloatNode {
self.title_rect.set(tr); self.title_rect.set(tr);
self.layout_scheduled.set(false); self.layout_scheduled.set(false);
self.schedule_render_titles(); self.schedule_render_titles();
self.layout_complete.trigger();
} }
pub fn schedule_render_titles(self: &Rc<Self>) { pub fn schedule_render_titles(self: &Rc<Self>) {

View file

@ -56,7 +56,7 @@ use {
clonecell::CloneCell, clonecell::CloneCell,
copyhashmap::CopyHashMap, copyhashmap::CopyHashMap,
errorfmt::ErrorFmt, errorfmt::ErrorFmt,
event_listener::EventSource, event_listener::{EventSource, LazyEventSource},
hash_map_ext::HashMapExt, hash_map_ext::HashMapExt,
linkedlist::{LinkedList, NodeRef}, linkedlist::{LinkedList, NodeRef},
on_drop_event::OnDropEvent, on_drop_event::OnDropEvent,
@ -127,6 +127,7 @@ pub struct OutputNode {
pub pinned: LinkedList<Rc<dyn PinnedNode>>, pub pinned: LinkedList<Rc<dyn PinnedNode>>,
pub tearing: Cell<bool>, pub tearing: Cell<bool>,
pub active_zwlr_gamma_control: CloneCell<Option<Rc<ZwlrGammaControlV1>>>, pub active_zwlr_gamma_control: CloneCell<Option<Rc<ZwlrGammaControlV1>>>,
pub workspace_switched: Rc<LazyEventSource>,
} }
#[derive(Copy, Clone, Debug, PartialEq)] #[derive(Copy, Clone, Debug, PartialEq)]

View file

@ -415,6 +415,8 @@ pub struct ToplevelData {
pub seat_foci: CopyHashMap<SeatId, ()>, pub seat_foci: CopyHashMap<SeatId, ()>,
pub content_type: Cell<Option<ContentType>>, pub content_type: Cell<Option<ContentType>>,
pub property_changed_source: OnceCell<Rc<LazyEventSource>>, pub property_changed_source: OnceCell<Rc<LazyEventSource>>,
pub mapped_source: Rc<LazyEventSource>,
pub unmapped_source: Rc<LazyEventSource>,
} }
impl ToplevelData { impl ToplevelData {
@ -469,6 +471,8 @@ impl ToplevelData {
seat_foci: Default::default(), seat_foci: Default::default(),
content_type: Default::default(), content_type: Default::default(),
property_changed_source: Default::default(), property_changed_source: Default::default(),
mapped_source: state.lazy_event_sources.create_source(),
unmapped_source: state.lazy_event_sources.create_source(),
} }
} }

View file

@ -14,8 +14,16 @@ use {
}; };
pub async fn handle_lazy_event_sources(state: Rc<State>) { pub async fn handle_lazy_event_sources(state: Rc<State>) {
handle_lazy_event_sources_of(&state.lazy_event_sources).await;
}
pub async fn handle_post_layout_event_sources(state: Rc<State>) {
handle_lazy_event_sources_of(&state.post_layout_event_sources).await;
}
async fn handle_lazy_event_sources_of(sources: &LazyEventSources) {
loop { loop {
let source = state.lazy_event_sources.queue.pop().await; let source = sources.queue.pop().await;
source.queued.set(false); source.queued.set(false);
for listener in source.listeners.iter() { for listener in source.listeners.iter() {
listener.triggered(); listener.triggered();