1- From 8736ddbc9db1d4ab3229ff8b21422cb37edf1db6 Mon Sep 17 00:00:00 2001
1+ From a30eafe28f638078c6f4f919ed90ebb67b5a676a Mon Sep 17 00:00:00 2001
22From: Yuri Nesterov <yuriy.nesterov@unikie.com>
33Date: Fri, 2 May 2025 20:43:32 +0300
44Subject: [PATCH] Add security context indicator
55
6- Signed-off-by: Kajus Naujokaitis <kajus.naujokaitis@unikie.com>
76---
87 cosmic-comp-config/src/lib.rs | 24 +++++++++
9- src/backend/render/mod.rs | 31 ++++++++ +++
10- src/shell/grabs/moving.rs | 76 ++++++++++++++++++++- ------
8+ src/backend/render/mod.rs | 7 +++
9+ src/shell/grabs/moving.rs | 75 +++++++++++++++++++++ ------
1110 src/shell/layout/floating/mod.rs | 36 +++++++++++--
12- src/wayland/handlers/xdg_shell/mod.rs | 45 + +++++++++++++++
13- 5 files changed, 187 insertions(+), 25 deletions(-)
11+ src/wayland/handlers/xdg_shell/mod.rs | 42 +++++++++++++++
12+ 5 files changed, 165 insertions(+), 19 deletions(-)
1413
1514diff --git a/cosmic-comp-config/src/lib.rs b/cosmic-comp-config/src/lib.rs
16- index aa85dd2..13c1201 100644
15+ index 6063d476..43c5bccf 100644
1716--- a/cosmic-comp-config/src/lib.rs
1817+++ b/cosmic-comp-config/src/lib.rs
19- @@ -81,6 +81,7 @@ pub struct CosmicCompConfig {
20- /// The threshold before windows snap themselves to output edges
18+ @@ -99,6 +99,7 @@ pub struct CosmicCompConfig {
2119 pub edge_snap_threshold: u32,
2220 pub accessibility_zoom: ZoomConfig,
21+ pub appearance_settings: AppearanceConfig,
2322+ pub security_context: SecurityContextConfig,
2423 }
25-
24+
2625 impl Default for CosmicCompConfig {
27- @@ -116,6 +117,7 @@ impl Default for CosmicCompConfig {
28- xwayland_eavesdropping: XwaylandEavesdropping::default(),
26+ @@ -135,6 +136,7 @@ impl Default for CosmicCompConfig {
2927 edge_snap_threshold: 0,
3028 accessibility_zoom: ZoomConfig::default(),
29+ appearance_settings: AppearanceConfig::default(),
3130+ security_context: SecurityContextConfig::default(),
3231 }
3332 }
3433 }
35- @@ -215 ,3 +217 ,25 @@ pub enum XwaylandDescaling {
34+ @@ -234 ,3 +236 ,25 @@ pub enum XwaylandDescaling {
3635 #[default]
3736 Fractional,
3837 }
@@ -59,13 +58,13 @@ index aa85dd2..13c1201 100644
5958+ }
6059+ }
6160diff --git a/src/backend/render/mod.rs b/src/backend/render/mod.rs
62- index 9b9faa9..deadb9d 100644
61+ index c7d79967..cb7ee466 100644
6362--- a/src/backend/render/mod.rs
6463+++ b/src/backend/render/mod.rs
65- @@ -128,6 +128,13 @@ pub enum Usage {
66- FocusIndicator,
64+ @@ -137,6 +137,13 @@ pub enum Usage {
6765 PotentialGroupIndicator,
6866 SnappingIndicator,
67+ Border,
6968+ SecurityContextIndicator,
7069+ }
7170+
@@ -74,78 +73,33 @@ index 9b9faa9..deadb9d 100644
7473+ pub border_color: [f32; 3],
7574+ pub border_size: u8,
7675 }
77-
76+
7877 #[derive(Clone)]
79- @@ -214,6 +221,30 @@ impl IndicatorShader {
80- )
81- }
82-
83- + pub fn focus_element_with_radius<R: AsGlowRenderer>(
84- + renderer: &R,
85- + key: impl Into<Key>,
86- + mut element_geo: Rectangle<i32, Local>,
87- + thickness: u8,
88- + alpha: f32,
89- + active_window_hint: [f32; 3],
90- + radius: u8,
91- + ) -> PixelShaderElement {
92- + let t = thickness as i32;
93- + element_geo.loc -= (t, t).into();
94- + element_geo.size += (t * 2, t * 2).into();
95- +
96- + IndicatorShader::element(
97- + renderer,
98- + key,
99- + element_geo,
100- + thickness,
101- + [radius, radius, radius, radius],
102- + alpha,
103- + active_window_hint,
104- + )
105- + }
106- +
107- pub fn element<R: AsGlowRenderer>(
108- renderer: &R,
109- key: impl Into<Key>,
11078diff --git a/src/shell/grabs/moving.rs b/src/shell/grabs/moving.rs
111- index 28939ff..cc4e42d 100644
79+ index f59f93d6..35ef8ba7 100644
11280--- a/src/shell/grabs/moving.rs
11381+++ b/src/shell/grabs/moving.rs
11482@@ -2,7 +2,7 @@
115-
83+
11684 use crate::{
11785 backend::render::{
11886- BackdropShader, IndicatorShader, Key, Usage, cursor::CursorState, element::AsGlowRenderer,
119- + BackdropShader, IndicatorShader, Key, Usage, cursor::CursorState, element::AsGlowRenderer, SecurityContextIndicatorSettings,
87+ + BackdropShader, IndicatorShader, Key, Usage, cursor::CursorState, element::AsGlowRenderer, SecurityContextIndicatorSettings
12088 },
12189 shell::{
12290 CosmicMapped, CosmicSurface, Direction, ManagedLayer,
123- @@ -47,7 +47,6 @@ use std::{
124- sync::{Mutex, atomic::Ordering},
125- time::Instant,
126- };
127- -
128- use super::{GrabStartData, ReleaseMode};
129-
130- pub type SeatMoveGrabState = Mutex<Option<MoveGrabState>>;
131- @@ -75,6 +74,7 @@ impl MoveGrabState {
132- CosmicMappedRenderElement<R>: RenderElement<R>,
133- I: From<CosmicMappedRenderElement<R>>,
134- {
135- +
136- let scale = if self.previous == ManagedLayer::Tiling {
137- 0.6 + ((1.0
138- - (Instant::now().duration_since(self.start).as_millis() as f64
139- @@ -108,36 +108,71 @@ impl MoveGrabState {
91+ @@ -108,26 +108,67 @@ impl MoveGrabState {
14092 + self.window_offset
14193 - scaling_offset;
142-
94+
95+ + // Security context indicator
14396+ let mut secctx_element = None;
14497+ let mut secctx_border_size = 0;
14598+ if self.window.is_window() {
14699+ let surface = self.window.active_window();
147100+ if let Some(secctx_settings) = surface.user_data().get::<SecurityContextIndicatorSettings>() {
148101+ secctx_border_size = secctx_settings.border_size;
102+ + let radius = self.element().corner_radius(window_geo.size, secctx_border_size);
149103+ secctx_element = Some(
150104+ CosmicMappedRenderElement::from(IndicatorShader::focus_element(
151105+ renderer,
@@ -160,9 +114,10 @@ index 28939ff..cc4e42d 100644
160114+ .to_i32_round(),
161115+ )
162116+ .as_local(),
163- + secctx_settings.border_size ,
164- + [secctx_settings.border_size, secctx_settings.border_size, secctx_settings.border_size, secctx_settings.border_size] ,
117+ + secctx_border_size ,
118+ + radius ,
165119+ alpha,
120+ + output_scale.x,
166121+ secctx_settings.border_color,
167122+ ))
168123+ .into(),
@@ -172,9 +127,10 @@ index 28939ff..cc4e42d 100644
172127+
173128 let active_window_hint = crate::theme::active_window_hint(theme);
174129- let radius = self
175- - .element()
176- - .corner_radius(window_geo.size, self.indicator_thickness);
177-
130+ + let mut radius = self
131+ .element()
132+ .corner_radius(window_geo.size, self.indicator_thickness);
133+
178134 let focus_element = if self.indicator_thickness > 0 {
179135- Some(CosmicMappedRenderElement::from(
180136- IndicatorShader::focus_element(
@@ -187,15 +143,16 @@ index 28939ff..cc4e42d 100644
187143+ .upscale(scale)
188144+ .to_i32_round(),
189145+ ).as_local();
190- + let mut radius = self.indicator_thickness * 2;
191146+ if secctx_border_size > 0 {
192- + let offset = ( secctx_border_size) as i32;
147+ + let offset = secctx_border_size as i32;
193148+ indicator_geometry.loc -= (offset, offset).into();
194149+ indicator_geometry.size += (offset * 2, offset * 2).into();
195- + radius = secctx_border_size as u8 * 2;
150+ + for r in &mut radius {
151+ + *r += offset as u8;
152+ + }
196153+ }
197154+ Some(
198- + CosmicMappedRenderElement::from(IndicatorShader::focus_element_with_radius (
155+ + CosmicMappedRenderElement::from(IndicatorShader::focus_element (
199156 renderer,
200157 Key::Window(Usage::MoveGrabIndicator, self.window.key()),
201158- Rectangle::new(
@@ -210,60 +167,60 @@ index 28939ff..cc4e42d 100644
210167- .as_local(),
211168+ indicator_geometry,
212169 self.indicator_thickness,
213- - radius,
170+ radius,
214171 alpha,
215- [
216- active_window_hint.red,
172+ @@ -137,8 +178,9 @@ impl MoveGrabState {
217173 active_window_hint.green,
218174 active_window_hint.blue,
219175 ],
220176- ),
221177- ))
222- + radius,
223178+ ))
224179+ .into(),
225180+ )
226181 } else {
227182 None
228183 };
229- @@ -218 ,6 +253 ,7 @@ impl MoveGrabState {
184+ @@ -229 ,6 +271 ,7 @@ impl MoveGrabState {
230185 })
231186 .chain(p_elements)
232187 .chain(focus_element)
233188+ .chain(secctx_element)
234- .chain(w_elements.into_iter().map(|elem| match elem {
235- CosmicMappedRenderElement::Stack(stack) => {
236- CosmicMappedRenderElement::GrabbedStack(
189+ .chain(
190+ w_elements
191+ .into_iter()
237192diff --git a/src/shell/layout/floating/mod.rs b/src/shell/layout/floating/mod.rs
238- index ae29e60..a5a1c1e 100644
193+ index 1f3a7334..c047743e 100644
239194--- a/src/shell/layout/floating/mod.rs
240195+++ b/src/shell/layout/floating/mod.rs
241- @@ -24 ,7 +24 ,7 @@ use smithay::{
196+ @@ -25 ,7 +25 ,7 @@ use smithay::{
242197 };
243-
198+
244199 use crate::{
245200- backend::render::{IndicatorShader, Key, Usage, element::AsGlowRenderer},
246201+ backend::render::{IndicatorShader, Key, Usage, element::AsGlowRenderer, SecurityContextIndicatorSettings},
247202 shell::{
248203 CosmicSurface, Direction, ManagedLayer, MoveResult, ResizeMode,
249204 element::{
250- @@ -1558 ,6 +1558,25 @@ impl FloatingLayout {
205+ @@ -1590 ,6 +1590,27 @@ impl FloatingLayout {
251206 .collect();
252207 }
253-
208+
254209+ // Security context indicator
255210+ let mut secctx_border_size = 0;
256211+ if elem.is_window() {
257212+ let surface = elem.active_window();
258213+ if let Some(secctx_settings) = surface.user_data().get::<SecurityContextIndicatorSettings>() {
259- + secctx_border_size = secctx_settings.border_size;
214+ + secctx_border_size = secctx_settings.border_size;
215+ + let radius = elem.corner_radius(geometry.size.as_logical(), secctx_border_size);
260216+ let element = IndicatorShader::focus_element(
261217+ renderer,
262218+ Key::Window(Usage::SecurityContextIndicator, elem.key()),
263219+ geometry,
264- + secctx_settings.border_size ,
265- + [secctx_settings.border_size, secctx_settings.border_size, secctx_settings.border_size, secctx_settings.border_size] ,
220+ + secctx_border_size ,
221+ + radius ,
266222+ alpha,
223+ + output_scale,
267224+ secctx_settings.border_color,
268225+ );
269226+ window_elements.insert(0, element.into());
@@ -273,40 +230,32 @@ index ae29e60..a5a1c1e 100644
273230 if focused == Some(elem) && !elem.is_maximized(false) {
274231 if let Some((mode, resize)) = resize_indicator.as_mut() {
275232 let mut resize_geometry = geometry;
276- @@ -1583,20 +1602,27 @@ impl FloatingLayout {
233+ @@ -1615,12 +1636,21 @@ impl FloatingLayout {
277234 }
278-
235+
279236 let active_window_hint = crate::theme::active_window_hint(theme);
280237- let radius = elem.corner_radius(geometry.size.as_logical(), indicator_thickness);
238+ + let mut radius = elem.corner_radius(geometry.size.as_logical(), indicator_thickness);
281239 if indicator_thickness > 0 {
282- - let element = IndicatorShader::focus_element(
283240+ let mut indicator_geometry = geometry.clone();
284- + let mut radius = indicator_thickness * 2;
285241+ if secctx_border_size > 0 {
286- + let offset = ( secctx_border_size) as i32;
242+ + let offset = secctx_border_size as i32;
287243+ indicator_geometry.loc -= (offset, offset).into();
288244+ indicator_geometry.size += (offset * 2, offset * 2).into();
289- + radius = secctx_border_size as u8 * 2;
245+ + for r in &mut radius {
246+ + *r += offset as u8;
247+ + }
290248+ }
291- + let element = IndicatorShader::focus_element_with_radius (
249+ let element = IndicatorShader::focus_element (
292250 renderer,
293251 Key::Window(Usage::FocusIndicator, elem.key()),
294252- geometry,
295253+ indicator_geometry,
296254 indicator_thickness,
297- - radius,
255+ radius,
298256 alpha,
299- [
300- active_window_hint.red,
301- active_window_hint.green,
302- active_window_hint.blue,
303- ],
304- + radius,
305- );
306- window_elements.insert(0, element.into());
307- }
308257diff --git a/src/wayland/handlers/xdg_shell/mod.rs b/src/wayland/handlers/xdg_shell/mod.rs
309- index 56efd92..955ef4a 100644
258+ index 43e6a46d..dcf69aca 100644
310259--- a/src/wayland/handlers/xdg_shell/mod.rs
311260+++ b/src/wayland/handlers/xdg_shell/mod.rs
312261@@ -3,6 +3,8 @@
@@ -326,11 +275,9 @@ index 56efd92..955ef4a 100644
326275 },
327276 utils::{Logical, Point, Serial},
328277 wayland::{
329- @@ -44,7 +47,49 @@ impl XdgShellHandler for State {
330- fn new_toplevel(&mut self, surface: ToplevelSurface) {
278+ @@ -45,6 +48,45 @@ impl XdgShellHandler for State {
331279 let mut shell = self.common.shell.write();
332280 let seat = shell.seats.last_active().clone();
333- +
334281 let window = CosmicSurface::from(surface);
335282+
336283+ // Get security context data
@@ -346,7 +293,6 @@ index 56efd92..955ef4a 100644
346293+ .as_ref()
347294+ .and_then(|data| data.downcast_ref::<ClientState>())
348295+ .and_then(|data| data.security_context.as_ref()) {
349- +
350296+ // Try to find a security context rule by sandbox engine and appid
351297+ let sandbox_engine = security_context
352298+ .sandbox_engine
@@ -362,7 +308,6 @@ index 56efd92..955ef4a 100644
362308+ .map(|config| config.border_color.clone());
363309+
364310+ if let Some(color) = border_color {
365- +
366311+ // Add security context indicator settings to the user data
367312+ let indicator = SecurityContextIndicatorSettings {
368313+ border_color: color,
@@ -376,5 +321,6 @@ index 56efd92..955ef4a 100644
376321 shell.pending_windows.push(PendingWindow {
377322 surface: window,
378323 seat,
379- - -
380- 2.51.0
324+ - -
325+ 2.43.0
326+
0 commit comments