server: check if connected to x server when output offset updates
Caused by the compositor reporting negative output coordinates to start. Fixes #187
This commit is contained in:
parent
117af56a83
commit
2e7c318ac2
3 changed files with 94 additions and 26 deletions
|
|
@ -151,7 +151,7 @@ impl SurfaceEvents {
|
||||||
x: dimensions.x - state.global_output_offset.x.value,
|
x: dimensions.x - state.global_output_offset.x.value,
|
||||||
y: dimensions.y - state.global_output_offset.y.value,
|
y: dimensions.y - state.global_output_offset.y.value,
|
||||||
},
|
},
|
||||||
state.connection.as_mut().unwrap(),
|
&mut state.connection,
|
||||||
);
|
);
|
||||||
if state.last_focused_toplevel == Some(*window) {
|
if state.last_focused_toplevel == Some(*window) {
|
||||||
let output = get_output_name(Some(&on_output), &state.world);
|
let output = get_output_name(Some(&on_output), &state.world);
|
||||||
|
|
@ -889,21 +889,19 @@ fn update_output_offset(
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(connection) = state.connection.as_mut() {
|
|
||||||
update_window_output_offsets(
|
update_window_output_offsets(
|
||||||
output,
|
output,
|
||||||
&state.global_output_offset,
|
&state.global_output_offset,
|
||||||
&state.world,
|
&state.world,
|
||||||
connection,
|
&mut state.connection,
|
||||||
);
|
);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_window_output_offsets(
|
fn update_window_output_offsets(
|
||||||
output: Entity,
|
output: Entity,
|
||||||
global_output_offset: &GlobalOutputOffset,
|
global_output_offset: &GlobalOutputOffset,
|
||||||
world: &World,
|
world: &World,
|
||||||
connection: &mut impl XConnection,
|
connection: &mut Option<impl XConnection>,
|
||||||
) {
|
) {
|
||||||
let dimensions = world.get::<&OutputDimensions>(output).unwrap();
|
let dimensions = world.get::<&OutputDimensions>(output).unwrap();
|
||||||
let mut query = world.query::<(&x::Window, &mut WindowData, &OnOutput)>();
|
let mut query = world.query::<(&x::Window, &mut WindowData, &OnOutput)>();
|
||||||
|
|
@ -927,7 +925,7 @@ pub(super) fn update_global_output_offset(
|
||||||
output: Entity,
|
output: Entity,
|
||||||
global_output_offset: &GlobalOutputOffset,
|
global_output_offset: &GlobalOutputOffset,
|
||||||
world: &World,
|
world: &World,
|
||||||
connection: &mut impl XConnection,
|
connection: &mut Option<impl XConnection>,
|
||||||
) {
|
) {
|
||||||
let entity = world.entity(output).unwrap();
|
let entity = world.entity(output).unwrap();
|
||||||
let mut query = entity.query::<(&OutputDimensions, &WlOutput)>();
|
let mut query = entity.query::<(&OutputDimensions, &WlOutput)>();
|
||||||
|
|
|
||||||
|
|
@ -138,7 +138,7 @@ impl WindowData {
|
||||||
&mut self,
|
&mut self,
|
||||||
window: x::Window,
|
window: x::Window,
|
||||||
offset: WindowOutputOffset,
|
offset: WindowOutputOffset,
|
||||||
connection: &mut C,
|
connection: &mut Option<C>,
|
||||||
) {
|
) {
|
||||||
log::trace!("offset: {offset:?}");
|
log::trace!("offset: {offset:?}");
|
||||||
if offset == self.output_offset {
|
if offset == self.output_offset {
|
||||||
|
|
@ -150,6 +150,7 @@ impl WindowData {
|
||||||
dims.y += (offset.y - self.output_offset.y) as i16;
|
dims.y += (offset.y - self.output_offset.y) as i16;
|
||||||
self.output_offset = offset;
|
self.output_offset = offset;
|
||||||
|
|
||||||
|
if let Some(connection) = connection.as_mut() {
|
||||||
connection.set_window_dims(
|
connection.set_window_dims(
|
||||||
window,
|
window,
|
||||||
PendingSurfaceState {
|
PendingSurfaceState {
|
||||||
|
|
@ -159,6 +160,7 @@ impl WindowData {
|
||||||
height: self.attrs.dims.height as _,
|
height: self.attrs.dims.height as _,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
debug!("set {:?} offset to {:?}", window, self.output_offset);
|
debug!("set {:?} offset to {:?}", window, self.output_offset);
|
||||||
}
|
}
|
||||||
|
|
@ -989,7 +991,7 @@ impl<C: XConnection> ServerState<C> {
|
||||||
e,
|
e,
|
||||||
&self.global_output_offset,
|
&self.global_output_offset,
|
||||||
&self.world,
|
&self.world,
|
||||||
self.connection.as_mut().unwrap(),
|
&mut self.connection,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
self.global_offset_updated = false;
|
self.global_offset_updated = false;
|
||||||
|
|
|
||||||
|
|
@ -321,8 +321,50 @@ impl PopupBuilder {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
trait PreConnectFn: Sized {
|
||||||
|
fn call(self, _: &mut testwl::Server) {}
|
||||||
|
}
|
||||||
|
impl<F: FnOnce(&mut testwl::Server)> PreConnectFn for F {
|
||||||
|
fn call(self, server: &mut testwl::Server) {
|
||||||
|
self(server);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl PreConnectFn for () {}
|
||||||
|
|
||||||
|
struct SetupOptions<F> {
|
||||||
|
pre_connect: Option<F>,
|
||||||
|
connect_x: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SetupOptions<()> {
|
||||||
|
fn dont_connect_x() -> Self {
|
||||||
|
Self {
|
||||||
|
pre_connect: None,
|
||||||
|
connect_x: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<F: PreConnectFn> SetupOptions<F> {
|
||||||
|
fn pre_connect(pre_connect: F) -> Self {
|
||||||
|
Self {
|
||||||
|
pre_connect: Some(pre_connect),
|
||||||
|
connect_x: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for SetupOptions<()> {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
pre_connect: None,
|
||||||
|
connect_x: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl TestFixture {
|
impl TestFixture {
|
||||||
fn new_pre_connect(pre_connect: impl FnOnce(&mut testwl::Server)) -> Self {
|
fn new_with_options<F: PreConnectFn>(options: SetupOptions<F>) -> Self {
|
||||||
INIT.call_once(|| {
|
INIT.call_once(|| {
|
||||||
env_logger::builder()
|
env_logger::builder()
|
||||||
.is_test(true)
|
.is_test(true)
|
||||||
|
|
@ -332,7 +374,9 @@ impl TestFixture {
|
||||||
|
|
||||||
let (client_s, server_s) = UnixStream::pair().unwrap();
|
let (client_s, server_s) = UnixStream::pair().unwrap();
|
||||||
let mut testwl = testwl::Server::new(true);
|
let mut testwl = testwl::Server::new(true);
|
||||||
pre_connect(&mut testwl);
|
if let Some(pre_connect) = options.pre_connect {
|
||||||
|
pre_connect.call(&mut testwl);
|
||||||
|
}
|
||||||
let display = Display::<FakeServerState>::new().unwrap();
|
let display = Display::<FakeServerState>::new().unwrap();
|
||||||
testwl.connect(server_s);
|
testwl.connect(server_s);
|
||||||
// Handle initial globals roundtrip setup requirement
|
// Handle initial globals roundtrip setup requirement
|
||||||
|
|
@ -350,7 +394,9 @@ impl TestFixture {
|
||||||
let (fake_client, xwls_server) = UnixStream::pair().unwrap();
|
let (fake_client, xwls_server) = UnixStream::pair().unwrap();
|
||||||
satellite.connect(xwls_server);
|
satellite.connect(xwls_server);
|
||||||
|
|
||||||
|
if options.connect_x {
|
||||||
satellite.set_x_connection(FakeXConnection::default());
|
satellite.set_x_connection(FakeXConnection::default());
|
||||||
|
}
|
||||||
|
|
||||||
let xwls_connection = Connection::from_socket(fake_client).unwrap();
|
let xwls_connection = Connection::from_socket(fake_client).unwrap();
|
||||||
let registry = TestObject::<WlRegistry>::from_request(
|
let registry = TestObject::<WlRegistry>::from_request(
|
||||||
|
|
@ -371,7 +417,11 @@ impl TestFixture {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new() -> Self {
|
fn new() -> Self {
|
||||||
Self::new_pre_connect(|_| {})
|
Self::new_with_options(SetupOptions::default())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn new_pre_connect(pre_connect: impl FnOnce(&mut testwl::Server)) -> Self {
|
||||||
|
Self::new_with_options(SetupOptions::pre_connect(pre_connect))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_with_compositor() -> (Self, Compositor) {
|
fn new_with_compositor() -> (Self, Compositor) {
|
||||||
|
|
@ -514,6 +564,7 @@ impl TestFixture {
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
self.run();
|
self.run();
|
||||||
|
self.run();
|
||||||
(output, self.testwl.last_created_output())
|
(output, self.testwl.last_created_output())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2359,6 +2410,23 @@ fn tablet_tool_fractional_scale() {
|
||||||
assert_eq!(y, 40.0 * 1.5);
|
assert_eq!(y, 40.0 * 1.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn output_updated_before_x_connection() {
|
||||||
|
let mut f = TestFixture::new_with_options(SetupOptions::dont_connect_x());
|
||||||
|
let comp = f.compositor();
|
||||||
|
let (_, output) = f.new_output(-20, -20);
|
||||||
|
|
||||||
|
f.satellite.set_x_connection(FakeXConnection::default());
|
||||||
|
|
||||||
|
let window = unsafe { Window::new(1) };
|
||||||
|
let (_, surface_id) = f.create_toplevel(&comp, window);
|
||||||
|
f.testwl.move_surface_to_output(surface_id, &output);
|
||||||
|
f.run();
|
||||||
|
f.run();
|
||||||
|
let data = &f.connection().windows[&window];
|
||||||
|
assert_eq!(data.dims.x, 0);
|
||||||
|
assert_eq!(data.dims.y, 0);
|
||||||
|
}
|
||||||
/// See Pointer::handle_event for an explanation.
|
/// See Pointer::handle_event for an explanation.
|
||||||
#[test]
|
#[test]
|
||||||
fn popup_pointer_motion_workaround() {}
|
fn popup_pointer_motion_workaround() {}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue