1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
use env::Environment;
use output::OutputMgr;
use std::sync::Mutex;
use wayland_client::protocol::wl_compositor::RequestsTrait as CompositorRequest;
use wayland_client::protocol::{wl_output, wl_surface};
use wayland_client::Proxy;
pub(crate) struct SurfaceUserData {
dpi_factor: i32,
outputs: Vec<Proxy<wl_output::WlOutput>>,
output_manager: OutputMgr,
dpi_change_cb: Box<FnMut(i32, Proxy<wl_surface::WlSurface>) + Send + 'static>,
}
impl SurfaceUserData {
fn new(
output_manager: OutputMgr,
dpi_change_cb: Box<FnMut(i32, Proxy<wl_surface::WlSurface>) + Send + 'static>,
) -> Self {
SurfaceUserData {
dpi_factor: 1,
outputs: Vec::new(),
output_manager,
dpi_change_cb,
}
}
pub(crate) fn enter(
&mut self,
output: Proxy<wl_output::WlOutput>,
surface: Proxy<wl_surface::WlSurface>,
) {
self.outputs.push(output);
self.compute_dpi_factor(surface);
}
pub(crate) fn leave(
&mut self,
output: &Proxy<wl_output::WlOutput>,
surface: Proxy<wl_surface::WlSurface>,
) {
self.outputs.retain(|output2| !output.equals(output2));
self.compute_dpi_factor(surface);
}
fn compute_dpi_factor(&mut self, surface: Proxy<wl_surface::WlSurface>) {
let mut scale_factor = 1;
for output in &self.outputs {
if let Some(scale_factor2) = self
.output_manager
.with_info(&output, |_id, info| info.scale_factor)
{
scale_factor = ::std::cmp::max(scale_factor, scale_factor2);
}
}
if self.dpi_factor != scale_factor {
self.dpi_factor = scale_factor;
(self.dpi_change_cb)(scale_factor, surface.clone());
}
}
}
pub(crate) fn create_surface<F>(
environment: &Environment,
dpi_change: Box<F>,
) -> Proxy<wl_surface::WlSurface>
where
F: FnMut(i32, Proxy<wl_surface::WlSurface>) + Send + 'static,
{
environment
.compositor
.create_surface(move |surface| {
surface.implement(
move |event, surface| {
let mut user_data = surface
.user_data::<Mutex<SurfaceUserData>>()
.unwrap()
.lock()
.unwrap();
match event {
wl_surface::Event::Enter { output } => {
user_data.enter(output, surface.clone());
}
wl_surface::Event::Leave { output } => {
user_data.leave(&output, surface.clone());
}
};
},
Mutex::new(SurfaceUserData::new(
environment.outputs.clone(),
dpi_change,
)),
)
})
.unwrap()
}
pub fn get_dpi_factor(surface: &Proxy<wl_surface::WlSurface>) -> i32 {
surface
.user_data::<Mutex<SurfaceUserData>>()
.expect("Surface was not created with create_surface.")
.lock()
.unwrap()
.dpi_factor
}
pub fn get_outputs(surface: &Proxy<wl_surface::WlSurface>) -> Vec<Proxy<wl_output::WlOutput>> {
surface
.user_data::<Mutex<SurfaceUserData>>()
.expect("Surface was not created with create_surface.")
.lock()
.unwrap()
.outputs
.clone()
}