feat: corner-radius protocol support

This commit is contained in:
Ashley Wulber 2025-09-24 15:11:16 -04:00 committed by Victoria Brekenfeld
parent b232a4b24a
commit b3aa10436a
11 changed files with 1130 additions and 490 deletions

1186
Cargo.lock generated

File diff suppressed because it is too large Load diff

View file

@ -143,8 +143,8 @@ inherits = "release"
lto = "fat" lto = "fat"
[patch."https://github.com/pop-os/cosmic-protocols"] [patch."https://github.com/pop-os/cosmic-protocols"]
cosmic-protocols = { git = "https://github.com/pop-os//cosmic-protocols", branch = "main" } cosmic-protocols = { git = "https://github.com/pop-os//cosmic-protocols", branch = "corner-radius" }
cosmic-client-toolkit = { git = "https://github.com/pop-os//cosmic-protocols", branch = "main" } cosmic-client-toolkit = { git = "https://github.com/pop-os//cosmic-protocols", branch = "corner-radius" }
[patch.crates-io] [patch.crates-io]
smithay = { git = "https://github.com/smithay/smithay.git", rev = "eb45814" } smithay = { git = "https://github.com/smithay/smithay.git", rev = "eb45814" }

View file

@ -195,6 +195,7 @@ impl IndicatorShader {
key: impl Into<Key>, key: impl Into<Key>,
mut element_geo: Rectangle<i32, Local>, mut element_geo: Rectangle<i32, Local>,
thickness: u8, thickness: u8,
radius: u8,
alpha: f32, alpha: f32,
active_window_hint: [f32; 3], active_window_hint: [f32; 3],
) -> PixelShaderElement { ) -> PixelShaderElement {
@ -207,7 +208,8 @@ impl IndicatorShader {
key, key,
element_geo, element_geo,
thickness, thickness,
thickness * 2, // FIXME, this seems to look OK, but I doubt it is correct
radius + thickness,
alpha, alpha,
active_window_hint, active_window_hint,
) )

View file

