dampen_dev/persistence/window_state.rs
1use crate::persistence::error::PersistenceError;
2use serde::{Deserialize, Serialize};
3
4/// Persisted window state for Dampen applications.
5#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
6pub struct WindowState {
7 /// Window width in logical pixels
8 pub width: u32,
9
10 /// Window height in logical pixels
11 pub height: u32,
12
13 /// Window X position (None if platform doesn't support absolute positioning)
14 ///
15 /// On Linux with Wayland, absolute window positioning is generally not supported
16 /// by compositors. In this case, `x` and `y` will be `None`, and the window
17 /// position will be determined by the compositor.
18 #[serde(skip_serializing_if = "Option::is_none")]
19 pub x: Option<i32>,
20
21 /// Window Y position (None if platform doesn't support absolute positioning)
22 ///
23 /// On Linux with Wayland, absolute window positioning is generally not supported
24 /// by compositors. In this case, `x` and `y` will be `None`, and the window
25 /// position will be determined by the compositor.
26 #[serde(skip_serializing_if = "Option::is_none")]
27 pub y: Option<i32>,
28
29 /// Whether the window was maximized.
30 ///
31 /// If true, the application should initialize the window in a maximized state,
32 /// regardless of the saved width/height/position.
33 pub maximized: bool,
34}
35
36impl WindowState {
37 /// Create a default WindowState with the given dimensions.
38 pub fn with_defaults(width: u32, height: u32) -> Self {
39 Self {
40 width,
41 height,
42 x: None,
43 y: None,
44 maximized: false,
45 }
46 }
47
48 /// Convert to Iced Size for use with `.window_size()`.
49 pub fn size(&self) -> iced::Size {
50 iced::Size::new(self.width as f32, self.height as f32)
51 }
52
53 /// Convert to Iced Point for use with `.position()`.
54 pub fn position(&self) -> Option<iced::Point> {
55 match (self.x, self.y) {
56 (Some(x), Some(y)) => Some(iced::Point::new(x as f32, y as f32)),
57 _ => None,
58 }
59 }
60
61 /// Validate the state against reasonable bounds
62 pub fn validate(&self) -> Result<(), PersistenceError> {
63 if self.width < 100 || self.height < 100 {
64 return Err(PersistenceError::InvalidState {
65 reason: format!(
66 "Window dimensions {}x{} are below minimum 100x100",
67 self.width, self.height
68 ),
69 });
70 }
71 if self.width > 16384 || self.height > 16384 {
72 return Err(PersistenceError::InvalidState {
73 reason: format!(
74 "Window dimensions {}x{} exceed maximum 16384x16384",
75 self.width, self.height
76 ),
77 });
78 }
79 Ok(())
80 }
81}