tawasuyu/llimphi
Sovereign retained-mode GPU UI framework in Rust (wgpu+vello+taffy+parley), Elm loop, 40+ widgets.
chore: refresco desde el monorepo — vello 0.9 / wgpu 29, 120 miembros
1//! Declarar el **tipo de contenido** de la ventana (`wp_content_type_v1`).
2//!
3//! Cicla `None → Photo → Video → Game` con cada click y se lo declara al
4//! compositor por [`Handle::set_content_type`]. No cambia nada de lo que se
5//! pinta: es una pista para que el compositor ajuste su política (mirada deja de
6//! animar su fondo de marca ante contenido con ritmo propio, y decide VRR y
7//! tearing con lo mismo).
8//!
9//! Corre con: `cargo run -p llimphi-ui --example content_type --release`.
10//!
11//! Para **ver el protocolo en el cable** (que es como se verificó el puente
12//! winit↔wayland-client):
13//!
14//! ```sh
15//! WAYLAND_DEBUG=1 cargo run -p llimphi-ui --example content_type --release 2>&1 \
16//! | grep content_type
17//! ```
18//!
19//! Tienen que aparecer el `get_surface_content_type` y un `set_content_type`
20//! por cada click. Si no aparece ninguno, el compositor no expone el global (el
21//! módulo avisa por stderr una sola vez y sigue sin romper nada).
22
23use llimphi_ui::llimphi_layout::taffy::{
24 prelude::{percent, Dimension, Size, Style},
25 AlignItems, JustifyContent,
26};
27use llimphi_ui::llimphi_raster::peniko::Color;
28use llimphi_ui::{App, ContentType, Handle, View};
29
30#[derive(Clone)]
31enum Msg {
32 Ciclar,
33}
34
35struct Demo;
36
37fn siguiente(k: ContentType) -> ContentType {
38 match k {
39 ContentType::None => ContentType::Photo,
40 ContentType::Photo => ContentType::Video,
41 ContentType::Video => ContentType::Game,
42 ContentType::Game => ContentType::None,
43 }
44}
45
46fn nombre(k: ContentType) -> &'static str {
47 match k {
48 ContentType::None => "none",
49 ContentType::Photo => "photo",
50 ContentType::Video => "video",
51 ContentType::Game => "game",
52 }
53}
54
55impl App for Demo {
56 type Model = ContentType;
57 type Msg = Msg;
58
59 fn title() -> &'static str {
60 "llimphi · content type"
61 }
62
63 fn init(handle: &Handle<Self::Msg>) -> Self::Model {
64 // Declarar el estado inicial también: el compositor arranca asumiendo
65 // `none`, y una app que nace mostrando video quiere decirlo ya.
66 handle.set_content_type(ContentType::None);
67 ContentType::None
68 }
69
70 fn update(model: Self::Model, msg: Self::Msg, handle: &Handle<Self::Msg>) -> Self::Model {
71 match msg {
72 Msg::Ciclar => {
73 let nuevo = siguiente(model);
74 handle.set_content_type(nuevo);
75 nuevo
76 }
77 }
78 }
79
80 fn view(model: &Self::Model) -> View<Self::Msg> {
81 View::new(Style {
82 size: Size {
83 width: percent(1.0_f32),
84 height: Dimension::auto(),
85 },
86 flex_grow: 1.0,
87 align_items: Some(AlignItems::CENTER),
88 justify_content: Some(JustifyContent::CENTER),
89 ..Default::default()
90 })
91 .fill(Color::from_rgba8(16, 18, 26, 255))
92 .text(
93 format!("content type: {}", nombre(*model)),
94 42.0,
95 Color::from_rgba8(230, 240, 250, 255),
96 )
97 .on_click(Msg::Ciclar)
98 }
99}
100
101fn main() {
102 llimphi_ui::run::<Demo>();
103}