refactor: explicit rc cloning

WIP/draft
drendog 2024-08-15 07:44:50 +02:00
parent efeb91be40
commit 1540ef72b2
Signed by: dwenya
GPG Key ID: 8DD77074645332D0
7 changed files with 49 additions and 78 deletions

View File

@ -1,24 +0,0 @@
use slint::PhysicalSize;
#[derive(Debug, Clone, Copy)]
pub struct LayerSize {
size: PhysicalSize,
}
impl LayerSize {
pub const fn new(width: u32, height: u32) -> Self {
Self {
size: PhysicalSize::new(width, height),
}
}
pub const fn physical_size(self) -> PhysicalSize {
self.size
}
}
impl Default for LayerSize {
fn default() -> Self {
Self::new(1, 1)
}
}

View File

@ -10,7 +10,7 @@ use glutin::{
use raw_window_handle::{ use raw_window_handle::{
RawDisplayHandle, RawWindowHandle, WaylandDisplayHandle, WaylandWindowHandle, RawDisplayHandle, RawWindowHandle, WaylandDisplayHandle, WaylandWindowHandle,
}; };
use slint::platform::femtovg_renderer::OpenGLInterface; use slint::{platform::femtovg_renderer::OpenGLInterface, PhysicalSize};
use std::{ use std::{
ffi::{self, c_void, CStr}, ffi::{self, c_void, CStr},
num::NonZeroU32, num::NonZeroU32,
@ -18,8 +18,6 @@ use std::{
}; };
use wayland_client::backend::ObjectId; use wayland_client::backend::ObjectId;
use crate::common::LayerSize;
pub struct EGLContext { pub struct EGLContext {
context: PossiblyCurrentContext, context: PossiblyCurrentContext,
surface: Surface<WindowSurface>, surface: Surface<WindowSurface>,
@ -28,7 +26,7 @@ pub struct EGLContext {
pub struct EGLContextBuilder { pub struct EGLContextBuilder {
display_id: Option<ObjectId>, display_id: Option<ObjectId>,
surface_id: Option<ObjectId>, surface_id: Option<ObjectId>,
size: Option<LayerSize>, size: Option<PhysicalSize>,
config_template: Option<ConfigTemplateBuilder>, config_template: Option<ConfigTemplateBuilder>,
context_attributes: Option<ContextAttributesBuilder>, context_attributes: Option<ContextAttributesBuilder>,
} }
@ -49,7 +47,7 @@ impl EGLContextBuilder {
self self
} }
pub const fn with_size(mut self, size: LayerSize) -> Self { pub const fn with_size(mut self, size: PhysicalSize) -> Self {
self.size = Some(size); self.size = Some(size);
self self
} }
@ -147,12 +145,12 @@ fn create_surface(
glutin_display: &Display, glutin_display: &Display,
config: &glutin::api::egl::config::Config, config: &glutin::api::egl::config::Config,
surface_handle: RawWindowHandle, surface_handle: RawWindowHandle,
size: LayerSize, size: PhysicalSize,
) -> Result<Surface<WindowSurface>> { ) -> Result<Surface<WindowSurface>> {
let attrs = SurfaceAttributesBuilder::<WindowSurface>::new().build( let attrs = SurfaceAttributesBuilder::<WindowSurface>::new().build(
surface_handle, surface_handle,
NonZeroU32::new(size.physical_size().width).unwrap(), NonZeroU32::new(size.width).unwrap(),
NonZeroU32::new(size.physical_size().height).unwrap(), NonZeroU32::new(size.height).unwrap(),
); );
unsafe { glutin_display.create_window_surface(config, &attrs) } unsafe { glutin_display.create_window_surface(config, &attrs) }
.map_err(|e| anyhow!("Failed to create window surface: {}", e)) .map_err(|e| anyhow!("Failed to create window surface: {}", e))

View File

@ -17,7 +17,7 @@ pub struct FemtoVGWindow {
impl FemtoVGWindow { impl FemtoVGWindow {
pub fn new(renderer: FemtoVGRenderer) -> Rc<Self> { pub fn new(renderer: FemtoVGRenderer) -> Rc<Self> {
Rc::new_cyclic(|weak_self| { Rc::new_cyclic(|weak_self| {
let window = Window::new(weak_self.clone() as Weak<dyn WindowAdapter>); let window = Window::new(Weak::clone(weak_self) as Weak<dyn WindowAdapter>);
Self { Self {
window, window,
renderer, renderer,

View File

@ -38,7 +38,7 @@ impl WindowEventHandler {
fn handle_pointer_enter(&self, surface_x: f64, surface_y: f64) { fn handle_pointer_enter(&self, surface_x: f64, surface_y: f64) {
if let Some(state) = self.state.upgrade() { if let Some(state) = self.state.upgrade() {
state state
.borrow() .borrow_mut()
.set_current_pointer_position(surface_x, surface_y); .set_current_pointer_position(surface_x, surface_y);
if let Some(window) = state.borrow().window() { if let Some(window) = state.borrow().window() {
let logical_position = state.borrow().current_pointer_position(); let logical_position = state.borrow().current_pointer_position();
@ -60,7 +60,7 @@ impl WindowEventHandler {
fn handle_pointer_motion(&self, surface_x: f64, surface_y: f64) { fn handle_pointer_motion(&self, surface_x: f64, surface_y: f64) {
if let Some(state) = self.state.upgrade() { if let Some(state) = self.state.upgrade() {
state state
.borrow() .borrow_mut()
.set_current_pointer_position(surface_x, surface_y); .set_current_pointer_position(surface_x, surface_y);
if let Some(window) = state.borrow().window() { if let Some(window) = state.borrow().window() {
let logical_position = state.borrow().current_pointer_position(); let logical_position = state.borrow().current_pointer_position();

View File

@ -34,12 +34,12 @@ impl EventLoopHandler {
pub fn setup_wayland_event_source(&self, loop_handle: &calloop::LoopHandle<()>) -> Result<()> { pub fn setup_wayland_event_source(&self, loop_handle: &calloop::LoopHandle<()>) -> Result<()> {
debug!("Setting up Wayland event source"); debug!("Setting up Wayland event source");
let wayland_queue = self.wayland_queue.clone(); let wayland_queue = Weak::clone(&self.wayland_queue);
let event_handler = self.event_handler.clone(); let event_handler = Weak::clone(&self.event_handler);
let connection = self.connection.upgrade().ok_or_else(|| { let connection = self.connection.upgrade().ok_or_else(|| {
anyhow!("Failed to get Wayland connection reference in Wayland event source") anyhow!("Failed to get Wayland connection reference in Wayland event source")
})?; })?;
let window = self.window.clone(); let window = Weak::clone(&self.window);
loop_handle loop_handle
.insert_source( .insert_source(

View File

@ -1,7 +1,6 @@
use self::{event_handler::WindowEventHandler, event_loop::EventLoopHandler, state::WindowState}; use self::{event_handler::WindowEventHandler, event_loop::EventLoopHandler, state::WindowState};
use crate::{ use crate::{
bind_globals, bind_globals,
common::LayerSize,
rendering::{ rendering::{
egl_context::EGLContext, femtovg_window::FemtoVGWindow, slint_platform::CustomSlintPlatform, egl_context::EGLContext, femtovg_window::FemtoVGWindow, slint_platform::CustomSlintPlatform,
}, },
@ -17,7 +16,10 @@ use smithay_client_toolkit::reexports::{
zwlr_layer_surface_v1::{Anchor, KeyboardInteractivity, ZwlrLayerSurfaceV1}, zwlr_layer_surface_v1::{Anchor, KeyboardInteractivity, ZwlrLayerSurfaceV1},
}, },
}; };
use std::{cell::RefCell, rc::Rc}; use std::{
cell::{Ref, RefCell},
rc::Rc,
};
use wayland_client::{ use wayland_client::{
globals::{registry_queue_init, GlobalList}, globals::{registry_queue_init, GlobalList},
protocol::{ protocol::{
@ -71,8 +73,8 @@ impl Default for WindowingSystemBuilder {
} }
impl WindowingSystemBuilder { impl WindowingSystemBuilder {
#[must_use]
#[inline] #[inline]
#[must_use]
pub fn new() -> Self { pub fn new() -> Self {
Self { Self {
config: WindowConfig::default(), config: WindowConfig::default(),
@ -86,26 +88,24 @@ impl WindowingSystemBuilder {
} }
#[must_use] #[must_use]
#[inline]
pub const fn with_layer(mut self, layer: zwlr_layer_shell_v1::Layer) -> Self { pub const fn with_layer(mut self, layer: zwlr_layer_shell_v1::Layer) -> Self {
self.config.layer = layer; self.config.layer = layer;
self self
} }
#[must_use] #[must_use]
#[inline]
pub const fn with_margin(mut self, top: i32, right: i32, bottom: i32, left: i32) -> Self { pub const fn with_margin(mut self, top: i32, right: i32, bottom: i32, left: i32) -> Self {
self.config.margin = (top, right, bottom, left); self.config.margin = (top, right, bottom, left);
self self
} }
#[must_use] #[must_use]
#[inline]
pub const fn with_anchor(mut self, anchor: Anchor) -> Self { pub const fn with_anchor(mut self, anchor: Anchor) -> Self {
self.config.anchor = anchor; self.config.anchor = anchor;
self self
} }
#[must_use] #[must_use]
#[inline]
pub const fn with_keyboard_interactivity( pub const fn with_keyboard_interactivity(
mut self, mut self,
interactivity: KeyboardInteractivity, interactivity: KeyboardInteractivity,
@ -113,26 +113,26 @@ impl WindowingSystemBuilder {
self.config.keyboard_interactivity = interactivity; self.config.keyboard_interactivity = interactivity;
self self
} }
#[must_use] #[must_use]
#[inline]
pub const fn with_exclusive_zone(mut self, zone: i32) -> Self { pub const fn with_exclusive_zone(mut self, zone: i32) -> Self {
self.config.exclusive_zone = zone; self.config.exclusive_zone = zone;
self self
} }
#[must_use] #[must_use]
#[inline]
pub fn with_namespace(mut self, namespace: String) -> Self { pub fn with_namespace(mut self, namespace: String) -> Self {
self.config.namespace = namespace; self.config.namespace = namespace;
self self
} }
#[must_use] #[must_use]
#[inline]
pub const fn with_scale_factor(mut self, scale_factor: f32) -> Self { pub const fn with_scale_factor(mut self, scale_factor: f32) -> Self {
self.config.scale_factor = scale_factor; self.config.scale_factor = scale_factor;
self self
} }
#[must_use] #[must_use]
#[inline]
pub fn with_component_definition(mut self, component: ComponentDefinition) -> Self { pub fn with_component_definition(mut self, component: ComponentDefinition) -> Self {
self.config.component_definition = Some(component); self.config.component_definition = Some(component);
self self
@ -234,7 +234,7 @@ impl<'a> WindowingSystem<'a> {
event_handler: &Rc<RefCell<WindowEventHandler>>, event_handler: &Rc<RefCell<WindowEventHandler>>,
config: &WindowConfig, config: &WindowConfig,
) { ) {
let surface = compositor.create_surface(queue_handle, ()); let surface = Rc::new(compositor.create_surface(queue_handle, ()));
let layer_surface = Rc::new(layer_shell.get_layer_surface( let layer_surface = Rc::new(layer_shell.get_layer_surface(
&surface, &surface,
Some(output), Some(output),
@ -244,13 +244,13 @@ impl<'a> WindowingSystem<'a> {
(), (),
)); ));
let pointer = seat.get_pointer(queue_handle, ()); let pointer = Rc::new(seat.get_pointer(queue_handle, ()));
let binding = event_handler.borrow_mut(); let binding = event_handler.borrow_mut();
let binding = binding.state(); let binding = binding.state();
let mut state = binding.borrow_mut(); let mut state = binding.borrow_mut();
state.set_surface(surface.clone()); state.set_surface(Rc::clone(&surface));
state.set_layer_surface(layer_surface.clone()); state.set_layer_surface(Rc::clone(&layer_surface));
state.set_pointer(pointer); state.set_pointer(pointer);
Self::configure_layer_surface(&layer_surface, &surface, config); Self::configure_layer_surface(&layer_surface, &surface, config);
@ -305,7 +305,7 @@ impl<'a> WindowingSystem<'a> {
let (window, component_instance) = let (window, component_instance) =
self.initialize_slint_ui(renderer, &component_definition)?; self.initialize_slint_ui(renderer, &component_definition)?;
self.window = Some(window.clone()); self.window = Some(Rc::clone(&window));
self.state.borrow_mut().set_window(window); self.state.borrow_mut().set_window(window);
self.component_instance = Some(component_instance); self.component_instance = Some(component_instance);
@ -313,17 +313,15 @@ impl<'a> WindowingSystem<'a> {
} }
fn create_renderer(&self) -> Result<FemtoVGRenderer> { fn create_renderer(&self) -> Result<FemtoVGRenderer> {
let size = self.state.borrow().size(); let state_borrow = self.state.borrow();
let binding = self.state.borrow(); let size = state_borrow.size();
let surface = binding let surface = state_borrow.surface().unwrap();
.surface()
.ok_or_else(|| anyhow::anyhow!("Surface not initialized"))?;
debug!("Creating EGL context with size: {:?}", size); debug!("Creating EGL context with size: {:?}", size);
let context = EGLContext::builder() let context = EGLContext::builder()
.with_display_id(self.display.id()) .with_display_id(self.display.id())
.with_surface_id(surface.id()) .with_surface_id(surface.id())
.with_size(LayerSize::new(size.width, size.height)) .with_size(size)
.build() .build()
.map_err(|e| anyhow::anyhow!("Failed to create EGL context: {:?}", e))?; .map_err(|e| anyhow::anyhow!("Failed to create EGL context: {:?}", e))?;
@ -396,16 +394,16 @@ impl<'a> WindowingSystem<'a> {
.map_err(|e| anyhow::anyhow!("Failed to run event loop: {}", e)) .map_err(|e| anyhow::anyhow!("Failed to run event loop: {}", e))
} }
pub fn component_instance(&self) -> Option<Rc<ComponentInstance>> { pub fn component_instance(&self) -> Rc<ComponentInstance> {
self.component_instance.clone() Rc::clone(self.component_instance.as_ref().unwrap())
} }
pub fn window(&self) -> Option<Rc<FemtoVGWindow>> { pub fn window(&self) -> Rc<FemtoVGWindow> {
self.window.clone() Rc::clone(self.window.as_ref().unwrap())
} }
pub fn state(&self) -> Rc<RefCell<WindowState>> { pub fn state(&self) -> Ref<WindowState> {
self.state.clone() self.state.borrow()
} }
pub const fn display(&self) -> &WlDisplay { pub const fn display(&self) -> &WlDisplay {

View File

@ -9,13 +9,13 @@ use crate::rendering::femtovg_window::FemtoVGWindow;
use super::WindowConfig; use super::WindowConfig;
pub struct WindowState { pub struct WindowState {
surface: Option<WlSurface>, surface: Option<Rc<WlSurface>>,
layer_surface: Option<Rc<ZwlrLayerSurfaceV1>>, layer_surface: Option<Rc<ZwlrLayerSurfaceV1>>,
size: Cell<PhysicalSize>, size: Cell<PhysicalSize>,
output_size: Cell<PhysicalSize>, output_size: Cell<PhysicalSize>,
pointer: Option<WlPointer>, pointer: Option<Rc<WlPointer>>,
window: Option<Rc<FemtoVGWindow>>, window: Option<Rc<FemtoVGWindow>>,
current_pointer_position: Cell<LogicalPosition>, current_pointer_position: LogicalPosition,
scale_factor: f32, scale_factor: f32,
height: u32, height: u32,
exclusive_zone: i32, exclusive_zone: i32,
@ -30,7 +30,7 @@ impl WindowState {
output_size: Cell::new(PhysicalSize::default()), output_size: Cell::new(PhysicalSize::default()),
pointer: None, pointer: None,
window: None, window: None,
current_pointer_position: Cell::new(LogicalPosition::default()), current_pointer_position: LogicalPosition::default(),
scale_factor: config.scale_factor, scale_factor: config.scale_factor,
height: config.height, height: config.height,
exclusive_zone: config.exclusive_zone, exclusive_zone: config.exclusive_zone,
@ -40,7 +40,6 @@ impl WindowState {
pub fn update_size(&self, width: u32, height: u32) { pub fn update_size(&self, width: u32, height: u32) {
let new_size = PhysicalSize::new(width, height); let new_size = PhysicalSize::new(width, height);
self.size.set(new_size); self.size.set(new_size);
if let Some(window) = &self.window() { if let Some(window) = &self.window() {
info!("Updating window size to {}x{}", width, height); info!("Updating window size to {}x{}", width, height);
window.set_size(slint::WindowSize::Physical(new_size)); window.set_size(slint::WindowSize::Physical(new_size));
@ -58,13 +57,13 @@ impl WindowState {
} }
} }
pub fn set_current_pointer_position(&self, physical_x: f64, physical_y: f64) { pub fn set_current_pointer_position(&mut self, physical_x: f64, physical_y: f64) {
let scale_factor = self.scale_factor; let scale_factor = self.scale_factor;
let logical_position = LogicalPosition::new( let logical_position = LogicalPosition::new(
physical_x as f32 / scale_factor, physical_x as f32 / scale_factor,
physical_y as f32 / scale_factor, physical_y as f32 / scale_factor,
); );
self.current_pointer_position.set(logical_position); self.current_pointer_position = logical_position;
} }
pub fn size(&self) -> PhysicalSize { pub fn size(&self) -> PhysicalSize {
@ -74,7 +73,7 @@ impl WindowState {
self.output_size.get() self.output_size.get()
} }
pub fn current_pointer_position(&self) -> LogicalPosition { pub fn current_pointer_position(&self) -> LogicalPosition {
self.current_pointer_position.get() self.current_pointer_position
} }
pub fn window(&self) -> Option<Rc<FemtoVGWindow>> { pub fn window(&self) -> Option<Rc<FemtoVGWindow>> {
self.window.clone() self.window.clone()
@ -83,8 +82,8 @@ impl WindowState {
pub fn layer_surface(&self) -> Option<Rc<ZwlrLayerSurfaceV1>> { pub fn layer_surface(&self) -> Option<Rc<ZwlrLayerSurfaceV1>> {
self.layer_surface.clone() self.layer_surface.clone()
} }
pub const fn surface(&self) -> Option<&WlSurface> { pub fn surface(&self) -> Option<Rc<WlSurface>> {
self.surface.as_ref() self.surface.clone()
} }
pub const fn height(&self) -> u32 { pub const fn height(&self) -> u32 {
@ -102,10 +101,10 @@ impl WindowState {
self.layer_surface = Some(layer_surface); self.layer_surface = Some(layer_surface);
} }
pub fn set_surface(&mut self, surface: WlSurface) { pub fn set_surface(&mut self, surface: Rc<WlSurface>) {
self.surface = Some(surface); self.surface = Some(surface);
} }
pub fn set_pointer(&mut self, pointer: WlPointer) { pub fn set_pointer(&mut self, pointer: Rc<WlPointer>) {
self.pointer = Some(pointer); self.pointer = Some(pointer);
} }
} }