ipc: Add PID to screencopy Casts

This commit is contained in:
Ivan Molodetskikh
2026-01-14 13:20:40 +03:00
parent b39edf405a
commit e546b339a3
5 changed files with 32 additions and 13 deletions
+4
View File
@@ -1505,6 +1505,10 @@ pub struct Cast {
/// This can be `false` for example when switching away to a different scene in OBS, which
/// pauses the stream.
pub is_active: bool,
/// Process ID of the screencast consumer, if known.
///
/// Currently, only wlr-screencopy screencasts can have a pid.
pub pid: Option<i32>,
}
/// Kind of screencast.
+4
View File
@@ -764,6 +764,10 @@ fn print_cast(cast: &Cast) {
if cast.is_dynamic_target {
println!(" Dynamic cast target");
}
if let Some(pid) = cast.pid {
println!(" PID: {pid}");
}
}
fn fmt_rounded(x: f64) -> String {
+3
View File
@@ -829,6 +829,7 @@ impl State {
target: niri_ipc::CastTarget::Nothing {},
is_dynamic_target: true,
is_active: false,
pid: None,
};
events.push(Event::CastStartedOrChanged { cast });
}
@@ -850,6 +851,7 @@ impl State {
target: cast.target.make_ipc(),
is_dynamic_target: cast.dynamic_target,
is_active: cast.is_active(),
pid: None,
};
events.push(Event::CastStartedOrChanged { cast });
}
@@ -883,6 +885,7 @@ impl State {
},
is_dynamic_target: false,
is_active: true,
pid: queue.credentials().map(|creds| creds.pid),
};
events.push(Event::CastStartedOrChanged { cast });
}
+15 -11
View File
@@ -20,10 +20,11 @@ use smithay::reexports::wayland_server::{
};
use smithay::utils::{Physical, Point, Rectangle, Size, Transform};
use smithay::wayland::{dmabuf, shm};
use wayland_backend::server::Credentials;
use zwlr_screencopy_frame_v1::{Flags, ZwlrScreencopyFrameV1};
use zwlr_screencopy_manager_v1::ZwlrScreencopyManagerV1;
use crate::utils::{get_monotonic_time, CastSessionId, CastStreamId};
use crate::utils::{get_credentials_for_client, get_monotonic_time, CastSessionId, CastStreamId};
const VERSION: u32 = 3;
@@ -35,6 +36,8 @@ const VERSION: u32 = 3;
const CAST_TIMEOUT: Duration = Duration::from_secs(10);
pub struct ScreencopyQueue {
/// Credentials of this wlr-screencopy client, if known.
credentials: Option<Credentials>,
damage_tracker: OutputDamageTracker,
/// Frames waiting for the client to call copy or destroy.
pending_frames: HashSet<ZwlrScreencopyFrameV1>,
@@ -83,19 +86,14 @@ impl ScreencopyCast {
}
}
impl Default for ScreencopyQueue {
fn default() -> Self {
Self::new()
}
}
impl ScreencopyQueue {
pub fn new() -> Self {
pub fn new(credentials: Option<Credentials>) -> Self {
Self {
damage_tracker: OutputDamageTracker::new((0, 0), 1.0, Transform::Normal),
pending_frames: HashSet::new(),
screencopies: Vec::new(),
cast: None,
credentials,
}
}
@@ -108,6 +106,10 @@ impl ScreencopyQueue {
self.cast.as_ref()
}
pub fn credentials(&self) -> Option<Credentials> {
self.credentials
}
pub fn split(&mut self) -> (&mut OutputDamageTracker, Option<&Screencopy>) {
let ScreencopyQueue {
damage_tracker,
@@ -287,8 +289,8 @@ where
{
fn bind(
state: &mut D,
_display: &DisplayHandle,
_client: &Client,
dh: &DisplayHandle,
client: &Client,
manager: New<ZwlrScreencopyManagerV1>,
_manager_state: &ScreencopyManagerGlobalData,
data_init: &mut DataInit<'_, D>,
@@ -296,7 +298,9 @@ where
let manager = data_init.init(manager, ());
let state = state.screencopy_state();
state.queues.insert(manager.clone(), ScreencopyQueue::new());
let credentials = get_credentials_for_client(dh, client);
let queue = ScreencopyQueue::new(credentials);
state.queues.insert(manager.clone(), queue);
}
fn can_view(client: Client, global_data: &ScreencopyManagerGlobalData) -> bool {
+6 -2
View File
@@ -21,7 +21,7 @@ use smithay::reexports::rustix::time::{clock_gettime, ClockId};
use smithay::reexports::wayland_protocols::xdg::decoration::zv1::server::zxdg_toplevel_decoration_v1;
use smithay::reexports::wayland_protocols::xdg::shell::server::xdg_toplevel;
use smithay::reexports::wayland_server::protocol::wl_surface::WlSurface;
use smithay::reexports::wayland_server::{DisplayHandle, Resource as _};
use smithay::reexports::wayland_server::{Client, DisplayHandle, Resource as _};
use smithay::utils::{Coordinate, Logical, Point, Rectangle, Size, Transform};
use smithay::wayland::compositor::{send_surface_state, with_states, SurfaceData};
use smithay::wayland::fractional_scale::with_fractional_scale;
@@ -457,12 +457,16 @@ pub fn get_credentials_for_surface(surface: &WlSurface) -> Option<Credentials> {
let dh = DisplayHandle::from(handle);
let client = dh.get_client(surface.id()).ok()?;
get_credentials_for_client(&dh, &client)
}
pub fn get_credentials_for_client(dh: &DisplayHandle, client: &Client) -> Option<Credentials> {
let data = client.get_data::<ClientState>().unwrap();
if data.credentials_unknown {
return None;
}
client.get_credentials(&dh).ok()
client.get_credentials(dh).ok()
}
pub fn ensure_min_max_size(mut x: i32, min_size: i32, max_size: i32) -> i32 {