wayland.shell.xdg: use UserDataMap

This commit is contained in:
Victor Berger 2019-04-23 23:52:14 +02:00 committed by Victor Berger
parent 19432460cd
commit d62fb4c8b5
5 changed files with 179 additions and 281 deletions

View File

@ -31,12 +31,12 @@ use crate::window_map::{Kind as SurfaceKind, WindowMap};
define_roles!(Roles =>
[ XdgSurface, XdgSurfaceRole ]
[ ShellSurface, ShellSurfaceRole<()>]
[ ShellSurface, ShellSurfaceRole]
[ DnDIcon, DnDIconRole ]
[ CursorImage, CursorImageRole ]
);
pub type MyWindowMap = WindowMap<Roles, (), (), fn(&SurfaceAttributes) -> Option<(i32, i32)>>;
pub type MyWindowMap = WindowMap<Roles, fn(&SurfaceAttributes) -> Option<(i32, i32)>>;
pub type MyCompositorToken = CompositorToken<Roles>;
@ -45,8 +45,8 @@ pub fn init_shell(
log: ::slog::Logger,
) -> (
CompositorToken<Roles>,
Arc<Mutex<XdgShellState<Roles, ()>>>,
Arc<Mutex<WlShellState<Roles, ()>>>,
Arc<Mutex<XdgShellState<Roles>>>,
Arc<Mutex<WlShellState<Roles>>>,
Rc<RefCell<MyWindowMap>>,
) {
// Create the compositor
@ -62,7 +62,7 @@ pub fn init_shell(
);
// Init a window map, to track the location of our windows
let window_map = Rc::new(RefCell::new(WindowMap::<_, (), (), _>::new(
let window_map = Rc::new(RefCell::new(WindowMap::<_, _>::new(
compositor_token,
get_size as _,
)));
@ -104,7 +104,7 @@ pub fn init_shell(
let (wl_shell_state, _) = wl_shell_init(
display,
compositor_token,
move |req: ShellRequest<_, ()>| {
move |req: ShellRequest<_>| {
if let ShellRequest::SetKind {
surface,
kind: ShellSurfaceKind::Toplevel,

View File

@ -12,16 +12,14 @@ use smithay::{
},
};
pub enum Kind<R, SD, D> {
Xdg(ToplevelSurface<R, SD>),
Wl(ShellSurface<R, D>),
pub enum Kind<R> {
Xdg(ToplevelSurface<R>),
Wl(ShellSurface<R>),
}
impl<R, SD, D> Kind<R, SD, D>
impl<R> Kind<R>
where
R: Role<SubsurfaceRole> + Role<XdgSurfaceRole> + Role<ShellSurfaceRole<D>> + 'static,
SD: 'static,
D: 'static,
R: Role<SubsurfaceRole> + Role<XdgSurfaceRole> + Role<ShellSurfaceRole> + 'static,
{
pub fn alive(&self) -> bool {
match *self {
@ -37,17 +35,15 @@ where
}
}
struct Window<R, SD, D> {
struct Window<R> {
location: (i32, i32),
surface: Rectangle,
toplevel: Kind<R, SD, D>,
toplevel: Kind<R>,
}
impl<R, SD, D> Window<R, SD, D>
impl<R> Window<R>
where
R: Role<SubsurfaceRole> + Role<XdgSurfaceRole> + Role<ShellSurfaceRole<D>> + 'static,
SD: 'static,
D: 'static,
R: Role<SubsurfaceRole> + Role<XdgSurfaceRole> + Role<ShellSurfaceRole> + 'static,
{
// Find the topmost surface under this point if any and the location of this surface
fn matching<F>(
@ -146,20 +142,18 @@ where
}
}
pub struct WindowMap<R, SD, D, F> {
pub struct WindowMap<R, F> {
ctoken: CompositorToken<R>,
windows: Vec<Window<R, SD, D>>,
windows: Vec<Window<R>>,
get_size: F,
}
impl<R, SD, D, F> WindowMap<R, SD, D, F>
impl<R, F> WindowMap<R, F>
where
F: Fn(&SurfaceAttributes) -> Option<(i32, i32)>,
R: Role<SubsurfaceRole> + Role<XdgSurfaceRole> + Role<ShellSurfaceRole<D>> + 'static,
SD: 'static,
D: 'static,
R: Role<SubsurfaceRole> + Role<XdgSurfaceRole> + Role<ShellSurfaceRole> + 'static,
{
pub fn new(ctoken: CompositorToken<R>, get_size: F) -> WindowMap<R, D, SD, F> {
pub fn new(ctoken: CompositorToken<R>, get_size: F) -> WindowMap<R, F> {
WindowMap {
ctoken,
windows: Vec::new(),
@ -167,7 +161,7 @@ where
}
}
pub fn insert(&mut self, toplevel: Kind<R, SD, D>, location: (i32, i32)) {
pub fn insert(&mut self, toplevel: Kind<R>, location: (i32, i32)) {
let mut window = Window {
location,
surface: Rectangle {
@ -213,7 +207,7 @@ where
pub fn with_windows_from_bottom_to_top<Func>(&self, mut f: Func)
where
Func: FnMut(&Kind<R, SD, D>, (i32, i32)),
Func: FnMut(&Kind<R>, (i32, i32)),
{
for w in self.windows.iter().rev() {
f(&w.toplevel, w.location)

View File

@ -60,7 +60,7 @@
//! // token from the compositor implementation
//! compositor_token,
//! // your implementation
//! |event: XdgRequest<_, MyShellData>| { /* ... */ },
//! |event: XdgRequest<_>| { /* ... */ },
//! None // put a logger if you want
//! );
//!
@ -96,6 +96,7 @@ use std::{
rc::Rc,
sync::{Arc, Mutex},
};
use wayland_commons::utils::UserDataMap;
use wayland_protocols::{
unstable::xdg_shell::v6::server::{zxdg_popup_v6, zxdg_shell_v6, zxdg_surface_v6, zxdg_toplevel_v6},
xdg_shell::server::{xdg_popup, xdg_positioner, xdg_surface, xdg_toplevel, xdg_wm_base},
@ -258,14 +259,14 @@ impl Default for XdgSurfacePendingState {
}
}
pub(crate) struct ShellData<R, SD> {
pub(crate) struct ShellData<R> {
log: ::slog::Logger,
compositor_token: CompositorToken<R>,
user_impl: Rc<RefCell<dyn FnMut(XdgRequest<R, SD>)>>,
shell_state: Arc<Mutex<ShellState<R, SD>>>,
user_impl: Rc<RefCell<dyn FnMut(XdgRequest<R>)>>,
shell_state: Arc<Mutex<ShellState<R>>>,
}
impl<R, SD> Clone for ShellData<R, SD> {
impl<R> Clone for ShellData<R> {
fn clone(&self) -> Self {
ShellData {
log: self.log.clone(),
@ -277,21 +278,20 @@ impl<R, SD> Clone for ShellData<R, SD> {
}
/// Create a new `xdg_shell` globals
pub fn xdg_shell_init<R, SD, L, Impl>(
pub fn xdg_shell_init<R, L, Impl>(
display: &mut Display,
ctoken: CompositorToken<R>,
implementation: Impl,
logger: L,
) -> (
Arc<Mutex<ShellState<R, SD>>>,
Arc<Mutex<ShellState<R>>>,
Global<xdg_wm_base::XdgWmBase>,
Global<zxdg_shell_v6::ZxdgShellV6>,
)
where
R: Role<XdgSurfaceRole> + 'static,
SD: Default + 'static,
L: Into<Option<::slog::Logger>>,
Impl: FnMut(XdgRequest<R, SD>) + 'static,
Impl: FnMut(XdgRequest<R>) + 'static,
{
let log = crate::slog_or_stdlog(logger);
let shell_state = Arc::new(Mutex::new(ShellState {
@ -323,23 +323,22 @@ where
///
/// This state allows you to retrieve a list of surfaces
/// currently known to the shell global.
pub struct ShellState<R, SD> {
known_toplevels: Vec<ToplevelSurface<R, SD>>,
known_popups: Vec<PopupSurface<R, SD>>,
pub struct ShellState<R> {
known_toplevels: Vec<ToplevelSurface<R>>,
known_popups: Vec<PopupSurface<R>>,
}
impl<R, SD> ShellState<R, SD>
impl<R> ShellState<R>
where
R: Role<XdgSurfaceRole> + 'static,
SD: 'static,
{
/// Access all the shell surfaces known by this handler
pub fn toplevel_surfaces(&self) -> &[ToplevelSurface<R, SD>] {
pub fn toplevel_surfaces(&self) -> &[ToplevelSurface<R>] {
&self.known_toplevels[..]
}
/// Access all the popup surfaces known by this handler
pub fn popup_surfaces(&self) -> &[PopupSurface<R, SD>] {
pub fn popup_surfaces(&self) -> &[PopupSurface<R>] {
&self.known_popups[..]
}
}
@ -353,15 +352,15 @@ enum ShellClientKind {
ZxdgV6(zxdg_shell_v6::ZxdgShellV6),
}
pub(crate) struct ShellClientData<SD> {
pub(crate) struct ShellClientData {
pending_ping: u32,
data: SD,
data: UserDataMap,
}
fn make_shell_client_data<SD: Default>() -> ShellClientData<SD> {
fn make_shell_client_data() -> ShellClientData {
ShellClientData {
pending_ping: 0,
data: Default::default(),
data: UserDataMap::new(),
}
}
@ -375,16 +374,14 @@ fn make_shell_client_data<SD: Default>() -> ShellClientData<SD> {
///
/// You can use this handle to access a storage for any
/// client-specific data you wish to associate with it.
pub struct ShellClient<R, SD> {
pub struct ShellClient<R> {
kind: ShellClientKind,
_token: CompositorToken<R>,
_data: ::std::marker::PhantomData<*mut SD>,
}
impl<R, SD> ShellClient<R, SD>
impl<R> ShellClient<R>
where
R: Role<XdgSurfaceRole> + 'static,
SD: 'static,
{
/// Is the shell client represented by this handle still connected?
pub fn alive(&self) -> bool {
@ -423,7 +420,7 @@ where
ShellClientKind::Xdg(ref shell) => {
let user_data = shell
.as_ref()
.user_data::<self::xdg_handlers::ShellUserData<R, SD>>()
.user_data::<self::xdg_handlers::ShellUserData<R>>()
.unwrap();
let mut guard = user_data.client_data.lock().unwrap();
if guard.pending_ping == 0 {
@ -435,7 +432,7 @@ where
ShellClientKind::ZxdgV6(ref shell) => {
let user_data = shell
.as_ref()
.user_data::<self::zxdgv6_handlers::ShellUserData<R, SD>>()
.user_data::<self::zxdgv6_handlers::ShellUserData<R>>()
.unwrap();
let mut guard = user_data.client_data.lock().unwrap();
if guard.pending_ping == 0 {
@ -451,7 +448,7 @@ where
/// Access the user data associated with this shell client
pub fn with_data<F, T>(&self, f: F) -> Result<T, ()>
where
F: FnOnce(&mut SD) -> T,
F: FnOnce(&mut UserDataMap) -> T,
{
if !self.alive() {
return Err(());
@ -460,7 +457,7 @@ where
ShellClientKind::Xdg(ref shell) => {
let data = shell
.as_ref()
.user_data::<self::xdg_handlers::ShellUserData<R, SD>>()
.user_data::<self::xdg_handlers::ShellUserData<R>>()
.unwrap();
let mut guard = data.client_data.lock().unwrap();
Ok(f(&mut guard.data))
@ -468,7 +465,7 @@ where
ShellClientKind::ZxdgV6(ref shell) => {
let data = shell
.as_ref()
.user_data::<self::zxdgv6_handlers::ShellUserData<R, SD>>()
.user_data::<self::zxdgv6_handlers::ShellUserData<R>>()
.unwrap();
let mut guard = data.client_data.lock().unwrap();
Ok(f(&mut guard.data))
@ -483,17 +480,15 @@ pub(crate) enum ToplevelKind {
}
/// A handle to a toplevel surface
pub struct ToplevelSurface<R, SD> {
pub struct ToplevelSurface<R> {
wl_surface: wl_surface::WlSurface,
shell_surface: ToplevelKind,
token: CompositorToken<R>,
_shell_data: ::std::marker::PhantomData<SD>,
}
impl<R, SD> ToplevelSurface<R, SD>
impl<R> ToplevelSurface<R>
where
R: Role<XdgSurfaceRole> + 'static,
SD: 'static,
{
/// Is the toplevel surface referred by this handle still alive?
pub fn alive(&self) -> bool {
@ -512,7 +507,7 @@ where
/// Retrieve the shell client owning this toplevel surface
///
/// Returns `None` if the surface does actually no longer exist.
pub fn client(&self) -> Option<ShellClient<R, SD>> {
pub fn client(&self) -> Option<ShellClient<R>> {
if !self.alive() {
return None;
}
@ -521,14 +516,14 @@ where
ToplevelKind::Xdg(ref s) => {
let data = s
.as_ref()
.user_data::<self::xdg_handlers::ShellSurfaceUserData<R, SD>>()
.user_data::<self::xdg_handlers::ShellSurfaceUserData<R>>()
.unwrap();
ShellClientKind::Xdg(data.wm_base.clone())
}
ToplevelKind::ZxdgV6(ref s) => {
let data = s
.as_ref()
.user_data::<self::zxdgv6_handlers::ShellSurfaceUserData<R, SD>>()
.user_data::<self::zxdgv6_handlers::ShellSurfaceUserData<R>>()
.unwrap();
ShellClientKind::ZxdgV6(data.shell.clone())
}
@ -537,7 +532,6 @@ where
Some(ShellClient {
kind: shell,
_token: self.token,
_data: ::std::marker::PhantomData,
})
}
@ -549,8 +543,8 @@ where
return;
}
match self.shell_surface {
ToplevelKind::Xdg(ref s) => self::xdg_handlers::send_toplevel_configure::<R, SD>(s, cfg),
ToplevelKind::ZxdgV6(ref s) => self::zxdgv6_handlers::send_toplevel_configure::<R, SD>(s, cfg),
ToplevelKind::Xdg(ref s) => self::xdg_handlers::send_toplevel_configure::<R>(s, cfg),
ToplevelKind::ZxdgV6(ref s) => self::zxdgv6_handlers::send_toplevel_configure::<R>(s, cfg),
}
}
@ -575,7 +569,7 @@ where
ToplevelKind::Xdg(ref s) => {
let data = s
.as_ref()
.user_data::<self::xdg_handlers::ShellSurfaceUserData<R, SD>>()
.user_data::<self::xdg_handlers::ShellSurfaceUserData<R>>()
.unwrap();
data.xdg_surface.as_ref().post_error(
xdg_surface::Error::NotConstructed as u32,
@ -585,7 +579,7 @@ where
ToplevelKind::ZxdgV6(ref s) => {
let data = s
.as_ref()
.user_data::<self::zxdgv6_handlers::ShellSurfaceUserData<R, SD>>()
.user_data::<self::zxdgv6_handlers::ShellSurfaceUserData<R>>()
.unwrap();
data.xdg_surface.as_ref().post_error(
zxdg_surface_v6::Error::NotConstructed as u32,
@ -642,17 +636,15 @@ pub(crate) enum PopupKind {
///
/// This is an unified abstraction over the popup surfaces
/// of both `wl_shell` and `xdg_shell`.
pub struct PopupSurface<R, SD> {
pub struct PopupSurface<R> {
wl_surface: wl_surface::WlSurface,
shell_surface: PopupKind,
token: CompositorToken<R>,
_shell_data: ::std::marker::PhantomData<SD>,
}
impl<R, SD> PopupSurface<R, SD>
impl<R> PopupSurface<R>
where
R: Role<XdgSurfaceRole> + 'static,
SD: 'static,
{
/// Is the popup surface referred by this handle still alive?
pub fn alive(&self) -> bool {
@ -671,7 +663,7 @@ where
/// Retrieve the shell client owning this popup surface
///
/// Returns `None` if the surface does actually no longer exist.
pub fn client(&self) -> Option<ShellClient<R, SD>> {
pub fn client(&self) -> Option<ShellClient<R>> {
if !self.alive() {
return None;
}
@ -680,14 +672,14 @@ where
PopupKind::Xdg(ref p) => {
let data = p
.as_ref()
.user_data::<self::xdg_handlers::ShellSurfaceUserData<R, SD>>()
.user_data::<self::xdg_handlers::ShellSurfaceUserData<R>>()
.unwrap();
ShellClientKind::Xdg(data.wm_base.clone())
}
PopupKind::ZxdgV6(ref p) => {
let data = p
.as_ref()
.user_data::<self::zxdgv6_handlers::ShellSurfaceUserData<R, SD>>()
.user_data::<self::zxdgv6_handlers::ShellSurfaceUserData<R>>()
.unwrap();
ShellClientKind::ZxdgV6(data.shell.clone())
}
@ -696,7 +688,6 @@ where
Some(ShellClient {
kind: shell,
_token: self.token,
_data: ::std::marker::PhantomData,
})
}
@ -709,10 +700,10 @@ where
}
match self.shell_surface {
PopupKind::Xdg(ref p) => {
self::xdg_handlers::send_popup_configure::<R, SD>(p, cfg);
self::xdg_handlers::send_popup_configure::<R>(p, cfg);
}
PopupKind::ZxdgV6(ref p) => {
self::zxdgv6_handlers::send_popup_configure::<R, SD>(p, cfg);
self::zxdgv6_handlers::send_popup_configure::<R>(p, cfg);
}
}
}
@ -738,7 +729,7 @@ where
PopupKind::Xdg(ref s) => {
let data = s
.as_ref()
.user_data::<self::xdg_handlers::ShellSurfaceUserData<R, SD>>()
.user_data::<self::xdg_handlers::ShellSurfaceUserData<R>>()
.unwrap();
data.xdg_surface.as_ref().post_error(
xdg_surface::Error::NotConstructed as u32,
@ -748,7 +739,7 @@ where
PopupKind::ZxdgV6(ref s) => {
let data = s
.as_ref()
.user_data::<self::zxdgv6_handlers::ShellSurfaceUserData<R, SD>>()
.user_data::<self::zxdgv6_handlers::ShellSurfaceUserData<R>>()
.unwrap();
data.xdg_surface.as_ref().post_error(
zxdg_surface_v6::Error::NotConstructed as u32,
@ -837,11 +828,11 @@ pub struct PopupConfigure {
/// for you directly.
///
/// Depending on what you want to do, you might ignore some of them
pub enum XdgRequest<R, SD> {
pub enum XdgRequest<R> {
/// A new shell client was instantiated
NewClient {
/// the client
client: ShellClient<R, SD>,
client: ShellClient<R>,
},
/// The pong for a pending ping of this shell client was received
///
@ -849,7 +840,7 @@ pub enum XdgRequest<R, SD> {
/// from the pending ping.
ClientPong {
/// the client
client: ShellClient<R, SD>,
client: ShellClient<R>,
},
/// A new toplevel surface was created
///
@ -857,7 +848,7 @@ pub enum XdgRequest<R, SD> {
/// client as to how its window should be
NewToplevel {
/// the surface
surface: ToplevelSurface<R, SD>,
surface: ToplevelSurface<R>,
},
/// A new popup surface was created
///
@ -865,12 +856,12 @@ pub enum XdgRequest<R, SD> {
/// client as to how its popup should be
NewPopup {
/// the surface
surface: PopupSurface<R, SD>,
surface: PopupSurface<R>,
},
/// The client requested the start of an interactive move for this surface
Move {
/// the surface
surface: ToplevelSurface<R, SD>,
surface: ToplevelSurface<R>,
/// the seat associated to this move
seat: wl_seat::WlSeat,
/// the grab serial
@ -879,7 +870,7 @@ pub enum XdgRequest<R, SD> {
/// The client requested the start of an interactive resize for this surface
Resize {
/// The surface
surface: ToplevelSurface<R, SD>,
surface: ToplevelSurface<R>,
/// The seat associated with this resize
seat: wl_seat::WlSeat,
/// The grab serial
@ -893,7 +884,7 @@ pub enum XdgRequest<R, SD> {
/// the grab area.
Grab {
/// The surface
surface: PopupSurface<R, SD>,
surface: PopupSurface<R>,
/// The seat to grab
seat: wl_seat::WlSeat,
/// The grab serial
@ -902,29 +893,29 @@ pub enum XdgRequest<R, SD> {
/// A toplevel surface requested to be maximized
Maximize {
/// The surface
surface: ToplevelSurface<R, SD>,
surface: ToplevelSurface<R>,
},
/// A toplevel surface requested to stop being maximized
UnMaximize {
/// The surface
surface: ToplevelSurface<R, SD>,
surface: ToplevelSurface<R>,
},
/// A toplevel surface requested to be set fullscreen
Fullscreen {
/// The surface
surface: ToplevelSurface<R, SD>,
surface: ToplevelSurface<R>,
/// The output (if any) on which the fullscreen is requested
output: Option<wl_output::WlOutput>,
},
/// A toplevel surface request to stop being fullscreen
UnFullscreen {
/// The surface
surface: ToplevelSurface<R, SD>,
surface: ToplevelSurface<R>,
},
/// A toplevel surface requested to be minimized
Minimize {
/// The surface
surface: ToplevelSurface<R, SD>,
surface: ToplevelSurface<R>,
},
/// The client requests the window menu to be displayed on this surface at this location
///
@ -932,7 +923,7 @@ pub enum XdgRequest<R, SD> {
/// control of the window (maximize/minimize/close/move/etc...).
ShowWindowMenu {
/// The surface
surface: ToplevelSurface<R, SD>,
surface: ToplevelSurface<R>,
/// The seat associated with this input grab
seat: wl_seat::WlSeat,
/// the grab serial

View File

@ -14,20 +14,19 @@ use super::{
XdgSurfacePendingState, XdgSurfaceRole,
};
pub(crate) fn implement_wm_base<R, SD>(
pub(crate) fn implement_wm_base<R>(
shell: NewResource<xdg_wm_base::XdgWmBase>,
shell_data: &ShellData<R, SD>,
shell_data: &ShellData<R>,
) -> xdg_wm_base::XdgWmBase
where
R: Role<XdgSurfaceRole> + 'static,
SD: Default + 'static,
{
let shell = shell.implement_closure(
wm_implementation::<R, SD>,
wm_implementation::<R>,
None::<fn(_)>,
ShellUserData {
shell_data: shell_data.clone(),
client_data: Mutex::new(make_shell_client_data::<SD>()),
client_data: Mutex::new(make_shell_client_data()),
},
);
let mut user_impl = shell_data.user_impl.borrow_mut();
@ -41,28 +40,26 @@ where
* xdg_shell
*/
pub(crate) struct ShellUserData<R, SD> {
shell_data: ShellData<R, SD>,
pub(crate) client_data: Mutex<ShellClientData<SD>>,
pub(crate) struct ShellUserData<R> {
shell_data: ShellData<R>,
pub(crate) client_data: Mutex<ShellClientData>,
}
pub(crate) fn make_shell_client<R, SD>(
pub(crate) fn make_shell_client<R>(
resource: &xdg_wm_base::XdgWmBase,
token: CompositorToken<R>,
) -> ShellClient<R, SD> {
) -> ShellClient<R> {
ShellClient {
kind: super::ShellClientKind::Xdg(resource.clone()),
_token: token,
_data: ::std::marker::PhantomData,
}
}
fn wm_implementation<R, SD>(request: xdg_wm_base::Request, shell: xdg_wm_base::XdgWmBase)
fn wm_implementation<R>(request: xdg_wm_base::Request, shell: xdg_wm_base::XdgWmBase)
where
R: Role<XdgSurfaceRole> + 'static,
SD: 'static,
{
let data = shell.as_ref().user_data::<ShellUserData<R, SD>>().unwrap();
let data = shell.as_ref().user_data::<ShellUserData<R>>().unwrap();
match request {
xdg_wm_base::Request::Destroy => {
// all is handled by destructor
@ -90,8 +87,8 @@ where
return;
}
id.implement_closure(
xdg_surface_implementation::<R, SD>,
Some(destroy_surface::<R, SD>),
xdg_surface_implementation::<R>,
Some(destroy_surface::<R>),
XdgSurfaceUserData {
shell_data: data.shell_data.clone(),
wl_surface: surface,
@ -186,18 +183,17 @@ fn implement_positioner(
* xdg_surface
*/
struct XdgSurfaceUserData<R, SD> {
shell_data: ShellData<R, SD>,
struct XdgSurfaceUserData<R> {
shell_data: ShellData<R>,
wl_surface: wl_surface::WlSurface,
wm_base: xdg_wm_base::XdgWmBase,
}
fn destroy_surface<R, SD>(surface: xdg_surface::XdgSurface)
fn destroy_surface<R>(surface: xdg_surface::XdgSurface)
where
R: Role<XdgSurfaceRole> + 'static,
SD: 'static,
{
let data = surface.as_ref().user_data::<XdgSurfaceUserData<R, SD>>().unwrap();
let data = surface.as_ref().user_data::<XdgSurfaceUserData<R>>().unwrap();
if !data.wl_surface.as_ref().is_alive() {
// the wl_surface is destroyed, this means the client is not
// trying to change the role but it's a cleanup (possibly a
@ -219,15 +215,11 @@ where
.expect("xdg_surface exists but surface has not shell_surface role?!");
}
fn xdg_surface_implementation<R, SD>(request: xdg_surface::Request, xdg_surface: xdg_surface::XdgSurface)
fn xdg_surface_implementation<R>(request: xdg_surface::Request, xdg_surface: xdg_surface::XdgSurface)
where
R: Role<XdgSurfaceRole> + 'static,
SD: 'static,
{
let data = xdg_surface
.as_ref()
.user_data::<XdgSurfaceUserData<R, SD>>()
.unwrap();
let data = xdg_surface.as_ref().user_data::<XdgSurfaceUserData<R>>().unwrap();
match request {
xdg_surface::Request::Destroy => {
// all is handled by our destructor
@ -246,8 +238,8 @@ where
})
.expect("xdg_surface exists but surface has not shell_surface role?!");
let toplevel = id.implement_closure(
toplevel_implementation::<R, SD>,
Some(destroy_toplevel::<R, SD>),
toplevel_implementation::<R>,
Some(destroy_toplevel::<R>),
ShellSurfaceUserData {
shell_data: data.shell_data.clone(),
wl_surface: data.wl_surface.clone(),
@ -278,7 +270,7 @@ where
.unwrap();
let parent_surface = parent.map(|parent| {
let parent_data = parent.as_ref().user_data::<XdgSurfaceUserData<R, SD>>().unwrap();
let parent_data = parent.as_ref().user_data::<XdgSurfaceUserData<R>>().unwrap();
parent_data.wl_surface.clone()
});
data.shell_data
@ -291,8 +283,8 @@ where
})
.expect("xdg_surface exists but surface has not shell_surface role?!");
let popup = id.implement_closure(
xg_popup_implementation::<R, SD>,
Some(destroy_popup::<R, SD>),
xg_popup_implementation::<R>,
Some(destroy_popup::<R>),
ShellSurfaceUserData {
shell_data: data.shell_data.clone(),
wl_surface: data.wl_surface.clone(),
@ -350,27 +342,20 @@ where
* xdg_toplevel
*/
pub(crate) struct ShellSurfaceUserData<R, SD> {
pub(crate) shell_data: ShellData<R, SD>,
pub(crate) struct ShellSurfaceUserData<R> {
pub(crate) shell_data: ShellData<R>,
pub(crate) wl_surface: wl_surface::WlSurface,
pub(crate) wm_base: xdg_wm_base::XdgWmBase,
pub(crate) xdg_surface: xdg_surface::XdgSurface,
}
// Utility functions allowing to factor out a lot of the upcoming logic
fn with_surface_toplevel_data<R, SD, F>(
shell_data: &ShellData<R, SD>,
toplevel: &xdg_toplevel::XdgToplevel,
f: F,
) where
fn with_surface_toplevel_data<R, F>(shell_data: &ShellData<R>, toplevel: &xdg_toplevel::XdgToplevel, f: F)
where
R: Role<XdgSurfaceRole> + 'static,
SD: 'static,
F: FnOnce(&mut ToplevelState),
{
let toplevel_data = toplevel
.as_ref()
.user_data::<ShellSurfaceUserData<R, SD>>()
.unwrap();
let toplevel_data = toplevel.as_ref().user_data::<ShellSurfaceUserData<R>>().unwrap();
shell_data
.compositor_token
.with_role_data::<XdgSurfaceRole, _, _>(&toplevel_data.wl_surface, |data| match data.pending_state {
@ -380,15 +365,11 @@ fn with_surface_toplevel_data<R, SD, F>(
.expect("xdg_toplevel exists but surface has not shell_surface role?!");
}
pub fn send_toplevel_configure<R, SD>(resource: &xdg_toplevel::XdgToplevel, configure: ToplevelConfigure)
pub fn send_toplevel_configure<R>(resource: &xdg_toplevel::XdgToplevel, configure: ToplevelConfigure)
where
R: Role<XdgSurfaceRole> + 'static,
SD: 'static,
{
let data = resource
.as_ref()
.user_data::<ShellSurfaceUserData<R, SD>>()
.unwrap();
let data = resource.as_ref().user_data::<ShellSurfaceUserData<R>>().unwrap();
let (width, height) = configure.size.unwrap_or((0, 0));
// convert the Vec<State> (which is really a Vec<u32>) into Vec<u8>
let states = {
@ -409,30 +390,20 @@ where
.expect("xdg_toplevel exists but surface has not shell_surface role?!");
}
fn make_toplevel_handle<R: 'static, SD: 'static>(
resource: &xdg_toplevel::XdgToplevel,
) -> super::ToplevelSurface<R, SD> {
let data = resource
.as_ref()
.user_data::<ShellSurfaceUserData<R, SD>>()
.unwrap();
fn make_toplevel_handle<R: 'static>(resource: &xdg_toplevel::XdgToplevel) -> super::ToplevelSurface<R> {
let data = resource.as_ref().user_data::<ShellSurfaceUserData<R>>().unwrap();
super::ToplevelSurface {
wl_surface: data.wl_surface.clone(),
shell_surface: ToplevelKind::Xdg(resource.clone()),
token: data.shell_data.compositor_token,
_shell_data: ::std::marker::PhantomData,
}
}
fn toplevel_implementation<R, SD>(request: xdg_toplevel::Request, toplevel: xdg_toplevel::XdgToplevel)
fn toplevel_implementation<R>(request: xdg_toplevel::Request, toplevel: xdg_toplevel::XdgToplevel)
where
R: Role<XdgSurfaceRole> + 'static,
SD: 'static,
{
let data = toplevel
.as_ref()
.user_data::<ShellSurfaceUserData<R, SD>>()
.unwrap();
let data = toplevel.as_ref().user_data::<ShellSurfaceUserData<R>>().unwrap();
match request {
xdg_toplevel::Request::Destroy => {
// all it done by the destructor
@ -442,7 +413,7 @@ where
toplevel_data.parent = parent.map(|toplevel_surface_parent| {
toplevel_surface_parent
.as_ref()
.user_data::<ShellSurfaceUserData<R, SD>>()
.user_data::<ShellSurfaceUserData<R>>()
.unwrap()
.wl_surface
.clone()
@ -531,15 +502,11 @@ where
}
}
fn destroy_toplevel<R, SD>(toplevel: xdg_toplevel::XdgToplevel)
fn destroy_toplevel<R>(toplevel: xdg_toplevel::XdgToplevel)
where
R: Role<XdgSurfaceRole> + 'static,
SD: 'static,
{
let data = toplevel
.as_ref()
.user_data::<ShellSurfaceUserData<R, SD>>()
.unwrap();
let data = toplevel.as_ref().user_data::<ShellSurfaceUserData<R>>().unwrap();
if !data.wl_surface.as_ref().is_alive() {
// the wl_surface is destroyed, this means the client is not
// trying to change the role but it's a cleanup (possibly a
@ -566,15 +533,11 @@ where
* xdg_popup
*/
pub(crate) fn send_popup_configure<R, SD>(resource: &xdg_popup::XdgPopup, configure: PopupConfigure)
pub(crate) fn send_popup_configure<R>(resource: &xdg_popup::XdgPopup, configure: PopupConfigure)
where
R: Role<XdgSurfaceRole> + 'static,
SD: 'static,
{
let data = resource
.as_ref()
.user_data::<ShellSurfaceUserData<R, SD>>()
.unwrap();
let data = resource.as_ref().user_data::<ShellSurfaceUserData<R>>().unwrap();
let (x, y) = configure.position;
let (width, height) = configure.size;
let serial = configure.serial;
@ -587,25 +550,20 @@ where
.expect("xdg_toplevel exists but surface has not shell_surface role?!");
}
fn make_popup_handle<R: 'static, SD: 'static>(resource: &xdg_popup::XdgPopup) -> super::PopupSurface<R, SD> {
let data = resource
.as_ref()
.user_data::<ShellSurfaceUserData<R, SD>>()
.unwrap();
fn make_popup_handle<R: 'static>(resource: &xdg_popup::XdgPopup) -> super::PopupSurface<R> {
let data = resource.as_ref().user_data::<ShellSurfaceUserData<R>>().unwrap();
super::PopupSurface {
wl_surface: data.wl_surface.clone(),
shell_surface: PopupKind::Xdg(resource.clone()),
token: data.shell_data.compositor_token,
_shell_data: ::std::marker::PhantomData,
}
}
fn xg_popup_implementation<R, SD>(request: xdg_popup::Request, popup: xdg_popup::XdgPopup)
fn xg_popup_implementation<R>(request: xdg_popup::Request, popup: xdg_popup::XdgPopup)
where
R: Role<XdgSurfaceRole> + 'static,
SD: 'static,
{
let data = popup.as_ref().user_data::<ShellSurfaceUserData<R, SD>>().unwrap();
let data = popup.as_ref().user_data::<ShellSurfaceUserData<R>>().unwrap();
match request {
xdg_popup::Request::Destroy => {
// all is handled by our destructor
@ -623,12 +581,11 @@ where
}
}
fn destroy_popup<R, SD>(popup: xdg_popup::XdgPopup)
fn destroy_popup<R>(popup: xdg_popup::XdgPopup)
where
R: Role<XdgSurfaceRole> + 'static,
SD: 'static,
{
let data = popup.as_ref().user_data::<ShellSurfaceUserData<R, SD>>().unwrap();
let data = popup.as_ref().user_data::<ShellSurfaceUserData<R>>().unwrap();
if !data.wl_surface.as_ref().is_alive() {
// the wl_surface is destroyed, this means the client is not
// trying to change the role but it's a cleanup (possibly a

View File

@ -17,20 +17,19 @@ use super::{
XdgSurfacePendingState, XdgSurfaceRole,
};
pub(crate) fn implement_shell<R, SD>(
pub(crate) fn implement_shell<R>(
shell: NewResource<zxdg_shell_v6::ZxdgShellV6>,
shell_data: &ShellData<R, SD>,
shell_data: &ShellData<R>,
) -> zxdg_shell_v6::ZxdgShellV6
where
R: Role<XdgSurfaceRole> + 'static,
SD: Default + 'static,
{
let shell = shell.implement_closure(
shell_implementation::<R, SD>,
shell_implementation::<R>,
None::<fn(_)>,
ShellUserData {
shell_data: shell_data.clone(),
client_data: Mutex::new(make_shell_client_data::<SD>()),
client_data: Mutex::new(make_shell_client_data()),
},
);
let mut user_impl = shell_data.user_impl.borrow_mut();
@ -44,28 +43,26 @@ where
* xdg_shell
*/
pub(crate) struct ShellUserData<R, SD> {
shell_data: ShellData<R, SD>,
pub(crate) client_data: Mutex<ShellClientData<SD>>,
pub(crate) struct ShellUserData<R> {
shell_data: ShellData<R>,
pub(crate) client_data: Mutex<ShellClientData>,
}
pub(crate) fn make_shell_client<R, SD>(
pub(crate) fn make_shell_client<R>(
resource: &zxdg_shell_v6::ZxdgShellV6,
token: CompositorToken<R>,
) -> ShellClient<R, SD> {
) -> ShellClient<R> {
ShellClient {
kind: super::ShellClientKind::ZxdgV6(resource.clone()),
_token: token,
_data: ::std::marker::PhantomData,
}
}
fn shell_implementation<R, SD>(request: zxdg_shell_v6::Request, shell: zxdg_shell_v6::ZxdgShellV6)
fn shell_implementation<R>(request: zxdg_shell_v6::Request, shell: zxdg_shell_v6::ZxdgShellV6)
where
R: Role<XdgSurfaceRole> + 'static,
SD: 'static,
{
let data = shell.as_ref().user_data::<ShellUserData<R, SD>>().unwrap();
let data = shell.as_ref().user_data::<ShellUserData<R>>().unwrap();
match request {
zxdg_shell_v6::Request::Destroy => {
// all is handled by destructor
@ -93,8 +90,8 @@ where
return;
}
id.implement_closure(
xdg_surface_implementation::<R, SD>,
Some(destroy_surface::<R, SD>),
xdg_surface_implementation::<R>,
Some(destroy_surface::<R>),
XdgSurfaceUserData {
shell_data: data.shell_data.clone(),
wl_surface: surface.clone(),
@ -203,18 +200,17 @@ fn implement_positioner(
* xdg_surface
*/
struct XdgSurfaceUserData<R, SD> {
shell_data: ShellData<R, SD>,
struct XdgSurfaceUserData<R> {
shell_data: ShellData<R>,
wl_surface: wl_surface::WlSurface,
shell: zxdg_shell_v6::ZxdgShellV6,
}
fn destroy_surface<R, SD>(surface: zxdg_surface_v6::ZxdgSurfaceV6)
fn destroy_surface<R>(surface: zxdg_surface_v6::ZxdgSurfaceV6)
where
R: Role<XdgSurfaceRole> + 'static,
SD: 'static,
{
let data = surface.as_ref().user_data::<XdgSurfaceUserData<R, SD>>().unwrap();
let data = surface.as_ref().user_data::<XdgSurfaceUserData<R>>().unwrap();
if !data.wl_surface.as_ref().is_alive() {
// the wl_surface is destroyed, this means the client is not
// trying to change the role but it's a cleanup (possibly a
@ -236,17 +232,13 @@ where
.expect("xdg_surface exists but surface has not shell_surface role?!");
}
fn xdg_surface_implementation<R, SD>(
fn xdg_surface_implementation<R>(
request: zxdg_surface_v6::Request,
xdg_surface: zxdg_surface_v6::ZxdgSurfaceV6,
) where
R: Role<XdgSurfaceRole> + 'static,
SD: 'static,
{
let data = xdg_surface
.as_ref()
.user_data::<XdgSurfaceUserData<R, SD>>()
.unwrap();
let data = xdg_surface.as_ref().user_data::<XdgSurfaceUserData<R>>().unwrap();
match request {
zxdg_surface_v6::Request::Destroy => {
// all is handled by our destructor
@ -265,8 +257,8 @@ fn xdg_surface_implementation<R, SD>(
})
.expect("xdg_surface exists but surface has not shell_surface role?!");
let toplevel = id.implement_closure(
toplevel_implementation::<R, SD>,
Some(destroy_toplevel::<R, SD>),
toplevel_implementation::<R>,
Some(destroy_toplevel::<R>),
ShellSurfaceUserData {
shell_data: data.shell_data.clone(),
wl_surface: data.wl_surface.clone(),
@ -296,7 +288,7 @@ fn xdg_surface_implementation<R, SD>(
.user_data::<RefCell<PositionerState>>()
.unwrap();
let parent_data = parent.as_ref().user_data::<XdgSurfaceUserData<R, SD>>().unwrap();
let parent_data = parent.as_ref().user_data::<XdgSurfaceUserData<R>>().unwrap();
data.shell_data
.compositor_token
.with_role_data::<XdgSurfaceRole, _, _>(&data.wl_surface, |data| {
@ -307,8 +299,8 @@ fn xdg_surface_implementation<R, SD>(
})
.expect("xdg_surface exists but surface has not shell_surface role?!");
let popup = id.implement_closure(
popup_implementation::<R, SD>,
Some(destroy_popup::<R, SD>),
popup_implementation::<R>,
Some(destroy_popup::<R>),
ShellSurfaceUserData {
shell_data: data.shell_data.clone(),
wl_surface: data.wl_surface.clone(),
@ -366,24 +358,20 @@ fn xdg_surface_implementation<R, SD>(
* xdg_toplevel
*/
pub struct ShellSurfaceUserData<R, SD> {
pub(crate) shell_data: ShellData<R, SD>,
pub struct ShellSurfaceUserData<R> {
pub(crate) shell_data: ShellData<R>,
pub(crate) wl_surface: wl_surface::WlSurface,
pub(crate) shell: zxdg_shell_v6::ZxdgShellV6,
pub(crate) xdg_surface: zxdg_surface_v6::ZxdgSurfaceV6,
}
// Utility functions allowing to factor out a lot of the upcoming logic
fn with_surface_toplevel_data<R, SD, F>(toplevel: &zxdg_toplevel_v6::ZxdgToplevelV6, f: F)
fn with_surface_toplevel_data<R, F>(toplevel: &zxdg_toplevel_v6::ZxdgToplevelV6, f: F)
where
R: Role<XdgSurfaceRole> + 'static,
SD: 'static,
F: FnOnce(&mut ToplevelState),
{
let data = toplevel
.as_ref()
.user_data::<ShellSurfaceUserData<R, SD>>()
.unwrap();
let data = toplevel.as_ref().user_data::<ShellSurfaceUserData<R>>().unwrap();
data.shell_data
.compositor_token
.with_role_data::<XdgSurfaceRole, _, _>(&data.wl_surface, |data| match data.pending_state {
@ -393,17 +381,11 @@ where
.expect("xdg_toplevel exists but surface has not shell_surface role?!");
}
pub fn send_toplevel_configure<R, SD>(
resource: &zxdg_toplevel_v6::ZxdgToplevelV6,
configure: ToplevelConfigure,
) where
pub fn send_toplevel_configure<R>(resource: &zxdg_toplevel_v6::ZxdgToplevelV6, configure: ToplevelConfigure)
where
R: Role<XdgSurfaceRole> + 'static,
SD: 'static,
{
let data = resource
.as_ref()
.user_data::<ShellSurfaceUserData<R, SD>>()
.unwrap();
let data = resource.as_ref().user_data::<ShellSurfaceUserData<R>>().unwrap();
let (width, height) = configure.size.unwrap_or((0, 0));
// convert the Vec<State> (which is really a Vec<u32>) into Vec<u8>
let states = {
@ -424,54 +406,44 @@ pub fn send_toplevel_configure<R, SD>(
.expect("xdg_toplevel exists but surface has not shell_surface role?!");
}
fn make_toplevel_handle<R: 'static, SD: 'static>(
fn make_toplevel_handle<R: 'static>(
resource: &zxdg_toplevel_v6::ZxdgToplevelV6,
) -> super::ToplevelSurface<R, SD> {
let data = resource
.as_ref()
.user_data::<ShellSurfaceUserData<R, SD>>()
.unwrap();
) -> super::ToplevelSurface<R> {
let data = resource.as_ref().user_data::<ShellSurfaceUserData<R>>().unwrap();
super::ToplevelSurface {
wl_surface: data.wl_surface.clone(),
shell_surface: ToplevelKind::ZxdgV6(resource.clone()),
token: data.shell_data.compositor_token,
_shell_data: ::std::marker::PhantomData,
}
}
fn toplevel_implementation<R, SD>(
request: zxdg_toplevel_v6::Request,
toplevel: zxdg_toplevel_v6::ZxdgToplevelV6,
) where
fn toplevel_implementation<R>(request: zxdg_toplevel_v6::Request, toplevel: zxdg_toplevel_v6::ZxdgToplevelV6)
where
R: Role<XdgSurfaceRole> + 'static,
SD: 'static,
{
let data = toplevel
.as_ref()
.user_data::<ShellSurfaceUserData<R, SD>>()
.unwrap();
let data = toplevel.as_ref().user_data::<ShellSurfaceUserData<R>>().unwrap();
match request {
zxdg_toplevel_v6::Request::Destroy => {
// all it done by the destructor
}
zxdg_toplevel_v6::Request::SetParent { parent } => {
with_surface_toplevel_data::<R, SD, _>(&toplevel, |toplevel_data| {
with_surface_toplevel_data::<R, _>(&toplevel, |toplevel_data| {
toplevel_data.parent = parent.map(|toplevel_surface_parent| {
let parent_data = toplevel_surface_parent
.as_ref()
.user_data::<ShellSurfaceUserData<R, SD>>()
.user_data::<ShellSurfaceUserData<R>>()
.unwrap();
parent_data.wl_surface.clone()
})
});
}
zxdg_toplevel_v6::Request::SetTitle { title } => {
with_surface_toplevel_data::<R, SD, _>(&toplevel, |toplevel_data| {
with_surface_toplevel_data::<R, _>(&toplevel, |toplevel_data| {
toplevel_data.title = title;
});
}
zxdg_toplevel_v6::Request::SetAppId { app_id } => {
with_surface_toplevel_data::<R, SD, _>(&toplevel, |toplevel_data| {
with_surface_toplevel_data::<R, _>(&toplevel, |toplevel_data| {
toplevel_data.app_id = app_id;
});
}
@ -507,12 +479,12 @@ fn toplevel_implementation<R, SD>(
});
}
zxdg_toplevel_v6::Request::SetMaxSize { width, height } => {
with_surface_toplevel_data::<R, SD, _>(&toplevel, |toplevel_data| {
with_surface_toplevel_data::<R, _>(&toplevel, |toplevel_data| {
toplevel_data.max_size = (width, height);
});
}
zxdg_toplevel_v6::Request::SetMinSize { width, height } => {
with_surface_toplevel_data::<R, SD, _>(&toplevel, |toplevel_data| {
with_surface_toplevel_data::<R, _>(&toplevel, |toplevel_data| {
toplevel_data.max_size = (width, height);
});
}
@ -548,15 +520,11 @@ fn toplevel_implementation<R, SD>(
}
}
fn destroy_toplevel<R, SD>(toplevel: zxdg_toplevel_v6::ZxdgToplevelV6)
fn destroy_toplevel<R>(toplevel: zxdg_toplevel_v6::ZxdgToplevelV6)
where
R: Role<XdgSurfaceRole> + 'static,
SD: 'static,
{
let data = toplevel
.as_ref()
.user_data::<ShellSurfaceUserData<R, SD>>()
.unwrap();
let data = toplevel.as_ref().user_data::<ShellSurfaceUserData<R>>().unwrap();
if !data.wl_surface.as_ref().is_alive() {
// the wl_surface is destroyed, this means the client is not
// trying to change the role but it's a cleanup (possibly a
@ -583,15 +551,11 @@ where
* xdg_popup
*/
pub(crate) fn send_popup_configure<R, SD>(resource: &zxdg_popup_v6::ZxdgPopupV6, configure: PopupConfigure)
pub(crate) fn send_popup_configure<R>(resource: &zxdg_popup_v6::ZxdgPopupV6, configure: PopupConfigure)
where
R: Role<XdgSurfaceRole> + 'static,
SD: 'static,
{
let data = resource
.as_ref()
.user_data::<ShellSurfaceUserData<R, SD>>()
.unwrap();
let data = resource.as_ref().user_data::<ShellSurfaceUserData<R>>().unwrap();
let (x, y) = configure.position;
let (width, height) = configure.size;
let serial = configure.serial;
@ -604,27 +568,20 @@ where
.expect("xdg_toplevel exists but surface has not shell_surface role?!");
}
fn make_popup_handle<R: 'static, SD: 'static>(
resource: &zxdg_popup_v6::ZxdgPopupV6,
) -> super::PopupSurface<R, SD> {
let data = resource
.as_ref()
.user_data::<ShellSurfaceUserData<R, SD>>()
.unwrap();
fn make_popup_handle<R: 'static>(resource: &zxdg_popup_v6::ZxdgPopupV6) -> super::PopupSurface<R> {
let data = resource.as_ref().user_data::<ShellSurfaceUserData<R>>().unwrap();
super::PopupSurface {
wl_surface: data.wl_surface.clone(),
shell_surface: PopupKind::ZxdgV6(resource.clone()),
token: data.shell_data.compositor_token,
_shell_data: ::std::marker::PhantomData,
}
}
fn popup_implementation<R, SD>(request: zxdg_popup_v6::Request, popup: zxdg_popup_v6::ZxdgPopupV6)
fn popup_implementation<R>(request: zxdg_popup_v6::Request, popup: zxdg_popup_v6::ZxdgPopupV6)
where
R: Role<XdgSurfaceRole> + 'static,
SD: 'static,
{
let data = popup.as_ref().user_data::<ShellSurfaceUserData<R, SD>>().unwrap();
let data = popup.as_ref().user_data::<ShellSurfaceUserData<R>>().unwrap();
match request {
zxdg_popup_v6::Request::Destroy => {
// all is handled by our destructor
@ -642,12 +599,11 @@ where
}
}
fn destroy_popup<R, SD>(popup: zxdg_popup_v6::ZxdgPopupV6)
fn destroy_popup<R>(popup: zxdg_popup_v6::ZxdgPopupV6)
where
R: Role<XdgSurfaceRole> + 'static,
SD: 'static,
{
let data = popup.as_ref().user_data::<ShellSurfaceUserData<R, SD>>().unwrap();
let data = popup.as_ref().user_data::<ShellSurfaceUserData<R>>().unwrap();
if !data.wl_surface.as_ref().is_alive() {
// the wl_surface is destroyed, this means the client is not
// trying to change the role but it's a cleanup (possibly a