Skip to content

Commit

Permalink
Unthrottle windows in screencopy sessions
Browse files Browse the repository at this point in the history
If an individual window was being screencast, and that window was not
visible, for example because it was minimized, that window would only
be rendered every 995ms, which did not look good on the screencast.

Now, non-visible windows with active screencopy sessions, as well as
windows that are mapped on non-visible workspaces with active
screencopy sessions, are rendered every 1/60th of a second, which
matches the frame rate of the video produced by
xdg-desktop-portal-cosmic.  In future, it might be good to let
screencopy clients suggest a redraw rate for captured windows.
  • Loading branch information
alyssais committed Nov 9, 2024
1 parent 641bb75 commit 29fea91
Showing 1 changed file with 21 additions and 8 deletions.
29 changes: 21 additions & 8 deletions src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use crate::{
input::{gestures::GestureState, PointerFocusState},
shell::{grabs::SeatMoveGrabState, CosmicSurface, SeatExt, Shell},
utils::prelude::OutputExt,
wayland::handlers::screencopy::SessionHolder,
wayland::protocols::{
atspi::AtspiState,
drm::WlDrmState,
Expand Down Expand Up @@ -108,6 +109,7 @@ use time::UtcOffset;

use std::{
cell::RefCell,
cmp::min,
collections::HashSet,
ffi::OsString,
process::Child,
Expand Down Expand Up @@ -935,7 +937,17 @@ impl Common {
None
}
};
let throttle = Some(Duration::from_millis(995));
const THROTTLE: Option<Duration> = Some(Duration::from_millis(995));
const SCREENCOPY_THROTTLE: Option<Duration> = Some(Duration::from_nanos(16_666_666));

fn throttle(session_holder: &impl SessionHolder) -> Option<Duration> {
if session_holder.sessions().is_empty() && session_holder.cursor_sessions().is_empty() {
THROTTLE
} else {
SCREENCOPY_THROTTLE
}
}

let shell = self.shell.read().unwrap();

if let Some(session_lock) = shell.session_lock.as_ref() {
Expand Down Expand Up @@ -982,7 +994,7 @@ impl Common {
if let Some(move_grab) = seat.user_data().get::<SeatMoveGrabState>() {
if let Some(grab_state) = move_grab.lock().unwrap().as_ref() {
for (window, _) in grab_state.element().windows() {
window.send_frame(output, time, throttle, should_send);
window.send_frame(output, time, throttle(&window), should_send);
}
}
}
Expand All @@ -997,21 +1009,21 @@ impl Common {
.mapped()
.for_each(|mapped| {
for (window, _) in mapped.windows() {
window.send_frame(output, time, throttle, should_send);
window.send_frame(output, time, throttle(&window), should_send);
}
});

let active = shell.active_space(output);
active.mapped().for_each(|mapped| {
for (window, _) in mapped.windows() {
window.send_frame(output, time, throttle, should_send);
window.send_frame(output, time, throttle(&window), should_send);
}
});

// other (throttled) windows
active.minimized_windows.iter().for_each(|m| {
for (window, _) in m.window.windows() {
window.send_frame(output, time, throttle, |_, _| None);
window.send_frame(output, time, throttle(&window), |_, _| None);
}
});
for space in shell
Expand All @@ -1021,25 +1033,26 @@ impl Common {
{
space.mapped().for_each(|mapped| {
for (window, _) in mapped.windows() {
let throttle = min(throttle(space), throttle(&window));
window.send_frame(output, time, throttle, |_, _| None);
}
});
space.minimized_windows.iter().for_each(|m| {
for (window, _) in m.window.windows() {
window.send_frame(output, time, throttle, |_, _| None);
window.send_frame(output, time, throttle(&window), |_, _| None);
}
})
}

shell.override_redirect_windows.iter().for_each(|or| {
if let Some(wl_surface) = or.wl_surface() {
send_frames_surface_tree(&wl_surface, output, time, throttle, should_send);
send_frames_surface_tree(&wl_surface, output, time, THROTTLE, should_send);
}
});

let map = smithay::desktop::layer_map_for_output(output);
for layer_surface in map.layers() {
layer_surface.send_frame(output, time, throttle, should_send);
layer_surface.send_frame(output, time, THROTTLE, should_send);
}
}
}

0 comments on commit 29fea91

Please sign in to comment.