feat: corner-radius protocol support
This commit is contained in:
parent
b232a4b24a
commit
b3aa10436a
11 changed files with 1130 additions and 490 deletions
1186
Cargo.lock
generated
1186
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
|
|
@ -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" }
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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],
|
||||||
));
|
));
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
44
src/wayland/handlers/corner_radius.rs
Normal file
44
src/wayland/handlers/corner_radius.rs
Normal 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);
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
236
src/wayland/protocols/corner_radius.rs
Normal file
236
src/wayland/protocols/corner_radius.rs
Normal 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;
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue