feat: handle global removals, recalc output scale (#367)
All `GlobalRemove` events sent from the server are now handled by recording them in a new clientside `vec` and passing the identifier returned by `create_global` (now stored by a map in the state) to `disable_global`. `handle_globals` (the top-level function) and `handle_new_globals` (the `InnerServerState` member function) have swapped names to better represent their new purposes. This enables action to be taken when globals are removed. In this case, the desired action is to forward output removal, so that the scaling calculation does not account for disconnected monitors in its logic. Resolves #351.
This commit is contained in:
parent
75c9f5e775
commit
0947c4685f
6 changed files with 153 additions and 33 deletions
|
|
@ -530,7 +530,19 @@ impl<C: XConnection> TestFixture<C> {
|
|||
);
|
||||
self.run();
|
||||
self.run();
|
||||
(output, self.testwl.last_created_output())
|
||||
(output, self.testwl.finalize_output())
|
||||
}
|
||||
|
||||
fn remove_output(&mut self, output_s: wayland_server::protocol::wl_output::WlOutput) {
|
||||
self.testwl.remove_output(output_s);
|
||||
self.run();
|
||||
self.run();
|
||||
let mut events = std::mem::take(&mut *self.registry.data.events.lock().unwrap());
|
||||
assert_eq!(events.len(), 1);
|
||||
let event = events.pop().unwrap();
|
||||
let Ev::<WlRegistry>::GlobalRemove { .. } = event else {
|
||||
panic!("Unexpected event: {event:?}");
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2725,6 +2737,52 @@ fn scaled_pointer_lock_position_hint() {
|
|||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn disconnected_output_rescaling() {
|
||||
let mut f = TestFixture::new_pre_connect(|testwl| {
|
||||
testwl.enable_fractional_scale();
|
||||
});
|
||||
let comp = f.compositor();
|
||||
let (_, output_main) = f.new_output(0, 0);
|
||||
let (_, output_ext) = f.new_output(1000, 0);
|
||||
|
||||
let window = Window::new(1);
|
||||
let (_, id) = f.create_toplevel(&comp, window);
|
||||
|
||||
let surface_data = f.testwl.get_surface_data(id).expect("No surface data");
|
||||
let fractional = surface_data
|
||||
.fractional
|
||||
.as_ref()
|
||||
.expect("No fractional scale for surface");
|
||||
fractional.preferred_scale(240); // 2.0 scale
|
||||
f.testwl.move_surface_to_output(id, &output_main);
|
||||
f.run();
|
||||
|
||||
let surface_data = f.testwl.get_surface_data(id).expect("No surface data");
|
||||
let fractional = surface_data
|
||||
.fractional
|
||||
.as_ref()
|
||||
.expect("No fractional scale for surface");
|
||||
fractional.preferred_scale(180); // 1.5 scale
|
||||
f.testwl.move_surface_to_output(id, &output_ext);
|
||||
f.run();
|
||||
// Multiple monitors with different scaling will select the lowest scale across monitors
|
||||
assert_eq!(f.satellite.inner.new_scale, Some(1.5));
|
||||
|
||||
f.remove_output(output_ext);
|
||||
f.testwl.move_surface_to_output(id, &output_main);
|
||||
let surface_data = f.testwl.get_surface_data(id).expect("No surface data");
|
||||
let fractional = surface_data
|
||||
.fractional
|
||||
.as_ref()
|
||||
.expect("No fractional scale for surface");
|
||||
fractional.preferred_scale(240); // 2.0 scale
|
||||
f.run();
|
||||
f.run();
|
||||
// Afteer the output is disconnected, only the 2x scale output remains, so use that scale
|
||||
assert_eq!(f.satellite.inner.new_scale, Some(2.0));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn client_side_decorations() {
|
||||
let (mut f, compositor) = TestFixture::new_with_compositor();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue