From e6f425842b67d24ae0bf996f12bbec2583a77754 Mon Sep 17 00:00:00 2001 From: drendog Date: Sun, 18 Jan 2026 03:20:01 +0100 Subject: [PATCH] refactor: decouple ui init from configure events --- .../wayland/event_handling/app_dispatcher.rs | 12 +- .../src/wayland/session_lock/manager/mod.rs | 59 ++++++++ .../src/wayland/session_lock/manager/state.rs | 127 ++++++++++++------ crates/adapters/src/wayland/shell_adapter.rs | 4 + 4 files changed, 153 insertions(+), 49 deletions(-) diff --git a/crates/adapters/src/wayland/event_handling/app_dispatcher.rs b/crates/adapters/src/wayland/event_handling/app_dispatcher.rs index dcfb6cc..1346c6d 100644 --- a/crates/adapters/src/wayland/event_handling/app_dispatcher.rs +++ b/crates/adapters/src/wayland/event_handling/app_dispatcher.rs @@ -677,11 +677,13 @@ impl Dispatch for AppState { }; if let Some(manager) = state.lock_manager_mut() { - if let Err(err) = - manager.handle_configure(&lock_surface_id, serial, width, height, output_ctx) - { - info!("Failed to configure session lock surface: {err}"); - } + manager.handle_surface_configured( + &lock_surface_id, + serial, + width, + height, + output_ctx, + ); } } } diff --git a/crates/adapters/src/wayland/session_lock/manager/mod.rs b/crates/adapters/src/wayland/session_lock/manager/mod.rs index f114049..049bafc 100644 --- a/crates/adapters/src/wayland/session_lock/manager/mod.rs +++ b/crates/adapters/src/wayland/session_lock/manager/mod.rs @@ -253,6 +253,65 @@ impl SessionLockManager { surface.handle_configure(serial, width, height, &context) } + pub fn handle_surface_configured( + &mut self, + lock_surface_id: &ObjectId, + serial: u32, + width: u32, + height: u32, + output_ctx: LockSurfaceOutputContext, + ) { + let component_name = self.component_definition.name().to_string(); + + let context = LockConfigureContext { + scale_factor: self.config.scale_factor.value(), + component_definition: self.component_definition.clone(), + compilation_result: self.compilation_result.clone(), + platform: Rc::clone(&self.platform), + callbacks: self.callbacks.clone(), + component_name, + output_handle: output_ctx.output_handle, + output_info: output_ctx.output_info, + primary_handle: output_ctx.primary_handle, + active_handle: output_ctx.active_handle, + }; + + let Some(surface) = self.find_surface_by_lock_surface_id_mut(lock_surface_id) else { + return; + }; + + surface.handle_surface_configured(serial, width, height, &context); + } + + pub fn initialize_pending_components(&mut self) -> Result<()> { + let component_name = self.component_definition.name().to_string(); + + for (_, surface) in &mut self.lock_surfaces { + if surface.has_pending_initialization() { + let Some(output_handle) = surface.output_handle else { + continue; + }; + + let context = LockConfigureContext { + scale_factor: self.config.scale_factor.value(), + component_definition: self.component_definition.clone(), + compilation_result: self.compilation_result.clone(), + platform: Rc::clone(&self.platform), + callbacks: self.callbacks.clone(), + component_name: component_name.clone(), + output_handle, + output_info: surface.output_info.clone(), + primary_handle: surface.primary_handle, + active_handle: surface.active_handle, + }; + + surface.initialize_pending_component(&context)?; + } + } + + Ok(()) + } + pub fn render_frames(&self) -> Result<()> { rendering::render_frames(&self.lock_surfaces) } diff --git a/crates/adapters/src/wayland/session_lock/manager/state.rs b/crates/adapters/src/wayland/session_lock/manager/state.rs index 844d162..9980db2 100644 --- a/crates/adapters/src/wayland/session_lock/manager/state.rs +++ b/crates/adapters/src/wayland/session_lock/manager/state.rs @@ -52,11 +52,12 @@ pub struct ActiveLockSurface { component: Option, scale_factor: f32, has_fractional_scale: bool, - output_handle: Option, component_name: Option, - output_info: Option, - primary_handle: Option, - active_handle: Option, + pub(super) output_handle: Option, + pub(super) output_info: Option, + pub(super) primary_handle: Option, + pub(super) active_handle: Option, + pending_component_initialization: bool, } impl ActiveLockSurface { @@ -72,16 +73,17 @@ impl ActiveLockSurface { output_info: None, primary_handle: None, active_handle: None, + pending_component_initialization: false, } } - pub fn handle_configure( + pub fn handle_surface_configured( &mut self, serial: u32, width: u32, height: u32, context: &LockConfigureContext, - ) -> Result<()> { + ) { self.surface.handle_configure(serial, width, height); self.scale_factor = context.scale_factor; self.output_handle = Some(context.output_handle); @@ -93,7 +95,7 @@ impl ActiveLockSurface { Ok(dimensions) => dimensions, Err(err) => { info!("Failed to calculate lock surface dimensions: {err}"); - return Ok(()); + return; } }; let scaling_mode = self.scaling_mode(); @@ -110,46 +112,72 @@ impl ActiveLockSurface { self.configure_surface(&dimensions, scaling_mode); if self.component.is_none() { - context.platform.add_window(Rc::clone(&self.window)); - let component = ComponentState::new( - context.component_definition.clone(), - context.compilation_result.clone(), - &self.window, - )?; - self.window - .window() - .dispatch_event(WindowEvent::WindowActiveChanged(true)); - - let callback_context = LockCallbackContext::new( - context.component_name.clone(), - context.output_handle, - context.output_info.clone(), - context.primary_handle, - context.active_handle, - ); - - for callback in &context.callbacks { - if let Err(err) = - callback.apply_with_context(component.component_instance(), &callback_context) - { - info!( - "Failed to register lock callback '{}': {err}", - callback.name() - ); - } else if callback.should_apply(&callback_context) { - info!("Registered lock callback '{}'", callback.name()); - } else { - info!( - "Skipping callback '{}' due to selector filter (output {:?})", - callback.name(), - context.output_handle - ); - } - } - self.component = Some(component); + self.pending_component_initialization = true; } RenderableWindow::request_redraw(self.window.as_ref()); + } + + pub fn handle_configure( + &mut self, + serial: u32, + width: u32, + height: u32, + context: &LockConfigureContext, + ) -> Result<()> { + self.handle_surface_configured(serial, width, height, context); + + if self.pending_component_initialization { + self.initialize_component(context)?; + } + + Ok(()) + } + + fn initialize_component(&mut self, context: &LockConfigureContext) -> Result<()> { + if self.component.is_some() { + return Ok(()); + } + + context.platform.add_window(Rc::clone(&self.window)); + let component = ComponentState::new( + context.component_definition.clone(), + context.compilation_result.clone(), + &self.window, + )?; + self.window + .window() + .dispatch_event(WindowEvent::WindowActiveChanged(true)); + + let callback_context = LockCallbackContext::new( + context.component_name.clone(), + context.output_handle, + context.output_info.clone(), + context.primary_handle, + context.active_handle, + ); + + for callback in &context.callbacks { + if let Err(err) = + callback.apply_with_context(component.component_instance(), &callback_context) + { + info!( + "Failed to register lock callback '{}': {err}", + callback.name() + ); + } else if callback.should_apply(&callback_context) { + info!("Registered lock callback '{}'", callback.name()); + } else { + info!( + "Skipping callback '{}' due to selector filter (output {:?})", + callback.name(), + context.output_handle + ); + } + } + self.component = Some(component); + self.pending_component_initialization = false; + Ok(()) } @@ -280,4 +308,15 @@ impl ActiveLockSurface { pub const fn component(&self) -> Option<&ComponentState> { self.component.as_ref() } + + pub const fn has_pending_initialization(&self) -> bool { + self.pending_component_initialization + } + + pub fn initialize_pending_component(&mut self, context: &LockConfigureContext) -> Result<()> { + if self.pending_component_initialization { + self.initialize_component(context)?; + } + Ok(()) + } } diff --git a/crates/adapters/src/wayland/shell_adapter.rs b/crates/adapters/src/wayland/shell_adapter.rs index 6c4e76a..46f0bc8 100644 --- a/crates/adapters/src/wayland/shell_adapter.rs +++ b/crates/adapters/src/wayland/shell_adapter.rs @@ -694,6 +694,10 @@ impl WaylandShellSystem { update_timers_and_animations(); + if let Some(lock_manager) = shared_data.lock_manager_mut() { + lock_manager.initialize_pending_components()?; + } + for surface in shared_data.all_outputs() { surface .window()