refactor: event routing

This commit is contained in:
drendog 2025-11-16 17:56:19 +01:00
parent 596f0a5cf6
commit ab47c3988b
Signed by: dwenya
GPG key ID: 8DD77074645332D0
4 changed files with 63 additions and 64 deletions

View file

@ -44,7 +44,7 @@ impl<'a> RuntimeStateFacade<'a> {
}
pub fn popup_manager(&self) -> Option<Rc<PopupManager>> {
self.window_state.popup_manager().cloned()
self.window_state.popup_manager()
}
pub fn component_instance(&self) -> &ComponentInstance {

View file

@ -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<Rc<SharedPointerSerial>>,
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 => {}
}
}

View file

@ -26,12 +26,10 @@ use wayland_protocols::wp::fractional_scale::v1::client::wp_fractional_scale_v1:
pub struct WindowState {
component: ComponentState,
rendering: RenderingState<FemtoVGWindow>,
event_context: EventContext,
event_context: RefCell<EventContext>,
display_metrics: SharedDisplayMetrics,
#[allow(dead_code)]
pointer: ManagedWlPointer,
active_popup_key: RefCell<Option<usize>>,
main_surface: Rc<WlSurface>,
}
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<FemtoVGWindow> {
@ -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<SharedPointerSerial>) {
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<PopupManager>) {
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<PopupManager>> {
self.event_context.popup_manager()
pub fn popup_manager(&self) -> Option<Rc<PopupManager>> {
self.event_context.borrow().popup_manager().cloned()
}
}

View file

@ -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<channel::Sender<PopupCommand>>,
) -> 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!(