tiling: Animate tree changes

This commit is contained in:
Victoria Brekenfeld 2023-05-12 20:01:37 +02:00
parent ea1b976076
commit 331b884f1e
23 changed files with 1641 additions and 395 deletions

959
Cargo.lock generated

File diff suppressed because it is too large Load diff

View file

@ -22,7 +22,6 @@ log-panics = { version = "2", features = ["with-backtrace"] }
thiserror = "1.0.26" thiserror = "1.0.26"
regex = "1" regex = "1"
xcursor = "0.3.3" xcursor = "0.3.3"
id_tree = "1.8.0"
xkbcommon = "0.4" xkbcommon = "0.4"
indexmap = "1.8.0" indexmap = "1.8.0"
xdg = "^2.1" xdg = "^2.1"
@ -40,6 +39,11 @@ tracing-journald = "0.3.0"
tracing = { version = "0.1.37", features = ["max_level_debug", "release_max_level_info"] } tracing = { version = "0.1.37", features = ["max_level_debug", "release_max_level_info"] }
puffin = { version = "0.14.3", optional = true } puffin = { version = "0.14.3", optional = true }
puffin_egui = { version = "0.21.0", optional = true } puffin_egui = { version = "0.21.0", optional = true }
cosmic-time = "0.2.0"
[dependencies.id_tree]
git = "https://github.com/Drakulix/id-tree.git"
branch = "feature/copy_clone"
[dependencies.smithay] [dependencies.smithay]
version = "0.3" version = "0.3"
@ -70,4 +74,4 @@ debug = true
lto = "fat" lto = "fat"
[patch."https://github.com/Smithay/smithay.git"] [patch."https://github.com/Smithay/smithay.git"]
smithay = { git = "https://github.com/smithay//smithay", rev = "25d1176484" } smithay = { git = "https://github.com/pop-os/smithay", branch = "tiling_rework" }

View file

@ -485,7 +485,9 @@ impl State {
} }
surface.pending = false; surface.pending = false;
surface.dirty.then(|| { (surface.dirty
|| data.state.common.shell.animations_going())
.then(|| {
(surface.output.clone(), surface.fps.avg_rendertime(5)) (surface.output.clone(), surface.fps.avg_rendertime(5))
}) })
} }

View file

@ -162,6 +162,7 @@ where
surface, surface,
position.to_physical_precise_round(scale), position.to_physical_precise_round(scale),
scale, scale,
1.0,
) )
} }
@ -190,6 +191,7 @@ where
surface, surface,
location.into().to_physical_precise_round(scale), location.into().to_physical_precise_round(scale),
scale, scale,
1.0,
) )
} }

View file

