feat: add builder pattern for surface reconfiguration

This commit is contained in:
drendog 2025-12-11 07:26:33 +01:00
parent 89832a4033
commit 16c8315a53
Signed by: dwenya
GPG key ID: 8DD77074645332D0
7 changed files with 116 additions and 22 deletions

View file

@ -49,6 +49,10 @@ impl Dispatch<ZwlrLayerSurfaceV1, ()> for AppState {
width, width,
height, height,
} => { } => {
info!(
"Layer surface configured with compositor size: {}x{}",
width, height
);
let layer_surface_id = layer_surface.id(); let layer_surface_id = layer_surface.id();
let Some(surface) = state.get_output_by_layer_surface_mut(&layer_surface_id) else { let Some(surface) = state.get_output_by_layer_surface_mut(&layer_surface_id) else {
info!( info!(
@ -198,8 +202,6 @@ impl Dispatch<WlPointer, ()> for AppState {
surface_x, surface_x,
surface_y, surface_y,
} => { } => {
info!("Pointer entered surface {:?}", surface.id());
let surface_id = surface.id(); let surface_id = surface.id();
if let Some(key) = state.get_key_by_surface(&surface_id).cloned() { if let Some(key) = state.get_key_by_surface(&surface_id).cloned() {

View file

@ -96,7 +96,6 @@ impl SurfaceState {
surface_x: f64, surface_x: f64,
surface_y: f64, surface_y: f64,
) { ) {
info!("Pointer entered surface {:?}", surface.id());
self.set_last_pointer_serial(serial); self.set_last_pointer_serial(serial);
self.set_current_pointer_position(surface_x, surface_y); self.set_current_pointer_position(surface_x, surface_y);

View file

@ -3,8 +3,8 @@
mod event_loop; mod event_loop;
mod layer_surface; mod layer_surface;
mod popup_builder; mod popup_builder;
mod selector;
mod selection; mod selection;
mod selector;
mod shell; mod shell;
mod shell_config; mod shell_config;
mod shell_runtime; mod shell_runtime;
@ -34,10 +34,12 @@ pub use layer_shika_domain::value_objects::popup_request::{
}; };
pub use layer_surface::{LayerSurfaceHandle, ShellSurfaceConfigHandler}; pub use layer_surface::{LayerSurfaceHandle, ShellSurfaceConfigHandler};
pub use popup_builder::PopupBuilder; pub use popup_builder::PopupBuilder;
pub use selector::{Output, Selector, Surface, SurfaceInfo};
pub use selection::Selection; pub use selection::Selection;
pub use selector::{Output, Selector, Surface, SurfaceInfo};
pub use shell_runtime::{DEFAULT_SURFACE_NAME, ShellRuntime}; pub use shell_runtime::{DEFAULT_SURFACE_NAME, ShellRuntime};
pub use system::{EventDispatchContext, ShellControl, SurfaceControlHandle}; pub use system::{
EventDispatchContext, RuntimeSurfaceConfigBuilder, ShellControl, SurfaceControlHandle,
};
pub use value_conversion::IntoValue; pub use value_conversion::IntoValue;
pub use shell::{ pub use shell::{

View file

@ -622,7 +622,7 @@ impl Shell {
} }
SurfaceCommand::ApplyConfig { name, config } => { SurfaceCommand::ApplyConfig { name, config } => {
log::debug!("Surface command: ApplyConfig '{}'", name); log::debug!("Surface command: ApplyConfig '{}'", name);
for surface in ctx.surfaces_by_name(&name) { for surface in ctx.surfaces_by_name_mut(&name) {
let handle = LayerSurfaceHandle::from_window_state(surface); let handle = LayerSurfaceHandle::from_window_state(surface);
handle.set_size(config.dimensions.width(), config.dimensions.height()); handle.set_size(config.dimensions.width(), config.dimensions.height());
@ -632,6 +632,11 @@ impl Shell {
handle.set_layer(config.layer); handle.set_layer(config.layer);
handle.set_keyboard_interactivity(config.keyboard_interactivity); handle.set_keyboard_interactivity(config.keyboard_interactivity);
handle.commit(); handle.commit();
surface.update_size_with_compositor_logic(
config.dimensions.width(),
config.dimensions.height(),
);
} }
} }
} }

View file

@ -13,7 +13,7 @@ use layer_shika_domain::errors::DomainError;
use layer_shika_domain::prelude::{ use layer_shika_domain::prelude::{
AnchorEdges, KeyboardInteractivity, Layer, Margins, OutputPolicy, ScaleFactor, AnchorEdges, KeyboardInteractivity, Layer, Margins, OutputPolicy, ScaleFactor,
}; };
use layer_shika_domain::value_objects::dimensions::PopupDimensions; use layer_shika_domain::value_objects::dimensions::{PopupDimensions, SurfaceDimension};
use layer_shika_domain::value_objects::output_handle::OutputHandle; use layer_shika_domain::value_objects::output_handle::OutputHandle;
use layer_shika_domain::value_objects::output_info::OutputInfo; use layer_shika_domain::value_objects::output_info::OutputInfo;
use layer_shika_domain::value_objects::popup_positioning_mode::PopupPositioningMode; use layer_shika_domain::value_objects::popup_positioning_mode::PopupPositioningMode;
@ -307,6 +307,90 @@ impl SurfaceControlHandle {
}) })
}) })
} }
pub fn configure(self) -> RuntimeSurfaceConfigBuilder {
RuntimeSurfaceConfigBuilder {
handle: self,
config: SurfaceConfig::new(),
}
}
}
pub struct RuntimeSurfaceConfigBuilder {
handle: SurfaceControlHandle,
config: SurfaceConfig,
}
impl RuntimeSurfaceConfigBuilder {
#[must_use]
pub fn size(mut self, width: u32, height: u32) -> Self {
self.config.dimensions = SurfaceDimension::from_raw(width, height);
self
}
#[must_use]
pub fn width(mut self, width: u32) -> Self {
self.config.dimensions = SurfaceDimension::from_raw(width, self.config.dimensions.height());
self
}
#[must_use]
pub fn height(mut self, height: u32) -> Self {
self.config.dimensions = SurfaceDimension::from_raw(self.config.dimensions.width(), height);
self
}
#[must_use]
pub const fn layer(mut self, layer: Layer) -> Self {
self.config.layer = layer;
self
}
#[must_use]
pub fn margins(mut self, margins: impl Into<Margins>) -> Self {
self.config.margin = margins.into();
self
}
#[must_use]
pub const fn anchor(mut self, anchor: AnchorEdges) -> Self {
self.config.anchor = anchor;
self
}
#[must_use]
pub const fn exclusive_zone(mut self, zone: i32) -> Self {
self.config.exclusive_zone = zone;
self
}
#[must_use]
pub fn namespace(mut self, namespace: impl Into<String>) -> Self {
self.config.namespace = namespace.into();
self
}
#[must_use]
pub const fn keyboard_interactivity(mut self, mode: KeyboardInteractivity) -> Self {
self.config.keyboard_interactivity = mode;
self
}
#[must_use]
pub fn output_policy(mut self, policy: OutputPolicy) -> Self {
self.config.output_policy = policy;
self
}
#[must_use]
pub fn scale_factor(mut self, sf: impl TryInto<ScaleFactor, Error = DomainError>) -> Self {
self.config.scale_factor = sf.try_into().unwrap_or_default();
self
}
pub fn apply(self) -> Result<()> {
self.handle.apply_config(self.config)
}
} }
pub struct EventDispatchContext<'a> { pub struct EventDispatchContext<'a> {

View file

@ -28,9 +28,13 @@ cargo run -p runtime-surface-config
```rust ```rust
shell.on("Bar", "toggle-size", move |control| { shell.on("Bar", "toggle-size", move |control| {
let bar = control.surface("Bar"); control.surface("Bar")
bar.resize(width, height)?; .configure()
bar.set_exclusive_zone(new_size)?; .size(0, new_size)
.exclusive_zone(new_size as i32)
.margins(0, 0, 0, 0)
.apply()?;
Value::Struct(Struct::from_iter([("expanded".into(), is_expanded.into())])) Value::Struct(Struct::from_iter([("expanded".into(), is_expanded.into())]))
})?; })?;
``` ```

View file

@ -96,17 +96,15 @@ fn setup_toggle_size_callback(
} }
}; };
let bar = control.surface("Bar"); if let Err(e) = control
if let Err(e) = bar.resize(width, height) { .surface("Bar")
log::error!("Failed to resize bar: {}", e); .configure()
} .size(width, height)
.exclusive_zone(new_size.try_into().unwrap_or(32))
if let Err(e) = bar.set_exclusive_zone(new_size.try_into().unwrap_or(32)) { .margins((0, 0, 0, 0))
log::error!("Failed to set exclusive zone: {}", e); .apply()
} {
log::error!("Failed to apply configuration: {}", e);
if let Err(e) = control.surface("Bar").set_margins((0, 0, 0, 0)) {
log::error!("Failed to set margins: {}", e);
} }
log::info!( log::info!(