diff --git a/CHANGELOG.md b/CHANGELOG.md index c3f5e69..8030f68 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ All notable changes to `ltk` are documented here. The format is based on [Keep a ### Added +- **`PatternGrid::size( impl Into )`** — explicit side for the square grid, resolved through `Canvas::resolve_geom` like the other geometry overrides; without it the theme's fluid default still applies. A lock screen can now size the grid from the surface (a share of the width in portrait, of the free height in landscape) instead of being capped at the default. - **`xdg-session-management-v1` (client)** — before the first commit of a `ShellMode::Window` toplevel the runtime binds `xdg_session_manager_v1`, issues `get_session( reason, stored_id )` and `restore_toplevel( toplevel, "main" )`, so a supporting compositor restores window geometry on every launch. Bindings are generated in-tree from the vendored XML under `protocols/` with `wayland-scanner` (`src/protocol/`). - **Runtime session persistence** — `$XDG_STATE_HOME//session.json` (compositor session id, clean-exit marker, pid) plus `state.bin` (the bytes from `App::save_state`), written atomically with mode `0600`; saved every 30 s when the bytes changed, on close and on signal; handed back through `App::restore_state` before the first frame only on a session restore (`LTK_SESSION_RESTORE=1`) or after an unclean exit. Module `src/session_state.rs`. - **`Layer::Window` overlays** — an `OverlaySpec` with `layer: Layer::Window` is materialised as an ordinary `xdg_toplevel` of the given fixed size instead of a layer-shell surface: decorated, stacked and listed by the compositor like an application window. Anchor, exclusive zone and keyboard exclusivity are ignored; the compositor's close button delivers `on_dismiss`. `App::overlay_title( id )` (defaulted to the app id) names it. Layer-shell apps now bind `xdg_wm_base` when available so they can open one. diff --git a/docs/widgets.md b/docs/widgets.md index 9cb5a3e..b2feb7b 100644 --- a/docs/widgets.md +++ b/docs/widgets.md @@ -368,6 +368,8 @@ repeat, or taking in the node a straight stroke crosses is the app's rule, not the widget's. `on_release( msg )` fires when the finger lifts. `hide_stroke( true )` draws only the dots, against shoulder surfing; `error( true )` paints the current path in the palette's `danger` colour. +`size( len )` sets the side of the square grid (any `Length`); without it the +theme's fluid default applies, capped by the width the parent allocates. It sizes itself square to `min( max_width, 264 )` design pixels; wrap it in a `container( … ).max_width( … )` to pin it. diff --git a/src/widget/pattern_grid/mod.rs b/src/widget/pattern_grid/mod.rs index 443f5ad..c0f3ea9 100644 --- a/src/widget/pattern_grid/mod.rs +++ b/src/widget/pattern_grid/mod.rs @@ -8,7 +8,7 @@ //! `on_release`. use std::sync::Arc; -use crate::types::{ Color, Point, Rect }; +use crate::types::{ Color, Length, Point, Rect }; use crate::render::Canvas; use super::Element; @@ -25,13 +25,21 @@ pub struct PatternGrid pub( crate ) on_release: Option, pub( crate ) hide_stroke: bool, pub( crate ) error: bool, + pub( crate ) size: Option, } impl PatternGrid { pub fn new( path: Vec ) -> Self { - Self { path, on_node: None, on_release: None, hide_stroke: false, error: false } + Self { path, on_node: None, on_release: None, hide_stroke: false, error: false, size: None } + } + + /// Side of the square grid; without it the theme's fluid default applies. + pub fn size( mut self, s: impl Into ) -> Self + { + self.size = Some( s.into() ); + self } pub fn on_node( mut self, f: impl Fn( u8 ) -> Msg + 'static ) -> Self @@ -77,12 +85,18 @@ impl PatternGrid on_release: self.on_release.map( |m| ( *f )( m ) ), hide_stroke: self.hide_stroke, error: self.error, + size: self.size, } } pub fn preferred_size( &self, max_width: f32, canvas: &Canvas ) -> ( f32, f32 ) { - let size = canvas.geom_px( theme::SIZE ).min( max_width ); + let size = match self.size + { + Some( l ) => canvas.resolve_geom( l ), + None => canvas.geom_px( theme::SIZE ), + }; + let size = size.min( max_width ); ( size, size ) }