@ -118,6 +118,16 @@ where
CosmicElement::Egui(elem) => elem.opaque_regions(scale), CosmicElement::Egui(elem) => elem.opaque_regions(scale),
} }
} }
fn alpha(&self) -> f32 {
match self {
CosmicElement::Workspace(elem) => elem.alpha(),
CosmicElement::Cursor(elem) => elem.alpha(),
CosmicElement::MoveGrab(elem) => elem.alpha(),
#[cfg(feature = "debug")]
CosmicElement::Egui(elem) => elem.alpha(),
}
}
} }
impl RenderElement<GlowRenderer> for CosmicElement<GlowRenderer> { impl RenderElement<GlowRenderer> for CosmicElement<GlowRenderer> {

View file

@ -66,7 +66,7 @@ pub type GlMultiFrame<'a, 'b, 'frame> =
MultiFrame<'a, 'a, 'b, 'frame, GbmGlesBackend<GlowRenderer>, GbmGlesBackend<GlowRenderer>>; MultiFrame<'a, 'a, 'b, 'frame, GbmGlesBackend<GlowRenderer>, GbmGlesBackend<GlowRenderer>>;
pub static CLEAR_COLOR: [f32; 4] = [0.153, 0.161, 0.165, 1.0]; pub static CLEAR_COLOR: [f32; 4] = [0.153, 0.161, 0.165, 1.0];
pub static FOCUS_INDICATOR_COLOR: [f32; 4] = [0.580, 0.921, 0.921, 1.0]; pub static FOCUS_INDICATOR_COLOR: [f32; 3] = [0.580, 0.921, 0.921];
pub static FOCUS_INDICATOR_SHADER: &str = include_str!("./shaders/focus_indicator.frag"); pub static FOCUS_INDICATOR_SHADER: &str = include_str!("./shaders/focus_indicator.frag");
pub struct IndicatorShader(pub GlesPixelProgram); pub struct IndicatorShader(pub GlesPixelProgram);
@ -87,6 +87,7 @@ impl IndicatorShader {
renderer: &R, renderer: &R,
geo: Rectangle<i32, Logical>, geo: Rectangle<i32, Logical>,
thickness: u8, thickness: u8,
alpha: f32,
) -> PixelShaderElement { ) -> PixelShaderElement {
let thickness: f32 = thickness as f32; let thickness: f32 = thickness as f32;
let thickness_loc = (thickness as i32, thickness as i32); let thickness_loc = (thickness as i32, thickness as i32);
@ -110,15 +111,14 @@ impl IndicatorShader {
} }
None => { None => {
let shader = Self::get(renderer); let shader = Self::get(renderer);
let color = FOCUS_INDICATOR_COLOR;
let elem = PixelShaderElement::new( let elem = PixelShaderElement::new(
shader, shader,
dbg!(geo), geo,
None, //TODO None, //TODO
color[3], alpha,
vec![ vec![
Uniform::new("color", [color[0], color[1], color[2]]), Uniform::new("color", FOCUS_INDICATOR_COLOR),
Uniform::new("thickness", thickness), Uniform::new("thickness", thickness),
Uniform::new("radius", thickness * 2.0), Uniform::new("radius", thickness * 2.0),
], ],
@ -283,6 +283,11 @@ where
} }
} }
state
.shell
.space_for_handle_mut(&handle)
.ok_or(OutputNoMode)?
.update_animations(&state.event_loop_handle);
let workspace = state.shell.space_for_handle(&handle).ok_or(OutputNoMode)?; let workspace = state.shell.space_for_handle(&handle).ok_or(OutputNoMode)?;
let last_active_seat = state.last_active_seat().clone(); let last_active_seat = state.last_active_seat().clone();
let move_active = last_active_seat let move_active = last_active_seat

View file

@ -95,7 +95,7 @@ impl WinitState {
.unwrap_or_default(), .unwrap_or_default(),
0, 0,
wp_presentation_feedback::Kind::Vsync, wp_presentation_feedback::Kind::Vsync,
) );
} }
} }
Err(err) => { Err(err) => {

View file

@ -66,6 +66,10 @@ fn main() -> Result<()> {
} }
// trigger routines // trigger routines
data.state
.common
.shell
.update_animations(&data.state.common.event_loop_handle);
data.state.common.shell.refresh(); data.state.common.shell.refresh();
state::Common::refresh_focus(&mut data.state); state::Common::refresh_focus(&mut data.state);

View file

@ -11,7 +11,10 @@ use smithay::{
backend::{ backend::{
input::KeyState, input::KeyState,
renderer::{ renderer::{
element::{AsRenderElements, Element, RenderElement, UnderlyingStorage}, element::{
utils::CropRenderElement, AsRenderElements, Element, RenderElement,
UnderlyingStorage,
},
gles::element::PixelShaderElement, gles::element::PixelShaderElement,
glow::GlowRenderer, glow::GlowRenderer,
multigpu::Error as MultiError, multigpu::Error as MultiError,
@ -418,15 +421,17 @@ impl CosmicMapped {
} }
} }
pub fn configure(&self) { pub fn configure(&self) -> Option<Serial> {
for window in match &self.element { match &self.element {
CosmicMappedInternal::Stack(s) => { CosmicMappedInternal::Stack(s) => {
Box::new(s.surfaces()) as Box<dyn Iterator<Item = CosmicSurface>> let active = s.active();
for surface in s.surfaces().filter(|s| s != &active) {
surface.send_configure();
}
active.send_configure()
} }
CosmicMappedInternal::Window(w) => Box::new(std::iter::once(w.surface())), CosmicMappedInternal::Window(w) => w.surface().send_configure(),
_ => unreachable!(), _ => unreachable!(),
} {
window.send_configure();
} }
} }
@ -676,6 +681,8 @@ where
{ {
Stack(self::stack::CosmicStackRenderElement<R>), Stack(self::stack::CosmicStackRenderElement<R>),
Window(self::window::CosmicWindowRenderElement<R>), Window(self::window::CosmicWindowRenderElement<R>),
CroppedStack(CropRenderElement<self::stack::CosmicStackRenderElement<R>>),
CroppedWindow(CropRenderElement<self::window::CosmicWindowRenderElement<R>>),
Indicator(PixelShaderElement), Indicator(PixelShaderElement),
#[cfg(feature = "debug")] #[cfg(feature = "debug")]
Egui(TextureRenderElement<GlesTexture>), Egui(TextureRenderElement<GlesTexture>),
@ -690,6 +697,8 @@ where
match self { match self {
CosmicMappedRenderElement::Stack(elem) => elem.id(), CosmicMappedRenderElement::Stack(elem) => elem.id(),
CosmicMappedRenderElement::Window(elem) => elem.id(), CosmicMappedRenderElement::Window(elem) => elem.id(),
CosmicMappedRenderElement::CroppedStack(elem) => elem.id(),
CosmicMappedRenderElement::CroppedWindow(elem) => elem.id(),
CosmicMappedRenderElement::Indicator(elem) => elem.id(), CosmicMappedRenderElement::Indicator(elem) => elem.id(),
#[cfg(feature = "debug")] #[cfg(feature = "debug")]
CosmicMappedRenderElement::Egui(elem) => elem.id(), CosmicMappedRenderElement::Egui(elem) => elem.id(),
@ -700,6 +709,8 @@ where
match self { match self {
CosmicMappedRenderElement::Stack(elem) => elem.current_commit(), CosmicMappedRenderElement::Stack(elem) => elem.current_commit(),
CosmicMappedRenderElement::Window(elem) => elem.current_commit(), CosmicMappedRenderElement::Window(elem) => elem.current_commit(),
CosmicMappedRenderElement::CroppedStack(elem) => elem.current_commit(),
CosmicMappedRenderElement::CroppedWindow(elem) => elem.current_commit(),
CosmicMappedRenderElement::Indicator(elem) => elem.current_commit(), CosmicMappedRenderElement::Indicator(elem) => elem.current_commit(),
#[cfg(feature = "debug")] #[cfg(feature = "debug")]
CosmicMappedRenderElement::Egui(elem) => elem.current_commit(), CosmicMappedRenderElement::Egui(elem) => elem.current_commit(),
@ -710,6 +721,8 @@ where
match self { match self {
CosmicMappedRenderElement::Stack(elem) => elem.src(), CosmicMappedRenderElement::Stack(elem) => elem.src(),
CosmicMappedRenderElement::Window(elem) => elem.src(), CosmicMappedRenderElement::Window(elem) => elem.src(),
CosmicMappedRenderElement::CroppedStack(elem) => elem.src(),
CosmicMappedRenderElement::CroppedWindow(elem) => elem.src(),
CosmicMappedRenderElement::Indicator(elem) => elem.src(), CosmicMappedRenderElement::Indicator(elem) => elem.src(),
#[cfg(feature = "debug")] #[cfg(feature = "debug")]
CosmicMappedRenderElement::Egui(elem) => elem.src(), CosmicMappedRenderElement::Egui(elem) => elem.src(),
@ -720,6 +733,8 @@ where
match self { match self {
CosmicMappedRenderElement::Stack(elem) => elem.geometry(scale), CosmicMappedRenderElement::Stack(elem) => elem.geometry(scale),
CosmicMappedRenderElement::Window(elem) => elem.geometry(scale), CosmicMappedRenderElement::Window(elem) => elem.geometry(scale),
CosmicMappedRenderElement::CroppedStack(elem) => elem.geometry(scale),
CosmicMappedRenderElement::CroppedWindow(elem) => elem.geometry(scale),
CosmicMappedRenderElement::Indicator(elem) => elem.geometry(scale), CosmicMappedRenderElement::Indicator(elem) => elem.geometry(scale),
#[cfg(feature = "debug")] #[cfg(feature = "debug")]
CosmicMappedRenderElement::Egui(elem) => elem.geometry(scale), CosmicMappedRenderElement::Egui(elem) => elem.geometry(scale),
@ -730,6 +745,8 @@ where
match self { match self {
CosmicMappedRenderElement::Stack(elem) => elem.location(scale), CosmicMappedRenderElement::Stack(elem) => elem.location(scale),
CosmicMappedRenderElement::Window(elem) => elem.location(scale), CosmicMappedRenderElement::Window(elem) => elem.location(scale),
CosmicMappedRenderElement::CroppedStack(elem) => elem.location(scale),
CosmicMappedRenderElement::CroppedWindow(elem) => elem.location(scale),
CosmicMappedRenderElement::Indicator(elem) => elem.location(scale), CosmicMappedRenderElement::Indicator(elem) => elem.location(scale),
#[cfg(feature = "debug")] #[cfg(feature = "debug")]
CosmicMappedRenderElement::Egui(elem) => elem.location(scale), CosmicMappedRenderElement::Egui(elem) => elem.location(scale),
@ -740,6 +757,8 @@ where
match self { match self {
CosmicMappedRenderElement::Stack(elem) => elem.transform(), CosmicMappedRenderElement::Stack(elem) => elem.transform(),
CosmicMappedRenderElement::Window(elem) => elem.transform(), CosmicMappedRenderElement::Window(elem) => elem.transform(),
CosmicMappedRenderElement::CroppedStack(elem) => elem.transform(),
CosmicMappedRenderElement::CroppedWindow(elem) => elem.transform(),
CosmicMappedRenderElement::Indicator(elem) => elem.transform(), CosmicMappedRenderElement::Indicator(elem) => elem.transform(),
#[cfg(feature = "debug")] #[cfg(feature = "debug")]
CosmicMappedRenderElement::Egui(elem) => elem.transform(), CosmicMappedRenderElement::Egui(elem) => elem.transform(),
@ -754,6 +773,8 @@ where
match self { match self {
CosmicMappedRenderElement::Stack(elem) => elem.damage_since(scale, commit), CosmicMappedRenderElement::Stack(elem) => elem.damage_since(scale, commit),
CosmicMappedRenderElement::Window(elem) => elem.damage_since(scale, commit), CosmicMappedRenderElement::Window(elem) => elem.damage_since(scale, commit),
CosmicMappedRenderElement::CroppedStack(elem) => elem.damage_since(scale, commit),
CosmicMappedRenderElement::CroppedWindow(elem) => elem.damage_since(scale, commit),
CosmicMappedRenderElement::Indicator(elem) => elem.damage_since(scale, commit), CosmicMappedRenderElement::Indicator(elem) => elem.damage_since(scale, commit),
#[cfg(feature = "debug")] #[cfg(feature = "debug")]
CosmicMappedRenderElement::Egui(elem) => elem.damage_since(scale, commit), CosmicMappedRenderElement::Egui(elem) => elem.damage_since(scale, commit),
@ -764,11 +785,25 @@ where
match self { match self {
CosmicMappedRenderElement::Stack(elem) => elem.opaque_regions(scale), CosmicMappedRenderElement::Stack(elem) => elem.opaque_regions(scale),
CosmicMappedRenderElement::Window(elem) => elem.opaque_regions(scale), CosmicMappedRenderElement::Window(elem) => elem.opaque_regions(scale),
CosmicMappedRenderElement::CroppedStack(elem) => elem.opaque_regions(scale),
CosmicMappedRenderElement::CroppedWindow(elem) => elem.opaque_regions(scale),
CosmicMappedRenderElement::Indicator(elem) => elem.opaque_regions(scale), CosmicMappedRenderElement::Indicator(elem) => elem.opaque_regions(scale),
#[cfg(feature = "debug")] #[cfg(feature = "debug")]
CosmicMappedRenderElement::Egui(elem) => elem.opaque_regions(scale), CosmicMappedRenderElement::Egui(elem) => elem.opaque_regions(scale),
} }
} }
fn alpha(&self) -> f32 {
match self {
CosmicMappedRenderElement::Stack(elem) => elem.alpha(),
CosmicMappedRenderElement::Window(elem) => elem.alpha(),
CosmicMappedRenderElement::CroppedStack(elem) => elem.alpha(),
CosmicMappedRenderElement::CroppedWindow(elem) => elem.alpha(),
CosmicMappedRenderElement::Indicator(elem) => elem.alpha(),
#[cfg(feature = "debug")]
CosmicMappedRenderElement::Egui(elem) => elem.alpha(),
}
}
} }
impl RenderElement<GlowRenderer> for CosmicMappedRenderElement<GlowRenderer> { impl RenderElement<GlowRenderer> for CosmicMappedRenderElement<GlowRenderer> {
@ -782,6 +817,8 @@ impl RenderElement<GlowRenderer> for CosmicMappedRenderElement<GlowRenderer> {
match self { match self {
CosmicMappedRenderElement::Stack(elem) => elem.draw(frame, src, dst, damage), CosmicMappedRenderElement::Stack(elem) => elem.draw(frame, src, dst, damage),
CosmicMappedRenderElement::Window(elem) => elem.draw(frame, src, dst, damage), CosmicMappedRenderElement::Window(elem) => elem.draw(frame, src, dst, damage),
CosmicMappedRenderElement::CroppedStack(elem) => elem.draw(frame, src, dst, damage),
CosmicMappedRenderElement::CroppedWindow(elem) => elem.draw(frame, src, dst, damage),
CosmicMappedRenderElement::Indicator(elem) => { CosmicMappedRenderElement::Indicator(elem) => {
RenderElement::<GlowRenderer>::draw(elem, frame, src, dst, damage) RenderElement::<GlowRenderer>::draw(elem, frame, src, dst, damage)
} }
@ -796,6 +833,8 @@ impl RenderElement<GlowRenderer> for CosmicMappedRenderElement<GlowRenderer> {
match self { match self {
CosmicMappedRenderElement::Stack(elem) => elem.underlying_storage(renderer), CosmicMappedRenderElement::Stack(elem) => elem.underlying_storage(renderer),
CosmicMappedRenderElement::Window(elem) => elem.underlying_storage(renderer), CosmicMappedRenderElement::Window(elem) => elem.underlying_storage(renderer),
CosmicMappedRenderElement::CroppedStack(elem) => elem.underlying_storage(renderer),
CosmicMappedRenderElement::CroppedWindow(elem) => elem.underlying_storage(renderer),
CosmicMappedRenderElement::Indicator(elem) => elem.underlying_storage(renderer), CosmicMappedRenderElement::Indicator(elem) => elem.underlying_storage(renderer),
#[cfg(feature = "debug")] #[cfg(feature = "debug")]
CosmicMappedRenderElement::Egui(elem) => elem.underlying_storage(renderer), CosmicMappedRenderElement::Egui(elem) => elem.underlying_storage(renderer),
@ -816,6 +855,8 @@ impl<'a, 'b> RenderElement<GlMultiRenderer<'a, 'b>>
match self { match self {
CosmicMappedRenderElement::Stack(elem) => elem.draw(frame, src, dst, damage), CosmicMappedRenderElement::Stack(elem) => elem.draw(frame, src, dst, damage),
CosmicMappedRenderElement::Window(elem) => elem.draw(frame, src, dst, damage), CosmicMappedRenderElement::Window(elem) => elem.draw(frame, src, dst, damage),
CosmicMappedRenderElement::CroppedStack(elem) => elem.draw(frame, src, dst, damage),
CosmicMappedRenderElement::CroppedWindow(elem) => elem.draw(frame, src, dst, damage),
CosmicMappedRenderElement::Indicator(elem) => { CosmicMappedRenderElement::Indicator(elem) => {
RenderElement::<GlowRenderer>::draw(elem, frame.glow_frame_mut(), src, dst, damage) RenderElement::<GlowRenderer>::draw(elem, frame.glow_frame_mut(), src, dst, damage)
.map_err(|err| MultiError::Render(err)) .map_err(|err| MultiError::Render(err))
@ -836,6 +877,8 @@ impl<'a, 'b> RenderElement<GlMultiRenderer<'a, 'b>>
match self { match self {
CosmicMappedRenderElement::Stack(elem) => elem.underlying_storage(renderer), CosmicMappedRenderElement::Stack(elem) => elem.underlying_storage(renderer),
CosmicMappedRenderElement::Window(elem) => elem.underlying_storage(renderer), CosmicMappedRenderElement::Window(elem) => elem.underlying_storage(renderer),
CosmicMappedRenderElement::CroppedStack(elem) => elem.underlying_storage(renderer),
CosmicMappedRenderElement::CroppedWindow(elem) => elem.underlying_storage(renderer),
CosmicMappedRenderElement::Indicator(elem) => { CosmicMappedRenderElement::Indicator(elem) => {
elem.underlying_storage(renderer.glow_renderer_mut()) elem.underlying_storage(renderer.glow_renderer_mut())
} }
@ -910,6 +953,7 @@ where
renderer: &mut R, renderer: &mut R,
location: Point<i32, Physical>, location: Point<i32, Physical>,
scale: Scale<f64>, scale: Scale<f64>,
alpha: f32,
) -> Vec<C> { ) -> Vec<C> {
#[cfg(feature = "debug")] #[cfg(feature = "debug")]
let mut elements = if let Some(debug) = self.debug.lock().unwrap().as_mut() { let mut elements = if let Some(debug) = self.debug.lock().unwrap().as_mut() {
@ -1080,12 +1124,12 @@ where
CosmicMappedInternal::Stack(s) => { CosmicMappedInternal::Stack(s) => {
elements.extend(AsRenderElements::<R>::render_elements::< elements.extend(AsRenderElements::<R>::render_elements::<
CosmicMappedRenderElement<R>, CosmicMappedRenderElement<R>,
>(s, renderer, location, scale)) >(s, renderer, location, scale, alpha))
} }
CosmicMappedInternal::Window(w) => { CosmicMappedInternal::Window(w) => {
elements.extend(AsRenderElements::<R>::render_elements::< elements.extend(AsRenderElements::<R>::render_elements::<
CosmicMappedRenderElement<R>, CosmicMappedRenderElement<R>,
>(w, renderer, location, scale)) >(w, renderer, location, scale, alpha))
} }
_ => {} _ => {}
}; };

View file

@ -604,9 +604,10 @@ where
renderer: &mut R, renderer: &mut R,
mut location: Point<i32, Physical>, mut location: Point<i32, Physical>,
scale: Scale<f64>, scale: Scale<f64>,
alpha: f32,
) -> Vec<C> { ) -> Vec<C> {
let mut elements = AsRenderElements::<R>::render_elements::<CosmicStackRenderElement<R>>( let mut elements = AsRenderElements::<R>::render_elements::<CosmicStackRenderElement<R>>(
&self.0, renderer, location, scale, &self.0, renderer, location, scale, alpha,
); );
location.y += TAB_HEIGHT; location.y += TAB_HEIGHT;
@ -616,6 +617,7 @@ where
renderer, renderer,
location, location,
scale, scale,
alpha,
); );
elements elements
})); }));

View file

@ -29,7 +29,7 @@ use smithay::{
wayland_server::protocol::wl_surface::WlSurface, wayland_server::protocol::wl_surface::WlSurface,
}, },
space_elements, space_elements,
utils::{user_data::UserDataMap, Logical, Rectangle, Size}, utils::{user_data::UserDataMap, Logical, Rectangle, Serial, Size},
wayland::{ wayland::{
compositor::{with_states, SurfaceData}, compositor::{with_states, SurfaceData},
seat::WaylandFocus, seat::WaylandFocus,
@ -345,11 +345,44 @@ impl CosmicSurface {
}) })
} }
pub fn send_configure(&self) { pub fn serial_acked(&self, serial: &Serial) -> bool {
match self { match self {
CosmicSurface::Wayland(window) => window.toplevel().send_configure(), CosmicSurface::Wayland(window) => {
with_states(window.toplevel().wl_surface(), |states| {
let attrs = states
.data_map
.get::<XdgToplevelSurfaceData>()
.unwrap()
.lock()
.unwrap();
attrs
.configure_serial
.as_ref()
.map(|s| s >= serial)
.unwrap_or(false)
})
}
_ => true,
}
}
pub fn force_configure(&self) -> Option<Serial> {
match self {
CosmicSurface::Wayland(window) => Some(window.toplevel().send_configure()),
CosmicSurface::X11(surface) => { CosmicSurface::X11(surface) => {
let _ = surface.configure(None); let _ = surface.configure(None);
None
}
_ => unreachable!(),
}
}
pub fn send_configure(&self) -> Option<Serial> {
match self {
CosmicSurface::Wayland(window) => window.toplevel().send_pending_configure(),
CosmicSurface::X11(surface) => {
let _ = surface.configure(None);
None
} }
_ => unreachable!(), _ => unreachable!(),
} }
@ -675,10 +708,15 @@ where
renderer: &mut R, renderer: &mut R,
location: smithay::utils::Point<i32, smithay::utils::Physical>, location: smithay::utils::Point<i32, smithay::utils::Physical>,
scale: smithay::utils::Scale<f64>, scale: smithay::utils::Scale<f64>,
alpha: f32,
) -> Vec<C> { ) -> Vec<C> {
match self { match self {
CosmicSurface::Wayland(window) => window.render_elements(renderer, location, scale), CosmicSurface::Wayland(window) => {
CosmicSurface::X11(surface) => surface.render_elements(renderer, location, scale), window.render_elements(renderer, location, scale, alpha)
}
CosmicSurface::X11(surface) => {
surface.render_elements(renderer, location, scale, alpha)
}
_ => unreachable!(), _ => unreachable!(),
} }
} }

View file

@ -640,6 +640,13 @@ where
CosmicWindowRenderElement::Window(w) => w.opaque_regions(scale), CosmicWindowRenderElement::Window(w) => w.opaque_regions(scale),
} }
} }
fn alpha(&self) -> f32 {
match self {
CosmicWindowRenderElement::Header(h) => h.alpha(),
CosmicWindowRenderElement::Window(w) => w.alpha(),
}
}
} }
impl RenderElement<GlowRenderer> for CosmicWindowRenderElement<GlowRenderer> { impl RenderElement<GlowRenderer> for CosmicWindowRenderElement<GlowRenderer> {
@ -710,6 +717,7 @@ where
renderer: &mut R, renderer: &mut R,
location: Point<i32, Physical>, location: Point<i32, Physical>,
scale: Scale<f64>, scale: Scale<f64>,
alpha: f32,
) -> Vec<C> { ) -> Vec<C> {
let has_ssd = self.0.with_program(|p| p.has_ssd()); let has_ssd = self.0.with_program(|p| p.has_ssd());
@ -721,14 +729,18 @@ where
let mut elements = self.0.with_program(|p| { let mut elements = self.0.with_program(|p| {
AsRenderElements::<R>::render_elements::<CosmicWindowRenderElement<R>>( AsRenderElements::<R>::render_elements::<CosmicWindowRenderElement<R>>(
&p.window, renderer, window_loc, scale, &p.window, renderer, window_loc, scale, alpha,
) )
}); });
if has_ssd { if has_ssd {
elements.extend(AsRenderElements::<GlowRenderer>::render_elements::< elements.extend(AsRenderElements::<GlowRenderer>::render_elements::<
CosmicWindowRenderElement<R>, CosmicWindowRenderElement<R>,
>( >(
&self.0, renderer.glow_renderer_mut(), location, scale &self.0,
renderer.glow_renderer_mut(),
location,
scale,
alpha,
)) ))
} }

View file

@ -68,6 +68,7 @@ impl MoveGrabState {
renderer, renderer,
Rectangle::from_loc_and_size(render_location, self.window.geometry().size), Rectangle::from_loc_and_size(render_location, self.window.geometry().size),
self.indicator_thickness, self.indicator_thickness,
1.0,
)) ))
.into(), .into(),
); );
@ -77,6 +78,7 @@ impl MoveGrabState {
renderer, renderer,
(render_location - self.window.geometry().loc).to_physical_precise_round(scale), (render_location - self.window.geometry().loc).to_physical_precise_round(scale),
scale, scale,
1.0,
)); ));
elements elements
} }
@ -266,7 +268,7 @@ impl MoveSurfaceGrab {
.active_space_mut(&output) .active_space_mut(&output)
.floating_layer .floating_layer
.map_internal(grab_state.window, &output, Some(window_location + offset)); .map_internal(grab_state.window, &output, Some(window_location + offset));
let pointer_pos = handle.current_location(); let pointer_pos = handle.current_location();
let relative_pos = state.common.shell.map_global_to_space(pointer_pos, &output); let relative_pos = state.common.shell.map_global_to_space(pointer_pos, &output);
Some(window_location + offset + (pointer_pos - relative_pos).to_i32_round()) Some(window_location + offset + (pointer_pos - relative_pos).to_i32_round())
@ -282,7 +284,10 @@ impl MoveSurfaceGrab {
if let Some(position) = position { if let Some(position) = position {
handle.motion( handle.motion(
state, state,
Some((PointerFocusTarget::from(self.window.clone()), position - self.window.geometry().loc)), Some((
PointerFocusTarget::from(self.window.clone()),
position - self.window.geometry().loc,
)),
&MotionEvent { &MotionEvent {
location: handle.current_location(), location: handle.current_location(),
serial: serial, serial: serial,

View file

@ -374,6 +374,7 @@ impl FloatingLayout {
renderer, renderer,
render_location.to_physical_precise_round(output_scale), render_location.to_physical_precise_round(output_scale),
output_scale.into(), output_scale.into(),
1.0,
); );
if focused == Some(elem) { if focused == Some(elem) {
if indicator_thickness > 0 { if indicator_thickness > 0 {
@ -384,6 +385,7 @@ impl FloatingLayout {
elem.geometry().size, elem.geometry().size,
), ),
indicator_thickness, indicator_thickness,
1.0,
); );
elements.insert(0, element.into()); elements.insert(0, element.into());
} }

View file

@ -0,0 +1,65 @@
use crate::{
shell::element::CosmicSurface, state::Data,
wayland::handlers::compositor::client_compositor_state,
};
use calloop::LoopHandle;
use smithay::{
reexports::wayland_server::{backend::ClientId, Client, Resource},
utils::Serial,
wayland::{
compositor::{Blocker, BlockerState},
seat::WaylandFocus,
},
};
use std::{
collections::HashMap,
time::{Duration, Instant},
};
#[derive(Debug, Clone)]
pub struct TilingBlocker {
pub necessary_acks: Vec<(CosmicSurface, Serial)>,
start: Instant,
}
impl Blocker for TilingBlocker {
fn state(&self) -> BlockerState {
if self.is_ready() {
BlockerState::Released
} else {
BlockerState::Pending
}
}
}
impl TilingBlocker {
pub fn new(configures: impl IntoIterator<Item = (CosmicSurface, Serial)>) -> Self {
TilingBlocker {
necessary_acks: configures.into_iter().collect(),
start: Instant::now(),
}
}
pub fn is_ready(&self) -> bool {
Instant::now().duration_since(self.start) >= Duration::from_millis(200)
|| self
.necessary_acks
.iter()
.all(|(surf, serial)| surf.serial_acked(serial))
}
pub fn signal_ready(&self, handle: &LoopHandle<'static, Data>) {
let clients = self
.necessary_acks
.iter()
.flat_map(|(surface, _)| surface.wl_surface().and_then(|s| s.client()))
.map(|client| (client.id(), client))
.collect::<HashMap<ClientId, Client>>();
handle.insert_idle(move |data| {
let dh = data.display.handle();
for client in clients.values() {
client_compositor_state(&client).blocker_cleared(&mut data.state, &dh);
}
});
}
}

View file

@ -64,7 +64,8 @@ impl PointerGrab<State> for ResizeForkGrab {
if let Some(output) = self.output.upgrade() { if let Some(output) = self.output.upgrade() {
let tiling_layer = &mut data.common.shell.active_space_mut(&output).tiling_layer; let tiling_layer = &mut data.common.shell.active_space_mut(&output).tiling_layer;
if let Some(tree) = tiling_layer.trees.get_mut(&output) { if let Some(queue) = tiling_layer.queues.get_mut(&output) {
let tree = &mut queue.trees.back_mut().unwrap().0;
if tree.get(&self.node).is_ok() { if tree.get(&self.node).is_ok() {
let orientation = tree.get(&self.node).unwrap().data().orientation(); let orientation = tree.get(&self.node).unwrap().data().orientation();
let delta = match orientation { let delta = match orientation {

File diff suppressed because it is too large Load diff

View file

@ -1,3 +1,4 @@
use calloop::LoopHandle;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::{cell::RefCell, collections::HashMap}; use std::{cell::RefCell, collections::HashMap};
use tracing::warn; use tracing::warn;
@ -1036,6 +1037,18 @@ impl Shell {
} }
} }
pub fn animations_going(&self) -> bool {
self.workspaces
.spaces()
.any(|workspace| workspace.animations_going())
}
pub fn update_animations(&mut self, handle: &LoopHandle<'static, crate::state::Data>) {
for workspace in self.workspaces.spaces_mut() {
workspace.update_animations(handle)
}
}
pub fn refresh(&mut self) { pub fn refresh(&mut self) {
#[cfg(feature = "debug")] #[cfg(feature = "debug")]
puffin::profile_function!(); puffin::profile_function!();

View file

@ -17,6 +17,7 @@ use crate::{
xwayland::XWaylandState, xwayland::XWaylandState,
}; };
use calloop::LoopHandle;
use indexmap::IndexSet; use indexmap::IndexSet;
use smithay::{ use smithay::{
backend::renderer::{ backend::renderer::{
@ -85,6 +86,14 @@ impl Workspace {
self.tiling_layer.refresh(); self.tiling_layer.refresh();
} }
pub fn animations_going(&self) -> bool {
self.tiling_layer.animations_going()
}
pub fn update_animations(&mut self, handle: &LoopHandle<'static, crate::state::Data>) {
self.tiling_layer.update_animation_state(handle)
}
pub fn commit(&mut self, surface: &WlSurface) { pub fn commit(&mut self, surface: &WlSurface) {
if let Some(mapped) = self.element_for_wl_surface(surface) { if let Some(mapped) = self.element_for_wl_surface(surface) {
mapped mapped
@ -484,6 +493,7 @@ impl Workspace {
renderer, renderer,
loc.to_physical_precise_round(output_scale), loc.to_physical_precise_round(output_scale),
Scale::from(output_scale), Scale::from(output_scale),
1.0,
) )
}), }),
); );
@ -499,6 +509,7 @@ impl Workspace {
(or.geometry().loc - output.geometry().loc) (or.geometry().loc - output.geometry().loc)
.to_physical_precise_round(output_scale), .to_physical_precise_round(output_scale),
Scale::from(output_scale), Scale::from(output_scale),
1.0,
) )
}), }),
); );
@ -507,7 +518,11 @@ impl Workspace {
render_elements.extend(AsRenderElements::<R>::render_elements::< render_elements.extend(AsRenderElements::<R>::render_elements::<
WorkspaceRenderElement<R>, WorkspaceRenderElement<R>,
>( >(
fullscreen, renderer, (0, 0).into(), output_scale.into() fullscreen,
renderer,
(0, 0).into(),
output_scale.into(),
1.0,
)); ));
if let Some(xwm) = xwm_state.and_then(|state| state.xwm.as_mut()) { if let Some(xwm) = xwm_state.and_then(|state| state.xwm.as_mut()) {
@ -551,6 +566,7 @@ impl Workspace {
renderer, renderer,
loc.to_physical_precise_round(output_scale), loc.to_physical_precise_round(output_scale),
Scale::from(output_scale), Scale::from(output_scale),
1.0,
) )
}), }),
); );
@ -570,6 +586,7 @@ impl Workspace {
(or.geometry().loc - output.geometry().loc) (or.geometry().loc - output.geometry().loc)
.to_physical_precise_round(output_scale), .to_physical_precise_round(output_scale),
Scale::from(output_scale), Scale::from(output_scale),
1.0,
) )
}), }),
); );
@ -620,6 +637,7 @@ impl Workspace {
renderer, renderer,
loc.to_physical_precise_round(output_scale), loc.to_physical_precise_round(output_scale),
Scale::from(output_scale), Scale::from(output_scale),
1.0,
) )
}), }),
); );
@ -715,6 +733,13 @@ where
WorkspaceRenderElement::Window(elem) => elem.opaque_regions(scale), WorkspaceRenderElement::Window(elem) => elem.opaque_regions(scale),
} }
} }
fn alpha(&self) -> f32 {
match self {
WorkspaceRenderElement::Wayland(elem) => elem.alpha(),
WorkspaceRenderElement::Window(elem) => elem.alpha(),
}
}
} }
impl<R> RenderElement<R> for WorkspaceRenderElement<R> impl<R> RenderElement<R> for WorkspaceRenderElement<R>

