mirror of
https://github.com/niri-wm/niri.git
synced 2026-06-21 02:01:55 +07:00
ipc: Add PID to screencopy Casts
This commit is contained in:
@@ -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.
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
@@ -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
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user