anvil.shell: refresh toplevels on commit

This updates the toplevel state in the WindowMap as soon as it's
committed. It will be used to update the toplevel location on top-left
resize, but this is a better approach in general than the current
update-every-drawn-frame. I think we should update the WindowMap state
as soon as possible, and only when necessary.
This commit is contained in:
Ivan Molodetskikh 2020-02-08 08:44:39 +03:00
parent ab45cdecdc
commit 09d7f597d4
No known key found for this signature in database
GPG Key ID: 02CE38DA47E9D691
1 changed files with 19 additions and 2 deletions

View File

@ -197,11 +197,19 @@ pub fn init_shell(
Arc<Mutex<WlShellState<Roles>>>, Arc<Mutex<WlShellState<Roles>>>,
Rc<RefCell<MyWindowMap>>, Rc<RefCell<MyWindowMap>>,
) { ) {
// TODO: this is awkward...
let almost_window_map = Rc::new(RefCell::new(None::<Rc<RefCell<MyWindowMap>>>));
let almost_window_map_compositor = almost_window_map.clone();
// Create the compositor // Create the compositor
let (compositor_token, _, _) = compositor_init( let (compositor_token, _, _) = compositor_init(
display, display,
move |request, surface, ctoken| match request { move |request, surface, ctoken| match request {
SurfaceEvent::Commit => surface_commit(&surface, ctoken, &buffer_utils), SurfaceEvent::Commit => {
let window_map = almost_window_map_compositor.borrow();
let window_map = window_map.as_ref().unwrap();
surface_commit(&surface, ctoken, &buffer_utils, &*window_map)
}
SurfaceEvent::Frame { callback } => callback SurfaceEvent::Frame { callback } => callback
.implement_closure(|_, _| unreachable!(), None::<fn(_)>, ()) .implement_closure(|_, _| unreachable!(), None::<fn(_)>, ())
.done(0), .done(0),
@ -211,6 +219,7 @@ pub fn init_shell(
// Init a window map, to track the location of our windows // Init a window map, to track the location of our windows
let window_map = Rc::new(RefCell::new(WindowMap::new(compositor_token))); let window_map = Rc::new(RefCell::new(WindowMap::new(compositor_token)));
*almost_window_map.borrow_mut() = Some(window_map.clone());
// init the xdg_shell // init the xdg_shell
let xdg_window_map = window_map.clone(); let xdg_window_map = window_map.clone();
@ -509,12 +518,13 @@ fn surface_commit(
surface: &wl_surface::WlSurface, surface: &wl_surface::WlSurface,
token: CompositorToken<Roles>, token: CompositorToken<Roles>,
buffer_utils: &BufferUtils, buffer_utils: &BufferUtils,
window_map: &RefCell<MyWindowMap>,
) { ) {
let geometry = token let geometry = token
.with_role_data(surface, |role: &mut XdgSurfaceRole| role.window_geometry) .with_role_data(surface, |role: &mut XdgSurfaceRole| role.window_geometry)
.unwrap_or(None); .unwrap_or(None);
token.with_surface_data(surface, |attributes| { let refresh = token.with_surface_data(surface, |attributes| {
attributes.user_data.insert_if_missing(SurfaceData::default); attributes.user_data.insert_if_missing(SurfaceData::default);
let data = attributes.user_data.get_mut::<SurfaceData>().unwrap(); let data = attributes.user_data.get_mut::<SurfaceData>().unwrap();
@ -543,5 +553,12 @@ fn surface_commit(
} }
None => {} None => {}
} }
window_map.borrow().find(surface)
}); });
if let Some(toplevel) = refresh {
let mut window_map = window_map.borrow_mut();
window_map.refresh_toplevel(&toplevel);
}
} }