Unthrottle windows in screencopy sessions
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.
This commit is contained in:
parent
cd9ff0b7bb
commit
7e8cb91d23
1 changed files with 21 additions and 8 deletions
29
src/state.rs
29
src/state.rs
|
|
@ -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,
|
||||
|
|
@ -108,6 +109,7 @@ use time::UtcOffset;
|
|||
|
||||
use std::{
|
||||
cell::RefCell,
|
||||
cmp::min,
|
||||
collections::HashSet,
|
||||
ffi::OsString,
|
||||
process::Child,
|
||||
|
|
@ -951,7 +953,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() {
|
||||
|
|
@ -998,7 +1010,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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1013,21 +1025,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
|
||||
|
|
@ -1037,25 +1049,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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue