diff --git a/anvil/src/drawing.rs b/anvil/src/drawing.rs index 7322eee..72aac05 100644 --- a/anvil/src/drawing.rs +++ b/anvil/src/drawing.rs @@ -32,10 +32,10 @@ pub fn draw_cursor( (x, y): (i32, i32), token: MyCompositorToken, log: &Logger, -) +) -> Result<(), SwapBuffersError> where R: Renderer, - E: std::error::Error, + E: std::error::Error + Into, T: Texture + 'static, { let (dx, dy) = match token.with_role_data::(surface, |data| data.hotspot) { @@ -48,7 +48,7 @@ pub fn draw_cursor( (0, 0) } }; - draw_surface_tree(renderer, renderer_id, texture_destruction_callback, buffer_utils, surface, (x - dx, y - dy), token, log); + draw_surface_tree(renderer, renderer_id, texture_destruction_callback, buffer_utils, surface, (x - dx, y - dy), token, log) } fn draw_surface_tree( @@ -60,12 +60,14 @@ fn draw_surface_tree( location: (i32, i32), compositor_token: MyCompositorToken, log: &Logger, -) +) -> Result<(), SwapBuffersError> where R: Renderer, - E: std::error::Error, + E: std::error::Error + Into, T: Texture + 'static, { + let mut result = Ok(()); + compositor_token.with_surface_tree_upward( root, (), @@ -137,12 +139,16 @@ fn draw_surface_tree( y += sub_y; } let texture = buffer_textures.load_texture(renderer_id, renderer, texture_destruction_callback).unwrap(); - renderer.render_texture_at(texture, (x, y), Transform::Normal /* TODO */, 1.0); + if let Err(err) = renderer.render_texture_at(texture, (x, y), Transform::Normal /* TODO */, 1.0) { + result = Err(err.into()); + } } } }, |_, _, _, _| true, ); + + result } pub fn draw_windows( @@ -154,39 +160,43 @@ pub fn draw_windows( output_rect: Option, compositor_token: MyCompositorToken, log: &::slog::Logger, -) +) -> Result<(), SwapBuffersError> where R: Renderer, - E: std::error::Error, + E: std::error::Error + Into, T: Texture + 'static, { + let mut result = Ok(()); + // redraw the frame, in a simple but inneficient way - { - window_map.with_windows_from_bottom_to_top( - |toplevel_surface, mut initial_place, bounding_box| { - // skip windows that do not overlap with a given output - if let Some(output) = output_rect { - if !output.overlaps(bounding_box) { - return; - } - initial_place.0 -= output.x; + window_map.with_windows_from_bottom_to_top( + |toplevel_surface, mut initial_place, bounding_box| { + // skip windows that do not overlap with a given output + if let Some(output) = output_rect { + if !output.overlaps(bounding_box) { + return; } - if let Some(wl_surface) = toplevel_surface.get_surface() { - // this surface is a root of a subsurface tree that needs to be drawn - draw_surface_tree( - renderer, - renderer_id, - texture_destruction_callback, - buffer_utils, - &wl_surface, - initial_place, - compositor_token, - log, - ); + initial_place.0 -= output.x; + } + if let Some(wl_surface) = toplevel_surface.get_surface() { + // this surface is a root of a subsurface tree that needs to be drawn + if let Err(err) = draw_surface_tree( + renderer, + renderer_id, + texture_destruction_callback, + buffer_utils, + &wl_surface, + initial_place, + compositor_token, + log, + ) { + result = Err(err); } - }, - ); - } + } + }, + ); + + result } pub fn draw_dnd_icon( @@ -198,10 +208,10 @@ pub fn draw_dnd_icon( (x, y): (i32, i32), token: MyCompositorToken, log: &::slog::Logger, -) +) -> Result<(), SwapBuffersError> where R: Renderer, - E: std::error::Error, + E: std::error::Error + Into, T: Texture + 'static, { if !token.has_role::(surface) { @@ -210,7 +220,7 @@ pub fn draw_dnd_icon( "Trying to display as a dnd icon a surface that does not have the DndIcon role." ); } - draw_surface_tree(renderer, renderer_id, texture_destruction_callback, buffer_utils, surface, (x, y), token, log); + draw_surface_tree(renderer, renderer_id, texture_destruction_callback, buffer_utils, surface, (x, y), token, log) } pub fn schedule_initial_render( diff --git a/anvil/src/udev.rs b/anvil/src/udev.rs index c02b6f0..1c10dbf 100644 --- a/anvil/src/udev.rs +++ b/anvil/src/udev.rs @@ -21,7 +21,6 @@ use smithay::{ device_bind, DrmRenderSurface, DrmError, - DrmRenderError, DevPath, }, egl::{EGLDisplay, EGLContext, display::EGLBufferReader}, @@ -781,8 +780,8 @@ impl DrmRenderer { .unwrap_or((0, 0)); // in this case the output will be removed. // and draw in sync with our monitor - surface.queue_frame().unwrap(); - surface.clear([0.8, 0.8, 0.9, 1.0]).unwrap(); + surface.queue_frame()?; + surface.clear([0.8, 0.8, 0.9, 1.0])?; // draw the surfaces draw_windows( surface, @@ -798,7 +797,7 @@ impl DrmRenderer { }), compositor_token.clone(), logger, - ); + )?; // get pointer coordinates let (ptr_x, ptr_y) = *pointer_location; @@ -811,7 +810,7 @@ impl DrmRenderer { { if let Some(ref wl_surface) = dnd_icon.as_ref() { if wl_surface.as_ref().is_alive() { - draw_dnd_icon(surface, device_id, texture_destruction_callback, buffer_utils, wl_surface, (ptr_x, ptr_y), compositor_token.clone(), logger); + draw_dnd_icon(surface, device_id, texture_destruction_callback, buffer_utils, wl_surface, (ptr_x, ptr_y), compositor_token.clone(), logger)?; } } } @@ -836,9 +835,9 @@ impl DrmRenderer { (ptr_x, ptr_y), compositor_token.clone(), logger, - ); + )?; } else { - surface.render_texture_at(pointer_image, (ptr_x, ptr_y), Transform::Normal, 1.0); + surface.render_texture_at(pointer_image, (ptr_x, ptr_y), Transform::Normal, 1.0)?; } } } diff --git a/anvil/src/winit.rs b/anvil/src/winit.rs index 89ab7b9..d7bd155 100644 --- a/anvil/src/winit.rs +++ b/anvil/src/winit.rs @@ -114,7 +114,7 @@ pub fn run_winit( renderer.clear([0.8, 0.8, 0.9, 1.0]).expect("Failed to clear frame"); // draw the windows - draw_windows(&mut renderer, 0, &texture_send, &buffer_utils, &*state.window_map.borrow(), None, state.ctoken, &log); + draw_windows(&mut renderer, 0, &texture_send, &buffer_utils, &*state.window_map.borrow(), None, state.ctoken, &log).expect("Failed to renderer windows"); let (x, y) = *state.pointer_location.borrow(); // draw the dnd icon if any @@ -122,7 +122,7 @@ pub fn run_winit( let guard = state.dnd_icon.lock().unwrap(); if let Some(ref surface) = *guard { if surface.as_ref().is_alive() { - draw_dnd_icon(&mut renderer, 0, &texture_send, &buffer_utils, surface, (x as i32, y as i32), state.ctoken, &log); + draw_dnd_icon(&mut renderer, 0, &texture_send, &buffer_utils, surface, (x as i32, y as i32), state.ctoken, &log).expect("Failed to render dnd icon"); } } } @@ -141,7 +141,7 @@ pub fn run_winit( // draw as relevant if let CursorImageStatus::Image(ref surface) = *guard { renderer.window().set_cursor_visible(false); - draw_cursor(&mut renderer, 0, &texture_send, &buffer_utils, surface, (x as i32, y as i32), state.ctoken, &log); + draw_cursor(&mut renderer, 0, &texture_send, &buffer_utils, surface, (x as i32, y as i32), state.ctoken, &log).expect("Failed to render cursor"); } else { renderer.window().set_cursor_visible(true); }