Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 5 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ xdg-user = "0.2.1"
xkbcommon = "0.8"
zbus = "5.7.1"
profiling = { version = "1.0" }
rustix = { version = "0.38.32", features = ["process"] }
rustix = { version = "0.38.32", features = ["net", "process"] }
smallvec = "1.13.2"
rand = "0.9.0"
reis = { version = "0.5", features = ["calloop"] }
Expand Down Expand Up @@ -120,8 +120,10 @@ inherits = "release"
lto = "fat"

[patch."https://github.com/pop-os/cosmic-protocols"]
cosmic-protocols = { git = "https://github.com/pop-os//cosmic-protocols", branch = "main" }
cosmic-client-toolkit = { git = "https://github.com/pop-os//cosmic-protocols", branch = "main" }
# cosmic-protocols = { git = "https://github.com/pop-os//cosmic-protocols", branch = "main" }
# cosmic-client-toolkit = { git = "https://github.com/pop-os//cosmic-protocols", branch = "main" }
cosmic-protocols = { git = "https://github.com/pop-os//cosmic-protocols", branch = "toplevel-info" }
cosmic-client-toolkit = { git = "https://github.com/pop-os//cosmic-protocols", branch = "toplevel-info" }

[patch.crates-io]
smithay = { git = "https://github.com/smithay/smithay.git", rev = "776ba42" }
16 changes: 9 additions & 7 deletions src/backend/kms/socket.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,13 +82,15 @@ impl State {
.common
.event_loop_handle
.insert_source(listener, move |client_stream, _, state: &mut State| {
if let Err(err) = state.common.display_handle.insert_client(
client_stream,
Arc::new(ClientState {
advertised_drm_node: Some(render_node),
..state.new_client_state()
}),
) {
let client_state = ClientState {
advertised_drm_node: Some(render_node),
..state.new_client_state(&client_stream)
};
if let Err(err) = state
.common
.display_handle
.insert_client(client_stream, Arc::new(client_state))
{
warn!(
socket_name = socket_name_clone,
?err,
Expand Down
2 changes: 1 addition & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ fn init_wayland_display(
event_loop
.handle()
.insert_source(source, |client_stream, _, state| {
let client_state = state.new_client_state();
let client_state = state.new_client_state(&client_stream);
if let Err(err) = state
.common
.display_handle
Expand Down
2 changes: 1 addition & 1 deletion src/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ pub fn setup_socket(handle: LoopHandle<State>, common: &Common) -> Result<()> {
let stream = unsafe { UnixStream::from_raw_fd(fd) };
let client_state = Arc::new(ClientState {
privileged: true,
..state.new_client_state()
..state.new_client_state(&stream)
});
if let Err(err) = state.common.display_handle.insert_client(stream, client_state) {
warn!(?err, "Failed to add privileged client to display");
Expand Down
15 changes: 13 additions & 2 deletions src/shell/element/surface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ use smithay::{
},
},
wayland_protocols_misc::server_decoration::server::org_kde_kwin_server_decoration::Mode as KdeMode,
wayland_server::protocol::wl_surface::WlSurface,
wayland_server::{protocol::wl_surface::WlSurface, Resource},
},
utils::{
user_data::UserDataMap, IsAlive, Logical, Physical, Point, Rectangle, Scale, Serial, Size,
Expand All @@ -49,9 +49,10 @@ use smithay::{
use tracing::trace;

use crate::{
state::{State, SurfaceDmabufFeedback},
state::{ClientState, State, SurfaceDmabufFeedback},
utils::prelude::*,
wayland::handlers::decoration::{KdeDecorationData, PreferredDecorationMode},
xwayland::X11SurfacePid,
};

#[derive(Debug, Clone, PartialEq)]
Expand Down Expand Up @@ -742,6 +743,16 @@ impl CosmicSurface {
pub fn x11_surface(&self) -> Option<&X11Surface> {
self.0.x11_surface()
}

pub fn pid(&self) -> Option<u32> {
match self.0.underlying_surface() {
WindowSurface::Wayland(toplevel) => {
let surface = toplevel.wl_surface();
surface.client()?.get_data::<ClientState>()?.pid
}
WindowSurface::X11(surface) => surface.user_data().get::<X11SurfacePid>().map(|x| x.0),
}
}
}

impl IsAlive for CosmicSurface {
Expand Down
12 changes: 11 additions & 1 deletion src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ use std::{
cmp::min,
collections::HashSet,
ffi::OsString,
os::unix::net::UnixStream,
process::Child,
sync::{atomic::AtomicBool, Arc, Mutex, Once},
time::{Duration, Instant},
Expand Down Expand Up @@ -145,6 +146,7 @@ pub struct ClientState {
pub privileged: bool,
pub evls: LoopSignal,
pub security_context: Option<SecurityContext>,
pub pid: Option<u32>,
}
impl ClientData for ClientState {
fn initialized(&self, _client_id: ClientId) {}
Expand Down Expand Up @@ -667,7 +669,14 @@ impl State {
}
}

pub fn new_client_state(&self) -> ClientState {
pub fn new_client_state(&self, unix_stream: &UnixStream) -> ClientState {
let pid = match rustix::net::sockopt::get_socket_peercred(&unix_stream) {
Ok(cred) => Some(rustix::process::Pid::as_raw(Some(cred.pid)) as u32),
Err(err) => {
tracing::warn!(?err, "Failed to get PID for Wayland client");
None
}
};
ClientState {
compositor_client_state: CompositorClientState::default(),
advertised_drm_node: match &self.backend {
Expand All @@ -677,6 +686,7 @@ impl State {
privileged: !enable_wayland_security(),
evls: self.common.event_loop_signal.clone(),
security_context: None,
pid,
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/wayland/handlers/security_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ impl SecurityContextHandler for State {
.map(|data| data.privileged)
.unwrap_or(false);

let new_state = state.new_client_state();
let new_state = state.new_client_state(&client_stream);

let drm_node = client_data
.as_ref()
Expand Down
4 changes: 4 additions & 0 deletions src/wayland/handlers/toplevel_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@ impl Window for CosmicSurface {
CosmicSurface::global_geometry(self)
}

fn pid(&self) -> Option<u32> {
CosmicSurface::pid(self)
}

fn user_data(&self) -> &UserDataMap {
CosmicSurface::user_data(self)
}
Expand Down
9 changes: 8 additions & 1 deletion src/wayland/protocols/toplevel_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ pub trait Window: IsAlive + Clone + PartialEq + Send {
fn is_sticky(&self) -> bool;
fn is_resizing(&self) -> bool;
fn global_geometry(&self) -> Option<Rectangle<i32, Global>>;
fn pid(&self) -> Option<u32>;
fn user_data(&self) -> &UserDataMap;
}

Expand Down Expand Up @@ -312,7 +313,7 @@ where
F: for<'a> Fn(&'a Client) -> bool + Send + Sync + Clone + 'static,
{
let global = dh.create_global::<D, ZcosmicToplevelInfoV1, _>(
3,
4,
ToplevelInfoGlobalData {
filter: Box::new(client_filter.clone()),
},
Expand Down Expand Up @@ -610,6 +611,12 @@ where
}
handle_state.workspaces = state.workspaces.clone();

if instance.version() >= zcosmic_toplevel_handle_v1::EVT_PID_SINCE {
if let Some(pid) = window.pid() {
instance.pid(pid);
}
}

if changed {
if instance.version() < zcosmic_toplevel_info_v1::REQ_GET_COSMIC_TOPLEVEL_SINCE {
instance.done();
Expand Down
15 changes: 14 additions & 1 deletion src/xwayland.rs
Original file line number Diff line number Diff line change
Expand Up @@ -694,6 +694,8 @@ impl Common {
}
}

pub struct X11SurfacePid(pub u32);

impl XwmHandler for State {
fn xwm_state(&mut self, _xwm: XwmId) -> &mut X11Wm {
self.common
Expand All @@ -703,7 +705,18 @@ impl XwmHandler for State {
.unwrap()
}

fn new_window(&mut self, _xwm: XwmId, _window: X11Surface) {}
fn new_window(&mut self, _xwm: XwmId, window: X11Surface) {
match window.get_client_pid() {
Ok(pid) => {
window
.user_data()
.insert_if_missing_threadsafe(|| X11SurfacePid(pid));
}
Err(err) => {
warn!(?window, ?err, "Failed to get pid for XWayland window");
}
};
}
fn new_override_redirect_window(&mut self, _xwm: XwmId, _window: X11Surface) {}
fn destroyed_window(&mut self, _xwm: XwmId, _window: X11Surface) {}

Expand Down
Loading