wayland: implement alpha_modifier_v1
This commit is contained in:
parent
131f0481e8
commit
ff54a8ab96
37 changed files with 655 additions and 89 deletions
|
|
@ -2,6 +2,7 @@ pub mod commit_timeline;
|
|||
pub mod cursor;
|
||||
pub mod ext_session_lock_surface_v1;
|
||||
pub mod wl_subsurface;
|
||||
pub mod wp_alpha_modifier_surface_v1;
|
||||
pub mod wp_fractional_scale_v1;
|
||||
pub mod wp_linux_drm_syncobj_surface_v1;
|
||||
pub mod wp_tearing_control_v1;
|
||||
|
|
@ -30,6 +31,7 @@ use {
|
|||
commit_timeline::{ClearReason, CommitTimeline, CommitTimelineError},
|
||||
cursor::CursorSurface,
|
||||
wl_subsurface::{PendingSubsurfaceData, SubsurfaceId, WlSubsurface},
|
||||
wp_alpha_modifier_surface_v1::WpAlphaModifierSurfaceV1,
|
||||
wp_fractional_scale_v1::WpFractionalScaleV1,
|
||||
wp_linux_drm_syncobj_surface_v1::WpLinuxDrmSyncobjSurfaceV1,
|
||||
wp_tearing_control_v1::WpTearingControlV1,
|
||||
|
|
@ -245,6 +247,8 @@ pub struct WlSurface {
|
|||
sync_obj_surface: CloneCell<Option<Rc<WpLinuxDrmSyncobjSurfaceV1>>>,
|
||||
destroyed: Cell<bool>,
|
||||
commit_timeline: CommitTimeline,
|
||||
alpha_modifier: CloneCell<Option<Rc<WpAlphaModifierSurfaceV1>>>,
|
||||
alpha: Cell<Option<f32>>,
|
||||
}
|
||||
|
||||
impl Debug for WlSurface {
|
||||
|
|
@ -366,6 +370,7 @@ struct PendingState {
|
|||
subsurfaces: AHashMap<SubsurfaceId, AttachedSubsurfaceState>,
|
||||
acquire_point: Option<(Rc<SyncObj>, SyncObjPoint)>,
|
||||
release_point: Option<(Rc<SyncObj>, SyncObjPoint)>,
|
||||
alpha_multiplier: Option<Option<f32>>,
|
||||
explicit_sync: bool,
|
||||
}
|
||||
|
||||
|
|
@ -416,6 +421,7 @@ impl PendingState {
|
|||
opt!(xwayland_serial);
|
||||
opt!(tearing);
|
||||
opt!(content_type);
|
||||
opt!(alpha_multiplier);
|
||||
{
|
||||
let (dx1, dy1) = self.offset;
|
||||
let (dx2, dy2) = mem::take(&mut next.offset);
|
||||
|
|
@ -525,6 +531,8 @@ impl WlSurface {
|
|||
sync_obj_surface: Default::default(),
|
||||
destroyed: Cell::new(false),
|
||||
commit_timeline: client.commit_timelines.create_timeline(),
|
||||
alpha_modifier: Default::default(),
|
||||
alpha: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -915,6 +923,11 @@ impl WlSurface {
|
|||
}
|
||||
}
|
||||
}
|
||||
let mut alpha_changed = false;
|
||||
if let Some(alpha) = pending.alpha_multiplier.take() {
|
||||
alpha_changed = true;
|
||||
self.alpha.set(alpha);
|
||||
}
|
||||
let mut buffer_changed = false;
|
||||
let mut old_raw_size = None;
|
||||
let (dx, dy) = mem::take(&mut pending.offset);
|
||||
|
|
@ -1076,7 +1089,7 @@ impl WlSurface {
|
|||
if self.need_extents_update.get() {
|
||||
self.calculate_extents();
|
||||
}
|
||||
if buffer_changed || transform_changed {
|
||||
if buffer_changed || transform_changed || alpha_changed {
|
||||
for (_, cursor) in &self.cursors {
|
||||
cursor.handle_buffer_change();
|
||||
cursor.update_hardware_cursor();
|
||||
|
|
@ -1278,6 +1291,10 @@ impl WlSurface {
|
|||
}
|
||||
self.set_visible(self.dnd_icons.is_not_empty() && self.client.state.root_visible());
|
||||
}
|
||||
|
||||
pub fn alpha(&self) -> Option<f32> {
|
||||
self.alpha.get()
|
||||
}
|
||||
}
|
||||
|
||||
object_base! {
|
||||
|
|
@ -1304,6 +1321,7 @@ impl Object for WlSurface {
|
|||
self.constraints.clear();
|
||||
self.drm_feedback.clear();
|
||||
self.commit_timeline.clear(ClearReason::BreakLoops);
|
||||
self.alpha_modifier.take();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
78
src/ifs/wl_surface/wp_alpha_modifier_surface_v1.rs
Normal file
78
src/ifs/wl_surface/wp_alpha_modifier_surface_v1.rs
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
use {
|
||||
crate::{
|
||||
client::{Client, ClientError},
|
||||
ifs::wl_surface::WlSurface,
|
||||
leaks::Tracker,
|
||||
object::{Object, Version},
|
||||
wire::{wp_alpha_modifier_surface_v1::*, WpAlphaModifierSurfaceV1Id},
|
||||
},
|
||||
std::rc::Rc,
|
||||
thiserror::Error,
|
||||
};
|
||||
|
||||
pub struct WpAlphaModifierSurfaceV1 {
|
||||
pub id: WpAlphaModifierSurfaceV1Id,
|
||||
pub version: Version,
|
||||
pub client: Rc<Client>,
|
||||
pub surface: Rc<WlSurface>,
|
||||
pub tracker: Tracker<Self>,
|
||||
}
|
||||
|
||||
impl WpAlphaModifierSurfaceV1 {
|
||||
pub fn new(id: WpAlphaModifierSurfaceV1Id, surface: &Rc<WlSurface>, version: Version) -> Self {
|
||||
Self {
|
||||
id,
|
||||
version,
|
||||
client: surface.client.clone(),
|
||||
surface: surface.clone(),
|
||||
tracker: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn install(self: &Rc<Self>) -> Result<(), WpAlphaModifierSurfaceV1Error> {
|
||||
if self.surface.alpha_modifier.is_some() {
|
||||
return Err(WpAlphaModifierSurfaceV1Error::Exists);
|
||||
}
|
||||
self.surface.alpha_modifier.set(Some(self.clone()));
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl WpAlphaModifierSurfaceV1RequestHandler for WpAlphaModifierSurfaceV1 {
|
||||
type Error = WpAlphaModifierSurfaceV1Error;
|
||||
|
||||
fn destroy(&self, _req: Destroy, _slf: &Rc<Self>) -> Result<(), Self::Error> {
|
||||
self.surface.alpha_modifier.take();
|
||||
self.surface.pending.borrow_mut().alpha_multiplier = Some(None);
|
||||
self.client.remove_obj(self)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn set_multiplier(&self, req: SetMultiplier, _slf: &Rc<Self>) -> Result<(), Self::Error> {
|
||||
let multiplier = if req.factor == u32::MAX {
|
||||
None
|
||||
} else {
|
||||
Some(((req.factor as f64) / (u32::MAX as f64)) as f32)
|
||||
};
|
||||
self.surface.pending.borrow_mut().alpha_multiplier = Some(multiplier);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
object_base! {
|
||||
self = WpAlphaModifierSurfaceV1;
|
||||
version = self.version;
|
||||
}
|
||||
|
||||
impl Object for WpAlphaModifierSurfaceV1 {}
|
||||
|
||||
simple_add_obj!(WpAlphaModifierSurfaceV1);
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum WpAlphaModifierSurfaceV1Error {
|
||||
#[error(transparent)]
|
||||
ClientError(Box<ClientError>),
|
||||
#[error("The surface already has an alpha modifier extension attached")]
|
||||
Exists,
|
||||
}
|
||||
efrom!(WpAlphaModifierSurfaceV1Error, ClientError);
|
||||
106
src/ifs/wp_alpha_modifier_v1.rs
Normal file
106
src/ifs/wp_alpha_modifier_v1.rs
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
use {
|
||||
crate::{
|
||||
client::{Client, ClientError},
|
||||
globals::{Global, GlobalName},
|
||||
ifs::wl_surface::wp_alpha_modifier_surface_v1::{
|
||||
WpAlphaModifierSurfaceV1, WpAlphaModifierSurfaceV1Error,
|
||||
},
|
||||
leaks::Tracker,
|
||||
object::{Object, Version},
|
||||
wire::{wp_alpha_modifier_v1::*, WpAlphaModifierV1Id},
|
||||
},
|
||||
std::rc::Rc,
|
||||
thiserror::Error,
|
||||
};
|
||||
|
||||
pub struct WpAlphaModifierV1Global {
|
||||
name: GlobalName,
|
||||
}
|
||||
|
||||
pub struct WpAlphaModifierV1 {
|
||||
id: WpAlphaModifierV1Id,
|
||||
client: Rc<Client>,
|
||||
version: Version,
|
||||
pub tracker: Tracker<Self>,
|
||||
}
|
||||
|
||||
impl WpAlphaModifierV1Global {
|
||||
pub fn new(name: GlobalName) -> Self {
|
||||
Self { name }
|
||||
}
|
||||
|
||||
fn bind_(
|
||||
self: Rc<Self>,
|
||||
id: WpAlphaModifierV1Id,
|
||||
client: &Rc<Client>,
|
||||
version: Version,
|
||||
) -> Result<(), WpAlphaModifierV1Error> {
|
||||
let obj = Rc::new(WpAlphaModifierV1 {
|
||||
id,
|
||||
client: client.clone(),
|
||||
version,
|
||||
tracker: Default::default(),
|
||||
});
|
||||
track!(client, obj);
|
||||
client.add_client_obj(&obj)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
impl WpAlphaModifierV1RequestHandler for WpAlphaModifierV1 {
|
||||
type Error = WpAlphaModifierV1Error;
|
||||
|
||||
fn destroy(&self, _req: Destroy, _slf: &Rc<Self>) -> Result<(), Self::Error> {
|
||||
self.client.remove_obj(self)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn get_surface(&self, req: GetSurface, _slf: &Rc<Self>) -> Result<(), Self::Error> {
|
||||
let surface = self.client.lookup(req.surface)?;
|
||||
let modifier = Rc::new(WpAlphaModifierSurfaceV1::new(
|
||||
req.id,
|
||||
&surface,
|
||||
self.version,
|
||||
));
|
||||
track!(self.client, surface);
|
||||
self.client.add_client_obj(&modifier)?;
|
||||
modifier.install()?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
global_base!(
|
||||
WpAlphaModifierV1Global,
|
||||
WpAlphaModifierV1,
|
||||
WpAlphaModifierV1Error
|
||||
);
|
||||
|
||||
impl Global for WpAlphaModifierV1Global {
|
||||
fn singleton(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn version(&self) -> u32 {
|
||||
1
|
||||
}
|
||||
}
|
||||
|
||||
simple_add_global!(WpAlphaModifierV1Global);
|
||||
|
||||
object_base! {
|
||||
self = WpAlphaModifierV1;
|
||||
version = self.version;
|
||||
}
|
||||
|
||||
impl Object for WpAlphaModifierV1 {}
|
||||
|
||||
simple_add_obj!(WpAlphaModifierV1);
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum WpAlphaModifierV1Error {
|
||||
#[error(transparent)]
|
||||
ClientError(Box<ClientError>),
|
||||
#[error(transparent)]
|
||||
WpAlphaModifierSurfaceV1Error(#[from] WpAlphaModifierSurfaceV1Error),
|
||||
}
|
||||
|
||||
efrom!(WpAlphaModifierV1Error, ClientError);
|
||||
Loading…
Add table
Add a link
Reference in a new issue