@ -14,11 +14,19 @@ use crate::{
CosmicMapped, CosmicSurface, Direction, ManagedLayer, CosmicMapped, CosmicSurface, Direction, ManagedLayer,
}, },
utils::prelude::*, utils::prelude::*,
wayland::protocols::toplevel_info::{toplevel_enter_output, toplevel_enter_workspace}, wayland::protocols::{
corner_radius::CornerRadiusData,
toplevel_info::{toplevel_enter_output, toplevel_enter_workspace},
},
};
use smithay::{
reexports::wayland_server::{Resource, Weak},
wayland::{compositor::with_states, seat::WaylandFocus},
}; };
use calloop::LoopHandle; use calloop::LoopHandle;
use cosmic::theme::CosmicTheme; use cosmic::theme::CosmicTheme;
use cosmic_protocols::corner_radius::v1::server::cosmic_corner_radius_toplevel_v1::CosmicCornerRadiusToplevelV1;
use smithay::{ use smithay::{
backend::{ backend::{
input::ButtonState, input::ButtonState,
@ -109,6 +117,29 @@ impl MoveGrabState {
- scaling_offset; - scaling_offset;
let active_window_hint = crate::theme::active_window_hint(theme); let active_window_hint = crate::theme::active_window_hint(theme);
let radius = self
.window()
.wl_surface()
.and_then(|surface| {
with_states(&surface, |s| {
let d = s
.data_map
.get::<Mutex<Weak<CosmicCornerRadiusToplevelV1>>>()?;
let guard = d.lock().unwrap();
let weak_data = guard.upgrade().ok()?;
let corners = weak_data.data::<CornerRadiusData>()?;
let guard = corners.lock().unwrap();
// TODO support multiple radius values
Some(guard.top_left)
})
})
.unwrap_or(self.indicator_thickness);
tracing::error!("{radius}");
let focus_element = if self.indicator_thickness > 0 { let focus_element = if self.indicator_thickness > 0 {
Some( Some(
CosmicMappedRenderElement::from(IndicatorShader::focus_element( CosmicMappedRenderElement::from(IndicatorShader::focus_element(
@ -125,6 +156,7 @@ impl MoveGrabState {
) )
.as_local(), .as_local(),
self.indicator_thickness, self.indicator_thickness,
radius,
alpha, alpha,
[ [
active_window_hint.red, active_window_hint.red,

View file

@ -1,11 +1,20 @@
// SPDX-License-Identifier: GPL-3.0-only // SPDX-License-Identifier: GPL-3.0-only
use crate::wayland::protocols::corner_radius::CornerRadiusData;
use smithay::{
reexports::wayland_server::{Resource, Weak},
wayland::compositor::with_states,
};
use std::{ use std::{
collections::{HashMap, VecDeque}, collections::{HashMap, VecDeque},
sync::atomic::{AtomicBool, Ordering}, sync::{
atomic::{AtomicBool, Ordering},
Mutex,
},
time::{Duration, Instant}, time::{Duration, Instant},
}; };
use cosmic_protocols::corner_radius::v1::server::cosmic_corner_radius_toplevel_v1::CosmicCornerRadiusToplevelV1;
use cosmic_settings_config::shortcuts::action::ResizeDirection; use cosmic_settings_config::shortcuts::action::ResizeDirection;
use keyframe::{ease, functions::EaseInOutCubic}; use keyframe::{ease, functions::EaseInOutCubic};
use smithay::{ use smithay::{
@ -1589,13 +1598,34 @@ impl FloatingLayout {
} }
let active_window_hint = crate::theme::active_window_hint(theme); let active_window_hint = crate::theme::active_window_hint(theme);
let radius = elem
.active_window()
.wl_surface()
.and_then(|surface| {
with_states(&surface, |s| {
let d = s
.data_map
.get::<Mutex<Weak<CosmicCornerRadiusToplevelV1>>>()?;
let guard = d.lock().unwrap();
let weak_data = guard.upgrade().ok()?;
let corners = weak_data.data::<CornerRadiusData>()?;
let guard = corners.lock().unwrap();
// TODO support multiple radius values
Some(guard.top_left)
})
})
.unwrap_or(indicator_thickness);
if indicator_thickness > 0 { if indicator_thickness > 0 {
let element = IndicatorShader::focus_element( let element = IndicatorShader::focus_element(
renderer, renderer,
Key::Window(Usage::FocusIndicator, elem.key()), Key::Window(Usage::FocusIndicator, elem.key()),
geometry, geometry,
indicator_thickness, indicator_thickness,
radius,
alpha, alpha,
[ [
active_window_hint.red, active_window_hint.red,

View file

@ -29,6 +29,7 @@ use crate::{
wayland::{ wayland::{
handlers::xdg_shell::popup::get_popup_toplevel, handlers::xdg_shell::popup::get_popup_toplevel,
protocols::{ protocols::{
corner_radius::CornerRadiusData,
toplevel_info::{ toplevel_info::{
toplevel_enter_output, toplevel_enter_workspace, toplevel_leave_output, toplevel_enter_output, toplevel_enter_workspace, toplevel_leave_output,
toplevel_leave_workspace, toplevel_leave_workspace,
@ -37,7 +38,9 @@ use crate::{
}, },
}, },
}; };
use smithay::{reexports::wayland_server::Resource, wayland::compositor::with_states};
use cosmic_protocols::corner_radius::v1::server::cosmic_corner_radius_toplevel_v1::CosmicCornerRadiusToplevelV1;
use cosmic_settings_config::shortcuts::action::{FocusDirection, ResizeDirection}; use cosmic_settings_config::shortcuts::action::{FocusDirection, ResizeDirection};
use id_tree::{InsertBehavior, MoveBehavior, Node, NodeId, NodeIdError, RemoveBehavior, Tree}; use id_tree::{InsertBehavior, MoveBehavior, Node, NodeId, NodeIdError, RemoveBehavior, Tree};
use keyframe::{ use keyframe::{
@ -59,13 +62,13 @@ use smithay::{
desktop::{layer_map_for_output, space::SpaceElement, PopupKind, WindowSurfaceType}, desktop::{layer_map_for_output, space::SpaceElement, PopupKind, WindowSurfaceType},
input::Seat, input::Seat,
output::Output, output::Output,
reexports::wayland_server::Client, reexports::wayland_server::{Client, Weak as WsWeak},
utils::{IsAlive, Logical, Physical, Point, Rectangle, Scale, Size}, utils::{IsAlive, Logical, Physical, Point, Rectangle, Scale, Size},
wayland::{compositor::add_blocker, seat::WaylandFocus}, wayland::{compositor::add_blocker, seat::WaylandFocus},
}; };
use std::{ use std::{
collections::{HashMap, VecDeque}, collections::{HashMap, VecDeque},
sync::{Arc, Weak}, sync::{Arc, Mutex, Weak},
time::{Duration, Instant}, time::{Duration, Instant},
}; };
use tracing::trace; use tracing::trace;
@ -5015,6 +5018,27 @@ where
x => Some(x), x => Some(x),
} }
})); }));
let radius = mapped
.active_window()
.wl_surface()
.and_then(|surface| {
with_states(&surface, |s| {
let d = s
.data_map
.get::<Mutex<WsWeak<CosmicCornerRadiusToplevelV1>>>()?;
let guard = d.lock().unwrap();
let weak_data = guard.upgrade().ok()?;
let corners = weak_data.data::<CornerRadiusData>()?;
let guard = corners.lock().unwrap();
// TODO support multiple radius values
Some(guard.top_left)
})
})
.unwrap_or(indicator_thickness);
if is_minimizing && indicator_thickness > 0 { if is_minimizing && indicator_thickness > 0 {
elements.push(CosmicMappedRenderElement::FocusIndicator( elements.push(CosmicMappedRenderElement::FocusIndicator(
IndicatorShader::focus_element( IndicatorShader::focus_element(
@ -5022,6 +5046,7 @@ where
Key::Window(Usage::FocusIndicator, mapped.clone().key()), Key::Window(Usage::FocusIndicator, mapped.clone().key()),
geo, geo,
indicator_thickness, indicator_thickness,
radius,
alpha, alpha,
[window_hint.red, window_hint.green, window_hint.blue], [window_hint.red, window_hint.green, window_hint.blue],
), ),
@ -5283,12 +5308,33 @@ where
) )
.unwrap(); .unwrap();
let radius = window
.wl_surface()
.and_then(|surface| {
with_states(&surface, |s| {
let d = s
.data_map
.get::<Mutex<WsWeak<CosmicCornerRadiusToplevelV1>>>()?;
let guard = d.lock().unwrap();
let weak_data = guard.upgrade().ok()?;
let corners = weak_data.data::<CornerRadiusData>()?;
let guard = corners.lock().unwrap();
// TODO support multiple radius values
Some(guard.top_left)
})
})
.unwrap_or(indicator_thickness);
swap_elements.push(CosmicMappedRenderElement::FocusIndicator( swap_elements.push(CosmicMappedRenderElement::FocusIndicator(
IndicatorShader::focus_element( IndicatorShader::focus_element(
renderer, renderer,
Key::from(swapping_stack_surface_id.clone()), Key::from(swapping_stack_surface_id.clone()),
swap_geo, swap_geo,
4, 4,
radius,
transition.unwrap_or(1.0), transition.unwrap_or(1.0),
[window_hint.red, window_hint.green, window_hint.blue], [window_hint.red, window_hint.green, window_hint.blue],
), ),
@ -5359,7 +5405,30 @@ where
group_color, group_color,
)); ));
} }
let radius = match data {
Data::Mapped { mapped, .. } => mapped
.active_window()
.wl_surface()
.and_then(|surface| {
with_states(&surface, |s| {
let d = s
.data_map
.get::<Mutex<WsWeak<CosmicCornerRadiusToplevelV1>>>()?;
let guard = d.lock().unwrap();
let weak_data = guard.upgrade().ok()?;
let corners = weak_data.data::<CornerRadiusData>()?;
let guard = corners.lock().unwrap();
// TODO support multiple radius values
Some(guard.top_left)
})
})
.unwrap_or(indicator_thickness),
_ => 1,
};
if !swap_desc if !swap_desc
.as_ref() .as_ref()
.map(|desc| desc.stack_window.is_some()) .map(|desc| desc.stack_window.is_some())
@ -5381,6 +5450,7 @@ where
} else { } else {
indicator_thickness indicator_thickness
}, },
radius,
alpha, alpha,
[window_hint.red, window_hint.green, window_hint.blue], [window_hint.red, window_hint.green, window_hint.blue],
)); ));

View file

@ -16,6 +16,7 @@ use crate::{
protocols::{ protocols::{
a11y::A11yState, a11y::A11yState,
atspi::AtspiState, atspi::AtspiState,
corner_radius::CornerRadiusState,
drm::WlDrmState, drm::WlDrmState,
image_capture_source::ImageCaptureSourceState, image_capture_source::ImageCaptureSourceState,
output_configuration::OutputConfigurationState, output_configuration::OutputConfigurationState,
@ -212,6 +213,7 @@ pub struct Common {
// wayland state // wayland state
pub compositor_state: CompositorState, pub compositor_state: CompositorState,
pub corner_radius_state: CornerRadiusState,
pub data_device_state: DataDeviceState, pub data_device_state: DataDeviceState,
pub dmabuf_state: DmabufState, pub dmabuf_state: DmabufState,
pub fractional_scale_state: FractionalScaleManagerState, pub fractional_scale_state: FractionalScaleManagerState,
@ -602,6 +604,7 @@ impl State {
let clock = Clock::new(); let clock = Clock::new();
let config = Config::load(&handle); let config = Config::load(&handle);
let compositor_state = CompositorState::new::<Self>(dh); let compositor_state = CompositorState::new::<Self>(dh);
let corner_radius_state = CornerRadiusState::new::<Self>(dh);
let data_device_state = DataDeviceState::new::<Self>(dh); let data_device_state = DataDeviceState::new::<Self>(dh);
let dmabuf_state = DmabufState::new(); let dmabuf_state = DmabufState::new();
let fractional_scale_state = FractionalScaleManagerState::new::<State>(dh); let fractional_scale_state = FractionalScaleManagerState::new::<State>(dh);
@ -709,6 +712,7 @@ impl State {
theme: cosmic::theme::system_preference(), theme: cosmic::theme::system_preference(),
compositor_state, compositor_state,
corner_radius_state,
data_device_state, data_device_state,
dmabuf_state, dmabuf_state,
fractional_scale_state, fractional_scale_state,

View file

@ -0,0 +1,44 @@
use smithay::wayland::shell::xdg::ToplevelSurface;
use crate::wayland::protocols::corner_radius::{
delegate_corner_radius, CornerRadiusData, CornerRadiusHandler,
};
use crate::state::State;
impl CornerRadiusHandler for State {
fn corner_radius_state(
&mut self,
) -> &mut crate::wayland::protocols::corner_radius::CornerRadiusState {
&mut self.common.corner_radius_state
}
fn toplevel_from_resource(
&mut self,
toplevel: &smithay::reexports::wayland_protocols::xdg::shell::server::xdg_toplevel::XdgToplevel,
) -> Option<ToplevelSurface> {
self.common.xdg_shell_state.get_toplevel(toplevel)
}
fn set_corner_radius(
&mut self,
_toplevel: &cosmic_protocols::corner_radius::v1::server::cosmic_corner_radius_toplevel_v1::CosmicCornerRadiusToplevelV1,
_data: &CornerRadiusData,
_top_left: u32,
_top_right: u32,
_bottom_right: u32,
_bottom_left: u32,
) {
// TODO force redraw? of focus element?
}
fn unset_corner_radius(
&mut self,
_toplevel: &cosmic_protocols::corner_radius::v1::server::cosmic_corner_radius_toplevel_v1::CosmicCornerRadiusToplevelV1,
_data: &CornerRadiusData,
) {
// TODO force redraw?
}
}
delegate_corner_radius!(State);

View file

@ -5,6 +5,7 @@ pub mod alpha_modifier;
pub mod atspi; pub mod atspi;
pub mod buffer; pub mod buffer;
pub mod compositor; pub mod compositor;
pub mod corner_radius;
pub mod data_control; pub mod data_control;
pub mod data_device; pub mod data_device;
pub mod decoration; pub mod decoration;

View file

@ -0,0 +1,236 @@
use cosmic_protocols::corner_radius::v1::server::{
cosmic_corner_radius_manager_v1, cosmic_corner_radius_toplevel_v1,
};
use smithay::reexports::{
wayland_protocols::xdg::shell::server::xdg_toplevel::XdgToplevel,
wayland_server::{Client, Dispatch, DisplayHandle, GlobalDispatch, Resource},
};
use smithay::wayland::compositor::with_states;
use smithay::wayland::shell::xdg::ToplevelSurface;
use std::sync::Mutex;
use wayland_backend::server::GlobalId;
#[derive(Debug)]
pub struct CornerRadiusState {
instances: Vec<cosmic_corner_radius_manager_v1::CosmicCornerRadiusManagerV1>,
global: GlobalId,
}
impl CornerRadiusState {
pub fn new<D>(dh: &DisplayHandle) -> CornerRadiusState
where
D: GlobalDispatch<cosmic_corner_radius_manager_v1::CosmicCornerRadiusManagerV1, ()>
+ Dispatch<cosmic_corner_radius_manager_v1::CosmicCornerRadiusManagerV1, ()>
+ Dispatch<
cosmic_corner_radius_toplevel_v1::CosmicCornerRadiusToplevelV1,
CornerRadiusData,
> + CornerRadiusHandler
+ 'static,
{
let global = dh
.create_global::<D, cosmic_corner_radius_manager_v1::CosmicCornerRadiusManagerV1, _>(
1,
(),
);
CornerRadiusState {
instances: Vec::new(),
global,
}
}
pub fn global_id(&self) -> GlobalId {
self.global.clone()
}
}
pub trait CornerRadiusHandler {
fn corner_radius_state(&mut self) -> &mut CornerRadiusState;
fn toplevel_from_resource(&mut self, toplevel: &XdgToplevel) -> Option<ToplevelSurface>;
fn set_corner_radius(
&mut self,
toplevel: &cosmic_corner_radius_toplevel_v1::CosmicCornerRadiusToplevelV1,
data: &CornerRadiusData,
top_left: u32,
top_right: u32,
bottom_right: u32,
bottom_left: u32,
);
fn unset_corner_radius(
&mut self,
toplevel: &cosmic_corner_radius_toplevel_v1::CosmicCornerRadiusToplevelV1,
data: &CornerRadiusData,
);
}
impl<D> GlobalDispatch<cosmic_corner_radius_manager_v1::CosmicCornerRadiusManagerV1, (), D>
for CornerRadiusState
where
D: GlobalDispatch<cosmic_corner_radius_manager_v1::CosmicCornerRadiusManagerV1, ()>
+ Dispatch<cosmic_corner_radius_manager_v1::CosmicCornerRadiusManagerV1, ()>
+ Dispatch<cosmic_corner_radius_toplevel_v1::CosmicCornerRadiusToplevelV1, CornerRadiusData>
+ CornerRadiusHandler
+ 'static,
{
fn bind(
state: &mut D,
_handle: &DisplayHandle,
_client: &Client,
resource: smithay::reexports::wayland_server::New<
cosmic_corner_radius_manager_v1::CosmicCornerRadiusManagerV1,
>,
_global_data: &(),
data_init: &mut smithay::reexports::wayland_server::DataInit<'_, D>,
) {
let instance = data_init.init(resource, ());
state.corner_radius_state().instances.push(instance);
}
}
impl<D> Dispatch<cosmic_corner_radius_manager_v1::CosmicCornerRadiusManagerV1, (), D>
for CornerRadiusState
where
D: GlobalDispatch<cosmic_corner_radius_manager_v1::CosmicCornerRadiusManagerV1, ()>
+ Dispatch<cosmic_corner_radius_manager_v1::CosmicCornerRadiusManagerV1, ()>
+ Dispatch<cosmic_corner_radius_toplevel_v1::CosmicCornerRadiusToplevelV1, CornerRadiusData>
+ CornerRadiusHandler
+ 'static,
{
fn request(
state: &mut D,
_client: &Client,
_resource: &cosmic_corner_radius_manager_v1::CosmicCornerRadiusManagerV1,
request: <cosmic_corner_radius_manager_v1::CosmicCornerRadiusManagerV1 as smithay::reexports::wayland_server::Resource>::Request,
_data: &(),
_dhandle: &DisplayHandle,
data_init: &mut smithay::reexports::wayland_server::DataInit<'_, D>,
) {
match request {
cosmic_corner_radius_manager_v1::Request::Destroy => {
let corner_radius_state = state.corner_radius_state();
corner_radius_state.instances.retain(|i| i != _resource);
}
cosmic_corner_radius_manager_v1::Request::GetCornerRadius { id, toplevel } => {
let data = CornerRadiusData::default();
let instance = data_init.init(id, data);
if let Some(surface) = state.toplevel_from_resource(&toplevel) {
with_states(surface.wl_surface(), |s| {
let data = s
.data_map
.get_or_insert_threadsafe(|| Mutex::new(instance.downgrade()));
let mut guard = data.lock().unwrap();
*guard = instance.downgrade();
});
}
}
_ => unimplemented!(),
}
}
fn destroyed(
state: &mut D,
_client: wayland_backend::server::ClientId,
resource: &cosmic_corner_radius_manager_v1::CosmicCornerRadiusManagerV1,
_data: &(),
) {
let corner_radius_state = state.corner_radius_state();
corner_radius_state.instances.retain(|i| i != resource);
}
}
impl<D>
Dispatch<cosmic_corner_radius_toplevel_v1::CosmicCornerRadiusToplevelV1, CornerRadiusData, D>
for CornerRadiusState
where
D: GlobalDispatch<cosmic_corner_radius_manager_v1::CosmicCornerRadiusManagerV1, ()>
+ Dispatch<cosmic_corner_radius_manager_v1::CosmicCornerRadiusManagerV1, ()>
+ Dispatch<cosmic_corner_radius_toplevel_v1::CosmicCornerRadiusToplevelV1, CornerRadiusData>
+ CornerRadiusHandler
+ 'static,
{
fn request(
_state: &mut D,
_client: &Client,
resource: &cosmic_corner_radius_toplevel_v1::CosmicCornerRadiusToplevelV1,
request: <cosmic_corner_radius_toplevel_v1::CosmicCornerRadiusToplevelV1 as Resource>::Request,
data: &CornerRadiusData,
_dhandle: &DisplayHandle,
_data_init: &mut smithay::reexports::wayland_server::DataInit<'_, D>,
) {
match request {
cosmic_corner_radius_toplevel_v1::Request::Destroy => {
// TODO do we want to unset it after it is destroyed or just leave it?
_state.unset_corner_radius(resource, data);
}
cosmic_corner_radius_toplevel_v1::Request::SetRadius {
top_left,
top_right,
bottom_right,
bottom_left,
} => {
{
let mut guard = data.lock().unwrap();
guard.set_corner_radius(
top_left as u8,
top_right as u8,
bottom_right as u8,
bottom_left as u8,
);
}
_state.set_corner_radius(
resource,
data,
top_left,
top_right,
bottom_right,
bottom_left,
);
}
cosmic_corner_radius_toplevel_v1::Request::UnsetRadius => {
_state.unset_corner_radius(resource, data);
}
_ => unimplemented!(),
}
}
}
pub type CornerRadiusData = Mutex<CornerRadiusInternal>;
#[derive(Debug, Default)]
pub struct CornerRadiusInternal {
pub top_left: u8,
pub top_right: u8,
pub bottom_right: u8,
pub bottom_left: u8,
}
impl CornerRadiusInternal {
fn set_corner_radius(
&mut self,
top_left: u8,
top_right: u8,
bottom_right: u8,
bottom_left: u8,
) {
self.top_left = top_left;
self.top_right = top_right;
self.bottom_right = bottom_right;
self.bottom_left = bottom_left;
}
}
macro_rules! delegate_corner_radius {
($(@<$( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+>)? $ty: ty) => {
smithay::reexports::wayland_server::delegate_global_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [
cosmic_protocols::corner_radius::v1::server::cosmic_corner_radius_manager_v1::CosmicCornerRadiusManagerV1: ()
] => $crate::wayland::protocols::corner_radius::CornerRadiusState);
smithay::reexports::wayland_server::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [
cosmic_protocols::corner_radius::v1::server::cosmic_corner_radius_manager_v1::CosmicCornerRadiusManagerV1: ()
] => $crate::wayland::protocols::corner_radius::CornerRadiusState);
smithay::reexports::wayland_server::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [
cosmic_protocols::corner_radius::v1::server::cosmic_corner_radius_toplevel_v1::CosmicCornerRadiusToplevelV1: CornerRadiusData
] => $crate::wayland::protocols::corner_radius::CornerRadiusState);
};
}
pub(crate) use delegate_corner_radius;

View file

@ -2,6 +2,7 @@
pub mod a11y; pub mod a11y;
pub mod atspi; pub mod atspi;
pub mod corner_radius;
pub mod drm; pub mod drm;
pub mod image_capture_source; pub mod image_capture_source;
pub mod output_configuration; pub mod output_configuration;