fix: dragging pop-ups causes them to stutter

Dragging a pop-up surface around regularly updates it via
`SurfaceEvents::xdg_event`. This called `XConnection::set_window_dims`,
which was enqueueing many `ConfigureRequest` events. These outdated
events would still be processed by XWayland and responded to with
`ConfigureNotify`, which updated the surface to an old position,
resulting in glitchy behavior.

This fix replaces the call of `set_window_dims` in `xdg_event`, instead
inserting the new position of the window into the ECS. Then, after all
Wayland events have been read, the pending position is popped from the ECS
and used to call `set_window_dims` for each window with it.

A solution to the issue posed in #314.
This commit is contained in:
En-En 2025-12-14 01:15:50 +00:00 committed by Supreeeme
parent 1bbd5cae7e
commit e81e787e1a
2 changed files with 25 additions and 10 deletions

View file

@ -330,23 +330,20 @@ impl SurfaceEvents {
}
}
connection.set_window_dims(
window,
PendingSurfaceState {
x,
y,
width: width as _,
height: height as _,
},
);
window_data.attrs.dims = WindowDims {
x: x as i16,
y: y as i16,
width,
height,
};
let pending = PendingSurfaceState {
x,
y,
width: width as _,
height: height as _,
};
drop(query);
state.world.insert_one(target, pending).unwrap();
update_surface_viewport(&state.world, state.world.query_one(target).unwrap());
}

View file

@ -613,6 +613,24 @@ impl<C: XConnection> ServerState<C> {
event.handle(target, self);
}
let query = self
.world
.query_mut::<(&PendingSurfaceState,)>()
.into_iter()
.map(|(e, _)| e)
.collect::<Vec<_>>();
for entity in query {
let dims = self
.world
.remove_one::<PendingSurfaceState>(entity)
.unwrap();
let entity = self.world.entity(entity).unwrap();
let mut query = entity.query::<(&x::Window,)>();
let window = *query.get().unwrap().0;
drop(query);
self.connection.set_window_dims(window, dims);
}
if self.global_offset_updated {
if self.global_output_offset.x.owner.is_none()
|| self.global_output_offset.y.owner.is_none()