diff --git a/src/ifs/jay_screencast.rs b/src/ifs/jay_screencast.rs index 9149c335..112a8a99 100644 --- a/src/ifs/jay_screencast.rs +++ b/src/ifs/jay_screencast.rs @@ -149,7 +149,12 @@ impl JayScreencast { }); } - pub fn copy_texture(&self, on: &OutputNode, texture: &Rc) { + pub fn copy_texture( + &self, + on: &OutputNode, + texture: &Rc, + render_hardware_cursors: bool, + ) { if !self.running.get() { return; } @@ -165,7 +170,15 @@ impl JayScreencast { let mut buffer = self.buffers.borrow_mut(); for (idx, buffer) in buffer.deref_mut().iter_mut().enumerate() { if buffer.free { - buffer.fb.copy_texture(texture, 0, 0); + self.client.state.perform_screencopy( + texture, + &buffer.fb, + on.global.preferred_scale.get(), + on.global.pos.get(), + render_hardware_cursors, + 0, + 0, + ); self.client.event(Ready { self_id: self.id, idx: idx as _, diff --git a/src/ifs/wl_output.rs b/src/ifs/wl_output.rs index b487a3f2..f1e3a70b 100644 --- a/src/ifs/wl_output.rs +++ b/src/ifs/wl_output.rs @@ -202,7 +202,12 @@ impl WlOutputGlobal { Ok(()) } - pub fn perform_screencopies(&self, fb: &dyn GfxFramebuffer, tex: &Rc) { + pub fn perform_screencopies( + &self, + fb: &dyn GfxFramebuffer, + tex: &Rc, + render_hardware_cursors: bool, + ) { if self.pending_captures.is_empty() { return; } @@ -278,7 +283,15 @@ impl WlOutputGlobal { continue; } }; - fb.copy_texture(tex, -capture.rect.x1(), -capture.rect.y1()); + self.state.perform_screencopy( + tex, + &fb, + self.preferred_scale.get(), + self.pos.get(), + render_hardware_cursors, + -capture.rect.x1(), + -capture.rect.y1(), + ); } if capture.with_damage.get() { capture.send_damage(); diff --git a/src/state.rs b/src/state.rs index 8892bf87..7db7be9e 100644 --- a/src/state.rs +++ b/src/state.rs @@ -13,6 +13,7 @@ use { cursor::{Cursor, ServerCursors}, dbus::Dbus, drm_feedback::DrmFeedback, + fixed::Fixed, forker::ForkerProxy, gfx_api::{GfxContext, GfxError, GfxFramebuffer, GfxTexture}, gfx_apis::create_gfx_context, @@ -36,9 +37,9 @@ use { leaks::Tracker, logger::Logger, rect::Rect, - renderer::RenderResult, + renderer::{renderer_base::RendererBase, RenderResult, Renderer}, scale::Scale, - theme::Theme, + theme::{Color, Theme}, tree::{ ContainerNode, ContainerSplit, Direction, DisplayNode, FloatNode, Node, NodeIds, NodeVisitorBase, OutputNode, PlaceholderNode, ToplevelNode, WorkspaceNode, @@ -752,6 +753,49 @@ impl State { fr.send_done(); let _ = fr.client.remove_obj(&*fr); } - output.perform_screencopies(&**fb, tex); + output.perform_screencopies(&**fb, tex, !render_hw_cursor); + } + + pub fn perform_screencopy( + &self, + src: &Rc, + target: &Rc, + scale: Scale, + position: Rect, + render_hardware_cursors: bool, + x_off: i32, + y_off: i32, + ) { + let mut ops = target.take_render_ops(); + let (width, height) = target.size(); + let mut renderer = Renderer { + base: RendererBase { + ops: &mut ops, + scaled: scale != 1, + scale, + scalef: scale.to_f64(), + }, + state: self, + result: None, + logical_extents: position.at_point(0, 0), + physical_extents: Rect::new_sized(0, 0, width, height).unwrap(), + }; + renderer + .base + .render_texture(src, x_off, y_off, None, None, scale, None); + if render_hardware_cursors { + for seat in self.globals.lock_seats().values() { + if let Some(cursor) = seat.get_cursor() { + let (mut x, mut y) = seat.get_position(); + if seat.hardware_cursor() { + x = x + x_off - Fixed::from_int(position.x1()); + y = y + y_off - Fixed::from_int(position.y1()); + cursor.render(&mut renderer, x, y); + } + } + } + } + let clear = target.format().has_alpha.then_some(&Color::TRANSPARENT); + target.render(ops, clear); } } diff --git a/src/tree/output.rs b/src/tree/output.rs index 8898501d..98667201 100644 --- a/src/tree/output.rs +++ b/src/tree/output.rs @@ -78,15 +78,21 @@ pub async fn output_render_data(state: Rc) { } impl OutputNode { - pub fn perform_screencopies(&self, fb: &dyn GfxFramebuffer, tex: &Rc) { + pub fn perform_screencopies( + &self, + fb: &dyn GfxFramebuffer, + tex: &Rc, + render_hardware_cursor: bool, + ) { if let Some(workspace) = self.workspace.get() { if !workspace.capture.get() { return; } } - self.global.perform_screencopies(fb, tex); + self.global + .perform_screencopies(fb, tex, render_hardware_cursor); for sc in self.screencasts.lock().values() { - sc.copy_texture(self, tex); + sc.copy_texture(self, tex, render_hardware_cursor); } }