diff --git a/adapters/src/wayland/event_handling/event_dispatcher.rs b/adapters/src/wayland/event_handling/event_dispatcher.rs index 5c0079f..2332ddd 100644 --- a/adapters/src/wayland/event_handling/event_dispatcher.rs +++ b/adapters/src/wayland/event_handling/event_dispatcher.rs @@ -171,7 +171,7 @@ impl Dispatch for WindowState { state.set_current_pointer_position(surface_x, surface_y); state.find_window_for_surface(&surface); - let position = *state.current_pointer_position(); + let position = state.current_pointer_position(); state.dispatch_to_active_window(WindowEvent::PointerMoved { position }); } @@ -182,7 +182,7 @@ impl Dispatch for WindowState { .. } => { state.set_current_pointer_position(surface_x, surface_y); - let position = *state.current_pointer_position(); + let position = state.current_pointer_position(); state.dispatch_to_active_window(WindowEvent::PointerMoved { position }); } @@ -198,7 +198,7 @@ impl Dispatch for WindowState { .. } => { state.set_last_pointer_serial(serial); - let position = *state.current_pointer_position(); + let position = state.current_pointer_position(); let event = match button_state { WEnum::Value(wl_pointer::ButtonState::Pressed) => WindowEvent::PointerPressed { button: PointerEventButton::Left, diff --git a/adapters/src/wayland/surfaces/surface_state.rs b/adapters/src/wayland/surfaces/surface_state.rs index ab20002..1e04930 100644 --- a/adapters/src/wayland/surfaces/surface_state.rs +++ b/adapters/src/wayland/surfaces/surface_state.rs @@ -60,6 +60,33 @@ enum ActiveWindow { Popup(usize), } +struct MutableWindowState { + size: PhysicalSize, + logical_size: PhysicalSize, + output_size: PhysicalSize, + current_pointer_position: LogicalPosition, + last_pointer_serial: u32, + shared_pointer_serial: Option>, + scale_factor: f32, + active_window: Option, +} + +impl MutableWindowState { + #[allow(clippy::cast_possible_truncation)] + fn set_pointer_position(&mut self, physical_x: f64, physical_y: f64, fractional_scale: bool) { + let logical_position = if fractional_scale { + LogicalPosition::new(physical_x as f32, physical_y as f32) + } else { + let scale_factor = self.scale_factor; + LogicalPosition::new( + (physical_x / f64::from(scale_factor)) as f32, + (physical_y / f64::from(scale_factor)) as f32, + ) + }; + self.current_pointer_position = logical_position; + } +} + pub struct WindowState { component_instance: ComponentInstance, viewport: Option, @@ -68,18 +95,11 @@ pub struct WindowState { surface: ManagedWlSurface, #[allow(dead_code)] pointer: ManagedWlPointer, - size: PhysicalSize, - logical_size: PhysicalSize, - output_size: PhysicalSize, window: Rc, - current_pointer_position: LogicalPosition, - last_pointer_serial: u32, - shared_pointer_serial: Option>, - scale_factor: f32, height: u32, exclusive_zone: i32, popup_manager: Option>, - active_window: Option, + mutable_state: RefCell, } impl WindowState { @@ -145,18 +165,20 @@ impl WindowState { layer_surface, surface, pointer, - size: builder.size.unwrap_or_default(), - logical_size: PhysicalSize::default(), - output_size: builder.output_size.unwrap_or_default(), window, - current_pointer_position: LogicalPosition::default(), - last_pointer_serial: 0, - shared_pointer_serial: None, - scale_factor: builder.scale_factor, height: builder.height, exclusive_zone: builder.exclusive_zone, popup_manager: None, - active_window: None, + mutable_state: RefCell::new(MutableWindowState { + size: builder.size.unwrap_or_default(), + logical_size: PhysicalSize::default(), + output_size: builder.output_size.unwrap_or_default(), + current_pointer_position: LogicalPosition::default(), + last_pointer_serial: 0, + shared_pointer_serial: None, + scale_factor: builder.scale_factor, + active_window: None, + }), }) } @@ -172,9 +194,10 @@ impl WindowState { #[allow(clippy::cast_precision_loss)] fn configure_slint_window(&self, dimensions: &SurfaceDimensions, mode: ScalingMode) { + let state = self.mutable_state.borrow(); match mode { ScalingMode::FractionalWithViewport => { - self.window.set_scale_factor(self.scale_factor); + self.window.set_scale_factor(state.scale_factor); self.window .set_size(slint::WindowSize::Logical(slint::LogicalSize::new( dimensions.logical_width as f32, @@ -190,7 +213,7 @@ impl WindowState { ))); } ScalingMode::Integer => { - self.window.set_scale_factor(self.scale_factor); + self.window.set_scale_factor(state.scale_factor); self.window .set_size(slint::WindowSize::Physical(dimensions.physical_size())); } @@ -226,7 +249,8 @@ impl WindowState { return; } - let dimensions = SurfaceDimensions::calculate(width, height, self.scale_factor); + let scale_factor = self.scale_factor(); + let dimensions = SurfaceDimensions::calculate(width, height, scale_factor); let scaling_mode = self.determine_scaling_mode(); info!( @@ -235,7 +259,7 @@ impl WindowState { dimensions.logical_height, dimensions.physical_width, dimensions.physical_height, - self.scale_factor, + scale_factor, dimensions.buffer_scale, scaling_mode ); @@ -245,31 +269,25 @@ impl WindowState { info!("Window physical size: {:?}", self.window.size()); - self.size = dimensions.physical_size(); - self.logical_size = dimensions.logical_size(); + let mut state = self.mutable_state.borrow_mut(); + state.size = dimensions.physical_size(); + state.logical_size = dimensions.logical_size(); self.window.request_redraw(); } #[allow(clippy::cast_possible_truncation)] pub fn set_current_pointer_position(&mut self, physical_x: f64, physical_y: f64) { - let logical_position = if self.fractional_scale.is_some() { - LogicalPosition::new(physical_x as f32, physical_y as f32) - } else { - let scale_factor = self.scale_factor; - LogicalPosition::new( - (physical_x / f64::from(scale_factor)) as f32, - (physical_y / f64::from(scale_factor)) as f32, - ) - }; - self.current_pointer_position = logical_position; + let has_fractional_scale = self.fractional_scale.is_some(); + let mut state = self.mutable_state.borrow_mut(); + state.set_pointer_position(physical_x, physical_y, has_fractional_scale); } - pub const fn size(&self) -> &PhysicalSize { - &self.size + pub fn size(&self) -> PhysicalSize { + self.mutable_state.borrow().size } - pub const fn current_pointer_position(&self) -> &LogicalPosition { - &self.current_pointer_position + pub fn current_pointer_position(&self) -> LogicalPosition { + self.mutable_state.borrow().current_pointer_position } pub(crate) fn window(&self) -> Rc { @@ -285,14 +303,14 @@ impl WindowState { } pub fn set_output_size(&mut self, output_size: PhysicalSize) { - self.output_size = output_size; + self.mutable_state.borrow_mut().output_size = output_size; if let Some(popup_manager) = &self.popup_manager { popup_manager.update_output_size(output_size); } } - pub const fn output_size(&self) -> &PhysicalSize { - &self.output_size + pub fn output_size(&self) -> PhysicalSize { + self.mutable_state.borrow().output_size } pub const fn component_instance(&self) -> &ComponentInstance { @@ -306,39 +324,41 @@ impl WindowState { #[allow(clippy::cast_precision_loss)] pub fn update_scale_factor(&mut self, scale_120ths: u32) { let new_scale_factor = scale_120ths as f32 / 120.0; + let old_scale_factor = self.scale_factor(); info!( "Updating scale factor from {} to {} ({}x)", - self.scale_factor, new_scale_factor, scale_120ths + old_scale_factor, new_scale_factor, scale_120ths ); - self.scale_factor = new_scale_factor; + self.mutable_state.borrow_mut().scale_factor = new_scale_factor; if let Some(popup_manager) = &self.popup_manager { popup_manager.update_scale_factor(new_scale_factor); } - let current_logical_size = self.logical_size; + let current_logical_size = self.mutable_state.borrow().logical_size; if current_logical_size.width > 0 && current_logical_size.height > 0 { self.update_size(current_logical_size.width, current_logical_size.height); } } - pub const fn scale_factor(&self) -> f32 { - self.scale_factor + pub fn scale_factor(&self) -> f32 { + self.mutable_state.borrow().scale_factor } - pub const fn last_pointer_serial(&self) -> u32 { - self.last_pointer_serial + pub fn last_pointer_serial(&self) -> u32 { + self.mutable_state.borrow().last_pointer_serial } pub fn set_last_pointer_serial(&mut self, serial: u32) { - self.last_pointer_serial = serial; - if let Some(ref shared_serial) = self.shared_pointer_serial { + let mut state = self.mutable_state.borrow_mut(); + state.last_pointer_serial = serial; + if let Some(ref shared_serial) = state.shared_pointer_serial { shared_serial.update(serial); } } pub fn set_shared_pointer_serial(&mut self, shared_serial: Rc) { - self.shared_pointer_serial = Some(shared_serial); + self.mutable_state.borrow_mut().shared_pointer_serial = Some(shared_serial); } pub fn set_popup_manager(&mut self, popup_manager: Rc) { @@ -349,22 +369,24 @@ impl WindowState { let surface_id = surface.id(); if (**self.surface.inner()).id() == surface_id { - self.active_window = Some(ActiveWindow::Main); + self.mutable_state.borrow_mut().active_window = Some(ActiveWindow::Main); return; } if let Some(popup_manager) = &self.popup_manager { if let Some(popup_key) = popup_manager.find_popup_key_by_surface_id(&surface_id) { - self.active_window = Some(ActiveWindow::Popup(popup_key)); + self.mutable_state.borrow_mut().active_window = + Some(ActiveWindow::Popup(popup_key)); return; } } - self.active_window = None; + self.mutable_state.borrow_mut().active_window = None; } pub fn dispatch_to_active_window(&self, event: WindowEvent) { - match self.active_window { + let active_window = self.mutable_state.borrow().active_window; + match active_window { Some(ActiveWindow::Main) => { self.window.window().dispatch_event(event); } @@ -408,13 +430,14 @@ impl WindowState { } } - pub const fn clear_active_window(&mut self) { - self.active_window = None; + pub fn clear_active_window(&mut self) { + self.mutable_state.borrow_mut().active_window = None; } pub fn clear_active_window_if_popup(&mut self, popup_key: usize) { - if self.active_window == Some(ActiveWindow::Popup(popup_key)) { - self.active_window = None; + let mut state = self.mutable_state.borrow_mut(); + if state.active_window == Some(ActiveWindow::Popup(popup_key)) { + state.active_window = None; } }