From ab47c3988b90055a446067072ef83a2d187376a4 Mon Sep 17 00:00:00 2001 From: drendog Date: Sun, 16 Nov 2025 17:56:19 +0100 Subject: [PATCH] refactor: event routing --- crates/adapters/src/wayland/facade.rs | 2 +- .../src/wayland/surfaces/event_context.rs | 37 ++++++++--- .../src/wayland/surfaces/surface_state.rs | 64 ++++++++----------- crates/composition/src/system.rs | 24 +++---- 4 files changed, 63 insertions(+), 64 deletions(-) diff --git a/crates/adapters/src/wayland/facade.rs b/crates/adapters/src/wayland/facade.rs index 8ac41e0..4a30973 100644 --- a/crates/adapters/src/wayland/facade.rs +++ b/crates/adapters/src/wayland/facade.rs @@ -44,7 +44,7 @@ impl<'a> RuntimeStateFacade<'a> { } pub fn popup_manager(&self) -> Option> { - self.window_state.popup_manager().cloned() + self.window_state.popup_manager() } pub fn component_instance(&self) -> &ComponentInstance { diff --git a/crates/adapters/src/wayland/surfaces/event_context.rs b/crates/adapters/src/wayland/surfaces/event_context.rs index efea7ba..5c20161 100644 --- a/crates/adapters/src/wayland/surfaces/event_context.rs +++ b/crates/adapters/src/wayland/surfaces/event_context.rs @@ -5,7 +5,7 @@ use slint::platform::{WindowAdapter, WindowEvent}; use slint::{LogicalPosition, PhysicalSize}; use std::cell::Cell; use std::rc::Rc; -use wayland_client::{backend::ObjectId, protocol::wl_surface::WlSurface}; +use wayland_client::{Proxy, backend::ObjectId, protocol::wl_surface::WlSurface}; use wayland_protocols::wp::fractional_scale::v1::client::wp_fractional_scale_v1::WpFractionalScaleV1; pub struct SharedPointerSerial { @@ -42,6 +42,7 @@ pub struct EventContext { current_pointer_position: LogicalPosition, last_pointer_serial: u32, shared_pointer_serial: Option>, + active_window: ActiveWindow, } impl EventContext { @@ -59,6 +60,7 @@ impl EventContext { current_pointer_position: LogicalPosition::new(0.0, 0.0), last_pointer_serial: 0, shared_pointer_serial: None, + active_window: ActiveWindow::None, } } @@ -123,19 +125,36 @@ impl EventContext { self.shared_pointer_serial = Some(shared_serial); } - pub fn dispatch_to_active_window(&self, event: WindowEvent, surface: &WlSurface) { - if let Some(popup_manager) = &self.popup_manager { - match popup_manager.get_active_window(surface, &self.main_surface_id) { - ActiveWindow::Main => { - self.main_window.window().dispatch_event(event); - } - ActiveWindow::Popup(handle) => { + pub fn set_entered_surface(&mut self, surface: &WlSurface) { + self.active_window = if let Some(popup_manager) = &self.popup_manager { + popup_manager.get_active_window(surface, &self.main_surface_id) + } else { + let surface_id = surface.id(); + if self.main_surface_id == surface_id { + ActiveWindow::Main + } else { + ActiveWindow::None + } + }; + } + + pub fn clear_entered_surface(&mut self) { + self.active_window = ActiveWindow::None; + } + + pub fn dispatch_to_active_window(&self, event: WindowEvent) { + match self.active_window { + ActiveWindow::Main => { + self.main_window.window().dispatch_event(event); + } + ActiveWindow::Popup(handle) => { + if let Some(popup_manager) = &self.popup_manager { if let Some(popup_window) = popup_manager.get_popup_window(handle.key()) { popup_window.dispatch_event(event); } } - ActiveWindow::None => {} } + ActiveWindow::None => {} } } diff --git a/crates/adapters/src/wayland/surfaces/surface_state.rs b/crates/adapters/src/wayland/surfaces/surface_state.rs index f50c167..3a8b4ad 100644 --- a/crates/adapters/src/wayland/surfaces/surface_state.rs +++ b/crates/adapters/src/wayland/surfaces/surface_state.rs @@ -26,12 +26,10 @@ use wayland_protocols::wp::fractional_scale::v1::client::wp_fractional_scale_v1: pub struct WindowState { component: ComponentState, rendering: RenderingState, - event_context: EventContext, + event_context: RefCell, display_metrics: SharedDisplayMetrics, #[allow(dead_code)] pointer: ManagedWlPointer, - active_popup_key: RefCell>, - main_surface: Rc, } impl WindowState { @@ -115,22 +113,21 @@ impl WindowState { Ok(Self { component, rendering, - event_context, + event_context: RefCell::new(event_context), display_metrics, pointer, - active_popup_key: RefCell::new(None), - main_surface: surface_rc, }) } pub fn update_size(&mut self, width: u32, height: u32) { - let scale_factor = self.event_context.scale_factor(); + let scale_factor = self.event_context.borrow().scale_factor(); self.rendering.update_size(width, height, scale_factor); } #[allow(clippy::cast_possible_truncation)] pub fn set_current_pointer_position(&mut self, physical_x: f64, physical_y: f64) { self.event_context + .borrow_mut() .set_current_pointer_position(physical_x, physical_y); } @@ -139,7 +136,7 @@ impl WindowState { } pub fn current_pointer_position(&self) -> LogicalPosition { - self.event_context.current_pointer_position() + self.event_context.borrow().current_pointer_position() } pub(crate) fn window(&self) -> Rc { @@ -158,7 +155,7 @@ impl WindowState { self.display_metrics .borrow_mut() .update_output_size(output_size); - self.event_context.update_output_size(output_size); + self.event_context.borrow().update_output_size(output_size); } pub fn output_size(&self) -> PhysicalSize { @@ -180,7 +177,9 @@ impl WindowState { #[allow(clippy::cast_precision_loss)] pub fn update_scale_factor(&mut self, scale_120ths: u32) { - self.event_context.update_scale_factor(scale_120ths); + self.event_context + .borrow_mut() + .update_scale_factor(scale_120ths); let current_logical_size = self.rendering.logical_size(); if current_logical_size.width > 0 && current_logical_size.height > 0 { @@ -189,7 +188,7 @@ impl WindowState { } pub fn scale_factor(&self) -> f32 { - self.event_context.scale_factor() + self.event_context.borrow().scale_factor() } pub const fn display_metrics(&self) -> &SharedDisplayMetrics { @@ -197,49 +196,37 @@ impl WindowState { } pub fn last_pointer_serial(&self) -> u32 { - self.event_context.last_pointer_serial() + self.event_context.borrow().last_pointer_serial() } pub fn set_last_pointer_serial(&mut self, serial: u32) { - self.event_context.set_last_pointer_serial(serial); + self.event_context + .borrow_mut() + .set_last_pointer_serial(serial); } pub fn set_shared_pointer_serial(&mut self, shared_serial: Rc) { - self.event_context.set_shared_pointer_serial(shared_serial); + self.event_context + .borrow_mut() + .set_shared_pointer_serial(shared_serial); } pub fn set_popup_manager(&mut self, popup_manager: Rc) { - self.event_context.set_popup_manager(popup_manager); + self.event_context + .borrow_mut() + .set_popup_manager(popup_manager); } pub fn set_entered_surface(&self, surface: &WlSurface) { - if let Some(popup_manager) = self.event_context.popup_manager() { - if let Some(popup_key) = popup_manager.find_popup_key_by_surface_id(&surface.id()) { - *self.active_popup_key.borrow_mut() = Some(popup_key); - return; - } - } - *self.active_popup_key.borrow_mut() = None; + self.event_context.borrow_mut().set_entered_surface(surface); } pub fn clear_entered_surface(&self) { - *self.active_popup_key.borrow_mut() = None; + self.event_context.borrow_mut().clear_entered_surface(); } pub fn dispatch_to_active_window(&self, event: WindowEvent) { - let active_popup = *self.active_popup_key.borrow(); - - if let Some(popup_key) = active_popup { - if let Some(popup_manager) = self.event_context.popup_manager() { - if let Some(popup_window) = popup_manager.get_popup_window(popup_key) { - popup_window.dispatch_event(event); - return; - } - } - } - - self.event_context - .dispatch_to_active_window(event, &self.main_surface); + self.event_context.borrow().dispatch_to_active_window(event); } #[allow(clippy::cast_precision_loss)] @@ -258,11 +245,12 @@ impl WindowState { } self.event_context + .borrow() .update_scale_for_fractional_scale_object(fractional_scale_proxy, scale_120ths); } - pub fn popup_manager(&self) -> Option<&Rc> { - self.event_context.popup_manager() + pub fn popup_manager(&self) -> Option> { + self.event_context.borrow().popup_manager().cloned() } } diff --git a/crates/composition/src/system.rs b/crates/composition/src/system.rs index 71efe6f..8204738 100644 --- a/crates/composition/src/system.rs +++ b/crates/composition/src/system.rs @@ -162,15 +162,11 @@ impl RuntimeState<'_> { self.close_current_popup()?; - let popup_manager = self - .window_state - .popup_manager() - .ok_or_else(|| { - Error::Domain(DomainError::Configuration { - message: "No popup manager available".to_string(), - }) + let popup_manager = self.window_state.popup_manager().ok_or_else(|| { + Error::Domain(DomainError::Configuration { + message: "No popup manager available".to_string(), }) - .cloned()?; + })?; let initial_dimensions = match req.size { PopupSize::Fixed { w, h } => { @@ -233,15 +229,11 @@ impl RuntimeState<'_> { height: f32, resize_sender: Option>, ) -> Result<()> { - let popup_manager = self - .window_state - .popup_manager() - .ok_or_else(|| { - Error::Domain(DomainError::Configuration { - message: "No popup manager available".to_string(), - }) + let popup_manager = self.window_state.popup_manager().ok_or_else(|| { + Error::Domain(DomainError::Configuration { + message: "No popup manager available".to_string(), }) - .cloned()?; + })?; let Some((request, _serial)) = popup_manager.get_popup_info(handle.key()) else { log::debug!(