shell: types documentation
This commit is contained in:
parent
30c0628959
commit
6dec2cb5da
248
src/shell/mod.rs
248
src/shell/mod.rs
|
@ -11,49 +11,109 @@ mod global;
|
||||||
mod wl_handlers;
|
mod wl_handlers;
|
||||||
mod xdg_handlers;
|
mod xdg_handlers;
|
||||||
|
|
||||||
|
/// Metadata associated with the `shell_surface` role
|
||||||
pub struct ShellSurfaceRole {
|
pub struct ShellSurfaceRole {
|
||||||
|
/// Pending state as requested by the client
|
||||||
|
///
|
||||||
|
/// The data in this field are double-buffered, you should
|
||||||
|
/// apply them on a surface commit.
|
||||||
pub pending_state: ShellSurfacePendingState,
|
pub pending_state: ShellSurfacePendingState,
|
||||||
|
/// Geometry of the surface
|
||||||
|
///
|
||||||
|
/// Defines, in surface relative coordinates, what should
|
||||||
|
/// be considered as "the surface itself", regarding focus,
|
||||||
|
/// window alignment, etc...
|
||||||
|
///
|
||||||
|
/// By default, you should consider the full contents of the
|
||||||
|
/// buffers of this surface and its subsurfaces.
|
||||||
pub window_geometry: Option<Rectangle>,
|
pub window_geometry: Option<Rectangle>,
|
||||||
|
/// List of non-acked configures pending
|
||||||
|
///
|
||||||
|
/// Whenever a configure is acked by the client, all configure
|
||||||
|
/// older than it are discarded as well. As such, this vec contains
|
||||||
|
/// the serials of all the configure send to this surface that are
|
||||||
|
/// newer than the last ack received.
|
||||||
pub pending_configures: Vec<u32>,
|
pub pending_configures: Vec<u32>,
|
||||||
|
/// Has this surface acked at least one configure?
|
||||||
|
///
|
||||||
|
/// xdg_shell defines it as illegal to commit on a surface that has
|
||||||
|
/// not yet acked a configure.
|
||||||
pub configured: bool,
|
pub configured: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug)]
|
#[derive(Copy, Clone, Debug)]
|
||||||
|
/// The state of a positioner, as set by the client
|
||||||
pub struct PositionerState {
|
pub struct PositionerState {
|
||||||
|
/// Size of the rectangle that needs to be positioned
|
||||||
pub rect_size: (i32, i32),
|
pub rect_size: (i32, i32),
|
||||||
|
/// Anchor rectangle in the parent surface coordinates
|
||||||
|
/// relative to which the surface must be positioned
|
||||||
pub anchor_rect: Rectangle,
|
pub anchor_rect: Rectangle,
|
||||||
|
/// Edges defining the anchor point
|
||||||
pub anchor_edges: xdg_positioner::Anchor,
|
pub anchor_edges: xdg_positioner::Anchor,
|
||||||
|
/// Gravity direction for positioning the child surface
|
||||||
|
/// relative to its anchor point
|
||||||
pub gravity: xdg_positioner::Gravity,
|
pub gravity: xdg_positioner::Gravity,
|
||||||
|
/// Adjustments to do if previous criterias constraint the
|
||||||
|
/// surface
|
||||||
pub constraint_adjustment: xdg_positioner::ConstraintAdjustment,
|
pub constraint_adjustment: xdg_positioner::ConstraintAdjustment,
|
||||||
|
/// Offset placement relative to the anchor point
|
||||||
pub offset: (i32, i32),
|
pub offset: (i32, i32),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Contents of the pending state of a shell surface, depending on its role
|
||||||
pub enum ShellSurfacePendingState {
|
pub enum ShellSurfacePendingState {
|
||||||
/// This a regular, toplevel surface
|
/// This a regular, toplevel surface
|
||||||
///
|
///
|
||||||
/// This corresponds to either the `xdg_toplevel` role from the
|
/// This corresponds to either the `xdg_toplevel` role from the
|
||||||
/// `xdg_shell` protocol, or the result of `set_toplevel` using the
|
/// `xdg_shell` protocol, or the result of `set_toplevel` using the
|
||||||
/// `wl_shell` protocol.
|
/// `wl_shell` protocol.
|
||||||
|
///
|
||||||
|
/// This is what you'll generaly interpret as "a window".
|
||||||
Toplevel(ToplevelState),
|
Toplevel(ToplevelState),
|
||||||
/// This is a popup surface
|
/// This is a popup surface
|
||||||
///
|
///
|
||||||
/// This corresponds to either the `xdg_popup` role from the
|
/// This corresponds to either the `xdg_popup` role from the
|
||||||
/// `xdg_shell` protocol, or the result of `set_popup` using the
|
/// `xdg_shell` protocol, or the result of `set_popup` using the
|
||||||
/// `wl_shell` protocole
|
/// `wl_shell` protocol.
|
||||||
|
///
|
||||||
|
/// This are mostly for small tooltips and similar short-lived
|
||||||
|
/// surfaces.
|
||||||
Popup(PopupState),
|
Popup(PopupState),
|
||||||
/// This surface was not yet assigned a kind
|
/// This surface was not yet assigned a kind
|
||||||
None,
|
None,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// State of a regular toplevel surface
|
||||||
pub struct ToplevelState {
|
pub struct ToplevelState {
|
||||||
|
/// Parent of this surface
|
||||||
|
///
|
||||||
|
/// If this surface has a parent, it should be hidden
|
||||||
|
/// or displayed, brought up at the same time as it.
|
||||||
pub parent: Option<wl_surface::WlSurface>,
|
pub parent: Option<wl_surface::WlSurface>,
|
||||||
|
/// Title of this shell surface
|
||||||
pub title: String,
|
pub title: String,
|
||||||
|
/// App id for this shell surface
|
||||||
|
///
|
||||||
|
/// This identifier can be used to group surface together
|
||||||
|
/// as being several instance of the same app. This can
|
||||||
|
/// also be used as the D-Bus name for the app.
|
||||||
pub app_id: String,
|
pub app_id: String,
|
||||||
|
/// Minimum size requested for this surface
|
||||||
|
///
|
||||||
|
/// A value of 0 on an axis means this axis is not constrained
|
||||||
pub min_size: (i32, i32),
|
pub min_size: (i32, i32),
|
||||||
|
/// Maximum size requested for this surface
|
||||||
|
///
|
||||||
|
/// A value of 0 on an axis means this axis is not constrained
|
||||||
pub max_size: (i32, i32),
|
pub max_size: (i32, i32),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToplevelState {
|
impl ToplevelState {
|
||||||
|
/// Clone this ToplevelState
|
||||||
|
///
|
||||||
|
/// If the parent surface refers to a surface that no longer
|
||||||
|
/// exists, it is replaced by `None` in the process.
|
||||||
pub fn clone(&self) -> ToplevelState {
|
pub fn clone(&self) -> ToplevelState {
|
||||||
ToplevelState {
|
ToplevelState {
|
||||||
parent: self.parent.as_ref().and_then(|p| p.clone()),
|
parent: self.parent.as_ref().and_then(|p| p.clone()),
|
||||||
|
@ -65,12 +125,21 @@ impl ToplevelState {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The pending state of a popup surface
|
||||||
pub struct PopupState {
|
pub struct PopupState {
|
||||||
|
/// Parent of this popup surface
|
||||||
pub parent: wl_surface::WlSurface,
|
pub parent: wl_surface::WlSurface,
|
||||||
|
/// The positioner specifying how this tooltip should
|
||||||
|
/// be placed relative to its parent.
|
||||||
pub positioner: PositionerState,
|
pub positioner: PositionerState,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PopupState {
|
impl PopupState {
|
||||||
|
/// Clone this PopupState
|
||||||
|
///
|
||||||
|
/// If the parent surface refers to a surface that no longer
|
||||||
|
/// exists, this will return `None`, as the popup can no
|
||||||
|
/// longer be meaningfully displayed.
|
||||||
pub fn clone(&self) -> Option<PopupState> {
|
pub fn clone(&self) -> Option<PopupState> {
|
||||||
if let Some(p) = self.parent.clone() {
|
if let Some(p) = self.parent.clone() {
|
||||||
Some(PopupState {
|
Some(PopupState {
|
||||||
|
@ -91,6 +160,9 @@ impl Default for ShellSurfacePendingState {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The handler for the shell globals
|
||||||
|
///
|
||||||
|
/// See module-level documentation for its use.
|
||||||
pub struct ShellHandler<U, R, H, SH, SD> {
|
pub struct ShellHandler<U, R, H, SH, SD> {
|
||||||
my_id: usize,
|
my_id: usize,
|
||||||
log: ::slog::Logger,
|
log: ::slog::Logger,
|
||||||
|
@ -167,12 +239,23 @@ struct ShellClientData<SD> {
|
||||||
data: SD,
|
data: SD,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A shell client
|
||||||
|
///
|
||||||
|
/// This represents an instanciation of a shell
|
||||||
|
/// global (be it `wl_shell` or `xdg_shell`).
|
||||||
|
///
|
||||||
|
/// Most of the time, you can consider that a
|
||||||
|
/// wayland client will be a single shell client.
|
||||||
|
///
|
||||||
|
/// You can use this handle to access a storage for any
|
||||||
|
/// client-specific data you wish to associate with it.
|
||||||
pub struct ShellClient<SD> {
|
pub struct ShellClient<SD> {
|
||||||
kind: ShellClientKind,
|
kind: ShellClientKind,
|
||||||
_data: ::std::marker::PhantomData<*mut SD>,
|
_data: ::std::marker::PhantomData<*mut SD>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<SD> ShellClient<SD> {
|
impl<SD> ShellClient<SD> {
|
||||||
|
/// Is the shell client represented by this handle still connected?
|
||||||
pub fn alive(&self) -> bool {
|
pub fn alive(&self) -> bool {
|
||||||
match self.kind {
|
match self.kind {
|
||||||
ShellClientKind::Wl(ref s) => s.status() == Liveness::Alive,
|
ShellClientKind::Wl(ref s) => s.status() == Liveness::Alive,
|
||||||
|
@ -180,6 +263,8 @@ impl<SD> ShellClient<SD> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Checks if this handle and the other one actually refer to the
|
||||||
|
/// same shell client
|
||||||
pub fn equals(&self, other: &Self) -> bool {
|
pub fn equals(&self, other: &Self) -> bool {
|
||||||
match (&self.kind, &other.kind) {
|
match (&self.kind, &other.kind) {
|
||||||
(&ShellClientKind::Wl(ref s1), &ShellClientKind::Wl(ref s2)) => s1.equals(s2),
|
(&ShellClientKind::Wl(ref s1), &ShellClientKind::Wl(ref s2)) => s1.equals(s2),
|
||||||
|
@ -230,6 +315,7 @@ impl<SD> ShellClient<SD> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Access the user data associated with this shell client
|
||||||
pub fn with_data<F, T>(&self, f: F) -> Result<T, ()>
|
pub fn with_data<F, T>(&self, f: F) -> Result<T, ()>
|
||||||
where
|
where
|
||||||
F: FnOnce(&mut SD) -> T,
|
F: FnOnce(&mut SD) -> T,
|
||||||
|
@ -259,6 +345,10 @@ enum SurfaceKind {
|
||||||
XdgPopup(zxdg_popup_v6::ZxdgPopupV6),
|
XdgPopup(zxdg_popup_v6::ZxdgPopupV6),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A handle to a toplevel surface
|
||||||
|
///
|
||||||
|
/// This is an unified abstraction over the toplevel surfaces
|
||||||
|
/// of both `wl_shell` and `xdg_shell`.
|
||||||
pub struct ToplevelSurface<U, R, H, SD> {
|
pub struct ToplevelSurface<U, R, H, SD> {
|
||||||
wl_surface: wl_surface::WlSurface,
|
wl_surface: wl_surface::WlSurface,
|
||||||
shell_surface: SurfaceKind,
|
shell_surface: SurfaceKind,
|
||||||
|
@ -272,6 +362,7 @@ where
|
||||||
R: Role<ShellSurfaceRole> + Send + 'static,
|
R: Role<ShellSurfaceRole> + Send + 'static,
|
||||||
H: CompositorHandler<U, R> + Send + 'static,
|
H: CompositorHandler<U, R> + Send + 'static,
|
||||||
{
|
{
|
||||||
|
/// Is the toplevel surface refered by this handle still alive?
|
||||||
pub fn alive(&self) -> bool {
|
pub fn alive(&self) -> bool {
|
||||||
let shell_surface_alive = match self.shell_surface {
|
let shell_surface_alive = match self.shell_surface {
|
||||||
SurfaceKind::Wl(ref s) => s.status() == Liveness::Alive,
|
SurfaceKind::Wl(ref s) => s.status() == Liveness::Alive,
|
||||||
|
@ -281,32 +372,40 @@ where
|
||||||
shell_surface_alive && self.wl_surface.status() == Liveness::Alive
|
shell_surface_alive && self.wl_surface.status() == Liveness::Alive
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Do this handle and the other one actually refer to the same toplevel surface?
|
||||||
pub fn equals(&self, other: &Self) -> bool {
|
pub fn equals(&self, other: &Self) -> bool {
|
||||||
self.alive() && other.alive() && self.wl_surface.equals(&other.wl_surface)
|
self.alive() && other.alive() && self.wl_surface.equals(&other.wl_surface)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn client(&self) -> ShellClient<SD> {
|
/// Retrieve the shell client owning this toplevel surface
|
||||||
|
///
|
||||||
|
/// Returns `None` if the surface does actually no longer exist.
|
||||||
|
pub fn client(&self) -> Option<ShellClient<SD>> {
|
||||||
|
if !self.alive() { return None }
|
||||||
match self.shell_surface {
|
match self.shell_surface {
|
||||||
SurfaceKind::Wl(ref s) => {
|
SurfaceKind::Wl(ref s) => {
|
||||||
let &(_, ref shell) =
|
let &(_, ref shell) =
|
||||||
unsafe { &*(s.get_user_data() as *mut self::wl_handlers::ShellSurfaceUserData) };
|
unsafe { &*(s.get_user_data() as *mut self::wl_handlers::ShellSurfaceUserData) };
|
||||||
ShellClient {
|
Some(ShellClient {
|
||||||
kind: ShellClientKind::Wl(unsafe { shell.clone_unchecked() }),
|
kind: ShellClientKind::Wl(unsafe { shell.clone_unchecked() }),
|
||||||
_data: ::std::marker::PhantomData,
|
_data: ::std::marker::PhantomData,
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
SurfaceKind::XdgToplevel(ref s) => {
|
SurfaceKind::XdgToplevel(ref s) => {
|
||||||
let &(_, ref shell, _) =
|
let &(_, ref shell, _) =
|
||||||
unsafe { &*(s.get_user_data() as *mut self::xdg_handlers::ShellSurfaceUserData) };
|
unsafe { &*(s.get_user_data() as *mut self::xdg_handlers::ShellSurfaceUserData) };
|
||||||
ShellClient {
|
Some(ShellClient {
|
||||||
kind: ShellClientKind::Xdg(unsafe { shell.clone_unchecked() }),
|
kind: ShellClientKind::Xdg(unsafe { shell.clone_unchecked() }),
|
||||||
_data: ::std::marker::PhantomData,
|
_data: ::std::marker::PhantomData,
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
SurfaceKind::XdgPopup(_) => unreachable!(),
|
SurfaceKind::XdgPopup(_) => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Send a configure event to this toplevel surface to suggest it a new configuration
|
||||||
|
///
|
||||||
|
/// The serial of this configure will be tracked waiting for the client to ACK it.
|
||||||
pub fn send_configure(&self, cfg: ToplevelConfigure) -> EventResult<()> {
|
pub fn send_configure(&self, cfg: ToplevelConfigure) -> EventResult<()> {
|
||||||
if !self.alive() {
|
if !self.alive() {
|
||||||
return EventResult::Destroyed;
|
return EventResult::Destroyed;
|
||||||
|
@ -354,6 +453,9 @@ where
|
||||||
configured
|
configured
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Access the underlying `wl_surface` of this toplevel surface
|
||||||
|
///
|
||||||
|
/// Returns `None` if the toplevel surface actually no longer exists.
|
||||||
pub fn get_surface(&self) -> Option<&wl_surface::WlSurface> {
|
pub fn get_surface(&self) -> Option<&wl_surface::WlSurface> {
|
||||||
if self.alive() {
|
if self.alive() {
|
||||||
Some(&self.wl_surface)
|
Some(&self.wl_surface)
|
||||||
|
@ -362,6 +464,9 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Retrieve a copy of the pending state of this toplevel surface
|
||||||
|
///
|
||||||
|
/// Returns `None` of the toplevel surface actually no longer exists.
|
||||||
pub fn get_pending_state(&self) -> Option<ToplevelState> {
|
pub fn get_pending_state(&self) -> Option<ToplevelState> {
|
||||||
if !self.alive() {
|
if !self.alive() {
|
||||||
return None;
|
return None;
|
||||||
|
@ -376,6 +481,10 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A handle to a popup surface
|
||||||
|
///
|
||||||
|
/// This is an unified abstraction over the popup surfaces
|
||||||
|
/// of both `wl_shell` and `xdg_shell`.
|
||||||
pub struct PopupSurface<U, R, H, SD> {
|
pub struct PopupSurface<U, R, H, SD> {
|
||||||
wl_surface: wl_surface::WlSurface,
|
wl_surface: wl_surface::WlSurface,
|
||||||
shell_surface: SurfaceKind,
|
shell_surface: SurfaceKind,
|
||||||
|
@ -389,6 +498,7 @@ where
|
||||||
R: Role<ShellSurfaceRole> + Send + 'static,
|
R: Role<ShellSurfaceRole> + Send + 'static,
|
||||||
H: CompositorHandler<U, R> + Send + 'static,
|
H: CompositorHandler<U, R> + Send + 'static,
|
||||||
{
|
{
|
||||||
|
/// Is the popup surface refered by this handle still alive?
|
||||||
pub fn alive(&self) -> bool {
|
pub fn alive(&self) -> bool {
|
||||||
let shell_surface_alive = match self.shell_surface {
|
let shell_surface_alive = match self.shell_surface {
|
||||||
SurfaceKind::Wl(ref s) => s.status() == Liveness::Alive,
|
SurfaceKind::Wl(ref s) => s.status() == Liveness::Alive,
|
||||||
|
@ -398,32 +508,40 @@ where
|
||||||
shell_surface_alive && self.wl_surface.status() == Liveness::Alive
|
shell_surface_alive && self.wl_surface.status() == Liveness::Alive
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Do this handle and the other one actually refer to the same popup surface?
|
||||||
pub fn equals(&self, other: &Self) -> bool {
|
pub fn equals(&self, other: &Self) -> bool {
|
||||||
self.alive() && other.alive() && self.wl_surface.equals(&other.wl_surface)
|
self.alive() && other.alive() && self.wl_surface.equals(&other.wl_surface)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn client(&self) -> ShellClient<SD> {
|
/// Retrieve the shell client owning this popup surface
|
||||||
|
///
|
||||||
|
/// Returns `None` if the surface does actually no longer exist.
|
||||||
|
pub fn client(&self) -> Option<ShellClient<SD>> {
|
||||||
|
if !self.alive() { return None }
|
||||||
match self.shell_surface {
|
match self.shell_surface {
|
||||||
SurfaceKind::Wl(ref s) => {
|
SurfaceKind::Wl(ref s) => {
|
||||||
let &(_, ref shell) =
|
let &(_, ref shell) =
|
||||||
unsafe { &*(s.get_user_data() as *mut self::wl_handlers::ShellSurfaceUserData) };
|
unsafe { &*(s.get_user_data() as *mut self::wl_handlers::ShellSurfaceUserData) };
|
||||||
ShellClient {
|
Some(ShellClient {
|
||||||
kind: ShellClientKind::Wl(unsafe { shell.clone_unchecked() }),
|
kind: ShellClientKind::Wl(unsafe { shell.clone_unchecked() }),
|
||||||
_data: ::std::marker::PhantomData,
|
_data: ::std::marker::PhantomData,
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
SurfaceKind::XdgPopup(ref s) => {
|
SurfaceKind::XdgPopup(ref s) => {
|
||||||
let &(_, ref shell, _) =
|
let &(_, ref shell, _) =
|
||||||
unsafe { &*(s.get_user_data() as *mut self::xdg_handlers::ShellSurfaceUserData) };
|
unsafe { &*(s.get_user_data() as *mut self::xdg_handlers::ShellSurfaceUserData) };
|
||||||
ShellClient {
|
Some(ShellClient {
|
||||||
kind: ShellClientKind::Xdg(unsafe { shell.clone_unchecked() }),
|
kind: ShellClientKind::Xdg(unsafe { shell.clone_unchecked() }),
|
||||||
_data: ::std::marker::PhantomData,
|
_data: ::std::marker::PhantomData,
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
SurfaceKind::XdgToplevel(_) => unreachable!(),
|
SurfaceKind::XdgToplevel(_) => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Send a configure event to this toplevel surface to suggest it a new configuration
|
||||||
|
///
|
||||||
|
/// The serial of this configure will be tracked waiting for the client to ACK it.
|
||||||
pub fn send_configure(&self, cfg: PopupConfigure) -> EventResult<()> {
|
pub fn send_configure(&self, cfg: PopupConfigure) -> EventResult<()> {
|
||||||
if !self.alive() {
|
if !self.alive() {
|
||||||
return EventResult::Destroyed;
|
return EventResult::Destroyed;
|
||||||
|
@ -436,6 +554,43 @@ where
|
||||||
EventResult::Sent(())
|
EventResult::Sent(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Make sure this surface was configured
|
||||||
|
///
|
||||||
|
/// Returns `true` if it was, if not, returns `false` and raise
|
||||||
|
/// a protocol error to the associated client. Also returns `false`
|
||||||
|
/// if the surface is already destroyed.
|
||||||
|
///
|
||||||
|
/// xdg_shell mandates that a client acks a configure before commiting
|
||||||
|
/// anything.
|
||||||
|
pub fn ensure_configured(&self) -> bool {
|
||||||
|
if !self.alive() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
let configured = self.token
|
||||||
|
.with_role_data::<ShellSurfaceRole, _, _>(&self.wl_surface, |data| data.configured)
|
||||||
|
.expect(
|
||||||
|
"A shell surface object exists but the surface does not have the shell_surface role ?!",
|
||||||
|
);
|
||||||
|
if !configured {
|
||||||
|
if let SurfaceKind::XdgPopup(ref s) = self.shell_surface {
|
||||||
|
let ptr = s.get_user_data();
|
||||||
|
let &(_, _, ref xdg_surface) =
|
||||||
|
unsafe { &*(ptr as *mut self::xdg_handlers::ShellSurfaceUserData) };
|
||||||
|
xdg_surface.post_error(
|
||||||
|
zxdg_surface_v6::Error::NotConstructed as u32,
|
||||||
|
"Surface has not been confgured yet.".into(),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
unreachable!();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
configured
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Send a 'popup_done' event to the popup surface
|
||||||
|
///
|
||||||
|
/// It means that the use has dismissed the popup surface, or that
|
||||||
|
/// the pointer has left the area of popup grab if there was a grab.
|
||||||
pub fn send_popup_done(&self) -> EventResult<()> {
|
pub fn send_popup_done(&self) -> EventResult<()> {
|
||||||
if !self.alive() {
|
if !self.alive() {
|
||||||
return EventResult::Destroyed;
|
return EventResult::Destroyed;
|
||||||
|
@ -447,6 +602,9 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Access the underlying `wl_surface` of this toplevel surface
|
||||||
|
///
|
||||||
|
/// Returns `None` if the toplevel surface actually no longer exists.
|
||||||
pub fn get_surface(&self) -> Option<&wl_surface::WlSurface> {
|
pub fn get_surface(&self) -> Option<&wl_surface::WlSurface> {
|
||||||
if self.alive() {
|
if self.alive() {
|
||||||
Some(&self.wl_surface)
|
Some(&self.wl_surface)
|
||||||
|
@ -455,6 +613,9 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Retrieve a copy of the pending state of this popup surface
|
||||||
|
///
|
||||||
|
/// Returns `None` of the popup surface actually no longer exists.
|
||||||
pub fn get_pending_state(&self) -> Option<PopupState> {
|
pub fn get_pending_state(&self) -> Option<PopupState> {
|
||||||
if !self.alive() {
|
if !self.alive() {
|
||||||
return None;
|
return None;
|
||||||
|
@ -469,35 +630,100 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A configure message for toplevel surfaces
|
||||||
pub struct ToplevelConfigure {
|
pub struct ToplevelConfigure {
|
||||||
|
/// A suggestion for a new size for the surface
|
||||||
pub size: Option<(i32, i32)>,
|
pub size: Option<(i32, i32)>,
|
||||||
|
/// A notification of what are the current states of this surface
|
||||||
|
///
|
||||||
|
/// A surface can be any combination of these possible states
|
||||||
|
/// at the same time.
|
||||||
pub states: Vec<zxdg_toplevel_v6::State>,
|
pub states: Vec<zxdg_toplevel_v6::State>,
|
||||||
|
/// A serial number to track ACK from the client
|
||||||
|
///
|
||||||
|
/// This should be an ever increasing number, as the ACK-ing
|
||||||
|
/// from a client for a serial will validate all pending lower
|
||||||
|
/// serials.
|
||||||
pub serial: u32,
|
pub serial: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A configure message for popup surface
|
||||||
pub struct PopupConfigure {
|
pub struct PopupConfigure {
|
||||||
|
/// The position chosen for this popup relative to
|
||||||
|
/// its parent
|
||||||
pub position: (i32, i32),
|
pub position: (i32, i32),
|
||||||
|
/// A suggested size for the popup
|
||||||
pub size: (i32, i32),
|
pub size: (i32, i32),
|
||||||
|
/// A serial number to track ACK from the client
|
||||||
|
///
|
||||||
|
/// This should be an ever increasing number, as the ACK-ing
|
||||||
|
/// from a client for a serial will validate all pending lower
|
||||||
|
/// serials.
|
||||||
pub serial: u32,
|
pub serial: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A trait for the sub-handler provided to the ShellHandler
|
||||||
|
///
|
||||||
|
/// You need to implement this trait to handle events that the ShellHandler
|
||||||
|
/// cannot process for you directly.
|
||||||
|
///
|
||||||
|
/// Depending on what you want to do, you might implement some of these methods
|
||||||
|
/// as doing nothing.
|
||||||
pub trait Handler<U, R, H, SD> {
|
pub trait Handler<U, R, H, SD> {
|
||||||
|
/// A new shell client was instanciated
|
||||||
fn new_client(&mut self, evlh: &mut EventLoopHandle, client: ShellClient<SD>);
|
fn new_client(&mut self, evlh: &mut EventLoopHandle, client: ShellClient<SD>);
|
||||||
|
/// The pong for a pending ping of this shell client was received
|
||||||
|
///
|
||||||
|
/// The SHellHandler already checked for you that the serial matches the one
|
||||||
|
/// from the pending ping.
|
||||||
fn client_pong(&mut self, evlh: &mut EventLoopHandle, client: ShellClient<SD>);
|
fn client_pong(&mut self, evlh: &mut EventLoopHandle, client: ShellClient<SD>);
|
||||||
|
/// A new toplevel surface was created
|
||||||
|
///
|
||||||
|
/// You need to return a `ToplevelConfigure` from this method, which will be sent
|
||||||
|
/// to the client to configure this surface
|
||||||
fn new_toplevel(&mut self, evlh: &mut EventLoopHandle, surface: ToplevelSurface<U, R, H, SD>)
|
fn new_toplevel(&mut self, evlh: &mut EventLoopHandle, surface: ToplevelSurface<U, R, H, SD>)
|
||||||
-> ToplevelConfigure;
|
-> ToplevelConfigure;
|
||||||
|
/// A new popup surface was created
|
||||||
|
///
|
||||||
|
/// You need to return a `PopupConfigure` from this method, which will be sent
|
||||||
|
/// to the client to configure this surface
|
||||||
fn new_popup(&mut self, evlh: &mut EventLoopHandle, surface: PopupSurface<U, R, H, SD>)
|
fn new_popup(&mut self, evlh: &mut EventLoopHandle, surface: PopupSurface<U, R, H, SD>)
|
||||||
-> PopupConfigure;
|
-> PopupConfigure;
|
||||||
|
/// The client requested the start of an interactive move for this surface
|
||||||
fn move_(&mut self, evlh: &mut EventLoopHandle, surface: ToplevelSurface<U, R, H, SD>,
|
fn move_(&mut self, evlh: &mut EventLoopHandle, surface: ToplevelSurface<U, R, H, SD>,
|
||||||
seat: &wl_seat::WlSeat, serial: u32);
|
seat: &wl_seat::WlSeat, serial: u32);
|
||||||
|
/// The client requested the start of an interactive resize for this surface
|
||||||
|
///
|
||||||
|
/// The `edges` argument specifies which part of the window's border is being dragged.
|
||||||
fn resize(&mut self, evlh: &mut EventLoopHandle, surface: ToplevelSurface<U, R, H, SD>,
|
fn resize(&mut self, evlh: &mut EventLoopHandle, surface: ToplevelSurface<U, R, H, SD>,
|
||||||
seat: &wl_seat::WlSeat, serial: u32, edges: zxdg_toplevel_v6::ResizeEdge);
|
seat: &wl_seat::WlSeat, serial: u32, edges: zxdg_toplevel_v6::ResizeEdge);
|
||||||
|
/// This popup requests a grab of the pointer
|
||||||
|
///
|
||||||
|
/// This means it requests to be sent a `popup_done` event when the pointer leaves
|
||||||
|
/// the grab area.
|
||||||
fn grab(&mut self, evlh: &mut EventLoopHandle, surface: PopupSurface<U, R, H, SD>,
|
fn grab(&mut self, evlh: &mut EventLoopHandle, surface: PopupSurface<U, R, H, SD>,
|
||||||
seat: &wl_seat::WlSeat, serial: u32);
|
seat: &wl_seat::WlSeat, serial: u32);
|
||||||
|
/// A toplevel surface requested its display state to be changed
|
||||||
|
///
|
||||||
|
/// Each field represents the request of the client for a specific property:
|
||||||
|
///
|
||||||
|
/// - `None`: no request is made to change this property
|
||||||
|
/// - `Some(true)`: this property should be enabled
|
||||||
|
/// - `Some(false)`: this property should be disabled
|
||||||
|
///
|
||||||
|
/// For fullscreen/maximization, the client can also optionnaly request a specific
|
||||||
|
/// output.
|
||||||
|
///
|
||||||
|
/// You are to answer with a `ToplevelConfigure` that will be sent to the client in
|
||||||
|
/// response.
|
||||||
fn change_display_state(&mut self, evlh: &mut EventLoopHandle, surface: ToplevelSurface<U, R, H, SD>,
|
fn change_display_state(&mut self, evlh: &mut EventLoopHandle, surface: ToplevelSurface<U, R, H, SD>,
|
||||||
maximized: Option<bool>, minimized: Option<bool>, fullscreen: Option<bool>,
|
maximized: Option<bool>, minimized: Option<bool>, fullscreen: Option<bool>,
|
||||||
output: Option<&wl_output::WlOutput>)
|
output: Option<&wl_output::WlOutput>)
|
||||||
-> ToplevelConfigure;
|
-> ToplevelConfigure;
|
||||||
|
/// The client requests the window menu to be displayed on this surface at this location
|
||||||
|
///
|
||||||
|
/// This menu belongs to the compositor. It is typically expected to contain options for
|
||||||
|
/// control of the window (maximize/minimize/close/move/etc...).
|
||||||
fn show_window_menu(&mut self, evlh: &mut EventLoopHandle, surface: ToplevelSurface<U, R, H, SD>,
|
fn show_window_menu(&mut self, evlh: &mut EventLoopHandle, surface: ToplevelSurface<U, R, H, SD>,
|
||||||
seat: &wl_seat::WlSeat, serial: u32, x: i32, y: i32);
|
seat: &wl_seat::WlSeat, serial: u32, x: i32, y: i32);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue