tiling: Animate tree changes
This commit is contained in:
parent
ea1b976076
commit
331b884f1e
23 changed files with 1641 additions and 395 deletions
959
Cargo.lock
generated
959
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
|
|
@ -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" }
|
||||||
|
|
|
||||||
|
|
@ -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))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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> {
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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) => {
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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))
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
}));
|
}));
|
||||||
|
|
|
||||||
|
|
@ -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!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
65
src/shell/layout/tiling/blocker.rs
Normal file
65
src/shell/layout/tiling/blocker.rs
Normal 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);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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
|
|
@ -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!();
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
|
||||||
|
|
@ -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),
|
||||||
|
|
|
||||||
|
|
@ -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),
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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() {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue