mirror of
https://codeberg.org/waydeer/layer-shika.git
synced 2026-01-01 21:06:08 +00:00
refactor: surface dimensions spec compliance
This commit is contained in:
parent
0f5bd88742
commit
22aa14417b
3 changed files with 59 additions and 24 deletions
|
|
@ -405,6 +405,10 @@ impl Shell {
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for def in &definitions {
|
||||||
|
def.config.validate().map_err(Error::Domain)?;
|
||||||
|
}
|
||||||
|
|
||||||
let is_single_window = definitions.len() == 1;
|
let is_single_window = definitions.len() == 1;
|
||||||
|
|
||||||
if is_single_window {
|
if is_single_window {
|
||||||
|
|
@ -693,6 +697,12 @@ impl Shell {
|
||||||
config: &SurfaceConfig,
|
config: &SurfaceConfig,
|
||||||
) {
|
) {
|
||||||
log::debug!("Surface command: ApplyConfig {:?}", target);
|
log::debug!("Surface command: ApplyConfig {:?}", target);
|
||||||
|
|
||||||
|
if let Err(e) = config.validate() {
|
||||||
|
log::error!("Invalid surface configuration: {}", e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for surface in Self::resolve_surface_target(ctx, target) {
|
for surface in Self::resolve_surface_target(ctx, target) {
|
||||||
let handle = LayerSurfaceHandle::from_window_state(surface);
|
let handle = LayerSurfaceHandle::from_window_state(surface);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
use crate::dimensions::ScaleFactor;
|
use crate::dimensions::ScaleFactor;
|
||||||
|
use crate::errors::{DomainError, Result};
|
||||||
use crate::value_objects::anchor::AnchorEdges;
|
use crate::value_objects::anchor::AnchorEdges;
|
||||||
use crate::value_objects::dimensions::SurfaceDimension;
|
use crate::value_objects::dimensions::SurfaceDimension;
|
||||||
use crate::value_objects::keyboard_interactivity::KeyboardInteractivity;
|
use crate::value_objects::keyboard_interactivity::KeyboardInteractivity;
|
||||||
|
|
@ -10,6 +11,14 @@ use crate::value_objects::output_policy::OutputPolicy;
|
||||||
///
|
///
|
||||||
/// Contains all positioning, sizing, and behavioral properties for a surface.
|
/// Contains all positioning, sizing, and behavioral properties for a surface.
|
||||||
/// Use with `ShellConfig` for declarative configuration or build via `ShellBuilder`.
|
/// Use with `ShellConfig` for declarative configuration or build via `ShellBuilder`.
|
||||||
|
///
|
||||||
|
/// # Wayland Protocol Requirements
|
||||||
|
///
|
||||||
|
/// According to the wlr-layer-shell protocol, dimensions and anchors must be coordinated:
|
||||||
|
/// - If width is 0, the surface must be anchored to both left and right edges
|
||||||
|
/// - If height is 0, the surface must be anchored to both top and bottom edges
|
||||||
|
///
|
||||||
|
/// Use `validate()` to check protocol compliance before use.
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct SurfaceConfig {
|
pub struct SurfaceConfig {
|
||||||
pub dimensions: SurfaceDimension,
|
pub dimensions: SurfaceDimension,
|
||||||
|
|
@ -38,6 +47,33 @@ impl SurfaceConfig {
|
||||||
output_policy: OutputPolicy::default(),
|
output_policy: OutputPolicy::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Validates the surface configuration according to Wayland layer-shell protocol requirements.
|
||||||
|
///
|
||||||
|
/// According to the protocol:
|
||||||
|
/// - If width is 0, the surface must be anchored to both left and right edges
|
||||||
|
/// - If height is 0, the surface must be anchored to both top and bottom edges
|
||||||
|
pub fn validate(&self) -> Result<()> {
|
||||||
|
if self.dimensions.width() == 0 && !(self.anchor.has_left() && self.anchor.has_right()) {
|
||||||
|
return Err(DomainError::Configuration {
|
||||||
|
message: "Width is 0 but surface is not anchored to both left and right edges. \
|
||||||
|
According to wlr-layer-shell protocol, you must set your anchor to \
|
||||||
|
opposite edges in the dimensions you omit."
|
||||||
|
.to_string(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.dimensions.height() == 0 && !(self.anchor.has_top() && self.anchor.has_bottom()) {
|
||||||
|
return Err(DomainError::Configuration {
|
||||||
|
message: "Height is 0 but surface is not anchored to both top and bottom edges. \
|
||||||
|
According to wlr-layer-shell protocol, you must set your anchor to \
|
||||||
|
opposite edges in the dimensions you omit."
|
||||||
|
.to_string(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for SurfaceConfig {
|
impl Default for SurfaceConfig {
|
||||||
|
|
|
||||||
|
|
@ -1,26 +1,24 @@
|
||||||
/// Width and height of a layer surface in pixels
|
/// Width and height of a layer surface in pixels
|
||||||
///
|
///
|
||||||
/// Use 0 for either dimension to let the surface stretch along that axis based on anchor edges.
|
/// According to the Wayland wlr-layer-shell protocol:
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
/// - Pass 0 for either width or height to have the compositor assign it
|
||||||
|
/// - The compositor will center the surface with respect to its anchors
|
||||||
|
/// - When using 0, you MUST anchor to opposite edges in that dimension:
|
||||||
|
/// - width = 0 requires both left and right anchors
|
||||||
|
/// - height = 0 requires both top and bottom anchors
|
||||||
|
/// - Not following this requirement is a protocol error
|
||||||
|
/// - Both values default to 0
|
||||||
|
///
|
||||||
|
/// Size is double-buffered via `wl_surface.commit`.
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
|
||||||
pub struct SurfaceDimension {
|
pub struct SurfaceDimension {
|
||||||
width: u32,
|
width: u32,
|
||||||
height: u32,
|
height: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SurfaceDimension {
|
impl SurfaceDimension {
|
||||||
pub fn new(width: u32, height: u32) -> Self {
|
pub const fn new(width: u32, height: u32) -> Self {
|
||||||
Self {
|
Self { width, height }
|
||||||
width: if width == 0 {
|
|
||||||
Self::default().width
|
|
||||||
} else {
|
|
||||||
width
|
|
||||||
},
|
|
||||||
height: if height == 0 {
|
|
||||||
Self::default().height
|
|
||||||
} else {
|
|
||||||
height
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const fn from_raw(width: u32, height: u32) -> Self {
|
pub const fn from_raw(width: u32, height: u32) -> Self {
|
||||||
|
|
@ -36,15 +34,6 @@ impl SurfaceDimension {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for SurfaceDimension {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self {
|
|
||||||
width: 20,
|
|
||||||
height: 20,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||||
pub struct PopupDimensions {
|
pub struct PopupDimensions {
|
||||||
pub width: f32,
|
pub width: f32,
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue