cosmic-comp/src/shell/workspace.rs

767 lines
26 KiB
Rust
Raw Normal View History

use crate::{
backend::render::element::AsGlowRenderer,
2022-11-03 18:51:27 +01:00
shell::layout::{
floating::{FloatingLayout, MoveSurfaceGrab},
tiling::TilingLayout,
2022-09-28 12:01:29 +02:00
},
state::State,
2022-09-28 12:01:29 +02:00
utils::prelude::*,
2022-11-03 18:51:27 +01:00
wayland::{
handlers::screencopy::{DropableSession, WORKSPACE_OVERVIEW_NAMESPACE},
2022-11-03 18:51:27 +01:00
protocols::{
screencopy::{BufferParams, Session as ScreencopySession},
toplevel_info::ToplevelInfoState,
2022-11-03 18:51:27 +01:00
workspace::WorkspaceHandle,
},
},
xwayland::XWaylandState,
};
2022-09-28 12:01:29 +02:00
use indexmap::IndexSet;
2022-03-24 20:32:31 +01:00
use smithay::{
2022-09-28 12:01:29 +02:00
backend::renderer::{
element::{surface::WaylandSurfaceRenderElement, AsRenderElements, Element, RenderElement},
ImportAll, ImportMem, Renderer,
2022-09-28 12:01:29 +02:00
},
desktop::{layer_map_for_output, space::SpaceElement, LayerSurface},
2022-08-31 13:01:23 +02:00
input::{pointer::GrabStartData as PointerGrabStartData, Seat},
2022-11-03 18:51:27 +01:00
output::Output,
2023-01-18 20:23:41 +01:00
reexports::wayland_server::protocol::wl_surface::WlSurface,
utils::{Buffer as BufferCoords, IsAlive, Logical, Physical, Point, Rectangle, Scale, Size},
wayland::{seat::WaylandFocus, shell::wlr_layer::Layer},
xwayland::X11Surface,
2022-09-28 12:01:29 +02:00
};
2022-11-03 18:51:27 +01:00
use std::collections::HashMap;
use tracing::warn;
2022-09-28 12:01:29 +02:00
use super::{
2023-03-07 22:20:44 +01:00
element::{window::CosmicWindowRenderElement, CosmicMapped},
2022-09-28 12:01:29 +02:00
focus::{FocusStack, FocusStackMut},
2023-01-18 20:23:41 +01:00
grabs::{ResizeEdge, ResizeGrab},
CosmicMappedRenderElement, CosmicSurface,
2022-03-24 20:32:31 +01:00
};
2022-03-30 22:00:44 +02:00
2022-09-28 12:01:29 +02:00
#[derive(Debug)]
2022-03-24 20:32:31 +01:00
pub struct Workspace {
pub tiling_layer: TilingLayout,
pub floating_layer: FloatingLayout,
2022-09-28 12:01:29 +02:00
pub tiling_enabled: bool,
pub fullscreen: HashMap<Output, CosmicSurface>,
pub handle: WorkspaceHandle,
2022-09-28 12:01:29 +02:00
pub focus_stack: FocusStacks,
2022-11-03 18:51:27 +01:00
pub pending_buffers: Vec<(ScreencopySession, BufferParams)>,
pub screencopy_sessions: Vec<DropableSession>,
2022-03-24 20:32:31 +01:00
}
2022-09-28 12:01:29 +02:00
#[derive(Debug, Default)]
pub struct FocusStacks(HashMap<Seat<State>, IndexSet<CosmicMapped>>);
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum ManagedState {
Tiling,
Floating,
}
2022-03-24 20:32:31 +01:00
impl Workspace {
2023-03-09 18:27:29 +01:00
pub fn new(handle: WorkspaceHandle, tiling_enabled: bool, gaps: (u8, u8)) -> Workspace {
2022-03-24 20:32:31 +01:00
Workspace {
2023-03-09 18:27:29 +01:00
tiling_layer: TilingLayout::new(gaps),
floating_layer: FloatingLayout::new(),
2023-01-27 13:26:28 +01:00
tiling_enabled,
2022-04-22 15:18:28 +02:00
fullscreen: HashMap::new(),
handle,
2022-09-28 12:01:29 +02:00
focus_stack: FocusStacks::default(),
2022-11-03 18:51:27 +01:00
pending_buffers: Vec::new(),
screencopy_sessions: Vec::new(),
2022-03-24 20:32:31 +01:00
}
}
2022-09-28 12:01:29 +02:00
pub fn refresh(&mut self) {
#[cfg(feature = "debug")]
puffin::profile_function!();
self.fullscreen.retain(|_, w| w.alive());
2022-09-28 12:01:29 +02:00
self.floating_layer.refresh();
self.tiling_layer.refresh();
}
pub fn commit(&mut self, surface: &WlSurface) {
2023-01-18 20:23:41 +01:00
if let Some(mapped) = self.element_for_wl_surface(surface) {
2022-09-28 12:01:29 +02:00
mapped
.windows()
.find(|(w, _)| w.wl_surface().as_ref() == Some(surface))
2022-09-28 12:01:29 +02:00
.unwrap()
.0
.on_commit();
}
}
pub fn map_output(&mut self, output: &Output, position: Point<i32, Logical>) {
self.tiling_layer.map_output(output, position);
self.floating_layer.map_output(output, position);
}
pub fn unmap_output(
&mut self,
output: &Output,
toplevel_info: &mut ToplevelInfoState<State, CosmicSurface>,
) {
2022-09-28 12:01:29 +02:00
if let Some(dead_output_window) = self.fullscreen.remove(output) {
self.unfullscreen_request(&dead_output_window);
}
self.tiling_layer.unmap_output(output, toplevel_info);
self.floating_layer.unmap_output(output, toplevel_info);
2022-09-28 12:01:29 +02:00
self.refresh();
}
pub fn unmap(&mut self, mapped: &CosmicMapped) -> Option<ManagedState> {
let was_floating = self.floating_layer.unmap(&mapped);
let was_tiling = self.tiling_layer.unmap(&mapped).is_some();
if was_floating || was_tiling {
assert!(was_floating != was_tiling);
}
if mapped.is_maximized() || mapped.is_fullscreen() {
self.unmaximize_request(&mapped.active_window());
}
self.focus_stack
.0
.values_mut()
.for_each(|set| set.retain(|m| m != mapped));
if was_floating {
Some(ManagedState::Floating)
} else if was_tiling {
Some(ManagedState::Tiling)
} else {
None
}
}
2023-01-18 20:23:41 +01:00
pub fn element_for_surface(&self, surface: &CosmicSurface) -> Option<&CosmicMapped> {
self.floating_layer
.mapped()
.chain(self.tiling_layer.mapped().map(|(_, w, _)| w))
.find(|e| e.windows().any(|(w, _)| &w == surface))
}
pub fn element_for_wl_surface(&self, surface: &WlSurface) -> Option<&CosmicMapped> {
2022-09-28 12:01:29 +02:00
self.floating_layer
.mapped()
.chain(self.tiling_layer.mapped().map(|(_, w, _)| w))
.find(|e| {
e.windows()
.any(|(w, _)| w.wl_surface().as_ref() == Some(surface))
2022-09-28 12:01:29 +02:00
})
}
2022-09-28 12:01:29 +02:00
pub fn outputs_for_element(&self, elem: &CosmicMapped) -> impl Iterator<Item = Output> {
self.floating_layer
.space
.outputs_for_element(elem)
.into_iter()
.chain(self.tiling_layer.output_for_element(elem).cloned())
}
pub fn output_under(&self, point: Point<i32, Logical>) -> Option<&Output> {
let space = &self.floating_layer.space;
space.outputs().find(|o| {
let internal_output_geo = space.output_geometry(o).unwrap();
let external_output_geo = o.geometry();
internal_output_geo.contains(point - external_output_geo.loc + internal_output_geo.loc)
})
}
pub fn element_under(
&self,
location: Point<f64, Logical>,
) -> Option<(&CosmicMapped, Point<i32, Logical>)> {
self.floating_layer
.space
.element_under(location)
.or_else(|| {
self.tiling_layer.mapped().find_map(|(_, mapped, loc)| {
let test_point = location - loc.to_f64() + mapped.geometry().loc.to_f64();
2022-09-28 12:01:29 +02:00
mapped
.is_in_input_region(&test_point)
.then_some((mapped, loc - mapped.geometry().loc))
2022-09-28 12:01:29 +02:00
})
})
}
pub fn element_geometry(&self, elem: &CosmicMapped) -> Option<Rectangle<i32, Logical>> {
let space = &self.floating_layer.space;
let outputs = space.outputs().collect::<Vec<_>>();
let offset = if outputs.len() == 1
&& space.output_geometry(&outputs[0]).unwrap().loc == Point::from((0, 0))
{
outputs[0].geometry().loc
} else {
(0, 0).into()
};
self.floating_layer
.space
.element_geometry(elem)
.or_else(|| self.tiling_layer.element_geometry(elem))
.map(|mut geo| {
geo.loc += offset;
geo
})
}
pub fn maximize_request(&mut self, window: &CosmicSurface, output: &Output) {
if self.fullscreen.contains_key(output) {
2022-04-22 15:18:28 +02:00
return;
}
self.floating_layer.maximize_request(window);
window.set_fullscreen(false);
window.set_maximized(true);
self.set_fullscreen(window, output)
2022-03-24 20:32:31 +01:00
}
pub fn unmaximize_request(&mut self, window: &CosmicSurface) -> Option<Size<i32, Logical>> {
if self.fullscreen.values().any(|w| w == window) {
self.unfullscreen_request(window);
self.floating_layer.unmaximize_request(window)
} else {
None
}
}
2022-03-24 20:32:31 +01:00
pub fn fullscreen_request(&mut self, window: &CosmicSurface, output: &Output) {
if self.fullscreen.contains_key(output) {
2022-04-22 15:18:28 +02:00
return;
}
window.set_maximized(false);
window.set_fullscreen(true);
self.set_fullscreen(window, output)
2022-03-24 20:32:31 +01:00
}
2022-04-22 15:18:28 +02:00
2023-02-13 20:28:07 +01:00
pub(super) fn set_fullscreen<'a>(
&mut self,
window: impl Into<Option<&'a CosmicSurface>>,
output: &Output,
) {
match window.into() {
Some(window) => {
if let Some(mapped) = self
.mapped()
.find(|m| m.windows().any(|(w, _)| &w == window))
{
mapped.set_active(window);
}
2022-04-22 15:18:28 +02:00
2023-02-13 20:28:07 +01:00
window.set_geometry(output.geometry());
window.send_configure();
self.fullscreen.insert(output.clone(), window.clone());
}
None => {
if let Some(surface) = self.fullscreen.get(output).cloned() {
self.unfullscreen_request(&surface);
}
}
}
2022-04-22 15:18:28 +02:00
}
2022-05-03 13:37:51 +02:00
pub fn unfullscreen_request(&mut self, window: &CosmicSurface) {
2022-04-22 15:18:28 +02:00
if self.fullscreen.values().any(|w| w == window) {
window.set_maximized(false);
window.set_fullscreen(false);
2023-01-03 19:17:51 +01:00
self.floating_layer.refresh();
self.tiling_layer.refresh();
window.send_configure();
2022-04-22 15:18:28 +02:00
self.fullscreen.retain(|_, w| w != window);
}
}
pub fn maximize_toggle(&mut self, window: &CosmicSurface, output: &Output) {
2022-09-28 12:01:29 +02:00
if self.fullscreen.contains_key(output) {
self.unmaximize_request(window);
2022-04-22 15:18:28 +02:00
} else {
self.maximize_request(window, output);
2022-04-22 15:18:28 +02:00
}
}
pub fn get_fullscreen(&self, output: &Output) -> Option<&CosmicSurface> {
2022-09-28 12:01:29 +02:00
self.fullscreen.get(output).filter(|w| w.alive())
2022-04-22 15:18:28 +02:00
}
2022-07-07 22:41:17 +02:00
pub fn resize_request(
2022-10-25 14:43:50 +02:00
&mut self,
mapped: &CosmicMapped,
seat: &Seat<State>,
start_data: PointerGrabStartData<State>,
edges: ResizeEdge,
) -> Option<ResizeGrab> {
2022-10-25 14:43:50 +02:00
if mapped.is_fullscreen() || mapped.is_maximized() {
return None;
}
2022-10-25 14:43:50 +02:00
if self.floating_layer.mapped().any(|m| m == mapped) {
self.floating_layer
2023-01-18 20:23:41 +01:00
.resize_request(mapped, seat, start_data.clone(), edges)
.map(Into::into)
2022-10-25 14:43:50 +02:00
} else if self.tiling_layer.mapped().any(|(_, m, _)| m == mapped) {
self.tiling_layer
2023-01-18 20:23:41 +01:00
.resize_request(mapped, seat, start_data, edges)
.map(Into::into)
2022-10-25 14:43:50 +02:00
} else {
None
}
}
pub fn move_request(
&mut self,
window: &CosmicSurface,
seat: &Seat<State>,
output: &Output,
start_data: PointerGrabStartData<State>,
indicator_thickness: u8,
) -> Option<MoveSurfaceGrab> {
let pointer = seat.get_pointer().unwrap();
let pos = pointer.current_location();
2023-01-18 20:23:41 +01:00
let mapped = self.element_for_surface(&window)?.clone();
let mut initial_window_location = self.element_geometry(&mapped).unwrap().loc;
if mapped.is_fullscreen() || mapped.is_maximized() {
// If surface is maximized then unmaximize it
let new_size = self.unmaximize_request(window);
let ratio = pos.x / output.geometry().size.w as f64;
initial_window_location = new_size
.map(|size| (pos.x - (size.w as f64 * ratio), pos.y).into())
.unwrap_or_else(|| pos)
.to_i32_round();
}
let was_floating = self.floating_layer.unmap(&mapped);
//let was_tiled = self.tiling_layer.unmap(&mapped);
//assert!(was_floating != was_tiled);
if was_floating {
Some(MoveSurfaceGrab::new(
start_data,
mapped,
seat,
pos,
initial_window_location,
indicator_thickness,
))
} else {
None // TODO
}
}
2022-07-07 22:41:17 +02:00
pub fn toggle_tiling(&mut self, seat: &Seat<State>) {
if self.tiling_enabled {
2022-09-28 12:01:29 +02:00
for window in self
.tiling_layer
.mapped()
.map(|(_, m, _)| m.clone())
.collect::<Vec<_>>()
.into_iter()
{
self.tiling_layer.unmap(&window);
self.floating_layer.map(window, seat, None);
2022-07-07 22:41:17 +02:00
}
self.tiling_enabled = false;
} else {
2022-09-28 12:01:29 +02:00
let focus_stack = self.focus_stack.get(seat);
for window in self
.floating_layer
.mapped()
.cloned()
.collect::<Vec<_>>()
.into_iter()
{
self.floating_layer.unmap(&window);
self.tiling_layer.map(window, seat, focus_stack.iter())
2022-07-07 22:41:17 +02:00
}
self.tiling_enabled = true;
}
}
pub fn toggle_floating_window(&mut self, seat: &Seat<State>) {
if self.tiling_enabled {
2022-09-28 12:01:29 +02:00
if let Some(window) = self.focus_stack.get(seat).iter().next().cloned() {
if self.tiling_layer.mapped().any(|(_, m, _)| m == &window) {
self.tiling_layer.unmap(&window);
self.floating_layer.map(window, seat, None);
} else if self.floating_layer.mapped().any(|w| w == &window) {
let focus_stack = self.focus_stack.get(seat);
self.floating_layer.unmap(&window);
self.tiling_layer.map(window, seat, focus_stack.iter())
2022-07-07 22:41:17 +02:00
}
}
}
}
2022-09-28 12:01:29 +02:00
pub fn mapped(&self) -> impl Iterator<Item = &CosmicMapped> {
self.floating_layer
.mapped()
.chain(self.tiling_layer.mapped().map(|(_, w, _)| w))
}
pub fn windows(&self) -> impl Iterator<Item = CosmicSurface> + '_ {
2022-09-28 12:01:29 +02:00
self.floating_layer
.windows()
.chain(self.tiling_layer.windows().map(|(_, w, _)| w))
}
pub fn is_fullscreen(&self, mapped: &CosmicMapped) -> bool {
self.fullscreen
.values()
.any(|s| s == &mapped.active_window())
}
2023-01-18 20:23:41 +01:00
pub fn is_floating(&self, mapped: &CosmicMapped) -> bool {
!self
.fullscreen
.values()
.any(|s| s == &mapped.active_window())
&& self.floating_layer.mapped().any(|m| m == mapped)
}
pub fn is_tiled(&self, mapped: &CosmicMapped) -> bool {
!self
.fullscreen
.values()
.any(|s| s == &mapped.active_window())
&& self.tiling_layer.mapped().any(|(_, m, _)| m == mapped)
2023-01-18 20:23:41 +01:00
}
pub fn render_output<'a, R>(
2022-09-28 12:01:29 +02:00
&self,
renderer: &mut R,
2022-09-28 12:01:29 +02:00
output: &Output,
override_redirect_windows: &[X11Surface],
2023-03-07 20:28:41 +01:00
xwm_state: Option<&'a mut XWaylandState>,
2023-02-25 00:17:54 +01:00
draw_focus_indicator: Option<&Seat<State>>,
indicator_thickness: u8,
exclude_workspace_overview: bool,
2022-09-28 12:01:29 +02:00
) -> Result<Vec<WorkspaceRenderElement<R>>, OutputNotMapped>
where
R: Renderer + ImportAll + ImportMem + AsGlowRenderer,
2022-09-28 12:01:29 +02:00
<R as Renderer>::TextureId: 'static,
CosmicMappedRenderElement<R>: RenderElement<R>,
2023-03-07 22:20:44 +01:00
CosmicWindowRenderElement<R>: RenderElement<R>,
2022-09-28 12:01:29 +02:00
{
#[cfg(feature = "debug")]
puffin::profile_function!();
2022-09-28 12:01:29 +02:00
let mut render_elements = Vec::new();
let output_scale = output.current_scale().fractional_scale();
let layer_map = layer_map_for_output(output);
if let Some(fullscreen) = self.fullscreen.get(output) {
// overlay layer surfaces
render_elements.extend(
layer_map
.layers()
.rev()
.filter(|s| {
s.layer() == Layer::Overlay
&& !(exclude_workspace_overview
&& s.namespace() == WORKSPACE_OVERVIEW_NAMESPACE)
})
2022-09-28 12:01:29 +02:00
.filter_map(|surface| {
layer_map
.layer_geometry(surface)
.map(|geo| (geo.loc, surface))
})
.flat_map(|(loc, surface)| {
AsRenderElements::<R>::render_elements::<WorkspaceRenderElement<R>>(
surface,
renderer,
2022-09-28 12:01:29 +02:00
loc.to_physical_precise_round(output_scale),
Scale::from(output_scale),
)
}),
);
render_elements.extend(
override_redirect_windows
.iter()
.filter(|or| or.geometry().intersection(output.geometry()).is_some())
.flat_map(|or| {
AsRenderElements::<R>::render_elements::<WorkspaceRenderElement<R>>(
or,
renderer,
(or.geometry().loc - output.geometry().loc)
.to_physical_precise_round(output_scale),
Scale::from(output_scale),
)
}),
);
2022-09-28 12:01:29 +02:00
// fullscreen window
render_elements.extend(AsRenderElements::<R>::render_elements::<
WorkspaceRenderElement<R>,
>(
fullscreen, renderer, (0, 0).into(), output_scale.into()
));
2023-03-07 20:28:41 +01:00
if let Some(xwm) = xwm_state.and_then(|state| state.xwm.as_mut()) {
if let Err(err) =
xwm.update_stacking_order_upwards(render_elements.iter().rev().map(|e| e.id()))
{
warn!(
wm_id = ?xwm.id(),
?err,
"Failed to update Xwm stacking order.",
);
}
}
2022-09-28 12:01:29 +02:00
} else {
// TODO: Handle modes like
// - keyboard window swapping
// - resizing / moving in tiling
// overlay and top layer surfaces
let lower = {
2022-11-06 11:49:51 +01:00
let (lower, upper): (Vec<&LayerSurface>, Vec<&LayerSurface>) = layer_map
2022-09-28 12:01:29 +02:00
.layers()
.rev()
.filter(|s| {
!(exclude_workspace_overview
&& s.namespace() == "cosmic-workspace-overview")
})
2022-09-28 12:01:29 +02:00
.partition(|s| matches!(s.layer(), Layer::Background | Layer::Bottom));
render_elements.extend(
upper
.into_iter()
.filter_map(|surface| {
layer_map
.layer_geometry(surface)
.map(|geo| (geo.loc, surface))
})
.flat_map(|(loc, surface)| {
AsRenderElements::<R>::render_elements::<WorkspaceRenderElement<R>>(
surface,
renderer,
2022-09-28 12:01:29 +02:00
loc.to_physical_precise_round(output_scale),
Scale::from(output_scale),
)
}),
);
lower
};
2023-01-23 18:25:01 +01:00
// OR windows above all
render_elements.extend(
2023-01-23 18:25:01 +01:00
override_redirect_windows
.iter()
.filter(|or| or.geometry().intersection(output.geometry()).is_some())
2023-01-23 18:25:01 +01:00
.flat_map(|or| {
AsRenderElements::<R>::render_elements::<WorkspaceRenderElement<R>>(
or,
2023-01-23 18:25:01 +01:00
renderer,
(or.geometry().loc - output.geometry().loc)
2023-01-23 18:25:01 +01:00
.to_physical_precise_round(output_scale),
Scale::from(output_scale),
)
}),
);
2023-02-25 00:17:54 +01:00
let focused =
draw_focus_indicator.and_then(|seat| self.focus_stack.get(seat).last().cloned());
2022-09-28 12:01:29 +02:00
// floating surfaces
render_elements.extend(
2022-09-28 12:01:29 +02:00
self.floating_layer
.render_output::<R>(renderer, output, focused.as_ref(), indicator_thickness)
2022-09-28 12:01:29 +02:00
.into_iter()
.map(WorkspaceRenderElement::from),
);
//tiling surfaces
render_elements.extend(
2022-09-28 12:01:29 +02:00
self.tiling_layer
.render_output::<R>(renderer, output, focused.as_ref(), indicator_thickness)?
2022-09-28 12:01:29 +02:00
.into_iter()
.map(WorkspaceRenderElement::from),
);
2023-03-07 20:28:41 +01:00
if let Some(xwm) = xwm_state.and_then(|state| state.xwm.as_mut()) {
if let Err(err) =
xwm.update_stacking_order_upwards(render_elements.iter().rev().map(|e| e.id()))
{
warn!(
wm_id = ?xwm.id(),
?err,
"Failed to update Xwm stacking order.",
);
}
}
2022-09-28 12:01:29 +02:00
// bottom and background layer surfaces
{
render_elements.extend(
lower
.into_iter()
.filter_map(|surface| {
layer_map
.layer_geometry(surface)
.map(|geo| (geo.loc, surface))
})
.flat_map(|(loc, surface)| {
AsRenderElements::<R>::render_elements::<WorkspaceRenderElement<R>>(
surface,
renderer,
2022-09-28 12:01:29 +02:00
loc.to_physical_precise_round(output_scale),
Scale::from(output_scale),
)
}),
);
}
}
Ok(render_elements)
}
}
impl FocusStacks {
pub fn get<'a>(&'a self, seat: &Seat<State>) -> FocusStack<'a> {
FocusStack(self.0.get(seat))
}
pub fn get_mut<'a>(&'a mut self, seat: &Seat<State>) -> FocusStackMut<'a> {
FocusStackMut(self.0.entry(seat.clone()).or_default())
}
}
pub struct OutputNotMapped;
pub enum WorkspaceRenderElement<R>
where
R: Renderer + ImportAll + ImportMem + AsGlowRenderer,
<R as Renderer>::TextureId: 'static,
{
Wayland(WaylandSurfaceRenderElement<R>),
Window(CosmicMappedRenderElement<R>),
}
impl<R> Element for WorkspaceRenderElement<R>
where
R: Renderer + ImportAll + ImportMem + AsGlowRenderer,
<R as Renderer>::TextureId: 'static,
{
fn id(&self) -> &smithay::backend::renderer::element::Id {
match self {
WorkspaceRenderElement::Wayland(elem) => elem.id(),
WorkspaceRenderElement::Window(elem) => elem.id(),
}
}
fn current_commit(&self) -> smithay::backend::renderer::utils::CommitCounter {
match self {
WorkspaceRenderElement::Wayland(elem) => elem.current_commit(),
WorkspaceRenderElement::Window(elem) => elem.current_commit(),
}
}
fn src(&self) -> Rectangle<f64, smithay::utils::Buffer> {
match self {
WorkspaceRenderElement::Wayland(elem) => elem.src(),
WorkspaceRenderElement::Window(elem) => elem.src(),
}
}
fn geometry(&self, scale: Scale<f64>) -> Rectangle<i32, smithay::utils::Physical> {
match self {
WorkspaceRenderElement::Wayland(elem) => elem.geometry(scale),
WorkspaceRenderElement::Window(elem) => elem.geometry(scale),
}
}
fn location(&self, scale: Scale<f64>) -> Point<i32, smithay::utils::Physical> {
match self {
WorkspaceRenderElement::Wayland(elem) => elem.location(scale),
WorkspaceRenderElement::Window(elem) => elem.location(scale),
}
}
fn transform(&self) -> smithay::utils::Transform {
match self {
WorkspaceRenderElement::Wayland(elem) => elem.transform(),
WorkspaceRenderElement::Window(elem) => elem.transform(),
}
}
fn damage_since(
&self,
scale: Scale<f64>,
commit: Option<smithay::backend::renderer::utils::CommitCounter>,
) -> Vec<Rectangle<i32, smithay::utils::Physical>> {
match self {
WorkspaceRenderElement::Wayland(elem) => elem.damage_since(scale, commit),
WorkspaceRenderElement::Window(elem) => elem.damage_since(scale, commit),
}
}
fn opaque_regions(&self, scale: Scale<f64>) -> Vec<Rectangle<i32, smithay::utils::Physical>> {
match self {
WorkspaceRenderElement::Wayland(elem) => elem.opaque_regions(scale),
WorkspaceRenderElement::Window(elem) => elem.opaque_regions(scale),
}
}
}
impl<R> RenderElement<R> for WorkspaceRenderElement<R>
where
R: Renderer + ImportAll + ImportMem + AsGlowRenderer,
<R as Renderer>::TextureId: 'static,
CosmicMappedRenderElement<R>: RenderElement<R>,
{
fn draw<'frame>(
&self,
frame: &mut <R as Renderer>::Frame<'frame>,
2022-12-27 18:27:29 +01:00
src: Rectangle<f64, BufferCoords>,
dst: Rectangle<i32, Physical>,
damage: &[Rectangle<i32, smithay::utils::Physical>],
) -> Result<(), <R as Renderer>::Error> {
match self {
WorkspaceRenderElement::Wayland(elem) => elem.draw(frame, src, dst, damage),
WorkspaceRenderElement::Window(elem) => elem.draw(frame, src, dst, damage),
}
}
fn underlying_storage(
&self,
2023-02-24 14:07:40 +01:00
renderer: &mut R,
) -> Option<smithay::backend::renderer::element::UnderlyingStorage> {
match self {
WorkspaceRenderElement::Wayland(elem) => elem.underlying_storage(renderer),
WorkspaceRenderElement::Window(elem) => elem.underlying_storage(renderer),
}
}
}
impl<R> From<WaylandSurfaceRenderElement<R>> for WorkspaceRenderElement<R>
where
R: Renderer + ImportAll + ImportMem + AsGlowRenderer,
<R as Renderer>::TextureId: 'static,
CosmicMappedRenderElement<R>: RenderElement<R>,
{
fn from(elem: WaylandSurfaceRenderElement<R>) -> Self {
WorkspaceRenderElement::Wayland(elem)
}
}
impl<R> From<CosmicMappedRenderElement<R>> for WorkspaceRenderElement<R>
where
R: Renderer + ImportAll + ImportMem + AsGlowRenderer,
<R as Renderer>::TextureId: 'static,
CosmicMappedRenderElement<R>: RenderElement<R>,
{
fn from(elem: CosmicMappedRenderElement<R>) -> Self {
WorkspaceRenderElement::Window(elem)
}
2022-03-24 20:32:31 +01:00
}