View file

@ -50,7 +50,7 @@ use smithay::{
}, },
utils::{Clock, IsAlive, Monotonic}, utils::{Clock, IsAlive, Monotonic},
wayland::{ wayland::{
compositor::CompositorState, compositor::{CompositorClientState, CompositorState},
data_device::DataDeviceState, data_device::DataDeviceState,
dmabuf::{DmabufFeedback, DmabufState}, dmabuf::{DmabufFeedback, DmabufState},
keyboard_shortcuts_inhibit::KeyboardShortcutsInhibitState, keyboard_shortcuts_inhibit::KeyboardShortcutsInhibitState,
@ -69,6 +69,7 @@ use std::{cell::RefCell, ffi::OsString, time::Duration};
use std::{collections::VecDeque, time::Instant}; use std::{collections::VecDeque, time::Instant};
pub struct ClientState { pub struct ClientState {
pub compositor_client_state: CompositorClientState,
pub workspace_client_state: WorkspaceClientState, pub workspace_client_state: WorkspaceClientState,
pub drm_node: Option<DrmNode>, pub drm_node: Option<DrmNode>,
pub privileged: bool, pub privileged: bool,
@ -312,6 +313,7 @@ impl State {
pub fn new_client_state(&self) -> ClientState { pub fn new_client_state(&self) -> ClientState {
ClientState { ClientState {
compositor_client_state: CompositorClientState::default(),
workspace_client_state: WorkspaceClientState::default(), workspace_client_state: WorkspaceClientState::default(),
drm_node: match &self.backend { drm_node: match &self.backend {
BackendData::Kms(kms_state) => { BackendData::Kms(kms_state) => {
@ -334,6 +336,7 @@ impl State {
pub fn new_client_state_with_node(&self, drm_node: DrmNode) -> ClientState { pub fn new_client_state_with_node(&self, drm_node: DrmNode) -> ClientState {
ClientState { ClientState {
compositor_client_state: CompositorClientState::default(),
workspace_client_state: WorkspaceClientState::default(), workspace_client_state: WorkspaceClientState::default(),
drm_node: Some(drm_node), drm_node: Some(drm_node),
privileged: false, privileged: false,
@ -342,6 +345,7 @@ impl State {
pub fn new_privileged_client_state(&self) -> ClientState { pub fn new_privileged_client_state(&self) -> ClientState {
ClientState { ClientState {
compositor_client_state: CompositorClientState::default(),
workspace_client_state: WorkspaceClientState::default(), workspace_client_state: WorkspaceClientState::default(),
drm_node: match &self.backend { drm_node: match &self.backend {
BackendData::Kms(kms_state) => Some(kms_state.primary), BackendData::Kms(kms_state) => Some(kms_state.primary),

View file

@ -567,6 +567,7 @@ where
renderer: &mut R, renderer: &mut R,
location: Point<i32, Physical>, location: Point<i32, Physical>,
scale: Scale<f64>, scale: Scale<f64>,
alpha: f32,
) -> Vec<C> { ) -> Vec<C> {
let mut internal = self.0.lock().unwrap(); let mut internal = self.0.lock().unwrap();
@ -633,7 +634,7 @@ where
renderer, renderer,
location.to_f64(), location.to_f64(),
&buffer, &buffer,
None, Some(alpha),
Some(Rectangle::from_loc_and_size( Some(Rectangle::from_loc_and_size(
(0., 0.), (0., 0.),
size.to_f64().to_logical(1.0, Transform::Normal), size.to_f64().to_logical(1.0, Transform::Normal),

View file

@ -2,17 +2,22 @@
use crate::{ use crate::{
shell::CosmicSurface, shell::CosmicSurface,
state::{BackendData, Data}, state::{BackendData, ClientState, Data},
utils::prelude::*, utils::prelude::*,
wayland::protocols::screencopy::SessionType, wayland::protocols::screencopy::SessionType,
}; };
use calloop::Interest;
use smithay::{ use smithay::{
backend::renderer::utils::{on_commit_buffer_handler, with_renderer_surface_state}, backend::renderer::utils::{on_commit_buffer_handler, with_renderer_surface_state},
delegate_compositor, delegate_compositor,
desktop::{layer_map_for_output, LayerSurface, PopupKind, WindowSurfaceType}, desktop::{layer_map_for_output, LayerSurface, PopupKind, WindowSurfaceType},
reexports::wayland_server::protocol::wl_surface::WlSurface, reexports::wayland_server::{protocol::wl_surface::WlSurface, Client, Resource},
wayland::{ wayland::{
compositor::{with_states, CompositorHandler, CompositorState}, compositor::{
add_blocker, add_pre_commit_hook, with_states, BufferAssignment, CompositorClientState,
CompositorHandler, CompositorState, SurfaceAttributes,
},
dmabuf::get_dmabuf,
seat::WaylandFocus, seat::WaylandFocus,
shell::{ shell::{
wlr_layer::LayerSurfaceAttributes, wlr_layer::LayerSurfaceAttributes,
@ -21,7 +26,7 @@ use smithay::{
}, },
}, },
}, },
xwayland::X11Wm, xwayland::{X11Wm, XWaylandClientData},
}; };
use std::sync::Mutex; use std::sync::Mutex;
@ -105,15 +110,63 @@ impl State {
} }
} }
pub fn client_compositor_state<'a>(client: &'a Client) -> &'a CompositorClientState {
if let Some(state) = client.get_data::<XWaylandClientData>() {
return &state.compositor_state;
}
if let Some(state) = client.get_data::<ClientState>() {
return &state.compositor_client_state;
}
panic!("Unknown client data type")
}
impl CompositorHandler for State { impl CompositorHandler for State {
fn compositor_state(&mut self) -> &mut CompositorState { fn compositor_state(&mut self) -> &mut CompositorState {
&mut self.common.compositor_state &mut self.common.compositor_state
} }
fn client_compositor_state<'a>(&self, client: &'a Client) -> &'a CompositorClientState {
client_compositor_state(client)
}
fn new_surface(&mut self, surface: &WlSurface) {
add_pre_commit_hook::<Self, _>(surface, move |state, _dh, surface| {
let maybe_dmabuf = with_states(surface, |surface_data| {
surface_data
.cached_state
.pending::<SurfaceAttributes>()
.buffer
.as_ref()
.and_then(|assignment| match assignment {
BufferAssignment::NewBuffer(buffer) => get_dmabuf(buffer).ok(),
_ => None,
})
});
if let Some(dmabuf) = maybe_dmabuf {
if let Ok((blocker, source)) = dmabuf.generate_blocker(Interest::READ) {
let client = surface.client().unwrap();
let res =
state
.common
.event_loop_handle
.insert_source(source, move |_, _, data| {
data.state
.client_compositor_state(&client)
.blocker_cleared(&mut data.state, &data.display.handle());
Ok(())
});
if res.is_ok() {
add_blocker(surface, blocker);
}
}
}
})
}
fn commit(&mut self, surface: &WlSurface) { fn commit(&mut self, surface: &WlSurface) {
X11Wm::commit_hook::<Data>(surface); X11Wm::commit_hook::<Data>(surface);
// first load the buffer for various smithay helper functions // first load the buffer for various smithay helper functions
on_commit_buffer_handler(surface); on_commit_buffer_handler::<Self>(surface);
// then handle initial configure events and map windows if necessary // then handle initial configure events and map windows if necessary
if let Some((window, seat)) = self if let Some((window, seat)) = self

View file

@ -947,6 +947,7 @@ pub fn render_window_to_buffer(
renderer, renderer,
(-geometry.loc.x, -geometry.loc.y).into(), (-geometry.loc.x, -geometry.loc.y).into(),
Scale::from(1.0), Scale::from(1.0),
1.0,
); );
for seat in common.seats() { for seat in common.seats() {