1#![allow(dead_code)]
16
17use alloc::{collections::BTreeMap, vec::Vec};
18
19use crate::error::KernelError;
20
21pub const ZWLR_LAYER_SHELL_V1: &str = "zwlr_layer_shell_v1";
27
28pub const ZWLR_LAYER_SHELL_V1_VERSION: u32 = 4;
30
31pub const ZWLR_LAYER_SHELL_V1_GET_LAYER_SURFACE: u16 = 0;
34pub const ZWLR_LAYER_SHELL_V1_DESTROY: u16 = 1;
36
37pub const ZWLR_LAYER_SURFACE_V1_SET_SIZE: u16 = 0;
40pub const ZWLR_LAYER_SURFACE_V1_SET_ANCHOR: u16 = 1;
42pub const ZWLR_LAYER_SURFACE_V1_SET_EXCLUSIVE_ZONE: u16 = 2;
44pub const ZWLR_LAYER_SURFACE_V1_SET_MARGIN: u16 = 3;
46pub const ZWLR_LAYER_SURFACE_V1_SET_KEYBOARD_INTERACTIVITY: u16 = 4;
48pub const ZWLR_LAYER_SURFACE_V1_GET_POPUP: u16 = 5;
50pub const ZWLR_LAYER_SURFACE_V1_ACK_CONFIGURE: u16 = 6;
52pub const ZWLR_LAYER_SURFACE_V1_DESTROY: u16 = 7;
54pub const ZWLR_LAYER_SURFACE_V1_SET_LAYER: u16 = 8;
56
57pub const ZWLR_LAYER_SURFACE_V1_CONFIGURE: u16 = 0;
60pub const ZWLR_LAYER_SURFACE_V1_CLOSED: u16 = 1;
62
63#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
72#[repr(u32)]
73pub enum Layer {
74 Background = 0,
76 Bottom = 1,
78 Top = 2,
80 Overlay = 3,
82}
83
84impl Layer {
85 pub fn from_u32(value: u32) -> Option<Self> {
87 match value {
88 0 => Some(Self::Background),
89 1 => Some(Self::Bottom),
90 2 => Some(Self::Top),
91 3 => Some(Self::Overlay),
92 _ => None,
93 }
94 }
95}
96
97#[derive(Debug, Clone, Copy, PartialEq, Eq)]
103pub struct Anchor {
104 pub top: bool,
105 pub bottom: bool,
106 pub left: bool,
107 pub right: bool,
108}
109
110impl Anchor {
111 pub fn none() -> Self {
113 Self {
114 top: false,
115 bottom: false,
116 left: false,
117 right: false,
118 }
119 }
120
121 pub fn from_bits(bits: u32) -> Self {
125 Self {
126 top: bits & 1 != 0,
127 bottom: bits & 2 != 0,
128 left: bits & 4 != 0,
129 right: bits & 8 != 0,
130 }
131 }
132
133 pub fn to_bits(&self) -> u32 {
135 let mut bits = 0u32;
136 if self.top {
137 bits |= 1;
138 }
139 if self.bottom {
140 bits |= 2;
141 }
142 if self.left {
143 bits |= 4;
144 }
145 if self.right {
146 bits |= 8;
147 }
148 bits
149 }
150
151 pub fn stretches_horizontal(&self) -> bool {
153 self.left && self.right
154 }
155
156 pub fn stretches_vertical(&self) -> bool {
158 self.top && self.bottom
159 }
160}
161
162#[derive(Debug, Clone, Copy, PartialEq, Eq)]
164#[repr(u32)]
165pub enum KeyboardInteractivity {
166 None = 0,
168 Exclusive = 1,
170 OnDemand = 2,
172}
173
174impl KeyboardInteractivity {
175 pub fn from_u32(value: u32) -> Option<Self> {
177 match value {
178 0 => Some(Self::None),
179 1 => Some(Self::Exclusive),
180 2 => Some(Self::OnDemand),
181 _ => None,
182 }
183 }
184}
185
186pub struct LayerSurface {
196 pub id: u32,
198 pub surface_id: u32,
200 pub layer: Layer,
202 pub anchor: Anchor,
204 pub exclusive_zone: i32,
206 pub margin_top: i32,
208 pub margin_bottom: i32,
210 pub margin_left: i32,
212 pub margin_right: i32,
214 pub keyboard_interactivity: KeyboardInteractivity,
216 pub desired_width: u32,
218 pub desired_height: u32,
220 pub actual_width: u32,
222 pub actual_height: u32,
224 pub namespace: [u8; 64],
226 pub namespace_len: usize,
228 pub configured: bool,
230 pub configure_serial: u32,
232 pub mapped: bool,
234}
235
236impl LayerSurface {
237 pub fn new(id: u32, surface_id: u32, layer: Layer) -> Self {
239 Self {
240 id,
241 surface_id,
242 layer,
243 anchor: Anchor::none(),
244 exclusive_zone: 0,
245 margin_top: 0,
246 margin_bottom: 0,
247 margin_left: 0,
248 margin_right: 0,
249 keyboard_interactivity: KeyboardInteractivity::None,
250 desired_width: 0,
251 desired_height: 0,
252 actual_width: 0,
253 actual_height: 0,
254 namespace: [0u8; 64],
255 namespace_len: 0,
256 configured: false,
257 configure_serial: 0,
258 mapped: false,
259 }
260 }
261
262 pub fn set_namespace(&mut self, ns: &[u8]) {
264 let copy_len = ns.len().min(self.namespace.len());
265 self.namespace[..copy_len].copy_from_slice(&ns[..copy_len]);
266 self.namespace_len = copy_len;
267 }
268
269 pub fn namespace_bytes(&self) -> &[u8] {
271 &self.namespace[..self.namespace_len]
272 }
273}
274
275#[derive(Debug, Clone, Copy, PartialEq, Eq)]
281pub struct UsableArea {
282 pub x: i32,
283 pub y: i32,
284 pub width: u32,
285 pub height: u32,
286}
287
288pub struct LayerShellManager {
292 surfaces: BTreeMap<u32, LayerSurface>,
294 next_id: u32,
296 next_serial: u32,
298}
299
300impl LayerShellManager {
301 pub fn new() -> Self {
303 Self {
304 surfaces: BTreeMap::new(),
305 next_id: 1,
306 next_serial: 1,
307 }
308 }
309
310 fn alloc_serial(&mut self) -> u32 {
312 let s = self.next_serial;
313 self.next_serial += 1;
314 s
315 }
316
317 pub fn create_surface(
321 &mut self,
322 surface_id: u32,
323 layer: Layer,
324 namespace: &[u8],
325 ) -> Result<u32, KernelError> {
326 let id = self.next_id;
327 self.next_id += 1;
328
329 let mut ls = LayerSurface::new(id, surface_id, layer);
330 ls.set_namespace(namespace);
331
332 self.surfaces.insert(id, ls);
333 Ok(id)
334 }
335
336 pub fn destroy_surface(&mut self, id: u32) -> Result<(), KernelError> {
338 self.surfaces.remove(&id).ok_or(KernelError::NotFound {
339 resource: "layer_surface",
340 id: id as u64,
341 })?;
342 Ok(())
343 }
344
345 pub fn get_surface(&self, id: u32) -> Option<&LayerSurface> {
347 self.surfaces.get(&id)
348 }
349
350 pub fn get_surface_mut(&mut self, id: u32) -> Option<&mut LayerSurface> {
352 self.surfaces.get_mut(&id)
353 }
354
355 pub fn configure_surface(
360 &mut self,
361 id: u32,
362 width: u32,
363 height: u32,
364 ) -> Result<u32, KernelError> {
365 let serial = self.alloc_serial();
366
367 let ls = self.surfaces.get_mut(&id).ok_or(KernelError::NotFound {
368 resource: "layer_surface",
369 id: id as u64,
370 })?;
371
372 ls.actual_width = width;
373 ls.actual_height = height;
374 ls.configure_serial = serial;
375 ls.configured = false;
376
377 Ok(serial)
378 }
379
380 pub fn ack_configure(&mut self, id: u32, serial: u32) -> bool {
382 if let Some(ls) = self.surfaces.get_mut(&id) {
383 if ls.configure_serial == serial {
384 ls.configured = true;
385 return true;
386 }
387 }
388 false
389 }
390
391 pub fn get_surfaces_for_layer(&self, layer: Layer) -> Vec<&LayerSurface> {
394 self.surfaces
395 .values()
396 .filter(|ls| ls.layer == layer)
397 .collect()
398 }
399
400 pub fn calculate_exclusive_zones(&self) -> (i32, i32, i32, i32) {
405 let mut top = 0i32;
406 let mut bottom = 0i32;
407 let mut left = 0i32;
408 let mut right = 0i32;
409
410 for ls in self.surfaces.values() {
411 if ls.exclusive_zone <= 0 || !ls.mapped {
412 continue;
413 }
414
415 let zone = ls.exclusive_zone;
416
417 if ls.anchor.top && !ls.anchor.bottom {
420 top = top.max(zone + ls.margin_top);
422 } else if ls.anchor.bottom && !ls.anchor.top {
423 bottom = bottom.max(zone + ls.margin_bottom);
425 } else if ls.anchor.left && !ls.anchor.right {
426 left = left.max(zone + ls.margin_left);
428 } else if ls.anchor.right && !ls.anchor.left {
429 right = right.max(zone + ls.margin_right);
431 } else if ls.anchor.top && ls.anchor.bottom {
432 if ls.anchor.left && !ls.anchor.right {
435 left = left.max(zone + ls.margin_left);
436 } else if ls.anchor.right && !ls.anchor.left {
437 right = right.max(zone + ls.margin_right);
438 }
439 } else if ls.anchor.left && ls.anchor.right {
440 if ls.anchor.top && !ls.anchor.bottom {
443 top = top.max(zone + ls.margin_top);
444 } else if ls.anchor.bottom && !ls.anchor.top {
445 bottom = bottom.max(zone + ls.margin_bottom);
446 }
447 }
448 }
449
450 (top, bottom, left, right)
451 }
452
453 pub fn get_usable_area(&self, output_width: u32, output_height: u32) -> UsableArea {
456 let (top, bottom, left, right) = self.calculate_exclusive_zones();
457
458 let x = left;
459 let y = top;
460 let w = (output_width as i32 - left - right).max(0) as u32;
461 let h = (output_height as i32 - top - bottom).max(0) as u32;
462
463 UsableArea {
464 x,
465 y,
466 width: w,
467 height: h,
468 }
469 }
470
471 pub fn surface_count(&self) -> usize {
473 self.surfaces.len()
474 }
475}
476
477impl Default for LayerShellManager {
478 fn default() -> Self {
479 Self::new()
480 }
481}
482
483#[cfg(test)]
488mod tests {
489 use super::*;
490
491 #[test]
492 fn test_layer_ordering() {
493 assert!(Layer::Background < Layer::Bottom);
494 assert!(Layer::Bottom < Layer::Top);
495 assert!(Layer::Top < Layer::Overlay);
496 }
497
498 #[test]
499 fn test_anchor_from_bits() {
500 let a = Anchor::from_bits(0b1111);
501 assert!(a.top && a.bottom && a.left && a.right);
502
503 let b = Anchor::from_bits(0b0001);
504 assert!(b.top && !b.bottom && !b.left && !b.right);
505
506 let c = Anchor::from_bits(0);
507 assert!(!c.top && !c.bottom && !c.left && !c.right);
508 }
509
510 #[test]
511 fn test_anchor_roundtrip() {
512 let a = Anchor {
513 top: true,
514 bottom: false,
515 left: true,
516 right: false,
517 };
518 let bits = a.to_bits();
519 let b = Anchor::from_bits(bits);
520 assert_eq!(a, b);
521 }
522
523 #[test]
524 fn test_layer_surface_creation() {
525 let mut mgr = LayerShellManager::new();
526 let id = mgr.create_surface(10, Layer::Top, b"panel").unwrap();
527 assert_eq!(mgr.surface_count(), 1);
528
529 let ls = mgr.get_surface(id).unwrap();
530 assert_eq!(ls.surface_id, 10);
531 assert_eq!(ls.layer, Layer::Top);
532 assert_eq!(ls.namespace_bytes(), b"panel");
533 }
534
535 #[test]
536 fn test_layer_surface_destroy() {
537 let mut mgr = LayerShellManager::new();
538 let id = mgr.create_surface(10, Layer::Bottom, b"dock").unwrap();
539 assert_eq!(mgr.surface_count(), 1);
540 mgr.destroy_surface(id).unwrap();
541 assert_eq!(mgr.surface_count(), 0);
542 }
543
544 #[test]
545 fn test_configure_ack() {
546 let mut mgr = LayerShellManager::new();
547 let id = mgr.create_surface(10, Layer::Top, b"bar").unwrap();
548
549 let serial = mgr.configure_surface(id, 1280, 32).unwrap();
550 assert!(!mgr.get_surface(id).unwrap().configured);
551
552 assert!(mgr.ack_configure(id, serial));
553 assert!(mgr.get_surface(id).unwrap().configured);
554
555 assert!(!mgr.ack_configure(id, serial + 999));
557 }
558
559 #[test]
560 fn test_exclusive_zones() {
561 let mut mgr = LayerShellManager::new();
562
563 let id = mgr.create_surface(10, Layer::Top, b"panel").unwrap();
565 {
566 let ls = mgr.get_surface_mut(id).unwrap();
567 ls.anchor = Anchor {
568 top: true,
569 bottom: false,
570 left: true,
571 right: true,
572 };
573 ls.exclusive_zone = 32;
574 ls.mapped = true;
575 }
576
577 let (top, bottom, left, right) = mgr.calculate_exclusive_zones();
578 assert_eq!(top, 32);
579 assert_eq!(bottom, 0);
580 assert_eq!(left, 0);
581 assert_eq!(right, 0);
582
583 let usable = mgr.get_usable_area(1280, 800);
584 assert_eq!(usable.x, 0);
585 assert_eq!(usable.y, 32);
586 assert_eq!(usable.width, 1280);
587 assert_eq!(usable.height, 768);
588 }
589
590 #[test]
591 fn test_usable_area_no_exclusions() {
592 let mgr = LayerShellManager::new();
593 let area = mgr.get_usable_area(1920, 1080);
594 assert_eq!(area.x, 0);
595 assert_eq!(area.y, 0);
596 assert_eq!(area.width, 1920);
597 assert_eq!(area.height, 1080);
598 }
599
600 #[test]
601 fn test_get_surfaces_for_layer() {
602 let mut mgr = LayerShellManager::new();
603 mgr.create_surface(1, Layer::Top, b"a").unwrap();
604 mgr.create_surface(2, Layer::Bottom, b"b").unwrap();
605 mgr.create_surface(3, Layer::Top, b"c").unwrap();
606
607 let top_surfaces = mgr.get_surfaces_for_layer(Layer::Top);
608 assert_eq!(top_surfaces.len(), 2);
609
610 let bottom_surfaces = mgr.get_surfaces_for_layer(Layer::Bottom);
611 assert_eq!(bottom_surfaces.len(), 1);
612
613 let bg_surfaces = mgr.get_surfaces_for_layer(Layer::Background);
614 assert_eq!(bg_surfaces.len(), 0);
615 }
616}