wayland.shell.xdg: review docs & API
This commit is contained in:
parent
ba6bef3e85
commit
e96272cae5
|
@ -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
|
||||
|
|
|
@ -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())
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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!(),
|
||||
}
|
||||
|
|
|
@ -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!(),
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue