async_window/common/
singletons.rs1use {
2 crate::common::protocols::wayland::{
3 wl_display::WlDisplay, wl_fixes::WlFixes, wl_registry::WlRegistry,
4 },
5 parking_lot::Mutex,
6 std::collections::HashMap,
7 wl_client::{proxy, proxy::OwnedProxy},
8};
9
10pub struct Singletons {
11 wl_registry: WlRegistry,
12 map: HashMap<String, (u32, u32)>,
13}
14
15impl Singletons {
16 pub fn get<P>(&self, min: u32, max: u32) -> P
17 where
18 P: OwnedProxy,
19 {
20 match self.get_opt(min, max) {
21 Some(p) => p,
22 _ => {
23 panic!(
24 "Compositor does not support {} ({}..={}) but it is required for this example",
25 P::INTERFACE,
26 min,
27 max,
28 );
29 }
30 }
31 }
32
33 pub fn get_opt<P>(&self, min: u32, max: u32) -> Option<P>
34 where
35 P: OwnedProxy,
36 {
37 let &(name, comp_max) = self.map.get(P::INTERFACE)?;
38 let version = comp_max.min(max);
39 if version < min {
40 return None;
41 }
42 Some(self.wl_registry.bind(name, version))
43 }
44}
45
46impl Drop for Singletons {
47 fn drop(&mut self) {
48 if let Some(fixes) = self.get_opt::<WlFixes>(1, 1) {
49 fixes.destroy_registry(&self.wl_registry);
50 fixes.destroy();
51 }
52 proxy::destroy(&self.wl_registry);
53 }
54}
55
56pub fn get_singletons(display: &WlDisplay) -> Singletons {
57 let map = Mutex::new(HashMap::new());
58
59 let queue = proxy::queue(display);
60 let wl_registry = display.get_registry();
61
62 queue.dispatch_scope_blocking(|scope| {
63 scope.set_event_handler(
64 &wl_registry,
65 WlRegistry::on_global(|_, name, interface, version| {
66 map.lock().insert(interface.to_owned(), (name, version));
67 }),
68 );
69 queue.dispatch_roundtrip_blocking().unwrap();
70 });
71
72 Singletons {
73 wl_registry,
74 map: map.into_inner(),
75 }
76}
77
78pub async fn get_singletons_async(display: &WlDisplay) -> Singletons {
79 let map = Mutex::new(HashMap::new());
80
81 let queue = proxy::queue(display);
82 let wl_registry = display.get_registry();
83
84 queue
85 .dispatch_scope_async(async |scope| {
86 scope.set_event_handler(
87 &wl_registry,
88 WlRegistry::on_global(|_, name, interface, version| {
89 map.lock().insert(interface.to_owned(), (name, version));
90 }),
91 );
92 queue.dispatch_roundtrip_async().await.unwrap();
93 })
94 .await;
95
96 Singletons {
97 wl_registry,
98 map: map.into_inner(),
99 }
100}