Skip to content

Commit a0651df

Browse files
authored
test_client: Subsurface position test client (#1895)
test_client: Introduce subsurface position test client
1 parent 63ae0c3 commit a0651df

File tree

4 files changed

+243
-10
lines changed

4 files changed

+243
-10
lines changed

test_clients/src/bin/test_pointer_constraints.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ impl App {
171171

172172
test_clients::draw(
173173
qh,
174-
&self.window,
174+
self.window.wl_surface(),
175175
&mut self.pool,
176176
&mut self.buffer,
177177
self.width,
Lines changed: 236 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,236 @@
1+
//! Attempt to reproduce https://github.com/Smithay/smithay/issues/1894
2+
3+
use smithay_client_toolkit::delegate_subcompositor;
4+
use smithay_client_toolkit::reexports::client::protocol::wl_subsurface::WlSubsurface;
5+
use smithay_client_toolkit::reexports::{calloop, client as wayland_client};
6+
7+
use smithay_client_toolkit::subcompositor::SubcompositorState;
8+
use smithay_client_toolkit::{
9+
compositor::{CompositorHandler, CompositorState},
10+
delegate_compositor, delegate_output, delegate_registry, delegate_shm, delegate_xdg_shell,
11+
delegate_xdg_window,
12+
output::{OutputHandler, OutputState},
13+
registry::{ProvidesRegistryState, RegistryState},
14+
registry_handlers,
15+
shell::{
16+
xdg::{
17+
window::{Window, WindowConfigure, WindowDecorations, WindowHandler},
18+
XdgShell,
19+
},
20+
WaylandSurface,
21+
},
22+
shm::{
23+
slot::{Buffer, SlotPool},
24+
Shm, ShmHandler,
25+
},
26+
};
27+
use tracing::info;
28+
use wayland_client::{
29+
protocol::{
30+
wl_output::{self, WlOutput},
31+
wl_surface::{self, WlSurface},
32+
},
33+
Connection, QueueHandle,
34+
};
35+
36+
fn main() {
37+
test_clients::init_logging();
38+
39+
let (mut event_loop, globals, qh) = test_clients::init_connection::<App>();
40+
41+
let compositor = CompositorState::bind(&globals, &qh).unwrap();
42+
let subcompositor = SubcompositorState::bind(compositor.wl_compositor().clone(), &globals, &qh).unwrap();
43+
let xdg_shell = XdgShell::bind(&globals, &qh).unwrap();
44+
45+
let surface = compositor.create_surface(&qh);
46+
let subsurface = subcompositor.create_subsurface(surface.clone(), &qh);
47+
48+
let window = xdg_shell.create_window(surface, WindowDecorations::RequestServer, &qh);
49+
50+
let shm = Shm::bind(&globals, &qh).unwrap();
51+
let pool = SlotPool::new(256 * 256 * 4, &shm).unwrap();
52+
53+
let mut app = App {
54+
registry_state: RegistryState::new(&globals),
55+
output_state: OutputState::new(&globals, &qh),
56+
shm,
57+
58+
should_be_mapped: false,
59+
60+
first_configure: true,
61+
pool,
62+
width: 256,
63+
height: 256,
64+
shift: 0,
65+
buffer: None,
66+
window,
67+
subsurface,
68+
commit_only_once: true,
69+
loop_signal: event_loop.get_signal(),
70+
};
71+
72+
app.map_toggle();
73+
74+
event_loop.run(None, &mut app, |_| {}).unwrap();
75+
}
76+
77+
struct App {
78+
registry_state: RegistryState,
79+
output_state: OutputState,
80+
shm: Shm,
81+
82+
should_be_mapped: bool,
83+
84+
first_configure: bool,
85+
pool: SlotPool,
86+
width: u32,
87+
height: u32,
88+
shift: u32,
89+
buffer: Option<Buffer>,
90+
window: Window,
91+
subsurface: (WlSubsurface, WlSurface),
92+
commit_only_once: bool,
93+
94+
loop_signal: calloop::LoopSignal,
95+
}
96+
97+
impl CompositorHandler for App {
98+
fn frame(
99+
&mut self,
100+
conn: &Connection,
101+
qh: &QueueHandle<Self>,
102+
_surface: &wl_surface::WlSurface,
103+
_time: u32,
104+
) {
105+
self.draw(conn, qh);
106+
}
107+
fn surface_enter(&mut self, _: &Connection, _: &QueueHandle<Self>, _: &WlSurface, _: &WlOutput) {}
108+
fn surface_leave(&mut self, _: &Connection, _: &QueueHandle<Self>, _: &WlSurface, _: &WlOutput) {}
109+
fn scale_factor_changed(&mut self, _: &Connection, _: &QueueHandle<Self>, _: &WlSurface, _: i32) {}
110+
fn transform_changed(
111+
&mut self,
112+
_: &Connection,
113+
_: &QueueHandle<Self>,
114+
_: &WlSurface,
115+
_: wl_output::Transform,
116+
) {
117+
}
118+
}
119+
120+
impl WindowHandler for App {
121+
fn request_close(&mut self, _: &Connection, _: &QueueHandle<Self>, _: &Window) {
122+
self.loop_signal.stop();
123+
}
124+
125+
fn configure(
126+
&mut self,
127+
conn: &Connection,
128+
qh: &QueueHandle<Self>,
129+
_window: &Window,
130+
configure: WindowConfigure,
131+
_serial: u32,
132+
) {
133+
if self.first_configure {
134+
info!("Window initial configure");
135+
} else {
136+
info!("Window configure");
137+
}
138+
139+
self.buffer = None;
140+
self.width = configure.new_size.0.map(|v| v.get()).unwrap_or(256);
141+
self.height = configure.new_size.1.map(|v| v.get()).unwrap_or(256);
142+
143+
if self.first_configure {
144+
self.first_configure = false;
145+
self.draw(conn, qh);
146+
}
147+
}
148+
}
149+
150+
impl App {
151+
fn map_toggle(&mut self) {
152+
if self.should_be_mapped {
153+
self.unmap()
154+
} else {
155+
self.map()
156+
}
157+
}
158+
159+
fn map(&mut self) {
160+
self.first_configure = true;
161+
self.should_be_mapped = true;
162+
self.window.commit();
163+
}
164+
165+
fn unmap(&mut self) {
166+
self.buffer = None;
167+
self.first_configure = false;
168+
self.should_be_mapped = false;
169+
self.window.attach(None, 0, 0);
170+
self.window.commit();
171+
}
172+
173+
fn draw(&mut self, _conn: &Connection, qh: &QueueHandle<Self>) {
174+
if !self.should_be_mapped {
175+
return;
176+
}
177+
178+
if std::mem::take(&mut self.commit_only_once) {
179+
test_clients::draw(
180+
qh,
181+
&self.subsurface.1,
182+
&mut self.pool,
183+
&mut self.buffer,
184+
self.width,
185+
self.height,
186+
&mut self.shift,
187+
);
188+
}
189+
190+
// Test if setting the pos and never calling commit on the subsurface still applies the pos on partent commit
191+
self.subsurface.0.set_position(self.shift as i32, 20);
192+
193+
test_clients::draw(
194+
qh,
195+
self.window.wl_surface(),
196+
&mut self.pool,
197+
&mut self.buffer,
198+
self.width,
199+
self.height,
200+
&mut self.shift,
201+
);
202+
}
203+
}
204+
205+
delegate_compositor!(App);
206+
delegate_subcompositor!(App);
207+
208+
delegate_output!(App);
209+
delegate_shm!(App);
210+
211+
delegate_xdg_shell!(App);
212+
delegate_xdg_window!(App);
213+
214+
delegate_registry!(App);
215+
216+
impl OutputHandler for App {
217+
fn output_state(&mut self) -> &mut OutputState {
218+
&mut self.output_state
219+
}
220+
fn new_output(&mut self, _: &Connection, _: &QueueHandle<Self>, _: WlOutput) {}
221+
fn update_output(&mut self, _: &Connection, _: &QueueHandle<Self>, _: WlOutput) {}
222+
fn output_destroyed(&mut self, _: &Connection, _: &QueueHandle<Self>, _: WlOutput) {}
223+
}
224+
225+
impl ShmHandler for App {
226+
fn shm_state(&mut self) -> &mut Shm {
227+
&mut self.shm
228+
}
229+
}
230+
231+
impl ProvidesRegistryState for App {
232+
fn registry(&mut self) -> &mut RegistryState {
233+
&mut self.registry_state
234+
}
235+
registry_handlers![OutputState,];
236+
}

test_clients/src/bin/test_xdg_map_unmap.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ impl App {
174174

175175
test_clients::draw(
176176
qh,
177-
&self.window,
177+
self.window.wl_surface(),
178178
&mut self.pool,
179179
&mut self.buffer,
180180
self.width,

test_clients/src/lib.rs

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ use smithay_client_toolkit::{
88
protocol::{wl_callback::WlCallback, wl_shm, wl_surface::WlSurface},
99
},
1010
},
11-
shell::{xdg::window::Window, WaylandSurface},
1211
shm::slot::{Buffer, SlotPool},
1312
};
1413

@@ -64,7 +63,7 @@ pub fn fill_with_gradient_bytes(canvas: &mut [u8], shift: u32, width: u32, heigh
6463

6564
pub fn draw<D>(
6665
qh: &QueueHandle<D>,
67-
window: &Window,
66+
wl_surface: &WlSurface,
6867
pool: &mut SlotPool,
6968
buffer: &mut Option<Buffer>,
7069
width: u32,
@@ -99,12 +98,10 @@ pub fn draw<D>(
9998
fill_with_gradient_bytes(canvas, *shift, width, height);
10099
*shift = (*shift + 1) % width;
101100

102-
window
103-
.wl_surface()
104-
.damage_buffer(0, 0, width as i32, height as i32);
101+
wl_surface.damage_buffer(0, 0, width as i32, height as i32);
105102

106-
window.wl_surface().frame(qh, window.wl_surface().clone());
103+
wl_surface.frame(qh, wl_surface.clone());
107104

108-
buffer.attach_to(window.wl_surface()).expect("buffer attach");
109-
window.commit();
105+
buffer.attach_to(wl_surface).expect("buffer attach");
106+
wl_surface.commit();
110107
}

0 commit comments

Comments
 (0)