Skip to content

Commit

Permalink
Statically type user data of objects
Browse files Browse the repository at this point in the history
  • Loading branch information
PolyMeilex committed Aug 15, 2023
1 parent 175fae8 commit 8c8925b
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 12 deletions.
11 changes: 8 additions & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ mod parts;
mod pointer;
pub mod theme;
mod title;
mod wl_typed;

use crate::theme::{
ColorMap, ColorTheme, BORDER_SIZE, CORNER_RADIUS, HEADER_SIZE, VISIBLE_BORDER_SIZE,
Expand All @@ -36,6 +37,7 @@ use config::get_button_layout_config;
use parts::DecorationParts;
use pointer::{Location, MouseState};
use title::TitleText;
use wl_typed::WlTyped;

/// XXX this is not result, so `must_use` when needed.
type SkiaResult = Option<()>;
Expand All @@ -44,7 +46,7 @@ type SkiaResult = Option<()>;
#[derive(Debug)]
pub struct AdwaitaFrame<State> {
/// The base surface used to create the window.
base_surface: WlSurface,
base_surface: WlTyped<WlSurface, SurfaceData>,

/// Subcompositor to create/drop subsurfaces ondemand.
subcompositor: Arc<SubcompositorState>,
Expand Down Expand Up @@ -84,7 +86,8 @@ where
queue_handle: QueueHandle<State>,
frame_config: FrameConfig,
) -> Result<Self, Box<dyn Error>> {
let base_surface = base_surface.wl_surface().clone();
let base_surface = WlTyped::wrap::<State>(base_surface.wl_surface().clone());

let pool = SlotPool::new(1, shm)?;

let decorations = Some(DecorationParts::new(
Expand Down Expand Up @@ -402,8 +405,10 @@ where
}

fn click_point_moved(&mut self, surface: &WlSurface, x: f64, y: f64) -> Option<&str> {
let surface = WlTyped::wrap::<State>(surface.clone());

let decorations = self.decorations.as_ref()?;
let location = decorations.find_surface(surface);
let location = decorations.find_surface(&surface);
if location == Location::None {
return None;
}
Expand Down
22 changes: 13 additions & 9 deletions src/parts.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
use smithay_client_toolkit::reexports::client::{
protocol::{wl_subsurface::WlSubsurface, wl_surface::WlSurface},
Dispatch, Proxy, QueueHandle,
Dispatch, QueueHandle,
};

use smithay_client_toolkit::{
compositor::SurfaceData,
subcompositor::{SubcompositorState, SubsurfaceData},
};

use crate::pointer::Location;
use crate::theme::{BORDER_SIZE, HEADER_SIZE};
use crate::{pointer::Location, wl_typed::WlTyped};

/// The decoration's 'parts'.
#[derive(Debug)]
Expand All @@ -26,7 +26,7 @@ impl DecorationParts {
pub const BOTTOM: usize = 4;

pub fn new<State>(
base_surface: &WlSurface,
base_surface: &WlTyped<WlSurface, SurfaceData>,
subcompositor: &SubcompositorState,
queue_handle: &QueueHandle<State>,
) -> Self
Expand Down Expand Up @@ -124,7 +124,7 @@ impl DecorationParts {
&self.parts[Self::HEADER]
}

pub fn find_surface(&self, surface: &WlSurface) -> Location {
pub fn find_surface(&self, surface: &WlTyped<WlSurface, SurfaceData>) -> Location {
let pos = match self.parts.iter().position(|part| &part.surface == surface) {
Some(pos) => pos,
None => return Location::None,
Expand All @@ -143,8 +143,8 @@ impl DecorationParts {

#[derive(Debug)]
pub struct Part {
pub surface: WlSurface,
pub subsurface: WlSubsurface,
pub surface: WlTyped<WlSurface, SurfaceData>,
pub subsurface: WlTyped<WlSubsurface, SubsurfaceData>,

pub width: u32,
pub height: u32,
Expand All @@ -154,7 +154,7 @@ pub struct Part {

impl Part {
fn new<State>(
parent: &WlSurface,
parent: &WlTyped<WlSurface, SurfaceData>,
subcompositor: &SubcompositorState,
queue_handle: &QueueHandle<State>,
width: u32,
Expand All @@ -164,7 +164,11 @@ impl Part {
where
State: Dispatch<WlSurface, SurfaceData> + Dispatch<WlSubsurface, SubsurfaceData> + 'static,
{
let (subsurface, surface) = subcompositor.create_subsurface(parent.clone(), queue_handle);
let (subsurface, surface) =
subcompositor.create_subsurface(parent.inner().clone(), queue_handle);

let subsurface = WlTyped::wrap::<State>(subsurface);
let surface = WlTyped::wrap::<State>(surface);

// Sync with the parent surface.
subsurface.set_sync();
Expand All @@ -179,7 +183,7 @@ impl Part {
}

pub fn scale(&self) -> u32 {
self.surface.data::<SurfaceData>().unwrap().scale_factor() as u32
self.surface.data().scale_factor() as u32
}
}

Expand Down
51 changes: 51 additions & 0 deletions src/wl_typed.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
use std::{marker::PhantomData, ops::Deref};

use smithay_client_toolkit::reexports::client::{Dispatch, Proxy};

#[derive(Debug)]
pub struct WlTyped<I, DATA>(I, PhantomData<DATA>);

impl<I, DATA> WlTyped<I, DATA>
where
I: Proxy,
DATA: Send + Sync + 'static,
{
#[allow(clippy::extra_unused_type_parameters)]
pub fn wrap<STATE>(i: I) -> Self
where
STATE: Dispatch<I, DATA>,
{
Self(i, PhantomData)
}

pub fn inner(&self) -> &I {
&self.0
}

pub fn data(&self) -> &DATA {
// Generic on Self::wrap makes sure that this will never panic
#[allow(clippy::unwrap_used)]
self.0.data().unwrap()
}
}

impl<I: Clone, D> Clone for WlTyped<I, D> {
fn clone(&self) -> Self {
Self(self.0.clone(), PhantomData)
}
}

impl<I, D> Deref for WlTyped<I, D> {
type Target = I;

fn deref(&self) -> &Self::Target {
&self.0
}
}

impl<I: PartialEq, D> PartialEq for WlTyped<I, D> {
fn eq(&self, other: &Self) -> bool {
self.0 == other.0
}
}
impl<I: Eq, D> Eq for WlTyped<I, D> {}

0 comments on commit 8c8925b

Please sign in to comment.