wayland.shell.xdg: review docs & API

This commit is contained in:
Victor Berger 2021-07-01 23:07:07 +02:00 committed by Victor Berger
parent ba6bef3e85
commit e96272cae5
6 changed files with 246 additions and 177 deletions

View File

@ -352,7 +352,7 @@ pub fn init_shell<BackendData: 'static>(display: Rc<RefCell<Display>>, log: ::sl
let xdg_output_map = output_map.clone();
let (xdg_shell_state, _, _) = xdg_shell_init(
&mut *display.borrow_mut(),
move |shell_event| match shell_event {
move |shell_event, _dispatch_data| match shell_event {
XdgRequest::NewToplevel { surface } => {
// place the window at a random location on the primary output
// or if there is not output in a [0;800]x[0;800] square

View File

@ -17,7 +17,7 @@ use crate::shell::SurfaceData;
#[cfg(feature = "xwayland")]
use crate::xwayland::X11Surface;
#[derive(Clone)]
#[derive(Clone, PartialEq)]
pub enum Kind {
Xdg(ToplevelSurface),
Wl(ShellSurface),
@ -44,17 +44,6 @@ impl Kind {
}
}
/// Do this handle and the other one actually refer to the same toplevel surface?
pub fn equals(&self, other: &Self) -> bool {
match (self, other) {
(Kind::Xdg(a), Kind::Xdg(b)) => a.equals(b),
(Kind::Wl(a), Kind::Wl(b)) => a.equals(b),
#[cfg(feature = "xwayland")]
(Kind::X11(a), Kind::X11(b)) => a.equals(b),
_ => false,
}
}
/// Activate/Deactivate this window
pub fn set_activated(&self, active: bool) {
if let Kind::Xdg(ref t) = self {
@ -357,7 +346,7 @@ impl WindowMap {
/// Refreshes the state of the toplevel, if it exists.
pub fn refresh_toplevel(&mut self, toplevel: &Kind) {
if let Some(w) = self.windows.iter_mut().find(|w| w.toplevel.equals(toplevel)) {
if let Some(w) = self.windows.iter_mut().find(|w| &w.toplevel == toplevel) {
w.self_update();
}
}
@ -400,13 +389,13 @@ impl WindowMap {
pub fn location(&self, toplevel: &Kind) -> Option<(i32, i32)> {
self.windows
.iter()
.find(|w| w.toplevel.equals(toplevel))
.find(|w| &w.toplevel == toplevel)
.map(|w| w.location)
}
/// Sets the location of the toplevel, if it exists.
pub fn set_location(&mut self, toplevel: &Kind, location: (i32, i32)) {
if let Some(w) = self.windows.iter_mut().find(|w| w.toplevel.equals(toplevel)) {
if let Some(w) = self.windows.iter_mut().find(|w| &w.toplevel == toplevel) {
w.location = location;
w.self_update();
}
@ -416,7 +405,7 @@ impl WindowMap {
pub fn geometry(&self, toplevel: &Kind) -> Option<Rectangle> {
self.windows
.iter()
.find(|w| w.toplevel.equals(toplevel))
.find(|w| &w.toplevel == toplevel)
.map(|w| w.geometry())
}

View File

@ -237,15 +237,17 @@ pub struct X11Surface {
surface: WlSurface,
}
impl std::cmp::PartialEq for X11Surface {
fn eq(&self, other: &Self) -> bool {
self.alive() && other.alive() && self.surface == other.surface
}
}
impl X11Surface {
pub fn alive(&self) -> bool {
self.surface.as_ref().is_alive()
}
pub fn equals(&self, other: &Self) -> bool {
self.alive() && other.alive() && self.surface.as_ref().equals(&other.surface.as_ref())
}
pub fn get_surface(&self) -> Option<&WlSurface> {
if self.alive() {
Some(&self.surface)

View File

@ -22,24 +22,19 @@
//! ### Initialization
//!
//! To initialize this handler, simple use the [`xdg_shell_init`] function provided in this module.
//! You need to provide a closure that will be invoked whenever some action is required from you,
//! are represented by the [`XdgRequest`] enum.
//!
//! ```no_run
//! # extern crate wayland_server;
//! #
//! use smithay::wayland::shell::xdg::{xdg_shell_init, XdgRequest};
//!
//!
//! // define the metadata you want associated with the shell clients
//! #[derive(Default)]
//! struct MyShellData {
//! /* ... */
//! }
//!
//! # let mut display = wayland_server::Display::new();
//! let (shell_state, _, _) = xdg_shell_init(
//! &mut display,
//! // your implementation
//! |event: XdgRequest| { /* ... */ },
//! |event: XdgRequest, dispatch_data| { /* handle the shell requests here */ },
//! None // put a logger if you want
//! );
//!
@ -52,8 +47,7 @@
//!
//! - [`ShellClient`]:
//! This is a handle representing an instantiation of a shell global
//! you can associate client-wise metadata to it (this is the `MyShellData` type in
//! the example above).
//! you can associate client-wise metadata to it through an [`UserDataMap`].
//! - [`ToplevelSurface`]:
//! This is a handle representing a toplevel surface, you can
//! retrieve a list of all currently alive toplevel surface from the
@ -84,6 +78,7 @@ use wayland_protocols::{
unstable::xdg_shell::v6::server::{zxdg_popup_v6, zxdg_shell_v6, zxdg_toplevel_v6},
xdg_shell::server::{xdg_popup, xdg_positioner, xdg_toplevel, xdg_wm_base},
};
use wayland_server::DispatchData;
use wayland_server::{
protocol::{wl_output, wl_seat, wl_surface},
Display, Filter, Global, UserDataMap,
@ -646,7 +641,7 @@ impl Cacheable for SurfaceCachedState {
pub(crate) struct ShellData {
log: ::slog::Logger,
user_impl: Rc<RefCell<dyn FnMut(XdgRequest)>>,
user_impl: Rc<RefCell<dyn FnMut(XdgRequest, DispatchData<'_>)>>,
shell_state: Arc<Mutex<ShellState>>,
}
@ -672,7 +667,7 @@ pub fn xdg_shell_init<L, Impl>(
)
where
L: Into<Option<::slog::Logger>>,
Impl: FnMut(XdgRequest) + 'static,
Impl: FnMut(XdgRequest, DispatchData<'_>) + 'static,
{
let log = crate::slog_or_fallback(logger);
let shell_state = Arc::new(Mutex::new(ShellState {
@ -690,15 +685,15 @@ where
let xdg_shell_global = display.create_global(
1,
Filter::new(move |(shell, _version), _, _data| {
self::xdg_handlers::implement_wm_base(shell, &shell_data);
Filter::new(move |(shell, _version), _, dispatch_data| {
self::xdg_handlers::implement_wm_base(shell, &shell_data, dispatch_data);
}),
);
let zxdgv6_shell_global = display.create_global(
1,
Filter::new(move |(shell, _version), _, _data| {
self::zxdgv6_handlers::implement_shell(shell, &shell_data_z);
Filter::new(move |(shell, _version), _, dispatch_data| {
self::zxdgv6_handlers::implement_shell(shell, &shell_data_z, dispatch_data);
}),
);
@ -764,6 +759,16 @@ pub struct ShellClient {
kind: ShellClientKind,
}
impl std::cmp::PartialEq for ShellClient {
fn eq(&self, other: &Self) -> bool {
match (&self.kind, &other.kind) {
(&ShellClientKind::Xdg(ref s1), &ShellClientKind::Xdg(ref s2)) => s1 == s2,
(&ShellClientKind::ZxdgV6(ref s1), &ShellClientKind::ZxdgV6(ref s2)) => s1 == s2,
_ => false,
}
}
}
impl ShellClient {
/// Is the shell client represented by this handle still connected?
pub fn alive(&self) -> bool {
@ -773,18 +778,6 @@ impl ShellClient {
}
}
/// Checks if this handle and the other one actually refer to the
/// same shell client
pub fn equals(&self, other: &Self) -> bool {
match (&self.kind, &other.kind) {
(&ShellClientKind::Xdg(ref s1), &ShellClientKind::Xdg(ref s2)) => s1.as_ref().equals(s2.as_ref()),
(&ShellClientKind::ZxdgV6(ref s1), &ShellClientKind::ZxdgV6(ref s2)) => {
s1.as_ref().equals(s2.as_ref())
}
_ => false,
}
}
/// Send a ping request to this shell client
///
/// You'll receive the reply as a [`XdgRequest::ClientPong`] request.
@ -873,6 +866,12 @@ pub struct ToplevelSurface {
shell_surface: ToplevelKind,
}
impl std::cmp::PartialEq for ToplevelSurface {
fn eq(&self, other: &Self) -> bool {
self.alive() && other.alive() && self.wl_surface == other.wl_surface
}
}
impl ToplevelSurface {
/// Is the toplevel surface referred by this handle still alive?
pub fn alive(&self) -> bool {
@ -883,11 +882,6 @@ impl ToplevelSurface {
shell_alive && self.wl_surface.as_ref().is_alive()
}
/// Do this handle and the other one actually refer to the same toplevel surface?
pub fn equals(&self, other: &Self) -> bool {
self.alive() && other.alive() && self.wl_surface.as_ref().equals(&other.wl_surface.as_ref())
}
/// Retrieve the shell client owning this toplevel surface
///
/// Returns `None` if the surface does actually no longer exist.
@ -957,6 +951,9 @@ impl ToplevelSurface {
/// 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.
///
/// You can manipulate the state that will be sent to the client with the [`with_pending_state`](#method.with_pending_state)
/// method.
pub fn send_configure(&self) {
if let Some(surface) = self.get_surface() {
let configure = compositor::with_states(surface, |states| {
@ -1084,13 +1081,10 @@ impl ToplevelSurface {
/// Allows the pending state of this toplevel to
/// be manipulated.
///
/// This should be used to inform the client about
/// size and state changes.
/// This should be used to inform the client about size and state changes,
/// for example after a resize request from the client.
///
/// For example after a resize request from the client.
///
/// The state will be sent to the client when calling
/// send_configure.
/// The state will be sent to the client when calling [`send_configure`](#method.send_configure).
pub fn with_pending_state<F, T>(&self, f: F) -> Result<T, DeadResource>
where
F: FnOnce(&mut ToplevelState) -> T,
@ -1157,6 +1151,12 @@ pub struct PopupSurface {
shell_surface: PopupKind,
}
impl std::cmp::PartialEq for PopupSurface {
fn eq(&self, other: &Self) -> bool {
self.alive() && other.alive() && self.wl_surface == other.wl_surface
}
}
impl PopupSurface {
/// Is the popup surface referred by this handle still alive?
pub fn alive(&self) -> bool {
@ -1187,11 +1187,6 @@ impl PopupSurface {
}
}
/// Do this handle and the other one actually refer to the same popup surface?
pub fn equals(&self, other: &Self) -> bool {
self.alive() && other.alive() && self.wl_surface.as_ref().equals(&other.wl_surface.as_ref())
}
/// Retrieve the shell client owning this popup surface
///
/// Returns `None` if the surface does actually no longer exist.
@ -1225,6 +1220,9 @@ impl PopupSurface {
/// Send a configure event to this popup surface to suggest it a new configuration
///
/// The serial of this configure will be tracked waiting for the client to ACK it.
///
/// You can manipulate the state that will be sent to the client with the [`with_pending_state`](#method.with_pending_state)
/// method.
pub fn send_configure(&self) {
if let Some(surface) = self.get_surface() {
let next_configure = compositor::with_states(surface, |states| {
@ -1406,13 +1404,10 @@ impl PopupSurface {
/// Allows the pending state of this popup to
/// be manipulated.
///
/// This should be used to inform the client about
/// size and position changes.
/// This should be used to inform the client about size and position changes,
/// for example after a move of the parent toplevel.
///
/// For example after a move of the parent toplevel.
///
/// The state will be sent to the client when calling
/// send_configure.
/// The state will be sent to the client when calling [`send_configure`](#method.send_configure).
pub fn with_pending_state<F, T>(&self, f: F) -> Result<T, DeadResource>
where
F: FnOnce(&mut PopupState) -> T,
@ -1515,7 +1510,7 @@ pub enum XdgRequest {
/// A new toplevel surface was created
///
/// You likely need to send a [`ToplevelConfigure`] to the surface, to hint the
/// client as to how its window should be
/// client as to how its window should be sized.
NewToplevel {
/// the surface
surface: ToplevelSurface,
@ -1523,7 +1518,7 @@ pub enum XdgRequest {
/// A new popup surface was created
///
/// You likely need to send a [`PopupConfigure`] to the surface, to hint the
/// client as to how its popup should be
/// client as to how its popup should be sized.
NewPopup {
/// the surface
surface: PopupSurface,

View File

@ -7,6 +7,7 @@ use crate::wayland::Serial;
use wayland_protocols::xdg_shell::server::{
xdg_popup, xdg_positioner, xdg_surface, xdg_toplevel, xdg_wm_base,
};
use wayland_server::DispatchData;
use wayland_server::{protocol::wl_surface, Filter, Main};
use crate::utils::Rectangle;
@ -23,16 +24,20 @@ static XDG_POPUP_ROLE: &str = "xdg_popup";
pub(crate) fn implement_wm_base(
shell: Main<xdg_wm_base::XdgWmBase>,
shell_data: &ShellData,
dispatch_data: DispatchData<'_>,
) -> xdg_wm_base::XdgWmBase {
shell.quick_assign(|shell, req, _data| wm_implementation(req, shell.deref().clone()));
shell.quick_assign(wm_implementation);
shell.as_ref().user_data().set(|| ShellUserData {
shell_data: shell_data.clone(),
client_data: Mutex::new(make_shell_client_data()),
});
let mut user_impl = shell_data.user_impl.borrow_mut();
(&mut *user_impl)(XdgRequest::NewClient {
(&mut *user_impl)(
XdgRequest::NewClient {
client: make_shell_client(&shell),
});
},
dispatch_data,
);
shell.deref().clone()
}
@ -51,7 +56,11 @@ pub(crate) fn make_shell_client(resource: &xdg_wm_base::XdgWmBase) -> ShellClien
}
}
fn wm_implementation(request: xdg_wm_base::Request, shell: xdg_wm_base::XdgWmBase) {
fn wm_implementation(
shell: Main<xdg_wm_base::XdgWmBase>,
request: xdg_wm_base::Request,
dispatch_data: DispatchData<'_>,
) {
let data = shell.as_ref().user_data().get::<ShellUserData>().unwrap();
match request {
xdg_wm_base::Request::Destroy => {
@ -64,12 +73,14 @@ fn wm_implementation(request: xdg_wm_base::Request, shell: xdg_wm_base::XdgWmBas
// Do not assign a role to the surface here
// xdg_surface is not role, only xdg_toplevel and
// xdg_popup are defined as roles
id.quick_assign(|surface, req, _data| xdg_surface_implementation(req, surface.deref().clone()));
id.quick_assign(|surface, req, dispatch_data| {
xdg_surface_implementation(req, surface.deref().clone(), dispatch_data)
});
id.assign_destructor(Filter::new(|surface, _, _data| destroy_surface(surface)));
id.as_ref().user_data().set(|| XdgSurfaceUserData {
shell_data: data.shell_data.clone(),
wl_surface: surface,
wm_base: shell.clone(),
wm_base: shell.deref().clone(),
has_active_role: AtomicBool::new(false),
});
}
@ -86,9 +97,12 @@ fn wm_implementation(request: xdg_wm_base::Request, shell: xdg_wm_base::XdgWmBas
};
if valid {
let mut user_impl = data.shell_data.user_impl.borrow_mut();
(&mut *user_impl)(XdgRequest::ClientPong {
(&mut *user_impl)(
XdgRequest::ClientPong {
client: make_shell_client(&shell),
});
},
dispatch_data,
);
}
}
_ => unreachable!(),
@ -191,7 +205,11 @@ fn destroy_surface(surface: xdg_surface::XdgSurface) {
}
}
fn xdg_surface_implementation(request: xdg_surface::Request, xdg_surface: xdg_surface::XdgSurface) {
fn xdg_surface_implementation(
request: xdg_surface::Request,
xdg_surface: xdg_surface::XdgSurface,
dispatch_data: DispatchData<'_>,
) {
let data = xdg_surface
.as_ref()
.user_data()
@ -225,7 +243,7 @@ fn xdg_surface_implementation(request: xdg_surface::Request, xdg_surface: xdg_su
compositor::add_commit_hook(surface, super::ToplevelSurface::commit_hook);
id.quick_assign(|toplevel, req, _data| toplevel_implementation(req, toplevel.deref().clone()));
id.quick_assign(toplevel_implementation);
id.assign_destructor(Filter::new(|toplevel, _, _data| destroy_toplevel(toplevel)));
id.as_ref().user_data().set(|| ShellSurfaceUserData {
shell_data: data.shell_data.clone(),
@ -243,7 +261,7 @@ fn xdg_surface_implementation(request: xdg_surface::Request, xdg_surface: xdg_su
let handle = make_toplevel_handle(&id);
let mut user_impl = data.shell_data.user_impl.borrow_mut();
(&mut *user_impl)(XdgRequest::NewToplevel { surface: handle });
(&mut *user_impl)(XdgRequest::NewToplevel { surface: handle }, dispatch_data);
}
xdg_surface::Request::GetPopup {
id,
@ -300,7 +318,7 @@ fn xdg_surface_implementation(request: xdg_surface::Request, xdg_surface: xdg_su
compositor::add_commit_hook(surface, super::PopupSurface::commit_hook);
id.quick_assign(|popup, req, _data| xdg_popup_implementation(req, popup.deref().clone()));
id.quick_assign(xdg_popup_implementation);
id.assign_destructor(Filter::new(|popup, _, _data| destroy_popup(popup)));
id.as_ref().user_data().set(|| ShellSurfaceUserData {
shell_data: data.shell_data.clone(),
@ -318,7 +336,7 @@ fn xdg_surface_implementation(request: xdg_surface::Request, xdg_surface: xdg_su
let handle = make_popup_handle(&id);
let mut user_impl = data.shell_data.user_impl.borrow_mut();
(&mut *user_impl)(XdgRequest::NewPopup { surface: handle });
(&mut *user_impl)(XdgRequest::NewPopup { surface: handle }, dispatch_data);
}
xdg_surface::Request::SetWindowGeometry { x, y, width, height } => {
// Check the role of the surface, this can be either xdg_toplevel
@ -417,10 +435,13 @@ fn xdg_surface_implementation(request: xdg_surface::Request, xdg_surface: xdg_su
};
let mut user_impl = data.shell_data.user_impl.borrow_mut();
(&mut *user_impl)(XdgRequest::AckConfigure {
(&mut *user_impl)(
XdgRequest::AckConfigure {
surface: surface.clone(),
configure,
});
},
dispatch_data,
);
}
_ => unreachable!(),
}
@ -512,7 +533,11 @@ fn make_toplevel_handle(resource: &xdg_toplevel::XdgToplevel) -> super::Toplevel
}
}
fn toplevel_implementation(request: xdg_toplevel::Request, toplevel: xdg_toplevel::XdgToplevel) {
fn toplevel_implementation(
toplevel: Main<xdg_toplevel::XdgToplevel>,
request: xdg_toplevel::Request,
dispatch_data: DispatchData<'_>,
) {
let data = toplevel
.as_ref()
.user_data()
@ -553,35 +578,44 @@ fn toplevel_implementation(request: xdg_toplevel::Request, toplevel: xdg_topleve
let handle = make_toplevel_handle(&toplevel);
let serial = Serial::from(serial);
let mut user_impl = data.shell_data.user_impl.borrow_mut();
(&mut *user_impl)(XdgRequest::ShowWindowMenu {
(&mut *user_impl)(
XdgRequest::ShowWindowMenu {
surface: handle,
seat,
serial,
location: (x, y),
});
},
dispatch_data,
);
}
xdg_toplevel::Request::Move { seat, serial } => {
// This has to be handled by the compositor
let handle = make_toplevel_handle(&toplevel);
let serial = Serial::from(serial);
let mut user_impl = data.shell_data.user_impl.borrow_mut();
(&mut *user_impl)(XdgRequest::Move {
(&mut *user_impl)(
XdgRequest::Move {
surface: handle,
seat,
serial,
});
},
dispatch_data,
);
}
xdg_toplevel::Request::Resize { seat, serial, edges } => {
// This has to be handled by the compositor
let handle = make_toplevel_handle(&toplevel);
let mut user_impl = data.shell_data.user_impl.borrow_mut();
let serial = Serial::from(serial);
(&mut *user_impl)(XdgRequest::Resize {
(&mut *user_impl)(
XdgRequest::Resize {
surface: handle,
seat,
serial,
edges,
});
},
dispatch_data,
);
}
xdg_toplevel::Request::SetMaxSize { width, height } => {
with_toplevel_pending_state(&toplevel, |toplevel_data| {
@ -596,32 +630,35 @@ fn toplevel_implementation(request: xdg_toplevel::Request, toplevel: xdg_topleve
xdg_toplevel::Request::SetMaximized => {
let handle = make_toplevel_handle(&toplevel);
let mut user_impl = data.shell_data.user_impl.borrow_mut();
(&mut *user_impl)(XdgRequest::Maximize { surface: handle });
(&mut *user_impl)(XdgRequest::Maximize { surface: handle }, dispatch_data);
}
xdg_toplevel::Request::UnsetMaximized => {
let handle = make_toplevel_handle(&toplevel);
let mut user_impl = data.shell_data.user_impl.borrow_mut();
(&mut *user_impl)(XdgRequest::UnMaximize { surface: handle });
(&mut *user_impl)(XdgRequest::UnMaximize { surface: handle }, dispatch_data);
}
xdg_toplevel::Request::SetFullscreen { output } => {
let handle = make_toplevel_handle(&toplevel);
let mut user_impl = data.shell_data.user_impl.borrow_mut();
(&mut *user_impl)(XdgRequest::Fullscreen {
(&mut *user_impl)(
XdgRequest::Fullscreen {
surface: handle,
output,
});
},
dispatch_data,
);
}
xdg_toplevel::Request::UnsetFullscreen => {
let handle = make_toplevel_handle(&toplevel);
let mut user_impl = data.shell_data.user_impl.borrow_mut();
(&mut *user_impl)(XdgRequest::UnFullscreen { surface: handle });
(&mut *user_impl)(XdgRequest::UnFullscreen { surface: handle }, dispatch_data);
}
xdg_toplevel::Request::SetMinimized => {
// This has to be handled by the compositor, may not be
// supported and just ignored
let handle = make_toplevel_handle(&toplevel);
let mut user_impl = data.shell_data.user_impl.borrow_mut();
(&mut *user_impl)(XdgRequest::Minimize { surface: handle });
(&mut *user_impl)(XdgRequest::Minimize { surface: handle }, dispatch_data);
}
_ => unreachable!(),
}
@ -679,7 +716,11 @@ fn make_popup_handle(resource: &xdg_popup::XdgPopup) -> super::PopupSurface {
}
}
fn xdg_popup_implementation(request: xdg_popup::Request, popup: xdg_popup::XdgPopup) {
fn xdg_popup_implementation(
popup: Main<xdg_popup::XdgPopup>,
request: xdg_popup::Request,
dispatch_data: DispatchData<'_>,
) {
let data = popup.as_ref().user_data().get::<ShellSurfaceUserData>().unwrap();
match request {
xdg_popup::Request::Destroy => {
@ -689,11 +730,14 @@ fn xdg_popup_implementation(request: xdg_popup::Request, popup: xdg_popup::XdgPo
let handle = make_popup_handle(&popup);
let mut user_impl = data.shell_data.user_impl.borrow_mut();
let serial = Serial::from(serial);
(&mut *user_impl)(XdgRequest::Grab {
(&mut *user_impl)(
XdgRequest::Grab {
surface: handle,
seat,
serial,
});
},
dispatch_data,
);
}
_ => unreachable!(),
}

View File

@ -10,6 +10,7 @@ use wayland_protocols::{
},
xdg_shell::server::{xdg_positioner, xdg_toplevel},
};
use wayland_server::DispatchData;
use wayland_server::{protocol::wl_surface, Filter, Main};
use crate::utils::Rectangle;
@ -26,16 +27,20 @@ static ZXDG_POPUP_ROLE: &str = "zxdg_toplevel";
pub(crate) fn implement_shell(
shell: Main<zxdg_shell_v6::ZxdgShellV6>,
shell_data: &ShellData,
dispatch_data: DispatchData<'_>,
) -> zxdg_shell_v6::ZxdgShellV6 {
shell.quick_assign(|shell, req, _data| shell_implementation(req, shell.deref().clone()));
shell.quick_assign(shell_implementation);
shell.as_ref().user_data().set(|| ShellUserData {
shell_data: shell_data.clone(),
client_data: Mutex::new(make_shell_client_data()),
});
let mut user_impl = shell_data.user_impl.borrow_mut();
(&mut *user_impl)(XdgRequest::NewClient {
(&mut *user_impl)(
XdgRequest::NewClient {
client: make_shell_client(&shell),
});
},
dispatch_data,
);
shell.deref().clone()
}
@ -54,7 +59,11 @@ pub(crate) fn make_shell_client(resource: &zxdg_shell_v6::ZxdgShellV6) -> ShellC
}
}
fn shell_implementation(request: zxdg_shell_v6::Request, shell: zxdg_shell_v6::ZxdgShellV6) {
fn shell_implementation(
shell: Main<zxdg_shell_v6::ZxdgShellV6>,
request: zxdg_shell_v6::Request,
dispatch_data: DispatchData<'_>,
) {
let data = shell.as_ref().user_data().get::<ShellUserData>().unwrap();
match request {
zxdg_shell_v6::Request::Destroy => {
@ -64,12 +73,12 @@ fn shell_implementation(request: zxdg_shell_v6::Request, shell: zxdg_shell_v6::Z
implement_positioner(id);
}
zxdg_shell_v6::Request::GetXdgSurface { id, surface } => {
id.quick_assign(|surface, req, _data| xdg_surface_implementation(req, surface.deref().clone()));
id.quick_assign(xdg_surface_implementation);
id.assign_destructor(Filter::new(|surface, _, _data| destroy_surface(surface)));
id.as_ref().user_data().set(|| XdgSurfaceUserData {
shell_data: data.shell_data.clone(),
wl_surface: surface,
shell: shell.clone(),
shell: shell.deref().clone(),
has_active_role: AtomicBool::new(false),
});
}
@ -86,9 +95,12 @@ fn shell_implementation(request: zxdg_shell_v6::Request, shell: zxdg_shell_v6::Z
};
if valid {
let mut user_impl = data.shell_data.user_impl.borrow_mut();
(&mut *user_impl)(XdgRequest::ClientPong {
(&mut *user_impl)(
XdgRequest::ClientPong {
client: make_shell_client(&shell),
});
},
dispatch_data,
);
}
}
_ => unreachable!(),
@ -208,8 +220,9 @@ fn destroy_surface(surface: zxdg_surface_v6::ZxdgSurfaceV6) {
}
fn xdg_surface_implementation(
xdg_surface: Main<zxdg_surface_v6::ZxdgSurfaceV6>,
request: zxdg_surface_v6::Request,
xdg_surface: zxdg_surface_v6::ZxdgSurfaceV6,
dispatch_data: DispatchData<'_>,
) {
let data = xdg_surface
.as_ref()
@ -244,13 +257,13 @@ fn xdg_surface_implementation(
compositor::add_commit_hook(surface, super::ToplevelSurface::commit_hook);
id.quick_assign(|toplevel, req, _data| toplevel_implementation(req, toplevel.deref().clone()));
id.quick_assign(toplevel_implementation);
id.assign_destructor(Filter::new(|toplevel, _, _data| destroy_toplevel(toplevel)));
id.as_ref().user_data().set(|| ShellSurfaceUserData {
shell_data: data.shell_data.clone(),
wl_surface: data.wl_surface.clone(),
shell: data.shell.clone(),
xdg_surface: xdg_surface.clone(),
xdg_surface: xdg_surface.deref().clone(),
});
data.shell_data
@ -262,7 +275,7 @@ fn xdg_surface_implementation(
let handle = make_toplevel_handle(&id);
let mut user_impl = data.shell_data.user_impl.borrow_mut();
(&mut *user_impl)(XdgRequest::NewToplevel { surface: handle });
(&mut *user_impl)(XdgRequest::NewToplevel { surface: handle }, dispatch_data);
}
zxdg_surface_v6::Request::GetPopup {
id,
@ -319,13 +332,13 @@ fn xdg_surface_implementation(
compositor::add_commit_hook(surface, super::PopupSurface::commit_hook);
id.quick_assign(|popup, req, _data| popup_implementation(req, popup.deref().clone()));
id.quick_assign(popup_implementation);
id.assign_destructor(Filter::new(|popup, _, _data| destroy_popup(popup)));
id.as_ref().user_data().set(|| ShellSurfaceUserData {
shell_data: data.shell_data.clone(),
wl_surface: data.wl_surface.clone(),
shell: data.shell.clone(),
xdg_surface: xdg_surface.clone(),
xdg_surface: xdg_surface.deref().clone(),
});
data.shell_data
@ -337,7 +350,7 @@ fn xdg_surface_implementation(
let handle = make_popup_handle(&id);
let mut user_impl = data.shell_data.user_impl.borrow_mut();
(&mut *user_impl)(XdgRequest::NewPopup { surface: handle });
(&mut *user_impl)(XdgRequest::NewPopup { surface: handle }, dispatch_data);
}
zxdg_surface_v6::Request::SetWindowGeometry { x, y, width, height } => {
// Check the role of the surface, this can be either xdg_toplevel
@ -437,10 +450,13 @@ fn xdg_surface_implementation(
};
let mut user_impl = data.shell_data.user_impl.borrow_mut();
(&mut *user_impl)(XdgRequest::AckConfigure {
(&mut *user_impl)(
XdgRequest::AckConfigure {
surface: surface.clone(),
configure,
});
},
dispatch_data,
);
}
_ => unreachable!(),
}
@ -532,7 +548,11 @@ fn make_toplevel_handle(resource: &zxdg_toplevel_v6::ZxdgToplevelV6) -> super::T
}
}
fn toplevel_implementation(request: zxdg_toplevel_v6::Request, toplevel: zxdg_toplevel_v6::ZxdgToplevelV6) {
fn toplevel_implementation(
toplevel: Main<zxdg_toplevel_v6::ZxdgToplevelV6>,
request: zxdg_toplevel_v6::Request,
dispatch_data: DispatchData<'_>,
) {
let data = toplevel
.as_ref()
.user_data()
@ -570,22 +590,28 @@ fn toplevel_implementation(request: zxdg_toplevel_v6::Request, toplevel: zxdg_to
let handle = make_toplevel_handle(&toplevel);
let mut user_impl = data.shell_data.user_impl.borrow_mut();
let serial = Serial::from(serial);
(&mut *user_impl)(XdgRequest::ShowWindowMenu {
(&mut *user_impl)(
XdgRequest::ShowWindowMenu {
surface: handle,
seat,
serial,
location: (x, y),
});
},
dispatch_data,
);
}
zxdg_toplevel_v6::Request::Move { seat, serial } => {
let handle = make_toplevel_handle(&toplevel);
let mut user_impl = data.shell_data.user_impl.borrow_mut();
let serial = Serial::from(serial);
(&mut *user_impl)(XdgRequest::Move {
(&mut *user_impl)(
XdgRequest::Move {
surface: handle,
seat,
serial,
});
},
dispatch_data,
);
}
zxdg_toplevel_v6::Request::Resize { seat, serial, edges } => {
let edges =
@ -593,12 +619,15 @@ fn toplevel_implementation(request: zxdg_toplevel_v6::Request, toplevel: zxdg_to
let handle = make_toplevel_handle(&toplevel);
let mut user_impl = data.shell_data.user_impl.borrow_mut();
let serial = Serial::from(serial);
(&mut *user_impl)(XdgRequest::Resize {
(&mut *user_impl)(
XdgRequest::Resize {
surface: handle,
seat,
serial,
edges: zxdg_edges_to_xdg(edges),
});
},
dispatch_data,
);
}
zxdg_toplevel_v6::Request::SetMaxSize { width, height } => {
with_toplevel_pending_state(&toplevel, |toplevel_data| {
@ -613,32 +642,35 @@ fn toplevel_implementation(request: zxdg_toplevel_v6::Request, toplevel: zxdg_to
zxdg_toplevel_v6::Request::SetMaximized => {
let handle = make_toplevel_handle(&toplevel);
let mut user_impl = data.shell_data.user_impl.borrow_mut();
(&mut *user_impl)(XdgRequest::Maximize { surface: handle });
(&mut *user_impl)(XdgRequest::Maximize { surface: handle }, dispatch_data);
}
zxdg_toplevel_v6::Request::UnsetMaximized => {
let handle = make_toplevel_handle(&toplevel);
let mut user_impl = data.shell_data.user_impl.borrow_mut();
(&mut *user_impl)(XdgRequest::UnMaximize { surface: handle });
(&mut *user_impl)(XdgRequest::UnMaximize { surface: handle }, dispatch_data);
}
zxdg_toplevel_v6::Request::SetFullscreen { output } => {
let handle = make_toplevel_handle(&toplevel);
let mut user_impl = data.shell_data.user_impl.borrow_mut();
(&mut *user_impl)(XdgRequest::Fullscreen {
(&mut *user_impl)(
XdgRequest::Fullscreen {
surface: handle,
output,
});
},
dispatch_data,
);
}
zxdg_toplevel_v6::Request::UnsetFullscreen => {
let handle = make_toplevel_handle(&toplevel);
let mut user_impl = data.shell_data.user_impl.borrow_mut();
(&mut *user_impl)(XdgRequest::UnFullscreen { surface: handle });
(&mut *user_impl)(XdgRequest::UnFullscreen { surface: handle }, dispatch_data);
}
zxdg_toplevel_v6::Request::SetMinimized => {
// This has to be handled by the compositor, may not be
// supported and just ignored
let handle = make_toplevel_handle(&toplevel);
let mut user_impl = data.shell_data.user_impl.borrow_mut();
(&mut *user_impl)(XdgRequest::Minimize { surface: handle });
(&mut *user_impl)(XdgRequest::Minimize { surface: handle }, dispatch_data);
}
_ => unreachable!(),
}
@ -696,7 +728,11 @@ fn make_popup_handle(resource: &zxdg_popup_v6::ZxdgPopupV6) -> super::PopupSurfa
}
}
fn popup_implementation(request: zxdg_popup_v6::Request, popup: zxdg_popup_v6::ZxdgPopupV6) {
fn popup_implementation(
popup: Main<zxdg_popup_v6::ZxdgPopupV6>,
request: zxdg_popup_v6::Request,
dispatch_data: DispatchData<'_>,
) {
let data = popup.as_ref().user_data().get::<ShellSurfaceUserData>().unwrap();
match request {
zxdg_popup_v6::Request::Destroy => {
@ -706,11 +742,14 @@ fn popup_implementation(request: zxdg_popup_v6::Request, popup: zxdg_popup_v6::Z
let handle = make_popup_handle(&popup);
let mut user_impl = data.shell_data.user_impl.borrow_mut();
let serial = Serial::from(serial);
(&mut *user_impl)(XdgRequest::Grab {
(&mut *user_impl)(
XdgRequest::Grab {
surface: handle,
seat,
serial,
});
},
dispatch_data,
);
}
_ => unreachable!(),
}