Watch
1
0
Fork
You've already forked smithay
0

Add Dispatch2 and GlobalDispatch2, replacing delegate macros

A single `delegate_dispatch2!` replaces all other delegate macros.

When wayland-rs updates the definition of `Dispatch`, this macro will be
unnecessary, and `Dispatch` type bounds should become inferable by the
type system.

`Dispatch` is now implemented for the user-data type, so `smithay` is
able to provide blanket implementations as long as the user data is a
type owned by `smithay`. Therefore, `GlobalData` replaces `()` as a user
data (`smithay-client-toolkit` already did this), and udata that is
simply a type like `Weak<WlSurface>` is wrapped.
This commit is contained in:
Ian Douglas Scott 2026-04-24 16:05:33 -07:00 • committed by Victoria Brekenfeld
commit 0d14cd655f
104 changed files with 1551 additions and 3761 deletions

View file

@ -103,6 +103,10 @@ The following methods are no longer needed as Smithay does them automatically no
You also no longer need to manually set `LayerSurfaceAttributes::initial_configure_sent`, Smithay handles it automatically.
The `delegate_*!` macros have been replaced with a single `delegate_dispatch2!` macro, which implements dispatch in terms
of new `Dipsatch2` and `GlobalDispatch2` traits. These will replace `Dispatch` and `GlobalDispatch` in a future version of
`wayland_server`.
### Additions
- ExtBackgroundEffect protocol is now available in `smithay::wayland::background_effect` module.

View file

@ -15,13 +15,7 @@ use smithay::{
RenderElementStates, default_primary_scanout_output_compare, utils::select_dmabuf_feedback,
},
},
delegate_compositor, delegate_data_control, delegate_data_device, delegate_fixes,
delegate_fractional_scale, delegate_input_method_manager, delegate_keyboard_shortcuts_inhibit,
delegate_layer_shell, delegate_output, delegate_pointer_constraints, delegate_pointer_gestures,
delegate_presentation, delegate_primary_selection, delegate_relative_pointer, delegate_seat,
delegate_security_context, delegate_shm, delegate_tablet_manager, delegate_text_input_manager,
delegate_viewporter, delegate_virtual_keyboard_manager, delegate_xdg_activation, delegate_xdg_decoration,
delegate_xdg_shell,
delegate_dispatch2,
desktop::{
PopupKind, PopupManager, Space,
space::SpaceElement,
@ -112,7 +106,6 @@ use crate::{
};
#[cfg(feature = "xwayland")]
use smithay::{
delegate_xwayland_keyboard_grab, delegate_xwayland_shell,
utils::Size,
wayland::selection::{SelectionSource, SelectionTarget},
wayland::xwayland_keyboard_grab::{XWaylandKeyboardGrabHandler, XWaylandKeyboardGrabState},
@ -197,8 +190,6 @@ pub struct DndIcon {
pub offset: Point<i32, Logical>,
}
delegate_compositor!(@<BackendData: Backend + 'static> AnvilState<BackendData>);
impl<BackendData: Backend> DataDeviceHandler for AnvilState<BackendData> {
fn data_device_state(&mut self) -> &mut DataDeviceState {
&mut self.data_device_state
@ -254,10 +245,8 @@ impl<BackendData: Backend> DndGrabHandler for AnvilState<BackendData> {
self.dnd_icon = None;
}
}
delegate_data_device!(@<BackendData: Backend + 'static> AnvilState<BackendData>);
impl<BackendData: Backend> OutputHandler for AnvilState<BackendData> {}
delegate_output!(@<BackendData: Backend + 'static> AnvilState<BackendData>);
impl<BackendData: Backend> SelectionHandler for AnvilState<BackendData> {
type SelectionUserData = ();
@ -293,7 +282,6 @@ impl<BackendData: Backend> PrimarySelectionHandler for AnvilState<BackendData> {
&mut self.primary_selection_state
}
}
delegate_primary_selection!(@<BackendData: Backend + 'static> AnvilState<BackendData>);
impl<BackendData: Backend> DataControlHandler for AnvilState<BackendData> {
fn data_control_state(&mut self) -> &mut DataControlState {
@ -301,14 +289,11 @@ impl<BackendData: Backend> DataControlHandler for AnvilState<BackendData> {
}
}
delegate_data_control!(@<BackendData: Backend + 'static> AnvilState<BackendData>);
impl<BackendData: Backend> ShmHandler for AnvilState<BackendData> {
fn shm_state(&self) -> &ShmState {
&self.shm_state
}
}
delegate_shm!(@<BackendData: Backend + 'static> AnvilState<BackendData>);
impl<BackendData: Backend> SeatHandler for AnvilState<BackendData> {
type KeyboardFocus = KeyboardFocusTarget;
@ -336,7 +321,6 @@ impl<BackendData: Backend> SeatHandler for AnvilState<BackendData> {
self.backend_data.update_led_state(led_state)
}
}
delegate_seat!(@<BackendData: Backend + 'static> AnvilState<BackendData>);
impl<BackendData: Backend> TabletSeatHandler for AnvilState<BackendData> {
fn tablet_tool_image(&mut self, _tool: &TabletToolDescriptor, image: CursorImageStatus) {
@ -344,9 +328,6 @@ impl<BackendData: Backend> TabletSeatHandler for AnvilState<BackendData> {
self.cursor_status = image;
}
}
delegate_tablet_manager!(@<BackendData: Backend + 'static> AnvilState<BackendData>);
delegate_text_input_manager!(@<BackendData: Backend + 'static> AnvilState<BackendData>);
impl<BackendData: Backend> InputMethodHandler for AnvilState<BackendData> {
fn new_popup(&mut self, surface: PopupSurface) {
@ -371,8 +352,6 @@ impl<BackendData: Backend> InputMethodHandler for AnvilState<BackendData> {
}
}
delegate_input_method_manager!(@<BackendData: Backend + 'static> AnvilState<BackendData>);
impl<BackendData: Backend> KeyboardShortcutsInhibitHandler for AnvilState<BackendData> {
fn keyboard_shortcuts_inhibit_state(&mut self) -> &mut KeyboardShortcutsInhibitState {
&mut self.keyboard_shortcuts_inhibit_state
@ -384,14 +363,6 @@ impl<BackendData: Backend> KeyboardShortcutsInhibitHandler for AnvilState<Backen
}
}
delegate_keyboard_shortcuts_inhibit!(@<BackendData: Backend + 'static> AnvilState<BackendData>);
delegate_virtual_keyboard_manager!(@<BackendData: Backend + 'static> AnvilState<BackendData>);
delegate_pointer_gestures!(@<BackendData: Backend + 'static> AnvilState<BackendData>);
delegate_relative_pointer!(@<BackendData: Backend + 'static> AnvilState<BackendData>);
impl<BackendData: Backend> PointerConstraintsHandler for AnvilState<BackendData> {
fn new_constraint(&mut self, surface: &WlSurface, pointer: &PointerHandle<Self>) {
// XXX region
@ -428,9 +399,6 @@ impl<BackendData: Backend> PointerConstraintsHandler for AnvilState<BackendData>
}
}
}
delegate_pointer_constraints!(@<BackendData: Backend + 'static> AnvilState<BackendData>);
delegate_viewporter!(@<BackendData: Backend + 'static> AnvilState<BackendData>);
impl<BackendData: Backend> XdgActivationHandler for AnvilState<BackendData> {
fn activation_state(&mut self) -> &mut XdgActivationState {
@ -469,7 +437,6 @@ impl<BackendData: Backend> XdgActivationHandler for AnvilState<BackendData> {
}
}
}
delegate_xdg_activation!(@<BackendData: Backend + 'static> AnvilState<BackendData>);
impl<BackendData: Backend> XdgDecorationHandler for AnvilState<BackendData> {
fn new_decoration(&mut self, toplevel: ToplevelSurface) {
@ -504,11 +471,6 @@ impl<BackendData: Backend> XdgDecorationHandler for AnvilState<BackendData> {
}
}
}
delegate_xdg_decoration!(@<BackendData: Backend + 'static> AnvilState<BackendData>);
delegate_xdg_shell!(@<BackendData: Backend + 'static> AnvilState<BackendData>);
delegate_layer_shell!(@<BackendData: Backend + 'static> AnvilState<BackendData>);
delegate_presentation!(@<BackendData: Backend + 'static> AnvilState<BackendData>);
impl<BackendData: Backend> FractionalScaleHandler for AnvilState<BackendData> {
fn new_fractional_scale(
@ -557,7 +519,6 @@ impl<BackendData: Backend> FractionalScaleHandler for AnvilState<BackendData> {
});
}
}
delegate_fractional_scale!(@<BackendData: Backend + 'static> AnvilState<BackendData>);
impl<BackendData: Backend + 'static> SecurityContextHandler for AnvilState<BackendData> {
fn context_created(&mut self, source: SecurityContextListenerSource, security_context: SecurityContext) {
@ -577,7 +538,6 @@ impl<BackendData: Backend + 'static> SecurityContextHandler for AnvilState<Backe
.expect("Failed to init wayland socket source");
}
}
delegate_security_context!(@<BackendData: Backend + 'static> AnvilState<BackendData>);
#[cfg(feature = "xwayland")]
impl<BackendData: Backend + 'static> XWaylandKeyboardGrabHandler for AnvilState<BackendData> {
@ -589,33 +549,18 @@ impl<BackendData: Backend + 'static> XWaylandKeyboardGrabHandler for AnvilState<
Some(KeyboardFocusTarget::Window(elem.0.clone()))
}
}
#[cfg(feature = "xwayland")]
delegate_xwayland_keyboard_grab!(@<BackendData: Backend + 'static> AnvilState<BackendData>);
#[cfg(feature = "xwayland")]
delegate_xwayland_shell!(@<BackendData: Backend + 'static> AnvilState<BackendData>);
impl<BackendData: Backend> XdgForeignHandler for AnvilState<BackendData> {
fn xdg_foreign_state(&mut self) -> &mut XdgForeignState {
&mut self.xdg_foreign_state
}
}
smithay::delegate_xdg_foreign!(@<BackendData: Backend + 'static> AnvilState<BackendData>);
smithay::delegate_single_pixel_buffer!(@<BackendData: Backend + 'static> AnvilState<BackendData>);
smithay::delegate_fifo!(@<BackendData: Backend + 'static> AnvilState<BackendData>);
smithay::delegate_commit_timing!(@<BackendData: Backend + 'static> AnvilState<BackendData>);
delegate_fixes!(@<BackendData: Backend + 'static> AnvilState<BackendData>);
impl<BackendData: Backend> ImageCaptureSourceHandler for AnvilState<BackendData> {
fn source_destroyed(&mut self, _source: ImageCaptureSource) {
// Anvil doesn't track sources
}
}
smithay::delegate_image_capture_source!(@<BackendData: Backend + 'static> AnvilState<BackendData>);
impl<BackendData: Backend> OutputCaptureSourceHandler for AnvilState<BackendData> {
fn output_capture_source_state(&mut self) -> &mut OutputCaptureSourceState {
@ -626,7 +571,6 @@ impl<BackendData: Backend> OutputCaptureSourceHandler for AnvilState<BackendData
source.user_data().insert_if_missing(|| output.downgrade());
}
}
smithay::delegate_output_capture_source!(@<BackendData: Backend + 'static> AnvilState<BackendData>);
impl<BackendData: Backend> ImageCopyCaptureHandler for AnvilState<BackendData> {
fn image_copy_capture_state(&mut self) -> &mut ImageCopyCaptureState {
@ -662,7 +606,8 @@ impl<BackendData: Backend> ImageCopyCaptureHandler for AnvilState<BackendData> {
frame.fail(smithay::wayland::image_copy_capture::CaptureFailureReason::Unknown);
}
}
smithay::delegate_image_copy_capture!(@<BackendData: Backend + 'static> AnvilState<BackendData>);
delegate_dispatch2!(@<BackendData: Backend + 'static> AnvilState<BackendData>);
impl<BackendData: Backend + 'static> AnvilState<BackendData> {
pub fn init(

View file

@ -57,7 +57,6 @@ use smithay::{
},
udev::{UdevBackend, UdevEvent, all_gpus, primary_gpu},
},
delegate_dmabuf, delegate_drm_lease,
desktop::{
space::{Space, SurfaceTree},
utils::OutputPresentationFeedback,
@ -183,7 +182,6 @@ impl DmabufHandler for AnvilState<UdevData> {
}
}
}
delegate_dmabuf!(AnvilState<UdevData>);
impl Backend for UdevData {
const HAS_RELATIVE_MOTION: bool = true;
@ -613,14 +611,11 @@ impl DrmLeaseHandler for AnvilState<UdevData> {
}
}
delegate_drm_lease!(AnvilState<UdevData>);
impl DrmSyncobjHandler for AnvilState<UdevData> {
fn drm_syncobj_state(&mut self) -> Option<&mut DrmSyncobjState> {
self.backend_data.syncobj_state.as_mut()
}
}
smithay::delegate_drm_syncobj!(AnvilState<UdevData>);
pub type RenderSurface = GbmBufferedSurface<GbmAllocator<DrmDeviceFd>, Option<OutputPresentationFeedback>>;

View file

@ -24,7 +24,6 @@ use smithay::{
},
winit::{self, WinitEvent, WinitGraphicsBackend},
},
delegate_dmabuf,
input::{
keyboard::LedState,
pointer::{CursorImageAttributes, CursorImageStatus},
@ -80,7 +79,6 @@ impl DmabufHandler for AnvilState<WinitData> {
}
}
}
delegate_dmabuf!(AnvilState<WinitData>);
impl Backend for WinitData {
fn seat_name(&self) -> String {

View file

@ -28,7 +28,6 @@ use smithay::{
vulkan::{Instance, PhysicalDevice, version::Version},
x11::{WindowBuilder, X11Backend, X11Event, X11Surface},
},
delegate_dmabuf,
input::{
keyboard::LedState,
pointer::{CursorImageAttributes, CursorImageStatus},
@ -83,7 +82,6 @@ impl DmabufHandler for AnvilState<X11Data> {
}
}
}
delegate_dmabuf!(AnvilState<X11Data>);
impl Backend for X11Data {
fn seat_name(&self) -> String {

View file

@ -1,6 +1,6 @@
use std::sync::Arc;
use smithay::delegate_compositor;
use smithay::delegate_dispatch2;
use smithay::reexports::wayland_server::Display;
use smithay::wayland::compositor::{CompositorClientState, CompositorHandler, CompositorState};
@ -75,4 +75,4 @@ impl AsMut<CompositorState> for App {
}
}
delegate_compositor!(App);
delegate_dispatch2!(App);

View file

@ -15,7 +15,6 @@ use smithay::{
},
winit::{self, WinitEvent},
},
delegate_compositor, delegate_data_device, delegate_seat, delegate_shm, delegate_xdg_shell,
input::{Seat, SeatHandler, SeatState, keyboard::FilterResult},
reexports::wayland_server::{Display, protocol::wl_seat},
utils::{Rectangle, Serial, Transform},
@ -290,9 +289,4 @@ impl ClientData for ClientState {
}
}
// Macros used to delegate protocol handling to types in the app state.
delegate_xdg_shell!(App);
delegate_compositor!(App);
delegate_shm!(App);
delegate_seat!(App);
delegate_data_device!(App);
smithay::delegate_dispatch2!(App);

View file

@ -7,7 +7,6 @@ use smithay::reexports::wayland_server::{
protocol::wl_surface::WlSurface,
};
use smithay::wayland::compositor::{CompositorClientState, CompositorHandler, CompositorState};
use smithay::{delegate_compositor, delegate_seat};
struct App {
compositor_state: CompositorState,
@ -104,5 +103,4 @@ impl CompositorHandler for App {
fn commit(&mut self, _surface: &WlSurface) {}
}
delegate_compositor!(App);
delegate_seat!(App);
smithay::delegate_dispatch2!(App);

View file

@ -1,7 +1,6 @@
use crate::{Smallvil, grabs::resize_grab, state::ClientState};
use smithay::{
backend::renderer::utils::on_commit_buffer_handler,
delegate_compositor, delegate_shm,
reexports::wayland_server::{
Client,
protocol::{wl_buffer, wl_surface::WlSurface},
@ -56,6 +55,3 @@ impl ShmHandler for Smallvil {
&self.shm_state
}
}
delegate_compositor!(Smallvil);
delegate_shm!(Smallvil);

View file

@ -18,7 +18,6 @@ use smithay::wayland::selection::SelectionHandler;
use smithay::wayland::selection::data_device::{
DataDeviceHandler, DataDeviceState, WaylandDndGrabHandler, set_data_device_focus,
};
use smithay::{delegate_data_device, delegate_output, delegate_seat};
impl SeatHandler for Smallvil {
type KeyboardFocus = WlSurface;
@ -38,8 +37,6 @@ impl SeatHandler for Smallvil {
}
}
delegate_seat!(Smallvil);
//
// Wl Data Device
//
@ -81,11 +78,10 @@ impl WaylandDndGrabHandler for Smallvil {
}
}
delegate_data_device!(Smallvil);
//
// Wl Output & Xdg Output
//
impl OutputHandler for Smallvil {}
delegate_output!(Smallvil);
smithay::delegate_dispatch2!(Smallvil);

View file

@ -1,5 +1,4 @@
use smithay::{
delegate_xdg_shell,
desktop::{PopupKind, PopupManager, Space, Window, find_popup_root_surface, get_popup_toplevel_coords},
input::{
Seat,
@ -123,9 +122,6 @@ impl XdgShellHandler for Smallvil {
}
}
// Xdg Shell
delegate_xdg_shell!(Smallvil);
fn check_grab(
seat: &Seat<Smallvil>,
surface: &WlSurface,

View file

@ -3,47 +3,39 @@ use wayland_protocols::wp::alpha_modifier::v1::server::{
wp_alpha_modifier_v1::{self, WpAlphaModifierV1},
};
use wayland_server::{
Client, DataInit, Dispatch, DisplayHandle, GlobalDispatch, New, Resource, backend::ClientId,
};
use wayland_server::{Client, DataInit, Dispatch, DisplayHandle, New, Resource, backend::ClientId};
use super::{
AlphaModifierState, AlphaModifierSurfaceCachedState, AlphaModifierSurfaceData,
AlphaModifierSurfaceUserData,
};
use crate::wayland::compositor;
use super::{AlphaModifierSurfaceCachedState, AlphaModifierSurfaceData, AlphaModifierSurfaceUserData};
use crate::wayland::{Dispatch2, GlobalData, GlobalDispatch2, compositor};
impl<D> GlobalDispatch<WpAlphaModifierV1, (), D> for AlphaModifierState
impl<D> GlobalDispatch2<WpAlphaModifierV1, D> for GlobalData
where
D: GlobalDispatch<WpAlphaModifierV1, ()>,
D: Dispatch<WpAlphaModifierV1, ()>,
D: Dispatch<WpAlphaModifierSurfaceV1, AlphaModifierSurfaceUserData>,
D: Dispatch<WpAlphaModifierV1, GlobalData>,
D: 'static,
{
fn bind(
&self,
_state: &mut D,
_: &DisplayHandle,
_: &Client,
resource: New<WpAlphaModifierV1>,
_: &(),
data_init: &mut DataInit<'_, D>,
) {
data_init.init(resource, ());
data_init.init(resource, GlobalData);
}
}
impl<D> Dispatch<WpAlphaModifierV1, (), D> for AlphaModifierState
impl<D> Dispatch2<WpAlphaModifierV1, D> for GlobalData
where
D: Dispatch<WpAlphaModifierV1, ()>,
D: Dispatch<WpAlphaModifierSurfaceV1, AlphaModifierSurfaceUserData>,
D: 'static,
{
fn request(
&self,
_state: &mut D,
_: &Client,
manager: &WpAlphaModifierV1,
request: wp_alpha_modifier_v1::Request,
_data: &(),
_dh: &DisplayHandle,
data_init: &mut DataInit<'_, D>,
) {
@ -80,22 +72,19 @@ where
}
}
impl<D> Dispatch<WpAlphaModifierSurfaceV1, AlphaModifierSurfaceUserData, D> for AlphaModifierState
where
D: Dispatch<WpAlphaModifierSurfaceV1, AlphaModifierSurfaceUserData>,
{
impl<D> Dispatch2<WpAlphaModifierSurfaceV1, D> for AlphaModifierSurfaceUserData {
fn request(
&self,
_state: &mut D,
_: &Client,
obj: &WpAlphaModifierSurfaceV1,
request: wp_alpha_modifier_surface_v1::Request,
data: &AlphaModifierSurfaceUserData,
_dh: &DisplayHandle,
_: &mut DataInit<'_, D>,
) {
match request {
wp_alpha_modifier_surface_v1::Request::SetMultiplier { factor } => {
let Some(surface) = data.wl_surface() else {
let Some(surface) = self.wl_surface() else {
obj.post_error(
wp_alpha_modifier_surface_v1::Error::NoSurface,
"wl_surface was destroyed",
@ -113,7 +102,7 @@ where
}
// Switch back to not specifying the alpha multiplier of this surface.
wp_alpha_modifier_surface_v1::Request::Destroy => {
let Some(surface) = data.wl_surface() else {
let Some(surface) = self.wl_surface() else {
obj.post_error(
wp_alpha_modifier_surface_v1::Error::NoSurface,
"wl_surface was destroyed",
@ -139,12 +128,7 @@ where
}
}
fn destroyed(
_state: &mut D,
_client: ClientId,
_object: &WpAlphaModifierSurfaceV1,
_data: &AlphaModifierSurfaceUserData,
) {
fn destroyed(&self, _state: &mut D, _client: ClientId, _object: &WpAlphaModifierSurfaceV1) {
// Nothing to do here, graceful Destroy is already handled with double buffering
// and in case of client close WlSurface destroyed handler will clean up the data anyway,
// so there is no point in queuing new update

View file

@ -10,7 +10,6 @@
//! #
//! use wayland_server::{protocol::wl_surface::WlSurface, DisplayHandle};
//! use smithay::{
//! delegate_alpha_modifier, delegate_compositor,
//! wayland::compositor::{self, CompositorState, CompositorClientState, CompositorHandler},
//! wayland::alpha_modifier::{AlphaModifierSurfaceCachedState, AlphaModifierState},
//! };
@ -21,8 +20,7 @@
//! struct ClientState { compositor_state: CompositorClientState }
//! impl wayland_server::backend::ClientData for ClientState {}
//!
//! delegate_alpha_modifier!(State);
//! delegate_compositor!(State);
//! smithay::delegate_dispatch2!(State);
//!
//! impl CompositorHandler for State {
//! fn compositor_state(&mut self) -> &mut CompositorState {
@ -66,6 +64,8 @@ use wayland_server::{
use super::compositor::Cacheable;
use crate::wayland::GlobalData;
mod dispatch;
/// Data associated with WlSurface
@ -161,12 +161,12 @@ impl AlphaModifierState {
/// Regiseter new [WpAlphaModifierV1] global
pub fn new<D>(display: &DisplayHandle) -> AlphaModifierState
where
D: GlobalDispatch<WpAlphaModifierV1, ()>
+ Dispatch<WpAlphaModifierV1, ()>
D: GlobalDispatch<WpAlphaModifierV1, GlobalData>
+ Dispatch<WpAlphaModifierV1, GlobalData>
+ Dispatch<WpAlphaModifierSurfaceV1, AlphaModifierSurfaceUserData>
+ 'static,
{
let global = display.create_global::<D, WpAlphaModifierV1, _>(1, ());
let global = display.create_global::<D, WpAlphaModifierV1, _>(1, GlobalData);
AlphaModifierState { global }
}
@ -176,32 +176,3 @@ impl AlphaModifierState {
self.global.clone()
}
}
/// Macro to delegate implementation of the alpha modifier protocol
#[macro_export]
macro_rules! delegate_alpha_modifier {
($(@<$( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+>)? $ty: ty) => {
type __WpAlphaModifierV1 =
$crate::reexports::wayland_protocols::wp::alpha_modifier::v1::server::wp_alpha_modifier_v1::WpAlphaModifierV1;
type __WpAlphaModifierSurfaceV1 =
$crate::reexports::wayland_protocols::wp::alpha_modifier::v1::server::wp_alpha_modifier_surface_v1::WpAlphaModifierSurfaceV1;
$crate::reexports::wayland_server::delegate_global_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty:
[
__WpAlphaModifierV1: ()
] => $crate::wayland::alpha_modifier::AlphaModifierState
);
$crate::reexports::wayland_server::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty:
[
__WpAlphaModifierV1: ()
] => $crate::wayland::alpha_modifier::AlphaModifierState
);
$crate::reexports::wayland_server::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty:
[
__WpAlphaModifierSurfaceV1: $crate::wayland::alpha_modifier::AlphaModifierSurfaceUserData
] => $crate::wayland::alpha_modifier::AlphaModifierState
);
};
}

View file

@ -1,8 +1,7 @@
use crate::wayland::background_effect::{
BackgroundEffectState, BackgroundEffectSurfaceData, ExtBackgroundEffectHandler,
};
use crate::wayland::background_effect::{BackgroundEffectSurfaceData, ExtBackgroundEffectHandler};
use crate::wayland::compositor;
use crate::wayland::{
Dispatch2, GlobalData, GlobalDispatch2,
background_effect::{BackgroundEffectSurfaceCachedState, BackgroundEffectSurfaceUserData},
compositor::with_states,
};
@ -14,31 +13,35 @@ use wayland_protocols::ext::background_effect::v1::server::{
Error as SurfaceError, ExtBackgroundEffectSurfaceV1, Request as SurfaceRequest,
},
};
use wayland_server::{Client, DataInit, Dispatch, DisplayHandle, GlobalDispatch, New, Resource};
use wayland_server::{Client, DataInit, Dispatch, DisplayHandle, New, Resource};
impl<D: ExtBackgroundEffectHandler> GlobalDispatch<ExtBackgroundEffectManagerV1, (), D>
for BackgroundEffectState
impl<D: ExtBackgroundEffectHandler> GlobalDispatch2<ExtBackgroundEffectManagerV1, D> for GlobalData
where
D: Dispatch<ExtBackgroundEffectManagerV1, GlobalData>,
{
fn bind(
&self,
state: &mut D,
_handle: &DisplayHandle,
_client: &Client,
resource: New<ExtBackgroundEffectManagerV1>,
_global_data: &(),
data_init: &mut DataInit<'_, D>,
) {
let manager = data_init.init(resource, ());
let manager = data_init.init(resource, GlobalData);
manager.capabilities(state.capabilities());
}
}
impl<D: ExtBackgroundEffectHandler> Dispatch<ExtBackgroundEffectManagerV1, (), D> for BackgroundEffectState {
impl<D: ExtBackgroundEffectHandler> Dispatch2<ExtBackgroundEffectManagerV1, D> for GlobalData
where
D: Dispatch<ExtBackgroundEffectSurfaceV1, BackgroundEffectSurfaceUserData>,
{
fn request(
&self,
_state: &mut D,
_client: &Client,
manager: &ExtBackgroundEffectManagerV1,
request: ManagerRequest,
_data: &(),
_dh: &DisplayHandle,
data_init: &mut DataInit<'_, D>,
) {
@ -70,21 +73,21 @@ impl<D: ExtBackgroundEffectHandler> Dispatch<ExtBackgroundEffectManagerV1, (), D
}
}
impl<D: ExtBackgroundEffectHandler> Dispatch<ExtBackgroundEffectSurfaceV1, BackgroundEffectSurfaceUserData, D>
for BackgroundEffectState
impl<D: ExtBackgroundEffectHandler> Dispatch2<ExtBackgroundEffectSurfaceV1, D>
for BackgroundEffectSurfaceUserData
{
fn request(
&self,
state: &mut D,
_client: &Client,
obj: &ExtBackgroundEffectSurfaceV1,
request: SurfaceRequest,
data: &BackgroundEffectSurfaceUserData,
_dh: &DisplayHandle,
_data_init: &mut DataInit<'_, D>,
) {
match request {
SurfaceRequest::SetBlurRegion { region } => {
let Some(surface) = data.wl_surface() else {
let Some(surface) = self.wl_surface() else {
obj.post_error(SurfaceError::SurfaceDestroyed, "wl_surface was destroyed");
return;
};
@ -104,7 +107,7 @@ impl<D: ExtBackgroundEffectHandler> Dispatch<ExtBackgroundEffectSurfaceV1, Backg
}
}
SurfaceRequest::Destroy => {
let Some(surface) = data.wl_surface() else {
let Some(surface) = self.wl_surface() else {
// object is inert, but destroy is still allowed. We are done here.
return;
};
@ -126,10 +129,10 @@ impl<D: ExtBackgroundEffectHandler> Dispatch<ExtBackgroundEffectSurfaceV1, Backg
}
fn destroyed(
&self,
_state: &mut D,
_client_id: wayland_server::backend::ClientId,
_object: &ExtBackgroundEffectSurfaceV1,
_data: &BackgroundEffectSurfaceUserData,
) {
// No-op: cleanup is handled by double-buffering and surface destruction
}

View file

@ -1,13 +1,11 @@
//! Implementation of `ext_background_effect_manager_v1` protocol
//!
//! In order to advertise background effect global call [BackgroundEffectState::new] and delegate
//! events to it with [`delegate_background_effect`][crate::delegate_background_effect].
//! In order to advertise background effect global call [BackgroundEffectState::new].
//! Currently attached effects are available in double-buffered [BackgroundEffectSurfaceCachedState]
//!
//! ```
//! use smithay::wayland::background_effect::{BackgroundEffectState, ExtBackgroundEffectHandler, Capability};
//! use wayland_server::protocol::wl_surface::WlSurface;
//! use smithay::delegate_background_effect;
//! use smithay::wayland::compositor;
//!
//! # struct State;
@ -28,7 +26,7 @@
//! }
//! }
//!
//! delegate_background_effect!(State);
//! smithay::delegate_dispatch2!(State);
//! ```
use std::sync::{
@ -36,14 +34,15 @@ use std::sync::{
atomic::{AtomicBool, Ordering},
};
use crate::wayland::compositor::{self, Cacheable};
use wayland_protocols::ext::background_effect::v1::server::{
ext_background_effect_manager_v1::{self, ExtBackgroundEffectManagerV1},
ext_background_effect_surface_v1::ExtBackgroundEffectSurfaceV1,
use crate::wayland::{
GlobalData,
compositor::{self, Cacheable},
};
use wayland_protocols::ext::background_effect::v1::server::ext_background_effect_manager_v1::{
self, ExtBackgroundEffectManagerV1,
};
use wayland_server::{
Dispatch, DisplayHandle, GlobalDispatch, Resource, Weak, backend::GlobalId,
protocol::wl_surface::WlSurface,
DisplayHandle, GlobalDispatch, Resource, Weak, backend::GlobalId, protocol::wl_surface::WlSurface,
};
pub use ext_background_effect_manager_v1::Capability;
@ -51,12 +50,7 @@ pub use ext_background_effect_manager_v1::Capability;
mod dispatch;
/// Handler trait for ext background effect events.
pub trait ExtBackgroundEffectHandler:
GlobalDispatch<ExtBackgroundEffectManagerV1, ()>
+ Dispatch<ExtBackgroundEffectManagerV1, ()>
+ Dispatch<ExtBackgroundEffectSurfaceV1, BackgroundEffectSurfaceUserData>
+ 'static
{
pub trait ExtBackgroundEffectHandler: 'static {
/// Getter for background-effect capabilities of the compositor
fn capabilities(&self) -> Capability {
// For now only blur is supported, so it's safe to assume it's supported by default
@ -148,8 +142,11 @@ pub struct BackgroundEffectState {
impl BackgroundEffectState {
/// Regiseter new [ExtBackgroundEffectManagerV1] global
pub fn new<D: ExtBackgroundEffectHandler>(display: &DisplayHandle) -> BackgroundEffectState {
let global = display.create_global::<D, ExtBackgroundEffectManagerV1, _>(1, ());
pub fn new<D>(display: &DisplayHandle) -> BackgroundEffectState
where
D: ExtBackgroundEffectHandler + GlobalDispatch<ExtBackgroundEffectManagerV1, GlobalData>,
{
let global = display.create_global::<D, ExtBackgroundEffectManagerV1, _>(1, GlobalData);
BackgroundEffectState { global }
}
@ -158,37 +155,3 @@ impl BackgroundEffectState {
self.global.clone()
}
}
/// Macro to delegate implementation of the background effect protocol
#[macro_export]
macro_rules! delegate_background_effect {
($(@<$( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+>)? $ty: ty) => {
const _: () = {
use $crate::{
reexports::{
wayland_protocols::ext::background_effect::v1::server::{
ext_background_effect_manager_v1::ExtBackgroundEffectManagerV1,
ext_background_effect_surface_v1::ExtBackgroundEffectSurfaceV1,
},
wayland_server::{delegate_dispatch, delegate_global_dispatch},
},
wayland::background_effect::{BackgroundEffectState, BackgroundEffectSurfaceUserData},
};
delegate_global_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [ExtBackgroundEffectManagerV1: ()] => BackgroundEffectState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [ExtBackgroundEffectManagerV1: ()] => BackgroundEffectState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [ExtBackgroundEffectSurfaceV1: BackgroundEffectSurfaceUserData] => BackgroundEffectState
);
};
};
}

View file

@ -7,7 +7,6 @@
//! To initialize this implementation create the [`CommitTimingManagerState`] and store it inside your `State` struct.
//!
//! ```
//! use smithay::delegate_commit_timing;
//! use smithay::wayland::compositor;
//! use smithay::wayland::commit_timing::CommitTimingManagerState;
//!
@ -21,7 +20,7 @@
//! // insert the CommitTimingManagerState into your state
//! // ..
//!
//! delegate_commit_timing!(State);
//! smithay::delegate_dispatch2!(State);
//!
//! // You're now ready to go!
//! ```
@ -93,7 +92,10 @@ use wayland_server::{
use crate::{
utils::Time,
wayland::compositor::{add_blocker, add_pre_commit_hook},
wayland::{
Dispatch2, GlobalDispatch2,
compositor::{add_blocker, add_pre_commit_hook},
},
};
use super::compositor::{Barrier, with_states};
@ -112,8 +114,7 @@ impl CommitTimingManagerState {
/// remove or disable this global in the future.
pub fn new<D>(display: &DisplayHandle) -> Self
where
D: GlobalDispatch<WpCommitTimingManagerV1, bool>,
D: Dispatch<WpCommitTimingManagerV1, bool>,
D: GlobalDispatch<WpCommitTimingManagerV1, CommitTimingManagerData>,
D: 'static,
{
Self::new_internal::<D>(display, true)
@ -125,8 +126,7 @@ impl CommitTimingManagerState {
/// remove or disable this global in the future.
pub fn unmanaged<D>(display: &DisplayHandle) -> Self
where
D: GlobalDispatch<WpCommitTimingManagerV1, bool>,
D: Dispatch<WpCommitTimingManagerV1, bool>,
D: GlobalDispatch<WpCommitTimingManagerV1, CommitTimingManagerData>,
D: 'static,
{
Self::new_internal::<D>(display, false)
@ -134,11 +134,11 @@ impl CommitTimingManagerState {
fn new_internal<D>(display: &DisplayHandle, is_managed: bool) -> Self
where
D: GlobalDispatch<WpCommitTimingManagerV1, bool>,
D: Dispatch<WpCommitTimingManagerV1, bool>,
D: GlobalDispatch<WpCommitTimingManagerV1, CommitTimingManagerData>,
D: 'static,
{
let global = display.create_global::<D, WpCommitTimingManagerV1, _>(1, is_managed);
let global =
display.create_global::<D, WpCommitTimingManagerV1, _>(1, CommitTimingManagerData { is_managed });
Self { global, is_managed }
}
@ -154,41 +154,43 @@ impl CommitTimingManagerState {
}
}
impl<D> GlobalDispatch<WpCommitTimingManagerV1, bool, D> for CommitTimingManagerState
#[doc(hidden)]
#[derive(Debug, Clone, Copy)]
pub struct CommitTimingManagerData {
is_managed: bool,
}
impl<D> GlobalDispatch2<WpCommitTimingManagerV1, D> for CommitTimingManagerData
where
D: GlobalDispatch<WpCommitTimingManagerV1, bool>,
D: Dispatch<WpCommitTimingManagerV1, bool>,
D: Dispatch<WpCommitTimingManagerV1, CommitTimingManagerData>,
D: 'static,
{
fn bind(
&self,
_state: &mut D,
_dh: &DisplayHandle,
_client: &wayland_server::Client,
resource: New<WpCommitTimingManagerV1>,
global_data: &bool,
data_init: &mut DataInit<'_, D>,
) {
data_init.init(resource, *global_data);
data_init.init(resource, *self);
}
}
impl<D> Dispatch<WpCommitTimingManagerV1, bool, D> for CommitTimingManagerState
impl<D> Dispatch2<WpCommitTimingManagerV1, D> for CommitTimingManagerData
where
D: Dispatch<WpCommitTimingManagerV1, bool>,
D: Dispatch<WpCommitTimerV1, Weak<WlSurface>>,
D: Dispatch<WpCommitTimerV1, CommitTimerData>,
D: 'static,
{
fn request(
&self,
_state: &mut D,
_client: &wayland_server::Client,
_resource: &WpCommitTimingManagerV1,
request: wp_commit_timing_manager_v1::Request,
data: &bool,
_dhandle: &DisplayHandle,
data_init: &mut DataInit<'_, D>,
) {
let is_managed = *data;
match request {
wp_commit_timing_manager_v1::Request::GetTimer { id, surface } => {
let (is_initial, has_active_commit_timer) = with_states(&surface, |states| {
@ -209,7 +211,7 @@ where
}
// Make sure we do not install the hook more then once in case the surface is being reused
if is_managed && is_initial {
if self.is_managed && is_initial {
add_pre_commit_hook::<D, _>(&surface, |_, _, surface| {
let timestamp = with_states(surface, |states| {
states
@ -231,7 +233,7 @@ where
});
}
let commit_timer: WpCommitTimerV1 = data_init.init(id, surface.downgrade());
let commit_timer: WpCommitTimerV1 = data_init.init(id, CommitTimerData(surface.downgrade()));
with_states(&surface, |states| {
states
@ -251,17 +253,20 @@ where
// Used to realize the `AlreadyExists` protocol check.
struct CommitTimerMarker(Option<WpCommitTimerV1>);
impl<D> Dispatch<WpCommitTimerV1, Weak<WlSurface>, D> for CommitTimingManagerState
#[doc(hidden)]
#[derive(Debug)]
pub struct CommitTimerData(Weak<WlSurface>);
impl<D> Dispatch2<WpCommitTimerV1, D> for CommitTimerData
where
D: Dispatch<WpCommitTimerV1, Weak<WlSurface>>,
D: 'static,
{
fn request(
&self,
_state: &mut D,
_client: &wayland_server::Client,
resource: &WpCommitTimerV1,
request: wp_commit_timer_v1::Request,
data: &Weak<WlSurface>,
_dhandle: &DisplayHandle,
_data_init: &mut DataInit<'_, D>,
) {
@ -271,7 +276,7 @@ where
tv_sec_lo,
tv_nsec,
} => {
let Ok(surface) = data.upgrade() else {
let Ok(surface) = self.0.upgrade() else {
resource.post_error(
wp_commit_timer_v1::Error::SurfaceDestroyed as u32,
"the surface associated with this commit timer object has been destroyed".to_string(),
@ -308,7 +313,7 @@ where
}
}
wp_commit_timer_v1::Request::Destroy => {
if let Ok(surface) = data.upgrade() {
if let Ok(surface) = self.0.upgrade() {
with_states(&surface, |states| {
states
.data_map
@ -434,20 +439,3 @@ impl std::cmp::PartialOrd for CommitTimerBarrier {
Some(self.cmp(other))
}
}
/// Macro used to delegate [`WpCommitTimingManagerV1`] events
#[macro_export]
macro_rules! delegate_commit_timing {
($(@<$( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+>)? $ty: ty) => {
$crate::reexports::wayland_server::delegate_global_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [
$crate::reexports::wayland_protocols::wp::commit_timing::v1::server::wp_commit_timing_manager_v1::WpCommitTimingManagerV1: bool
] => $crate::wayland::commit_timing::CommitTimingManagerState);
$crate::reexports::wayland_server::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [
$crate::reexports::wayland_protocols::wp::commit_timing::v1::server::wp_commit_timing_manager_v1::WpCommitTimingManagerV1: bool
] => $crate::wayland::commit_timing::CommitTimingManagerState);
$crate::reexports::wayland_server::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [
$crate::reexports::wayland_protocols::wp::commit_timing::v1::server::wp_commit_timer_v1::WpCommitTimerV1: $crate::reexports::wayland_server::Weak<$crate::reexports::wayland_server::protocol::wl_surface::WlSurface>
] => $crate::wayland::commit_timing::CommitTimingManagerState);
};
}

View file

@ -4,7 +4,7 @@ use std::sync::{
};
use wayland_server::{
DataInit, Dispatch, DisplayHandle, GlobalDispatch, New, Resource, WEnum,
DataInit, Dispatch, DisplayHandle, New, Resource, WEnum,
protocol::{
wl_callback::{self, WlCallback},
wl_compositor::{self, WlCompositor},
@ -20,9 +20,11 @@ use crate::utils::{
alive_tracker::{AliveTracker, IsAlive},
};
use crate::wayland::{Dispatch2, GlobalData, GlobalDispatch2};
use super::{
AlreadyHasRole, BufferAssignment, CompositorHandler, CompositorState, Damage, Rectangle, RectangleKind,
RegionAttributes, SurfaceAttributes,
AlreadyHasRole, BufferAssignment, CompositorHandler, Damage, Rectangle, RectangleKind, RegionAttributes,
SurfaceAttributes,
cache::Cacheable,
tree::{Location, PrivateSurfaceData},
};
@ -33,41 +35,39 @@ use tracing::trace;
* wl_compositor
*/
impl<D> GlobalDispatch<WlCompositor, (), D> for CompositorState
impl<D> GlobalDispatch2<WlCompositor, D> for GlobalData
where
D: GlobalDispatch<WlCompositor, ()>,
D: Dispatch<WlCompositor, ()>,
D: Dispatch<WlCompositor, GlobalData>,
D: Dispatch<WlSurface, SurfaceUserData>,
D: Dispatch<WlRegion, RegionUserData>,
D: CompositorHandler,
D: 'static,
{
fn bind(
&self,
_state: &mut D,
_handle: &DisplayHandle,
_client: &wayland_server::Client,
resource: New<WlCompositor>,
_global_data: &(),
data_init: &mut DataInit<'_, D>,
) {
data_init.init(resource, ());
data_init.init(resource, GlobalData);
}
}
impl<D> Dispatch<WlCompositor, (), D> for CompositorState
impl<D> Dispatch2<WlCompositor, D> for GlobalData
where
D: Dispatch<WlCompositor, ()>,
D: Dispatch<WlSurface, SurfaceUserData>,
D: Dispatch<WlRegion, RegionUserData>,
D: CompositorHandler,
D: 'static,
{
fn request(
&self,
state: &mut D,
_client: &wayland_server::Client,
_resource: &WlCompositor,
request: wl_compositor::Request,
_data: &(),
_dhandle: &DisplayHandle,
data_init: &mut DataInit<'_, D>,
) {
@ -156,19 +156,18 @@ pub struct SurfaceUserData {
pub(super) user_state_type: (std::any::TypeId, &'static str),
}
impl<D> Dispatch<WlSurface, SurfaceUserData, D> for CompositorState
impl<D> Dispatch2<WlSurface, D> for SurfaceUserData
where
D: Dispatch<WlSurface, SurfaceUserData>,
D: Dispatch<WlCallback, ()>,
D: Dispatch<WlCallback, GlobalData>,
D: CompositorHandler,
D: 'static,
{
fn request(
&self,
state: &mut D,
client: &wayland_server::Client,
surface: &WlSurface,
request: wl_surface::Request,
_data: &SurfaceUserData,
handle: &DisplayHandle,
data_init: &mut wayland_server::DataInit<'_, D>,
) {
@ -227,7 +226,7 @@ where
});
}
wl_surface::Request::Frame { callback } => {
let callback = data_init.init(callback, ());
let callback = data_init.init(callback, GlobalData);
PrivateSurfaceData::with_states(surface, |states| {
states
@ -341,15 +340,10 @@ where
}
}
fn destroyed(
state: &mut D,
_client_id: wayland_server::backend::ClientId,
surface: &WlSurface,
data: &SurfaceUserData,
) {
fn destroyed(&self, state: &mut D, _client_id: wayland_server::backend::ClientId, surface: &WlSurface) {
// We let the destruction hooks run first and then tell the compositor handler the surface was
// destroyed.
data.alive_tracker.destroy_notify();
self.alive_tracker.destroy_notify();
state.destroyed(surface);
// Remove the surface after the callback is invoked.
@ -357,7 +351,7 @@ where
.compositor_state()
.surfaces
.retain(|s| s.id() != surface.id());
PrivateSurfaceData::cleanup(state, data, surface);
PrivateSurfaceData::cleanup(state, self, surface);
}
}
@ -379,21 +373,20 @@ pub struct RegionUserData {
pub(crate) inner: Mutex<RegionAttributes>,
}
impl<D> Dispatch<WlRegion, RegionUserData, D> for CompositorState
impl<D> Dispatch2<WlRegion, D> for RegionUserData
where
D: Dispatch<WlRegion, RegionUserData>,
D: CompositorHandler,
{
fn request(
&self,
state: &mut D,
client: &wayland_server::Client,
_resource: &WlRegion,
request: wl_region::Request,
data: &RegionUserData,
_dhandle: &DisplayHandle,
_init: &mut wayland_server::DataInit<'_, D>,
) {
let mut guard = data.inner.lock().unwrap();
let mut guard = self.inner.lock().unwrap();
let client_scale = state.client_compositor_state(client).client_scale();
match request {
@ -423,39 +416,37 @@ where
* wl_subcompositor
*/
impl<D> GlobalDispatch<WlSubcompositor, (), D> for CompositorState
impl<D> GlobalDispatch2<WlSubcompositor, D> for GlobalData
where
D: GlobalDispatch<WlSubcompositor, ()>,
D: Dispatch<WlSubcompositor, ()>,
D: Dispatch<WlSubcompositor, GlobalData>,
D: Dispatch<WlSubsurface, SubsurfaceUserData>,
D: CompositorHandler,
D: 'static,
{
fn bind(
&self,
_state: &mut D,
_handle: &DisplayHandle,
_client: &wayland_server::Client,
resource: New<WlSubcompositor>,
_global_data: &(),
data_init: &mut DataInit<'_, D>,
) {
data_init.init(resource, ());
data_init.init(resource, GlobalData);
}
}
impl<D> Dispatch<WlSubcompositor, (), D> for CompositorState
impl<D> Dispatch2<WlSubcompositor, D> for GlobalData
where
D: Dispatch<WlSubcompositor, ()>,
D: Dispatch<WlSubsurface, SubsurfaceUserData>,
D: CompositorHandler,
D: 'static,
{
fn request(
&self,
state: &mut D,
_client: &wayland_server::Client,
subcompositor: &WlSubcompositor,
request: wl_subcompositor::Request,
_data: &(),
_dh: &DisplayHandle,
data_init: &mut DataInit<'_, D>,
) {
@ -561,25 +552,24 @@ pub fn is_effectively_sync(surface: &wl_surface::WlSurface) -> bool {
}
}
impl<D> Dispatch<WlSubsurface, SubsurfaceUserData, D> for CompositorState
impl<D> Dispatch2<WlSubsurface, D> for SubsurfaceUserData
where
D: Dispatch<WlSubsurface, SubsurfaceUserData>,
D: CompositorHandler,
D: 'static,
{
fn request(
&self,
state: &mut D,
client: &wayland_server::Client,
subsurface: &WlSubsurface,
request: wl_subsurface::Request,
data: &SubsurfaceUserData,
_dh: &DisplayHandle,
_data_init: &mut DataInit<'_, D>,
) {
match request {
wl_subsurface::Request::SetPosition { x, y } => {
let client_scale = state.client_compositor_state(client).client_scale();
PrivateSurfaceData::with_states(&data.surface, |state| {
PrivateSurfaceData::with_states(&self.surface, |state| {
state
.cached_state
.get::<SubsurfaceCachedState>()
@ -591,7 +581,7 @@ where
})
}
wl_subsurface::Request::PlaceAbove { sibling } => {
if let Err(()) = PrivateSurfaceData::reorder(&data.surface, Location::After, &sibling) {
if let Err(()) = PrivateSurfaceData::reorder(&self.surface, Location::After, &sibling) {
subsurface.post_error(
wl_subsurface::Error::BadSurface,
"Provided surface is not a sibling or parent.",
@ -599,14 +589,14 @@ where
}
}
wl_subsurface::Request::PlaceBelow { sibling } => {
if let Err(()) = PrivateSurfaceData::reorder(&data.surface, Location::Before, &sibling) {
if let Err(()) = PrivateSurfaceData::reorder(&self.surface, Location::Before, &sibling) {
subsurface.post_error(
wl_subsurface::Error::BadSurface,
"Provided surface is not a sibling or parent.",
)
}
}
wl_subsurface::Request::SetSync => PrivateSurfaceData::with_states(&data.surface, |state| {
wl_subsurface::Request::SetSync => PrivateSurfaceData::with_states(&self.surface, |state| {
state
.data_map
.get::<SubsurfaceState>()
@ -614,7 +604,7 @@ where
.sync
.store(true, Ordering::Release);
}),
wl_subsurface::Request::SetDesync => PrivateSurfaceData::with_states(&data.surface, |state| {
wl_subsurface::Request::SetDesync => PrivateSurfaceData::with_states(&self.surface, |state| {
state
.data_map
.get::<SubsurfaceState>()
@ -630,13 +620,13 @@ where
}
fn destroyed(
&self,
_state: &mut D,
_client_id: wayland_server::backend::ClientId,
_object: &WlSubsurface,
data: &SubsurfaceUserData,
) {
PrivateSurfaceData::unset_parent(&data.surface);
PrivateSurfaceData::with_states(&data.surface, |state| {
PrivateSurfaceData::unset_parent(&self.surface);
PrivateSurfaceData::with_states(&self.surface, |state| {
state
.data_map
.get::<SubsurfaceState>()
@ -651,18 +641,17 @@ where
}
}
impl<D> Dispatch<WlCallback, (), D> for CompositorState
impl<D> Dispatch2<WlCallback, D> for GlobalData
where
D: Dispatch<WlCallback, ()>,
D: CompositorHandler,
D: 'static,
{
fn request(
&self,
_state: &mut D,
_client: &wayland_server::Client,
_subsurface: &WlCallback,
_request: wl_callback::Request,
_data: &(),
_handle: &DisplayHandle,
_data_init: &mut DataInit<'_, D>,
) {

View file

@ -30,7 +30,6 @@
//! ```
//! # extern crate wayland_server;
//! # #[macro_use] extern crate smithay;
//! use smithay::delegate_compositor;
//! use smithay::wayland::compositor::{CompositorState, CompositorClientState, CompositorHandler};
//!
//! # struct State { compositor_state: CompositorState }
@ -60,7 +59,8 @@
//! // .. your implementation ..
//! }
//! }
//! delegate_compositor!(State);
//!
//! smithay::delegate_dispatch2!(State);
//!
//! // You're now ready to go!
//! ```
@ -124,6 +124,7 @@ use self::tree::{PrivateSurfaceData, SuggestedSurfaceState};
use crate::utils::Transform;
pub use crate::utils::hook::HookId;
use crate::utils::{Buffer, Logical, Point, Rectangle, user_data::UserDataMap};
use crate::wayland::GlobalData;
use atomic_float::AtomicF64;
use wayland_server::backend::GlobalId;
use wayland_server::protocol::wl_compositor::WlCompositor;
@ -683,7 +684,7 @@ impl CompositorState {
/// [`wl_subcompositor`]: wayland_server::protocol::wl_subcompositor
pub fn new<D>(display: &DisplayHandle) -> Self
where
D: GlobalDispatch<WlCompositor, ()> + GlobalDispatch<WlSubcompositor, ()> + 'static,
D: GlobalDispatch<WlCompositor, GlobalData> + GlobalDispatch<WlSubcompositor, GlobalData> + 'static,
{
Self::new_with_version::<D>(display, 5)
}
@ -697,17 +698,17 @@ impl CompositorState {
/// [`wl_compositor`]: wayland_server::protocol::wl_compositor
pub fn new_v6<D>(display: &DisplayHandle) -> Self
where
D: GlobalDispatch<WlCompositor, ()> + GlobalDispatch<WlSubcompositor, ()> + 'static,
D: GlobalDispatch<WlCompositor, GlobalData> + GlobalDispatch<WlSubcompositor, GlobalData> + 'static,
{
Self::new_with_version::<D>(display, 6)
}
fn new_with_version<D>(display: &DisplayHandle, version: u32) -> Self
where
D: GlobalDispatch<WlCompositor, ()> + GlobalDispatch<WlSubcompositor, ()> + 'static,
D: GlobalDispatch<WlCompositor, GlobalData> + GlobalDispatch<WlSubcompositor, GlobalData> + 'static,
{
let compositor = display.create_global::<D, WlCompositor, ()>(version, ());
let subcompositor = display.create_global::<D, WlSubcompositor, ()>(1, ());
let compositor = display.create_global::<D, WlCompositor, _>(version, GlobalData);
let subcompositor = display.create_global::<D, WlSubcompositor, _>(1, GlobalData);
CompositorState {
compositor,
@ -727,61 +728,6 @@ impl CompositorState {
}
}
#[allow(missing_docs)] // TODO
#[macro_export]
macro_rules! delegate_compositor {
($(@<$( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+>)? $ty: ty) => {
const _: () = {
use $crate::{
reexports::wayland_server::{
delegate_dispatch, delegate_global_dispatch,
protocol::{
wl_callback::WlCallback, wl_compositor::WlCompositor, wl_region::WlRegion,
wl_subcompositor::WlSubcompositor, wl_subsurface::WlSubsurface,
wl_surface::WlSurface,
},
},
wayland::compositor::{CompositorState, RegionUserData, SubsurfaceUserData, SurfaceUserData},
};
delegate_global_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [WlCompositor: ()] => CompositorState
);
delegate_global_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [WlSubcompositor: ()] => CompositorState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [WlCompositor: ()] => CompositorState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [WlSurface: SurfaceUserData] => CompositorState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [WlRegion: RegionUserData] => CompositorState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [WlCallback: ()] => CompositorState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [WlSubcompositor: ()] => CompositorState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [WlSubsurface: SubsurfaceUserData] => CompositorState
);
};
};
}
#[cfg(test)]
mod tests {
use super::*;

View file

@ -2,44 +2,39 @@ use wayland_protocols::wp::content_type::v1::server::{
wp_content_type_manager_v1::{self, WpContentTypeManagerV1},
wp_content_type_v1::{self, WpContentTypeV1},
};
use wayland_server::{
Client, DataInit, Dispatch, DisplayHandle, GlobalDispatch, New, Resource, backend::ClientId,
};
use wayland_server::{Client, DataInit, Dispatch, DisplayHandle, New, Resource, backend::ClientId};
use super::{ContentTypeState, ContentTypeSurfaceCachedState, ContentTypeSurfaceData, ContentTypeUserData};
use crate::wayland::compositor;
use super::{ContentTypeSurfaceCachedState, ContentTypeSurfaceData, ContentTypeUserData};
use crate::wayland::{Dispatch2, GlobalData, GlobalDispatch2, compositor};
impl<D> GlobalDispatch<WpContentTypeManagerV1, (), D> for ContentTypeState
impl<D> GlobalDispatch2<WpContentTypeManagerV1, D> for GlobalData
where
D: GlobalDispatch<WpContentTypeManagerV1, ()>,
D: Dispatch<WpContentTypeManagerV1, ()>,
D: Dispatch<WpContentTypeV1, ContentTypeUserData>,
D: Dispatch<WpContentTypeManagerV1, GlobalData>,
D: 'static,
{
fn bind(
&self,
_state: &mut D,
_: &DisplayHandle,
_: &Client,
resource: New<WpContentTypeManagerV1>,
_: &(),
data_init: &mut DataInit<'_, D>,
) {
data_init.init(resource, ());
data_init.init(resource, GlobalData);
}
}
impl<D> Dispatch<WpContentTypeManagerV1, (), D> for ContentTypeState
impl<D> Dispatch2<WpContentTypeManagerV1, D> for GlobalData
where
D: Dispatch<WpContentTypeManagerV1, ()>,
D: Dispatch<WpContentTypeV1, ContentTypeUserData>,
D: 'static,
{
fn request(
&self,
_state: &mut D,
_: &Client,
manager: &wp_content_type_manager_v1::WpContentTypeManagerV1,
request: wp_content_type_manager_v1::Request,
_data: &(),
_dh: &DisplayHandle,
data_init: &mut DataInit<'_, D>,
) {
@ -76,16 +71,13 @@ where
}
}
impl<D> Dispatch<WpContentTypeV1, ContentTypeUserData, D> for ContentTypeState
where
D: Dispatch<WpContentTypeV1, ContentTypeUserData>,
{
impl<D> Dispatch2<WpContentTypeV1, D> for ContentTypeUserData {
fn request(
&self,
_state: &mut D,
_: &Client,
_: &WpContentTypeV1,
request: wp_content_type_v1::Request,
data: &ContentTypeUserData,
_dh: &DisplayHandle,
_: &mut DataInit<'_, D>,
) {
@ -94,7 +86,7 @@ where
let wayland_server::WEnum::Value(content_type) = content_type else {
return;
};
let Some(surface) = data.wl_surface() else {
let Some(surface) = self.wl_surface() else {
return;
};
@ -110,7 +102,7 @@ where
// This is equivalent to setting the content type to none,
// including double buffering semantics.
wp_content_type_v1::Request::Destroy => {
let Some(surface) = data.wl_surface() else {
let Some(surface) = self.wl_surface() else {
return;
};
@ -132,7 +124,7 @@ where
}
}
fn destroyed(_state: &mut D, _client: ClientId, _object: &WpContentTypeV1, _data: &ContentTypeUserData) {
fn destroyed(&self, _state: &mut D, _client: ClientId, _object: &WpContentTypeV1) {
// Nothing to do here, graceful Destroy is already handled with double buffering
// and in case of client close WlSurface destroyed handler will clean up the data anyway,
// so there is no point in queuing new update

View file

@ -7,7 +7,6 @@
//! #
//! use wayland_server::{protocol::wl_surface::WlSurface, DisplayHandle};
//! use smithay::{
//! delegate_content_type, delegate_compositor,
//! wayland::compositor::{self, CompositorState, CompositorClientState, CompositorHandler},
//! wayland::content_type::{ContentTypeSurfaceCachedState, ContentTypeState},
//! };
@ -18,8 +17,7 @@
//! struct ClientState { compositor_state: CompositorClientState }
//! impl wayland_server::backend::ClientData for ClientState {}
//!
//! delegate_content_type!(State);
//! delegate_compositor!(State);
//! smithay::delegate_dispatch2!(State);
//!
//! impl CompositorHandler for State {
//! fn compositor_state(&mut self) -> &mut CompositorState {
@ -55,16 +53,16 @@ use std::sync::{
};
use wayland_protocols::wp::content_type::v1::server::{
wp_content_type_manager_v1::WpContentTypeManagerV1,
wp_content_type_v1::{self, WpContentTypeV1},
wp_content_type_manager_v1::WpContentTypeManagerV1, wp_content_type_v1,
};
use wayland_server::{
Dispatch, DisplayHandle, GlobalDispatch, Resource, Weak, backend::GlobalId,
protocol::wl_surface::WlSurface,
DisplayHandle, GlobalDispatch, Resource, Weak, backend::GlobalId, protocol::wl_surface::WlSurface,
};
use super::compositor::Cacheable;
use crate::wayland::GlobalData;
mod dispatch;
/// Data associated with WlSurface
@ -158,12 +156,9 @@ impl ContentTypeState {
/// Regiseter new [WpContentTypeManagerV1] global
pub fn new<D>(display: &DisplayHandle) -> ContentTypeState
where
D: GlobalDispatch<WpContentTypeManagerV1, ()>
+ Dispatch<WpContentTypeManagerV1, ()>
+ Dispatch<WpContentTypeV1, ContentTypeUserData>
+ 'static,
D: GlobalDispatch<WpContentTypeManagerV1, GlobalData> + 'static,
{
let global = display.create_global::<D, WpContentTypeManagerV1, _>(1, ());
let global = display.create_global::<D, WpContentTypeManagerV1, _>(1, GlobalData);
ContentTypeState { global }
}
@ -173,37 +168,3 @@ impl ContentTypeState {
self.global.clone()
}
}
/// Macro to delegate implementation of the wp content type protocol
#[macro_export]
macro_rules! delegate_content_type {
($(@<$( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+>)? $ty: ty) => {
const _: () = {
use $crate::{
reexports::{
wayland_protocols::wp::content_type::v1::server::{
wp_content_type_manager_v1::WpContentTypeManagerV1,
wp_content_type_v1::WpContentTypeV1,
},
wayland_server::{delegate_dispatch, delegate_global_dispatch},
},
wayland::content_type::{ContentTypeState, ContentTypeUserData},
};
delegate_global_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [WpContentTypeManagerV1: ()] => ContentTypeState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [WpContentTypeManagerV1: ()] => ContentTypeState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [WpContentTypeV1: ContentTypeUserData] => ContentTypeState
);
};
};
}

View file

@ -10,7 +10,6 @@
//! extern crate wayland_server;
//!
//! use smithay::wayland::cursor_shape::CursorShapeManagerState;
//! use smithay::delegate_cursor_shape;
//!
//! # use smithay::backend::input::KeyState;
//! # use smithay::input::{
@ -95,7 +94,7 @@
//!
//! let state = CursorShapeManagerState::new::<State>(&display.handle());
//!
//! delegate_cursor_shape!(State);
//! smithay::delegate_dispatch2!(State);
//! ```
use wayland_protocols::wp::cursor_shape::v1::server::wp_cursor_shape_device_v1::Request as ShapeRequest;
@ -115,6 +114,7 @@ use crate::input::WeakSeat;
use crate::input::pointer::{CursorIcon, CursorImageStatus};
use crate::utils::Serial;
use crate::wayland::seat::{WaylandFocus, pointer::allow_setting_cursor};
use crate::wayland::{Dispatch2, GlobalData, GlobalDispatch2};
use super::seat::PointerUserData;
use super::tablet_manager::{TabletSeatHandler, TabletToolUserData};
@ -129,12 +129,12 @@ impl CursorShapeManagerState {
/// Register new [CursorShapeManager] global.
pub fn new<D>(display: &DisplayHandle) -> Self
where
D: GlobalDispatch<CursorShapeManager, ()>,
D: Dispatch<CursorShapeManager, ()>,
D: GlobalDispatch<CursorShapeManager, GlobalData>,
D: Dispatch<CursorShapeManager, GlobalData>,
D: SeatHandler,
D: 'static,
{
let global = display.create_global::<D, CursorShapeManager, _>(2, ());
let global = display.create_global::<D, CursorShapeManager, _>(2, GlobalData);
Self { global }
}
@ -144,38 +144,36 @@ impl CursorShapeManagerState {
}
}
impl<D> GlobalDispatch<CursorShapeManager, (), D> for CursorShapeManagerState
impl<D> GlobalDispatch2<CursorShapeManager, D> for GlobalData
where
D: GlobalDispatch<CursorShapeManager, ()>,
D: Dispatch<CursorShapeManager, ()>,
D: Dispatch<CursorShapeManager, GlobalData>,
D: SeatHandler,
D: 'static,
{
fn bind(
&self,
_state: &mut D,
_handle: &DisplayHandle,
_client: &wayland_server::Client,
resource: wayland_server::New<CursorShapeManager>,
_global_data: &(),
data_init: &mut wayland_server::DataInit<'_, D>,
) {
data_init.init(resource, ());
data_init.init(resource, GlobalData);
}
}
impl<D> Dispatch<CursorShapeManager, (), D> for CursorShapeManagerState
impl<D> Dispatch2<CursorShapeManager, D> for GlobalData
where
D: Dispatch<CursorShapeManager, ()>,
D: Dispatch<CursorShapeDevice, CursorShapeDeviceUserData<D>>,
D: SeatHandler,
D: 'static,
{
fn request(
&self,
state: &mut D,
_client: &wayland_server::Client,
_resource: &CursorShapeManager,
request: <CursorShapeManager as wayland_server::Resource>::Request,
_data: &(),
_dhandle: &DisplayHandle,
data_init: &mut wayland_server::DataInit<'_, D>,
) {
@ -236,20 +234,18 @@ pub(crate) enum CursorShapeDeviceUserDataInner<D: SeatHandler> {
Tablet(Weak<ZwpTabletToolV2>),
}
impl<D> Dispatch<CursorShapeDevice, CursorShapeDeviceUserData<D>, D> for CursorShapeManagerState
impl<D> Dispatch2<CursorShapeDevice, D> for CursorShapeDeviceUserData<D>
where
D: Dispatch<CursorShapeManager, ()>,
D: Dispatch<CursorShapeDevice, CursorShapeDeviceUserData<D>>,
D: SeatHandler + TabletSeatHandler,
<D as SeatHandler>::PointerFocus: WaylandFocus,
D: 'static,
{
fn request(
&self,
state: &mut D,
_client: &wayland_server::Client,
resource: &CursorShapeDevice,
request: <CursorShapeDevice as wayland_server::Resource>::Request,
data: &CursorShapeDeviceUserData<D>,
_dhandle: &DisplayHandle,
_data_init: &mut wayland_server::DataInit<'_, D>,
) {
@ -258,7 +254,7 @@ where
serial,
shape: WEnum::Value(shape),
} => {
match &data.0 {
match &self.0 {
CursorShapeDeviceUserDataInner::Pointer { seat } => {
let Some(seat) = seat.upgrade() else {
return;
@ -356,37 +352,3 @@ fn shape_to_cursor_icon(shape: Shape) -> CursorIcon {
_ => CursorIcon::Default,
}
}
#[allow(missing_docs)] // TODO
#[macro_export]
macro_rules! delegate_cursor_shape {
($(@<$( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+>)? $ty: ty) => {
const _: () = {
use $crate::{
reexports::{
wayland_protocols::wp::cursor_shape::v1::server::{
wp_cursor_shape_device_v1::WpCursorShapeDeviceV1,
wp_cursor_shape_manager_v1::WpCursorShapeManagerV1,
},
wayland_server::{delegate_dispatch, delegate_global_dispatch},
},
wayland::cursor_shape::{CursorShapeDeviceUserData, CursorShapeManagerState},
};
delegate_global_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [WpCursorShapeManagerV1: ()] => CursorShapeManagerState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [WpCursorShapeManagerV1: ()] => CursorShapeManagerState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [WpCursorShapeDeviceV1: CursorShapeDeviceUserData<$ty>] => CursorShapeManagerState
);
};
};
}

91
src/wayland/dispatch2.rs Normal file
View file

@ -0,0 +1,91 @@
use wayland_server::{Client, DataInit, DisplayHandle, New, Resource, backend::ClientId};
/// A simplified version of [`wayland_server::Dispatch`]
///
/// A future version of `wayland-server` will replace `Dispatch` with this.
pub trait Dispatch2<I: Resource, State> {
/// Called when a request from a client is processed.
fn request(
&self,
state: &mut State,
client: &Client,
resource: &I,
request: I::Request,
dhandle: &DisplayHandle,
data_init: &mut DataInit<'_, State>,
);
/// Called when the object this user data is associated with has been destroyed.
fn destroyed(&self, _state: &mut State, _client: ClientId, _resource: &I) {}
}
/// A simplified version of [`wayland_server::GlobalDispatch`]
///
/// A future version of `wayland-server` will replace `GlobalDispatch` with this.
pub trait GlobalDispatch2<I: Resource, State> {
/// Called when a client has bound this global.
fn bind(
&self,
state: &mut State,
handle: &DisplayHandle,
client: &Client,
resource: New<I>,
data_init: &mut DataInit<'_, State>,
);
/// Checks if the global should be advertised to some client.
fn can_view(&self, _client: &Client) -> bool {
true
}
}
/// Implement `Dispatch` and `GlobalDispatch` for every implementation of [`Dispatch2`] and
/// [`GlobalDispatch2`].
#[macro_export]
macro_rules! delegate_dispatch2 {
($(@< $( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+ >)? $ty:ty) => {
impl<$( $( $lt $( : $clt $(+ $dlt )* )? ),+, )? I, UserData> $crate::reexports::wayland_server::Dispatch<I, UserData> for $ty
where
I: $crate::reexports::wayland_server::Resource,
UserData: $crate::wayland::Dispatch2<I, $ty> {
fn request(
state: &mut Self,
client: &$crate::reexports::wayland_server::Client,
resource: &I,
request: <I as $crate::reexports::wayland_server::Resource>::Request,
data: &UserData,
dhandle: &$crate::reexports::wayland_server::DisplayHandle,
data_init: &mut $crate::reexports::wayland_server::DataInit<'_, Self>,
) {
data.request(state, client, resource, request, dhandle, data_init);
}
fn destroyed(state: &mut Self, client: $crate::reexports::wayland_server::backend::ClientId, resource: &I, data: &UserData) {
data.destroyed(state, client, resource);
}
}
impl<$( $( $lt $( : $clt $(+ $dlt )* )? ),+, )? I, UserData> $crate::reexports::wayland_server::GlobalDispatch<I, UserData> for $ty
where
I: $crate::reexports::wayland_server::Resource,
UserData: $crate::wayland::GlobalDispatch2<I, $ty> {
fn bind(
state: &mut Self,
dhandle: &$crate::reexports::wayland_server::DisplayHandle,
client: &$crate::reexports::wayland_server::Client,
resource: $crate::reexports::wayland_server::New<I>,
data: &UserData,
data_init: &mut $crate::reexports::wayland_server::DataInit<'_, Self>,
) {
data.bind(state, dhandle, client, resource, data_init);
}
fn can_view(
client: $crate::reexports::wayland_server::Client,
data: &UserData
) -> bool {
data.can_view(&client)
}
}
};
}

View file

@ -4,30 +4,32 @@ use wayland_protocols::wp::linux_dmabuf::zv1::server::{
zwp_linux_buffer_params_v1, zwp_linux_dmabuf_feedback_v1, zwp_linux_dmabuf_v1,
};
use wayland_server::{
Client, DataInit, Dispatch, DisplayHandle, GlobalDispatch, New, Resource, backend::ClientId,
protocol::wl_buffer,
Client, DataInit, Dispatch, DisplayHandle, New, Resource, backend::ClientId, protocol::wl_buffer,
};
use crate::{
backend::allocator::dmabuf::{Dmabuf, MAX_PLANES, Plane},
wayland::{buffer::BufferHandler, compositor, dmabuf::SurfaceDmabufFeedbackStateInner},
wayland::{
Dispatch2, GlobalDispatch2, buffer::BufferHandler, compositor,
dmabuf::SurfaceDmabufFeedbackStateInner,
},
};
use super::{
DmabufData, DmabufFeedbackData, DmabufGlobal, DmabufGlobalData, DmabufHandler, DmabufParamsData,
DmabufState, Import, ImportNotifier, Modifier, SurfaceDmabufFeedbackState,
DmabufData, DmabufFeedbackData, DmabufGlobal, DmabufGlobalData, DmabufHandler, DmabufParamsData, Import,
ImportNotifier, Modifier, SurfaceDmabufFeedbackState,
};
impl<D> Dispatch<wl_buffer::WlBuffer, Dmabuf, D> for DmabufState
impl<D> Dispatch2<wl_buffer::WlBuffer, D> for Dmabuf
where
D: Dispatch<wl_buffer::WlBuffer, Dmabuf> + BufferHandler,
D: BufferHandler,
{
fn request(
&self,
_data: &mut D,
_client: &Client,
_buffer: &wl_buffer::WlBuffer,
request: wl_buffer::Request,
_udata: &Dmabuf,
_dh: &DisplayHandle,
_data_init: &mut DataInit<'_, D>,
) {
@ -40,25 +42,24 @@ where
}
}
fn destroyed(data: &mut D, _client: ClientId, buffer: &wl_buffer::WlBuffer, _udata: &Dmabuf) {
fn destroyed(&self, data: &mut D, _client: ClientId, buffer: &wl_buffer::WlBuffer) {
data.buffer_destroyed(buffer);
}
}
impl<D> Dispatch<zwp_linux_dmabuf_v1::ZwpLinuxDmabufV1, DmabufData, D> for DmabufState
impl<D> Dispatch2<zwp_linux_dmabuf_v1::ZwpLinuxDmabufV1, D> for DmabufData
where
D: Dispatch<zwp_linux_dmabuf_v1::ZwpLinuxDmabufV1, DmabufData>
+ Dispatch<zwp_linux_buffer_params_v1::ZwpLinuxBufferParamsV1, DmabufParamsData>
D: Dispatch<zwp_linux_buffer_params_v1::ZwpLinuxBufferParamsV1, DmabufParamsData>
+ Dispatch<zwp_linux_dmabuf_feedback_v1::ZwpLinuxDmabufFeedbackV1, DmabufFeedbackData>
+ DmabufHandler
+ 'static,
{
fn request(
&self,
state: &mut D,
_client: &Client,
_resource: &zwp_linux_dmabuf_v1::ZwpLinuxDmabufV1,
request: zwp_linux_dmabuf_v1::Request,
data: &DmabufData,
_dh: &DisplayHandle,
data_init: &mut DataInit<'_, D>,
) {
@ -69,9 +70,9 @@ where
data_init.init(
params_id,
DmabufParamsData {
id: data.id,
id: self.id,
used: AtomicBool::new(false),
formats: data.formats.clone(),
formats: self.formats.clone(),
modifier: Mutex::new(None),
planes: Mutex::new(Vec::with_capacity(MAX_PLANES)),
},
@ -82,17 +83,17 @@ where
let feedback = data_init.init(
id,
DmabufFeedbackData {
known_default_feedbacks: data.known_default_feedbacks.clone(),
known_default_feedbacks: self.known_default_feedbacks.clone(),
surface: None,
},
);
data.known_default_feedbacks
self.known_default_feedbacks
.lock()
.unwrap()
.push(feedback.downgrade());
data.default_feedback
self.default_feedback
.as_ref()
.unwrap()
.lock()
@ -104,7 +105,7 @@ where
let feedback = data_init.init(
id,
DmabufFeedbackData {
known_default_feedbacks: data.known_default_feedbacks.clone(),
known_default_feedbacks: self.known_default_feedbacks.clone(),
surface: Some(surface.downgrade()),
},
);
@ -113,8 +114,8 @@ where
states.data_map.get::<SurfaceDmabufFeedbackState>().is_none()
}) {
let new_feedback = state
.new_surface_feedback(&surface, &DmabufGlobal { id: data.id })
.unwrap_or_else(|| data.default_feedback.as_ref().unwrap().lock().unwrap().clone());
.new_surface_feedback(&surface, &DmabufGlobal { id: self.id })
.unwrap_or_else(|| self.default_feedback.as_ref().unwrap().lock().unwrap().clone());
compositor::with_states(&surface, |states| {
states
.data_map
@ -140,31 +141,24 @@ where
}
}
impl<D> Dispatch<zwp_linux_dmabuf_feedback_v1::ZwpLinuxDmabufFeedbackV1, DmabufFeedbackData, D>
for DmabufState
where
D: Dispatch<zwp_linux_dmabuf_v1::ZwpLinuxDmabufV1, DmabufData>
+ Dispatch<zwp_linux_buffer_params_v1::ZwpLinuxBufferParamsV1, DmabufParamsData>
+ Dispatch<zwp_linux_dmabuf_feedback_v1::ZwpLinuxDmabufFeedbackV1, DmabufFeedbackData>
+ 'static,
{
impl<D> Dispatch2<zwp_linux_dmabuf_feedback_v1::ZwpLinuxDmabufFeedbackV1, D> for DmabufFeedbackData {
fn request(
&self,
_state: &mut D,
_client: &Client,
resource: &zwp_linux_dmabuf_feedback_v1::ZwpLinuxDmabufFeedbackV1,
request: <zwp_linux_dmabuf_feedback_v1::ZwpLinuxDmabufFeedbackV1 as Resource>::Request,
data: &DmabufFeedbackData,
_dhandle: &DisplayHandle,
_data_init: &mut DataInit<'_, D>,
) {
match request {
zwp_linux_dmabuf_feedback_v1::Request::Destroy => {
data.known_default_feedbacks
self.known_default_feedbacks
.lock()
.unwrap()
.retain(|feedback| feedback != resource);
if let Some(surface) = data.surface.as_ref().and_then(|s| s.upgrade().ok()) {
if let Some(surface) = self.surface.as_ref().and_then(|s| s.upgrade().ok()) {
compositor::with_states(&surface, |states| {
if let Some(surface_state) = states.data_map.get::<SurfaceDmabufFeedbackState>() {
surface_state.remove_instance(resource);
@ -177,26 +171,23 @@ where
}
}
impl<D> GlobalDispatch<zwp_linux_dmabuf_v1::ZwpLinuxDmabufV1, DmabufGlobalData, D> for DmabufState
impl<D> GlobalDispatch2<zwp_linux_dmabuf_v1::ZwpLinuxDmabufV1, D> for DmabufGlobalData
where
D: GlobalDispatch<zwp_linux_dmabuf_v1::ZwpLinuxDmabufV1, DmabufGlobalData>
+ Dispatch<zwp_linux_dmabuf_v1::ZwpLinuxDmabufV1, DmabufData>
+ Dispatch<zwp_linux_buffer_params_v1::ZwpLinuxBufferParamsV1, DmabufParamsData>
+ 'static,
D: Dispatch<zwp_linux_dmabuf_v1::ZwpLinuxDmabufV1, DmabufData> + 'static,
{
fn bind(
&self,
_state: &mut D,
_dh: &DisplayHandle,
_client: &Client,
resource: New<zwp_linux_dmabuf_v1::ZwpLinuxDmabufV1>,
global_data: &DmabufGlobalData,
data_init: &mut DataInit<'_, D>,
) {
let data = DmabufData {
formats: global_data.formats.clone(),
id: global_data.id,
default_feedback: global_data.default_feedback.clone(),
known_default_feedbacks: global_data.known_default_feedbacks.clone(),
formats: self.formats.clone(),
id: self.id,
default_feedback: self.default_feedback.clone(),
known_default_feedbacks: self.known_default_feedbacks.clone(),
};
let zwp_dmabuf = data_init.init(resource, data);
@ -205,7 +196,7 @@ where
//
// These events are deprecated in version 4 of the protocol.
if zwp_dmabuf.version() < zwp_linux_dmabuf_v1::REQ_GET_DEFAULT_FEEDBACK_SINCE {
for (fourcc, modifiers) in &*global_data.formats {
for (fourcc, modifiers) in &*self.formats {
// Modifier support got added in version 3
if zwp_dmabuf.version() < zwp_linux_dmabuf_v1::EVT_MODIFIER_SINCE {
if modifiers.contains(&Modifier::Invalid) || modifiers.contains(&Modifier::Linear) {
@ -223,24 +214,21 @@ where
}
}
fn can_view(client: Client, global_data: &DmabufGlobalData) -> bool {
(global_data.filter)(&client)
fn can_view(&self, client: &Client) -> bool {
(self.filter)(client)
}
}
impl<D> Dispatch<zwp_linux_buffer_params_v1::ZwpLinuxBufferParamsV1, DmabufParamsData, D> for DmabufState
impl<D> Dispatch2<zwp_linux_buffer_params_v1::ZwpLinuxBufferParamsV1, D> for DmabufParamsData
where
D: Dispatch<zwp_linux_buffer_params_v1::ZwpLinuxBufferParamsV1, DmabufParamsData>
+ Dispatch<wl_buffer::WlBuffer, Dmabuf>
+ BufferHandler
+ DmabufHandler,
D: Dispatch<wl_buffer::WlBuffer, Dmabuf> + BufferHandler + DmabufHandler,
{
fn request(
&self,
state: &mut D,
_client: &Client,
params: &zwp_linux_buffer_params_v1::ZwpLinuxBufferParamsV1,
request: zwp_linux_buffer_params_v1::Request,
data: &DmabufParamsData,
dh: &DisplayHandle,
data_init: &mut DataInit<'_, D>,
) {
@ -255,7 +243,7 @@ where
modifier_hi,
modifier_lo,
} => {
if !data.ensure_unused(params) {
if !self.ensure_unused(params) {
return;
}
@ -268,7 +256,7 @@ where
return;
}
let mut planes = data.planes.lock().unwrap();
let mut planes = self.planes.lock().unwrap();
// Is the index already set?
if planes.iter().any(|plane| plane.plane_idx == plane_idx) {
@ -287,7 +275,7 @@ where
});
let modifier = Modifier::from(((modifier_hi as u64) << 32) + (modifier_lo as u64));
let mut data_modifier = data.modifier.lock().unwrap();
let mut data_modifier = self.modifier.lock().unwrap();
if let Some(data_modifier) = *data_modifier {
if params.version() >= 5 && modifier != data_modifier {
params.post_error(
@ -307,15 +295,15 @@ where
flags,
} => {
// create_dmabuf performs an implicit ensure_unused function call.
if let Some(dmabuf) = data.create_dmabuf(params, width, height, format, flags, None) {
if state.dmabuf_state().globals.contains_key(&data.id) {
if let Some(dmabuf) = self.create_dmabuf(params, width, height, format, flags, None) {
if state.dmabuf_state().globals.contains_key(&self.id) {
let notifier = ImportNotifier::new(
params.clone(),
dh.clone(),
dmabuf.clone(),
Import::Falliable,
);
state.dmabuf_imported(&DmabufGlobal { id: data.id }, dmabuf, notifier);
state.dmabuf_imported(&DmabufGlobal { id: self.id }, dmabuf, notifier);
} else {
// If the dmabuf global was destroyed, we cannot import any buffers.
params.failed();
@ -332,8 +320,8 @@ where
} => {
// Client is killed if the if statement is not taken.
// create_dmabuf performs an implicit ensure_unused function call.
if let Some(dmabuf) = data.create_dmabuf(params, width, height, format, flags, None) {
if state.dmabuf_state().globals.contains_key(&data.id) {
if let Some(dmabuf) = self.create_dmabuf(params, width, height, format, flags, None) {
if state.dmabuf_state().globals.contains_key(&self.id) {
// The buffer isn't technically valid during data_init, but the client is not allowed to use the buffer until ready.
let buffer = data_init.init(buffer_id, dmabuf.clone());
let notifier = ImportNotifier::new(
@ -342,7 +330,7 @@ where
dmabuf.clone(),
Import::Infallible(buffer),
);
state.dmabuf_imported(&DmabufGlobal { id: data.id }, dmabuf, notifier);
state.dmabuf_imported(&DmabufGlobal { id: self.id }, dmabuf, notifier);
} else {
// Buffer import failed. The protocol documentation heavily implies killing the
// client is the right thing to do here.

View file

@ -17,7 +17,6 @@
//!
//! ```no_run
//! use smithay::{
//! delegate_dmabuf,
//! backend::allocator::dmabuf::{Dmabuf},
//! reexports::{
//! wayland_server::protocol::{
@ -73,8 +72,7 @@
//! }
//! }
//!
//! // Delegate dmabuf handling for State to DmabufState.
//! delegate_dmabuf!(State);
//! smithay::delegate_dispatch2!(State);
//!
//! # let mut display = wayland_server::Display::<State>::new().unwrap();
//! # let display_handle = display.handle();
@ -140,7 +138,6 @@
//! ```no_run
//! # extern crate wayland_server;
//! # use smithay::{
//! # delegate_dmabuf,
//! # backend::allocator::dmabuf::Dmabuf,
//! # reexports::{wayland_server::protocol::wl_buffer::WlBuffer},
//! # wayland::{
@ -161,7 +158,6 @@
//! # }
//! # fn dmabuf_imported(&mut self, global: &DmabufGlobal, dmabuf: Dmabuf, notifier: ImportNotifier) {}
//! # }
//! # delegate_dmabuf!(State);
//! # let mut display = wayland_server::Display::<State>::new().unwrap();
//! # let display_handle = display.handle();
//! # let mut dmabuf_state = DmabufState::new();
@ -182,6 +178,8 @@
//! dmabuf_global,
//! };
//!
//! smithay::delegate_dispatch2!(State);
//!
//! // Rest of the compositor goes here...
//! ```
@ -1004,55 +1002,6 @@ pub fn get_dmabuf(buffer: &wl_buffer::WlBuffer) -> Result<&Dmabuf, UnmanagedReso
buffer.data::<Dmabuf>().ok_or(UnmanagedResource)
}
/// Macro to delegate implementation of the linux dmabuf to [`DmabufState`].
///
/// You must also implement [`DmabufHandler`] to use this.
#[macro_export]
macro_rules! delegate_dmabuf {
($(@<$( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+>)? $ty: ty) => {
const _: () = {
use $crate::{
backend::allocator::dmabuf::Dmabuf,
reexports::{
wayland_protocols::wp::linux_dmabuf::zv1::server::{
zwp_linux_buffer_params_v1::ZwpLinuxBufferParamsV1,
zwp_linux_dmabuf_feedback_v1::ZwpLinuxDmabufFeedbackV1,
zwp_linux_dmabuf_v1::ZwpLinuxDmabufV1,
},
wayland_server::{
delegate_dispatch, delegate_global_dispatch, protocol::wl_buffer::WlBuffer,
},
},
wayland::dmabuf::{
DmabufData, DmabufFeedbackData, DmabufGlobalData, DmabufParamsData, DmabufState,
},
};
delegate_global_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [ZwpLinuxDmabufV1: DmabufGlobalData] => DmabufState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [ZwpLinuxDmabufV1: DmabufData] => DmabufState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [ZwpLinuxBufferParamsV1: DmabufParamsData] => DmabufState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [WlBuffer: Dmabuf] => DmabufState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [ZwpLinuxDmabufFeedbackV1: DmabufFeedbackData] => DmabufState
);
};
};
}
impl DmabufParamsData {
/// Emits a protocol error if the params have already been used to create a dmabuf.
///

View file

@ -18,7 +18,6 @@
//! allows you to add additional needed DRM resources to the lease and accept or decline the request.
//!
//! ```no_run
//! # use smithay::delegate_drm_lease;
//! # use smithay::wayland::drm_lease::*;
//! # use smithay::backend::drm::{DrmDevice, DrmNode};
//!
@ -50,7 +49,7 @@
//! fn lease_destroyed(&mut self, node: DrmNode, lease_id: u32) { self.active_leases.retain(|l| l.id() != lease_id); }
//! }
//!
//! delegate_drm_lease!(State);
//! smithay::delegate_dispatch2!(State);
//!
//! # let mut display = wayland_server::Display::<State>::new().unwrap();
//! # let display_handle = display.handle();
@ -92,7 +91,10 @@ use wayland_protocols::wp::drm_lease::v1::server::*;
use wayland_server::backend::GlobalId;
use wayland_server::{Client, DataInit, Dispatch, DisplayHandle, GlobalDispatch, New, Resource};
use crate::backend::drm::{DrmDevice, DrmDeviceFd, DrmNode, NodeType, PlaneClaim};
use crate::{
backend::drm::{DrmDevice, DrmDeviceFd, DrmNode, NodeType, PlaneClaim},
wayland::{Dispatch2, GlobalDispatch2},
};
/// Delegate type for a drm_lease global
#[derive(Debug)]
@ -300,14 +302,7 @@ impl LeaseRejected {
}
/// Handler trait for drm leasing from the compositor.
pub trait DrmLeaseHandler:
GlobalDispatch<wp_drm_lease_device_v1::WpDrmLeaseDeviceV1, DrmLeaseDeviceGlobalData>
+ Dispatch<wp_drm_lease_connector_v1::WpDrmLeaseConnectorV1, DrmNode, Self>
+ Dispatch<wp_drm_lease_device_v1::WpDrmLeaseDeviceV1, DrmNode, Self>
+ Dispatch<wp_drm_lease_request_v1::WpDrmLeaseRequestV1, DrmLeaseRequestData, Self>
+ Dispatch<wp_drm_lease_v1::WpDrmLeaseV1, DrmLeaseData, Self>
+ 'static
{
pub trait DrmLeaseHandler {
/// Returns a mutable reference to the [`DrmLeaseState`] delegate type
fn drm_lease_state(&mut self, node: DrmNode) -> &mut DrmLeaseState;
/// A client has issued a new request.
@ -390,10 +385,6 @@ impl DrmLeaseState {
where
D: DrmLeaseHandler
+ GlobalDispatch<wp_drm_lease_device_v1::WpDrmLeaseDeviceV1, DrmLeaseDeviceGlobalData>
+ Dispatch<wp_drm_lease_connector_v1::WpDrmLeaseConnectorV1, DrmNode, D>
+ Dispatch<wp_drm_lease_device_v1::WpDrmLeaseDeviceV1, DrmNode, D>
+ Dispatch<wp_drm_lease_request_v1::WpDrmLeaseRequestV1, DrmLeaseRequestData, D>
+ Dispatch<wp_drm_lease_v1::WpDrmLeaseV1, DrmLeaseData, D>
+ 'static,
{
Self::new_with_filter::<D, _>(display, drm_node, |_| true)
@ -410,10 +401,6 @@ impl DrmLeaseState {
where
D: DrmLeaseHandler
+ GlobalDispatch<wp_drm_lease_device_v1::WpDrmLeaseDeviceV1, DrmLeaseDeviceGlobalData>
+ Dispatch<wp_drm_lease_connector_v1::WpDrmLeaseConnectorV1, DrmNode, D>
+ Dispatch<wp_drm_lease_device_v1::WpDrmLeaseDeviceV1, DrmNode, D>
+ Dispatch<wp_drm_lease_request_v1::WpDrmLeaseRequestV1, DrmLeaseRequestData, D>
+ Dispatch<wp_drm_lease_v1::WpDrmLeaseV1, DrmLeaseData, D>
+ 'static,
F: for<'c> Fn(&'c Client) -> bool + Send + Sync + 'static,
{
@ -446,11 +433,7 @@ impl DrmLeaseState {
pub fn add_connector<D>(&mut self, connector: connector::Handle, name: String, description: String)
where
D: DrmLeaseHandler
+ GlobalDispatch<wp_drm_lease_device_v1::WpDrmLeaseDeviceV1, DrmLeaseDeviceGlobalData>
+ Dispatch<wp_drm_lease_connector_v1::WpDrmLeaseConnectorV1, DrmNode, D>
+ Dispatch<wp_drm_lease_device_v1::WpDrmLeaseDeviceV1, DrmNode, D>
+ Dispatch<wp_drm_lease_request_v1::WpDrmLeaseRequestV1, DrmLeaseRequestData, D>
+ Dispatch<wp_drm_lease_v1::WpDrmLeaseV1, DrmLeaseData, D>
+ Dispatch<wp_drm_lease_connector_v1::WpDrmLeaseConnectorV1, DrmLeaseConnectorData>
+ 'static,
{
if self.connectors.iter().any(|conn| conn.handle == connector) {
@ -462,7 +445,9 @@ impl DrmLeaseState {
if let Ok(client) = self.dh.get_client(instance.id()) {
if let Ok(lease_connector) = client
.create_resource::<wp_drm_lease_connector_v1::WpDrmLeaseConnectorV1, _, D>(
&self.dh, 1, self.node,
&self.dh,
1,
DrmLeaseConnectorData { node: self.node },
)
{
instance.connector(&lease_connector);
@ -546,11 +531,7 @@ impl DrmLeaseState {
pub fn resume<D>(&mut self)
where
D: DrmLeaseHandler
+ GlobalDispatch<wp_drm_lease_device_v1::WpDrmLeaseDeviceV1, DrmLeaseDeviceGlobalData>
+ Dispatch<wp_drm_lease_connector_v1::WpDrmLeaseConnectorV1, DrmNode, D>
+ Dispatch<wp_drm_lease_device_v1::WpDrmLeaseDeviceV1, DrmNode, D>
+ Dispatch<wp_drm_lease_request_v1::WpDrmLeaseRequestV1, DrmLeaseRequestData, D>
+ Dispatch<wp_drm_lease_v1::WpDrmLeaseV1, DrmLeaseData, D>
+ Dispatch<wp_drm_lease_connector_v1::WpDrmLeaseConnectorV1, DrmLeaseConnectorData>
+ 'static,
{
self.resume_internal::<D>(None);
@ -559,11 +540,7 @@ impl DrmLeaseState {
fn resume_internal<D>(&mut self, connectors: Option<&HashSet<connector::Handle>>)
where
D: DrmLeaseHandler
+ GlobalDispatch<wp_drm_lease_device_v1::WpDrmLeaseDeviceV1, DrmLeaseDeviceGlobalData>
+ Dispatch<wp_drm_lease_connector_v1::WpDrmLeaseConnectorV1, DrmNode, D>
+ Dispatch<wp_drm_lease_device_v1::WpDrmLeaseDeviceV1, DrmNode, D>
+ Dispatch<wp_drm_lease_request_v1::WpDrmLeaseRequestV1, DrmLeaseRequestData, D>
+ Dispatch<wp_drm_lease_v1::WpDrmLeaseV1, DrmLeaseData, D>
+ Dispatch<wp_drm_lease_connector_v1::WpDrmLeaseConnectorV1, DrmLeaseConnectorData>
+ 'static,
{
for (instance, client) in self
@ -599,11 +576,7 @@ impl DrmLeaseState {
fn remove_lease<D>(&mut self, id: u32) -> Option<DrmLeaseRef>
where
D: DrmLeaseHandler
+ GlobalDispatch<wp_drm_lease_device_v1::WpDrmLeaseDeviceV1, DrmLeaseDeviceGlobalData>
+ Dispatch<wp_drm_lease_connector_v1::WpDrmLeaseConnectorV1, DrmNode, D>
+ Dispatch<wp_drm_lease_device_v1::WpDrmLeaseDeviceV1, DrmNode, D>
+ Dispatch<wp_drm_lease_request_v1::WpDrmLeaseRequestV1, DrmLeaseRequestData, D>
+ Dispatch<wp_drm_lease_v1::WpDrmLeaseV1, DrmLeaseData, D>
+ Dispatch<wp_drm_lease_connector_v1::WpDrmLeaseConnectorV1, DrmLeaseConnectorData>
+ 'static,
{
let lease_ref = {
@ -631,13 +604,7 @@ impl DrmLeaseState {
/// Disable the global, it will no longer be advertised to new clients
pub fn disable_global<D>(&mut self)
where
D: DrmLeaseHandler
+ GlobalDispatch<wp_drm_lease_device_v1::WpDrmLeaseDeviceV1, DrmLeaseDeviceGlobalData>
+ Dispatch<wp_drm_lease_connector_v1::WpDrmLeaseConnectorV1, DrmNode, D>
+ Dispatch<wp_drm_lease_device_v1::WpDrmLeaseDeviceV1, DrmNode, D>
+ Dispatch<wp_drm_lease_request_v1::WpDrmLeaseRequestV1, DrmLeaseRequestData, D>
+ Dispatch<wp_drm_lease_v1::WpDrmLeaseV1, DrmLeaseData, D>
+ 'static,
D: DrmLeaseHandler + 'static,
{
if let Some(global) = self.global.take() {
self.dh.disable_global::<D>(global);
@ -672,15 +639,15 @@ impl DrmLeaseConnector {
) -> Option<wp_drm_lease_connector_v1::WpDrmLeaseConnectorV1>
where
D: DrmLeaseHandler
+ GlobalDispatch<wp_drm_lease_device_v1::WpDrmLeaseDeviceV1, DrmLeaseDeviceGlobalData>
+ Dispatch<wp_drm_lease_connector_v1::WpDrmLeaseConnectorV1, DrmNode, D>
+ Dispatch<wp_drm_lease_device_v1::WpDrmLeaseDeviceV1, DrmNode, D>
+ Dispatch<wp_drm_lease_request_v1::WpDrmLeaseRequestV1, DrmLeaseRequestData, D>
+ Dispatch<wp_drm_lease_v1::WpDrmLeaseV1, DrmLeaseData, D>
+ Dispatch<wp_drm_lease_connector_v1::WpDrmLeaseConnectorV1, DrmLeaseConnectorData>
+ 'static,
{
if let Ok(lease_connector) =
client.create_resource::<wp_drm_lease_connector_v1::WpDrmLeaseConnectorV1, _, D>(dh, 1, self.node)
if let Ok(lease_connector) = client
.create_resource::<wp_drm_lease_connector_v1::WpDrmLeaseConnectorV1, _, D>(
dh,
1,
DrmLeaseConnectorData { node: self.node },
)
{
self.known_instances.push(lease_connector.clone());
@ -698,29 +665,25 @@ impl DrmLeaseConnector {
}
}
impl<D> GlobalDispatch<wp_drm_lease_device_v1::WpDrmLeaseDeviceV1, DrmLeaseDeviceGlobalData, D>
for DrmLeaseState
impl<D> GlobalDispatch2<wp_drm_lease_device_v1::WpDrmLeaseDeviceV1, D> for DrmLeaseDeviceGlobalData
where
D: DrmLeaseHandler
+ GlobalDispatch<wp_drm_lease_device_v1::WpDrmLeaseDeviceV1, DrmLeaseDeviceGlobalData>
+ Dispatch<wp_drm_lease_connector_v1::WpDrmLeaseConnectorV1, DrmNode, D>
+ Dispatch<wp_drm_lease_device_v1::WpDrmLeaseDeviceV1, DrmNode, D>
+ Dispatch<wp_drm_lease_request_v1::WpDrmLeaseRequestV1, DrmLeaseRequestData, D>
+ Dispatch<wp_drm_lease_v1::WpDrmLeaseV1, DrmLeaseData, D>
+ Dispatch<wp_drm_lease_connector_v1::WpDrmLeaseConnectorV1, DrmLeaseConnectorData>
+ Dispatch<wp_drm_lease_device_v1::WpDrmLeaseDeviceV1, DrmLeaseDeviceData>
+ 'static,
{
fn bind(
&self,
state: &mut D,
dh: &DisplayHandle,
client: &Client,
resource: New<wp_drm_lease_device_v1::WpDrmLeaseDeviceV1>,
global_data: &DrmLeaseDeviceGlobalData,
data_init: &mut DataInit<'_, D>,
) {
let drm_lease_state = state.drm_lease_state(global_data.node);
let wp_drm_lease_device = data_init.init(resource, global_data.node);
let drm_lease_state = state.drm_lease_state(self.node);
let wp_drm_lease_device = data_init.init(resource, DrmLeaseDeviceData { node: self.node });
let Ok(fd) = get_non_master_fd(&global_data.path) else {
let Ok(fd) = get_non_master_fd(&self.path) else {
// nothing we can do
wp_drm_lease_device.released();
return;
@ -738,27 +701,29 @@ where
drm_lease_state.known_lease_devices.push(wp_drm_lease_device);
}
fn can_view(client: Client, global_data: &DrmLeaseDeviceGlobalData) -> bool {
(global_data.filter)(&client)
fn can_view(&self, client: &Client) -> bool {
(self.filter)(client)
}
}
impl<D> Dispatch<wp_drm_lease_device_v1::WpDrmLeaseDeviceV1, DrmNode, D> for DrmLeaseState
#[doc(hidden)]
#[derive(Debug)]
pub struct DrmLeaseDeviceData {
node: DrmNode,
}
impl<D> Dispatch2<wp_drm_lease_device_v1::WpDrmLeaseDeviceV1, D> for DrmLeaseDeviceData
where
D: DrmLeaseHandler
+ GlobalDispatch<wp_drm_lease_device_v1::WpDrmLeaseDeviceV1, DrmLeaseDeviceGlobalData>
+ Dispatch<wp_drm_lease_connector_v1::WpDrmLeaseConnectorV1, DrmNode, D>
+ Dispatch<wp_drm_lease_device_v1::WpDrmLeaseDeviceV1, DrmNode, D>
+ Dispatch<wp_drm_lease_request_v1::WpDrmLeaseRequestV1, DrmLeaseRequestData, D>
+ Dispatch<wp_drm_lease_v1::WpDrmLeaseV1, DrmLeaseData, D>
+ 'static,
{
fn request(
&self,
state: &mut D,
_client: &Client,
resource: &wp_drm_lease_device_v1::WpDrmLeaseDeviceV1,
request: <wp_drm_lease_device_v1::WpDrmLeaseDeviceV1 as Resource>::Request,
data: &DrmNode,
_dhandle: &DisplayHandle,
data_init: &mut DataInit<'_, D>,
) {
@ -767,13 +732,13 @@ where
data_init.init(
id,
DrmLeaseRequestData {
node: *data,
node: self.node,
connectors: Mutex::new(Vec::new()),
},
);
}
wp_drm_lease_device_v1::Request::Release => {
let drm_lease_state = state.drm_lease_state(*data);
let drm_lease_state = state.drm_lease_state(self.node);
drm_lease_state
.known_lease_devices
.retain(|device| device != resource);
@ -784,68 +749,62 @@ where
}
}
impl<D> Dispatch<wp_drm_lease_connector_v1::WpDrmLeaseConnectorV1, DrmNode, D> for DrmLeaseState
#[doc(hidden)]
#[derive(Debug)]
pub struct DrmLeaseConnectorData {
node: DrmNode,
}
impl<D> Dispatch2<wp_drm_lease_connector_v1::WpDrmLeaseConnectorV1, D> for DrmLeaseConnectorData
where
D: DrmLeaseHandler
+ GlobalDispatch<wp_drm_lease_device_v1::WpDrmLeaseDeviceV1, DrmLeaseDeviceGlobalData>
+ Dispatch<wp_drm_lease_connector_v1::WpDrmLeaseConnectorV1, DrmNode, D>
+ Dispatch<wp_drm_lease_device_v1::WpDrmLeaseDeviceV1, DrmNode, D>
+ Dispatch<wp_drm_lease_request_v1::WpDrmLeaseRequestV1, DrmLeaseRequestData, D>
+ Dispatch<wp_drm_lease_v1::WpDrmLeaseV1, DrmLeaseData, D>
+ 'static,
D: DrmLeaseHandler + 'static,
{
fn request(
&self,
_state: &mut D,
_client: &Client,
_resource: &wp_drm_lease_connector_v1::WpDrmLeaseConnectorV1,
_request: <wp_drm_lease_connector_v1::WpDrmLeaseConnectorV1 as Resource>::Request,
_data: &DrmNode,
_dhandle: &DisplayHandle,
_data_init: &mut DataInit<'_, D>,
) {
}
fn destroyed(
&self,
state: &mut D,
_client: wayland_server::backend::ClientId,
resource: &wp_drm_lease_connector_v1::WpDrmLeaseConnectorV1,
data: &DrmNode,
) {
let drm_lease_state = state.drm_lease_state(*data);
let drm_lease_state = state.drm_lease_state(self.node);
drm_lease_state.connectors.iter_mut().for_each(|connector| {
connector.known_instances.retain(|obj| obj != resource);
});
}
}
impl<D> Dispatch<wp_drm_lease_request_v1::WpDrmLeaseRequestV1, DrmLeaseRequestData, D> for DrmLeaseState
impl<D> Dispatch2<wp_drm_lease_request_v1::WpDrmLeaseRequestV1, D> for DrmLeaseRequestData
where
D: DrmLeaseHandler
+ GlobalDispatch<wp_drm_lease_device_v1::WpDrmLeaseDeviceV1, DrmLeaseDeviceGlobalData>
+ Dispatch<wp_drm_lease_connector_v1::WpDrmLeaseConnectorV1, DrmNode, D>
+ Dispatch<wp_drm_lease_device_v1::WpDrmLeaseDeviceV1, DrmNode, D>
+ Dispatch<wp_drm_lease_request_v1::WpDrmLeaseRequestV1, DrmLeaseRequestData, D>
+ Dispatch<wp_drm_lease_v1::WpDrmLeaseV1, DrmLeaseData, D>
+ 'static,
D: DrmLeaseHandler + Dispatch<wp_drm_lease_v1::WpDrmLeaseV1, DrmLeaseData> + 'static,
{
fn request(
&self,
state: &mut D,
_client: &Client,
resource: &wp_drm_lease_request_v1::WpDrmLeaseRequestV1,
request: <wp_drm_lease_request_v1::WpDrmLeaseRequestV1 as Resource>::Request,
data: &DrmLeaseRequestData,
_dhandle: &DisplayHandle,
data_init: &mut DataInit<'_, D>,
) {
match request {
wp_drm_lease_request_v1::Request::RequestConnector { connector } => {
data.connectors.lock().unwrap().push(connector);
self.connectors.lock().unwrap().push(connector);
}
wp_drm_lease_request_v1::Request::Submit { id } => {
let drm_lease_state = state.drm_lease_state(data.node);
let drm_lease_state = state.drm_lease_state(self.node);
let mut connector_handles = Vec::new();
for connector in &*data.connectors.lock().unwrap() {
for connector in &*self.connectors.lock().unwrap() {
if let Some(conn) = drm_lease_state
.connectors
.iter()
@ -877,7 +836,7 @@ where
}
match state.lease_request(
data.node,
self.node,
DrmLeaseRequest {
connectors: connector_handles,
},
@ -888,7 +847,7 @@ where
id,
DrmLeaseData {
id: lease.lease_id.get(),
node: data.node,
node: self.node,
},
);
lease.set_obj(lease_obj.clone());
@ -903,11 +862,11 @@ where
revoked: lease.revoked.clone(),
};
let drm_lease_state = state.drm_lease_state(data.node);
let drm_lease_state = state.drm_lease_state(self.node);
drm_lease_state.suspend_internal(Some(&lease.connectors));
drm_lease_state.active_leases.push(lease_ref);
state.new_active_lease(data.node, lease);
state.new_active_lease(self.node, lease);
}
Err(err) => {
tracing::error!(?err, "Failed to create lease");
@ -915,7 +874,7 @@ where
id,
DrmLeaseData {
id: 0,
node: data.node,
node: self.node,
},
);
lease_obj.finished();
@ -927,7 +886,7 @@ where
id,
DrmLeaseData {
id: 0,
node: data.node,
node: self.node,
},
);
lease_obj.finished();
@ -939,85 +898,32 @@ where
}
}
impl<D> Dispatch<wp_drm_lease_v1::WpDrmLeaseV1, DrmLeaseData, D> for DrmLeaseState
impl<D> Dispatch2<wp_drm_lease_v1::WpDrmLeaseV1, D> for DrmLeaseData
where
D: DrmLeaseHandler
+ GlobalDispatch<wp_drm_lease_device_v1::WpDrmLeaseDeviceV1, DrmLeaseDeviceGlobalData>
+ Dispatch<wp_drm_lease_connector_v1::WpDrmLeaseConnectorV1, DrmNode, D>
+ Dispatch<wp_drm_lease_device_v1::WpDrmLeaseDeviceV1, DrmNode, D>
+ Dispatch<wp_drm_lease_request_v1::WpDrmLeaseRequestV1, DrmLeaseRequestData, D>
+ Dispatch<wp_drm_lease_v1::WpDrmLeaseV1, DrmLeaseData, D>
+ Dispatch<wp_drm_lease_connector_v1::WpDrmLeaseConnectorV1, DrmLeaseConnectorData>
+ 'static,
{
fn request(
&self,
_state: &mut D,
_client: &Client,
_resource: &wp_drm_lease_v1::WpDrmLeaseV1,
_request: <wp_drm_lease_v1::WpDrmLeaseV1 as Resource>::Request,
_data: &DrmLeaseData,
_dhandle: &DisplayHandle,
_data_init: &mut DataInit<'_, D>,
) {
}
fn destroyed(
&self,
state: &mut D,
_client: wayland_server::backend::ClientId,
_resource: &wp_drm_lease_v1::WpDrmLeaseV1,
data: &DrmLeaseData,
) {
let drm_lease_state = state.drm_lease_state(data.node);
if let Some(lease_ref) = drm_lease_state.remove_lease::<D>(data.id) {
state.lease_destroyed(data.node, lease_ref.lease_id.get());
let drm_lease_state = state.drm_lease_state(self.node);
if let Some(lease_ref) = drm_lease_state.remove_lease::<D>(self.id) {
state.lease_destroyed(self.node, lease_ref.lease_id.get());
}
}
}
/// Macro to delegate implementation of the drm-lease protocol to [`DrmLeaseState`].
///
/// You must also implement [`DrmLeaseHandler`] to use this.
#[macro_export]
macro_rules! delegate_drm_lease {
($(@<$( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+>)? $ty: ty) => {
const _: () = {
use $crate::{
backend::drm::DrmNode,
reexports::{
wayland_protocols::wp::drm_lease::v1::server::{
wp_drm_lease_connector_v1::WpDrmLeaseConnectorV1,
wp_drm_lease_device_v1::WpDrmLeaseDeviceV1,
wp_drm_lease_request_v1::WpDrmLeaseRequestV1, wp_drm_lease_v1::WpDrmLeaseV1,
},
wayland_server::{
delegate_dispatch, delegate_global_dispatch, protocol::wl_buffer::WlBuffer,
},
},
wayland::drm_lease::{
DrmLeaseData, DrmLeaseDeviceGlobalData, DrmLeaseRequestData, DrmLeaseState,
},
};
delegate_global_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [WpDrmLeaseDeviceV1: DrmLeaseDeviceGlobalData] => DrmLeaseState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [WpDrmLeaseConnectorV1: DrmNode] => DrmLeaseState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [WpDrmLeaseDeviceV1: DrmNode] => DrmLeaseState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [WpDrmLeaseRequestV1: DrmLeaseRequestData] => DrmLeaseState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [WpDrmLeaseV1: DrmLeaseData] => DrmLeaseState
);
};
};
}

View file

@ -14,7 +14,6 @@
//! [`Buffer`][crate::backend::renderer::utils::Buffer] are dropped.
//!
//! ```no_run
//! # use smithay::delegate_drm_syncobj;
//! # use smithay::wayland::drm_syncobj::*;
//!
//! pub struct State {
@ -36,7 +35,7 @@
//! None
//! };
//!
//! delegate_drm_syncobj!(State);
//! smithay::delegate_dispatch2!(State);
//! ```
use std::{
@ -59,7 +58,10 @@ use super::{
compositor::{self, BufferAssignment, Cacheable, HookId, SurfaceAttributes, with_states},
dmabuf::get_dmabuf,
};
use crate::backend::drm::DrmDeviceFd;
use crate::{
backend::drm::DrmDeviceFd,
wayland::{Dispatch2, GlobalData, GlobalDispatch2},
};
mod sync_point;
pub use sync_point::*;
@ -185,23 +187,23 @@ impl DrmSyncobjState {
}
}
impl<D> GlobalDispatch<WpLinuxDrmSyncobjManagerV1, DrmSyncobjGlobalData, D> for DrmSyncobjState
impl<D> GlobalDispatch2<WpLinuxDrmSyncobjManagerV1, D> for DrmSyncobjGlobalData
where
D: Dispatch<WpLinuxDrmSyncobjManagerV1, ()>,
D: Dispatch<WpLinuxDrmSyncobjManagerV1, GlobalData>,
{
fn bind(
&self,
_state: &mut D,
_dh: &DisplayHandle,
_client: &Client,
resource: New<WpLinuxDrmSyncobjManagerV1>,
_global_data: &DrmSyncobjGlobalData,
data_init: &mut DataInit<'_, D>,
) {
data_init.init::<_, _>(resource, ());
data_init.init::<_, _>(resource, GlobalData);
}
fn can_view(client: Client, global_data: &DrmSyncobjGlobalData) -> bool {
(global_data.filter)(&client)
fn can_view(&self, client: &Client) -> bool {
(self.filter)(client)
}
}
@ -277,18 +279,18 @@ fn destruction_hook<D: DrmSyncobjHandler>(_data: &mut D, surface: &WlSurface) {
});
}
impl<D> Dispatch<WpLinuxDrmSyncobjManagerV1, (), D> for DrmSyncobjState
impl<D> Dispatch2<WpLinuxDrmSyncobjManagerV1, D> for GlobalData
where
D: Dispatch<WpLinuxDrmSyncobjSurfaceV1, DrmSyncobjSurfaceData>,
D: Dispatch<WpLinuxDrmSyncobjTimelineV1, DrmSyncobjTimelineData>,
D: DrmSyncobjHandler,
{
fn request(
&self,
state: &mut D,
_client: &Client,
resource: &WpLinuxDrmSyncobjManagerV1,
request: wp_linux_drm_syncobj_manager_v1::Request,
_data: &(),
_dh: &DisplayHandle,
data_init: &mut DataInit<'_, D>,
) {
@ -360,24 +362,24 @@ pub struct DrmSyncobjSurfaceData {
destruction_hook_id: HookId,
}
impl<D> Dispatch<WpLinuxDrmSyncobjSurfaceV1, DrmSyncobjSurfaceData, D> for DrmSyncobjState
impl<D> Dispatch2<WpLinuxDrmSyncobjSurfaceV1, D> for DrmSyncobjSurfaceData
where
D: DrmSyncobjHandler,
{
fn request(
&self,
_state: &mut D,
_client: &Client,
resource: &WpLinuxDrmSyncobjSurfaceV1,
request: wp_linux_drm_syncobj_surface_v1::Request,
data: &DrmSyncobjSurfaceData,
_dh: &DisplayHandle,
_data_init: &mut DataInit<'_, D>,
) {
match request {
wp_linux_drm_syncobj_surface_v1::Request::Destroy => {
if let Ok(surface) = data.surface.upgrade() {
compositor::remove_pre_commit_hook(&surface, &data.commit_hook_id);
compositor::remove_destruction_hook(&surface, &data.destruction_hook_id);
if let Ok(surface) = self.surface.upgrade() {
compositor::remove_pre_commit_hook(&surface, &self.commit_hook_id);
compositor::remove_destruction_hook(&surface, &self.destruction_hook_id);
with_states(&surface, |states| {
*states
.data_map
@ -401,7 +403,7 @@ where
point_hi,
point_lo,
} => {
let Ok(surface) = data.surface.upgrade() else {
let Ok(surface) = self.surface.upgrade() else {
resource.post_error(
wp_linux_drm_syncobj_surface_v1::Error::NoSurface,
"Set acquire point for destroyed surface.",
@ -428,7 +430,7 @@ where
point_hi,
point_lo,
} => {
let Ok(surface) = data.surface.upgrade() else {
let Ok(surface) = self.surface.upgrade() else {
resource.post_error(
wp_linux_drm_syncobj_surface_v1::Error::NoSurface,
"Set release point for destroyed surface.",
@ -461,15 +463,13 @@ pub struct DrmSyncobjTimelineData {
timeline: DrmTimeline,
}
impl<D: DrmSyncobjHandler> Dispatch<WpLinuxDrmSyncobjTimelineV1, DrmSyncobjTimelineData, D>
for DrmSyncobjState
{
impl<D: DrmSyncobjHandler> Dispatch2<WpLinuxDrmSyncobjTimelineV1, D> for DrmSyncobjTimelineData {
fn request(
&self,
_state: &mut D,
_client: &Client,
_resource: &WpLinuxDrmSyncobjTimelineV1,
request: wp_linux_drm_syncobj_timeline_v1::Request,
_data: &DrmSyncobjTimelineData,
_dh: &DisplayHandle,
_data_init: &mut DataInit<'_, D>,
) {
@ -480,60 +480,15 @@ impl<D: DrmSyncobjHandler> Dispatch<WpLinuxDrmSyncobjTimelineV1, DrmSyncobjTimel
}
fn destroyed(
&self,
state: &mut D,
_client: wayland_server::backend::ClientId,
_resource: &WpLinuxDrmSyncobjTimelineV1,
data: &DrmSyncobjTimelineData,
) {
if let Some(state) = state.drm_syncobj_state() {
state
.known_timelines
.retain(|t| t.upgrade().is_some_and(|t| !Arc::ptr_eq(&t, &data.timeline.0)))
.retain(|t| t.upgrade().is_some_and(|t| !Arc::ptr_eq(&t, &self.timeline.0)))
}
}
}
/// Macro to delegate implementation of the drm syncobj protocol to [`DrmSyncobjState`].
///
/// You must also implement [`DrmSyncobjHandler`] to use this.
#[macro_export]
macro_rules! delegate_drm_syncobj {
($(@<$( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+>)? $ty: ty) => {
const _: () = {
use $crate::{
backend::drm::DrmNode,
reexports::{
wayland_protocols::wp::linux_drm_syncobj::v1::server::{
wp_linux_drm_syncobj_manager_v1::WpLinuxDrmSyncobjManagerV1,
wp_linux_drm_syncobj_surface_v1::WpLinuxDrmSyncobjSurfaceV1,
wp_linux_drm_syncobj_timeline_v1::WpLinuxDrmSyncobjTimelineV1,
},
wayland_server::{
delegate_dispatch, delegate_global_dispatch, protocol::wl_buffer::WlBuffer,
},
},
wayland::drm_syncobj::{
DrmSyncobjGlobalData, DrmSyncobjState, DrmSyncobjSurfaceData, DrmSyncobjTimelineData,
},
};
delegate_global_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [WpLinuxDrmSyncobjManagerV1: DrmSyncobjGlobalData] => DrmSyncobjState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [WpLinuxDrmSyncobjManagerV1: ()] => DrmSyncobjState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [WpLinuxDrmSyncobjSurfaceV1: DrmSyncobjSurfaceData] => DrmSyncobjState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [WpLinuxDrmSyncobjTimelineV1: DrmSyncobjTimelineData] => DrmSyncobjState
);
};
};
}

View file

@ -7,7 +7,6 @@
//! To initialize this implementation create the [`FifoManagerState`] and store it inside your `State` struct.
//!
//! ```
//! use smithay::delegate_fifo;
//! use smithay::wayland::compositor;
//! use smithay::wayland::fifo::FifoManagerState;
//!
@ -21,7 +20,7 @@
//! // insert the FifoManagerState into your state
//! // ..
//!
//! delegate_fifo!(State);
//! smithay::delegate_dispatch2!(State);
//!
//! // You're now ready to go!
//! ```
@ -90,7 +89,10 @@ use wayland_server::{
protocol::wl_surface::WlSurface,
};
use crate::wayland::compositor::{add_blocker, add_pre_commit_hook};
use crate::wayland::{
Dispatch2, GlobalDispatch2,
compositor::{add_blocker, add_pre_commit_hook},
};
use super::compositor::{Barrier, Cacheable, is_sync_subsurface, with_states};
@ -108,8 +110,8 @@ impl FifoManagerState {
/// remove or disable this global in the future.
pub fn new<D>(display: &DisplayHandle) -> Self
where
D: GlobalDispatch<WpFifoManagerV1, bool>,
D: Dispatch<WpFifoManagerV1, bool>,
D: GlobalDispatch<WpFifoManagerV1, FifoManagerData>,
D: Dispatch<WpFifoManagerV1, FifoManagerData>,
D: 'static,
{
Self::new_internal::<D>(display, true)
@ -121,8 +123,8 @@ impl FifoManagerState {
/// remove or disable this global in the future.
pub fn unmanaged<D>(display: &DisplayHandle) -> Self
where
D: GlobalDispatch<WpFifoManagerV1, bool>,
D: Dispatch<WpFifoManagerV1, bool>,
D: GlobalDispatch<WpFifoManagerV1, FifoManagerData>,
D: Dispatch<WpFifoManagerV1, FifoManagerData>,
D: 'static,
{
Self::new_internal::<D>(display, false)
@ -130,11 +132,10 @@ impl FifoManagerState {
fn new_internal<D>(display: &DisplayHandle, is_managed: bool) -> Self
where
D: GlobalDispatch<WpFifoManagerV1, bool>,
D: Dispatch<WpFifoManagerV1, bool>,
D: GlobalDispatch<WpFifoManagerV1, FifoManagerData>,
D: 'static,
{
let global = display.create_global::<D, WpFifoManagerV1, _>(1, is_managed);
let global = display.create_global::<D, WpFifoManagerV1, _>(1, FifoManagerData { is_managed });
Self { global, is_managed }
}
@ -150,41 +151,43 @@ impl FifoManagerState {
}
}
impl<D> GlobalDispatch<WpFifoManagerV1, bool, D> for FifoManagerState
#[doc(hidden)]
#[derive(Debug, Clone, Copy)]
pub struct FifoManagerData {
is_managed: bool,
}
impl<D> GlobalDispatch2<WpFifoManagerV1, D> for FifoManagerData
where
D: GlobalDispatch<WpFifoManagerV1, bool>,
D: Dispatch<WpFifoManagerV1, bool>,
D: Dispatch<WpFifoManagerV1, FifoManagerData>,
D: 'static,
{
fn bind(
&self,
_state: &mut D,
_dh: &DisplayHandle,
_client: &wayland_server::Client,
resource: New<WpFifoManagerV1>,
global_data: &bool,
data_init: &mut DataInit<'_, D>,
) {
data_init.init(resource, *global_data);
data_init.init(resource, *self);
}
}
impl<D> Dispatch<WpFifoManagerV1, bool, D> for FifoManagerState
impl<D> Dispatch2<WpFifoManagerV1, D> for FifoManagerData
where
D: Dispatch<WpFifoManagerV1, bool>,
D: Dispatch<WpFifoV1, Weak<WlSurface>>,
D: Dispatch<WpFifoV1, FifoData>,
D: 'static,
{
fn request(
&self,
_state: &mut D,
_client: &wayland_server::Client,
_resource: &WpFifoManagerV1,
request: wp_fifo_manager_v1::Request,
data: &bool,
_dhandle: &DisplayHandle,
data_init: &mut DataInit<'_, D>,
) {
let is_managed = *data;
match request {
wp_fifo_manager_v1::Request::GetFifo { id, surface } => {
let (is_initial, has_active_fifo) = with_states(&surface, |states| {
@ -205,7 +208,7 @@ where
}
// Make sure we do not install the hook more then once in case the surface is being reused
if is_managed && is_initial {
if self.is_managed && is_initial {
add_pre_commit_hook::<D, _>(&surface, |_, _, surface| {
let fifo_barrier = with_states(surface, |states| {
let fifo_state = *states.cached_state.get::<FifoCachedState>().pending();
@ -259,7 +262,7 @@ where
});
}
let fifo: WpFifoV1 = data_init.init(id, surface.downgrade());
let fifo: WpFifoV1 = data_init.init(id, FifoData(surface.downgrade()));
with_states(&surface, |states| {
states
@ -279,23 +282,26 @@ where
// Used to realize the `AlreadyExists` protocol check.
struct FifoMarker(Option<WpFifoV1>);
impl<D> Dispatch<WpFifoV1, Weak<WlSurface>, D> for FifoManagerState
#[doc(hidden)]
#[derive(Debug)]
pub struct FifoData(Weak<WlSurface>);
impl<D> Dispatch2<WpFifoV1, D> for FifoData
where
D: Dispatch<WpFifoV1, Weak<WlSurface>>,
D: 'static,
{
fn request(
&self,
_state: &mut D,
_client: &wayland_server::Client,
resource: &WpFifoV1,
request: wp_fifo_v1::Request,
data: &Weak<WlSurface>,
_dhandle: &DisplayHandle,
_data_init: &mut DataInit<'_, D>,
) {
match request {
wp_fifo_v1::Request::SetBarrier => {
let Ok(surface) = data.upgrade() else {
let Ok(surface) = self.0.upgrade() else {
resource.post_error(
wp_fifo_v1::Error::SurfaceDestroyed as u32,
"the surface associated with this fifo object has been destroyed".to_string(),
@ -307,7 +313,7 @@ where
});
}
wp_fifo_v1::Request::WaitBarrier => {
let Ok(surface) = data.upgrade() else {
let Ok(surface) = self.0.upgrade() else {
resource.post_error(
wp_fifo_v1::Error::SurfaceDestroyed as u32,
"the surface associated with this fifo object has been destroyed".to_string(),
@ -323,7 +329,7 @@ where
});
}
wp_fifo_v1::Request::Destroy => {
if let Ok(surface) = data.upgrade() {
if let Ok(surface) = self.0.upgrade() {
with_states(&surface, |states| {
states
.data_map
@ -388,38 +394,3 @@ impl Cacheable for FifoBarrierCachedState {
}
}
}
/// Macro used to delegate [`WpFifoManagerV1`] events
#[macro_export]
macro_rules! delegate_fifo {
($(@<$( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+>)? $ty: ty) => {
const _: () = {
use $crate::{
reexports::{
wayland_protocols::wp::fifo::v1::server::{
wp_fifo_manager_v1::WpFifoManagerV1, wp_fifo_v1::WpFifoV1,
},
wayland_server::{
delegate_dispatch, delegate_global_dispatch, protocol::wl_buffer::WlBuffer,
protocol::wl_surface::WlSurface, Weak,
},
},
wayland::fifo::FifoManagerState,
};
delegate_global_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [WpFifoManagerV1: bool] => FifoManagerState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [WpFifoManagerV1: bool] => FifoManagerState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [WpFifoV1: Weak<WlSurface>] => FifoManagerState
);
};
};
}

View file

@ -6,6 +6,8 @@ use wayland_server::{
protocol::wl_fixes,
};
use crate::wayland::{Dispatch2, GlobalData, GlobalDispatch2};
/// Delegate type for handling wl fixes requests.
#[derive(Debug, Clone)]
pub struct FixesState {
@ -16,11 +18,11 @@ impl FixesState {
/// Creates a new delegate type for handling [`wl_fixes::WlFixes`] events.
pub fn new<D>(display: &DisplayHandle) -> Self
where
D: GlobalDispatch<wl_fixes::WlFixes, ()>,
D: Dispatch<wl_fixes::WlFixes, ()>,
D: GlobalDispatch<wl_fixes::WlFixes, GlobalData>,
D: Dispatch<wl_fixes::WlFixes, GlobalData>,
D: 'static,
{
let global = display.create_global::<D, wl_fixes::WlFixes, _>(1, ());
let global = display.create_global::<D, wl_fixes::WlFixes, _>(1, GlobalData);
Self { global }
}
@ -30,35 +32,33 @@ impl FixesState {
}
}
impl<D> GlobalDispatch<wl_fixes::WlFixes, (), D> for FixesState
impl<D> GlobalDispatch2<wl_fixes::WlFixes, D> for GlobalData
where
D: GlobalDispatch<wl_fixes::WlFixes, ()>,
D: Dispatch<wl_fixes::WlFixes, ()>,
D: Dispatch<wl_fixes::WlFixes, GlobalData>,
D: 'static,
{
fn bind(
&self,
_state: &mut D,
_dh: &DisplayHandle,
_client: &Client,
resource: New<wl_fixes::WlFixes>,
_global_data: &(),
data_init: &mut DataInit<'_, D>,
) {
data_init.init(resource, ());
data_init.init(resource, GlobalData);
}
}
impl<D> Dispatch<wl_fixes::WlFixes, (), D> for FixesState
impl<D> Dispatch2<wl_fixes::WlFixes, D> for GlobalData
where
D: Dispatch<wl_fixes::WlFixes, ()>,
D: 'static,
{
fn request(
&self,
_state: &mut D,
_client: &Client,
_resource: &wl_fixes::WlFixes,
request: wl_fixes::Request,
_data: &(),
dh: &DisplayHandle,
_data_init: &mut DataInit<'_, D>,
) {
@ -73,16 +73,3 @@ where
}
}
}
/// Macro to delegate implementation of wl fixes protocol to [`FixesState`].
#[macro_export]
macro_rules! delegate_fixes {
($(@<$( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+>)? $ty: ty) => {
$crate::reexports::wayland_server::delegate_global_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [
$crate::reexports::wayland_server::protocol::wl_fixes::WlFixes: ()
] => $crate::wayland::fixes::FixesState);
$crate::reexports::wayland_server::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [
$crate::reexports::wayland_server::protocol::wl_fixes::WlFixes: ()
] => $crate::wayland::fixes::FixesState);
};
}

View file

@ -9,7 +9,7 @@
//! foreign_toplevel_list: ForeignToplevelListState,
//! }
//!
//! smithay::delegate_foreign_toplevel_list!(State);
//! smithay::delegate_dispatch2!(State);
//!
//! impl ForeignToplevelListHandler for State {
//! fn foreign_toplevel_list_state(&mut self) -> &mut ForeignToplevelListState {
@ -46,15 +46,13 @@ use wayland_server::{
backend::{ClientId, GlobalId},
};
use crate::utils::user_data::UserDataMap;
use crate::{
utils::user_data::UserDataMap,
wayland::{Dispatch2, GlobalData, GlobalDispatch2},
};
/// Handler for foreign toplevel list protocol
pub trait ForeignToplevelListHandler:
GlobalDispatch<ExtForeignToplevelListV1, ForeignToplevelListGlobalData>
+ Dispatch<ExtForeignToplevelListV1, ()>
+ Dispatch<ExtForeignToplevelHandleV1, ForeignToplevelHandle>
+ 'static
{
pub trait ForeignToplevelListHandler: 'static {
/// [ForeignToplevelListState] getter
fn foreign_toplevel_list_state(&mut self) -> &mut ForeignToplevelListState;
}
@ -292,15 +290,23 @@ pub struct ForeignToplevelListState {
impl ForeignToplevelListState {
/// Register new [ExtForeignToplevelListV1] global
pub fn new<D: ForeignToplevelListHandler>(dh: &DisplayHandle) -> Self {
pub fn new<D>(dh: &DisplayHandle) -> Self
where
D: ForeignToplevelListHandler
+ GlobalDispatch<ExtForeignToplevelListV1, ForeignToplevelListGlobalData>,
{
Self::new_with_filter::<D>(dh, |_| true)
}
/// Register new [ExtForeignToplevelListV1] global with filter
pub fn new_with_filter<D: ForeignToplevelListHandler>(
pub fn new_with_filter<D>(
dh: &DisplayHandle,
can_view: impl Fn(&Client) -> bool + Send + Sync + 'static,
) -> Self {
) -> Self
where
D: ForeignToplevelListHandler
+ GlobalDispatch<ExtForeignToplevelListV1, ForeignToplevelListGlobalData>,
{
let global = dh.create_global::<D, ExtForeignToplevelListV1, _>(
1,
ForeignToplevelListGlobalData {
@ -323,11 +329,14 @@ impl ForeignToplevelListState {
/// This event is emitted whenever a new toplevel window is created.
/// It is emitted for all toplevels, regardless of the app that has created them.
pub fn new_toplevel<D: ForeignToplevelListHandler>(
pub fn new_toplevel<D>(
&mut self,
title: impl Into<String>,
app_id: impl Into<String>,
) -> ForeignToplevelHandle {
) -> ForeignToplevelHandle
where
D: ForeignToplevelListHandler + Dispatch<ExtForeignToplevelHandleV1, ForeignToplevelHandle>,
{
let handle = ForeignToplevelHandle::new(
title.into(),
app_id.into(),
@ -398,18 +407,21 @@ impl std::fmt::Debug for ForeignToplevelListGlobalData {
}
}
impl<D: ForeignToplevelListHandler> GlobalDispatch<ExtForeignToplevelListV1, ForeignToplevelListGlobalData, D>
for ForeignToplevelListState
impl<D: ForeignToplevelListHandler> GlobalDispatch2<ExtForeignToplevelListV1, D>
for ForeignToplevelListGlobalData
where
D: Dispatch<ExtForeignToplevelListV1, GlobalData>
+ Dispatch<ExtForeignToplevelHandleV1, ForeignToplevelHandle>,
{
fn bind(
&self,
state: &mut D,
dh: &DisplayHandle,
client: &Client,
resource: New<ExtForeignToplevelListV1>,
_global_data: &ForeignToplevelListGlobalData,
data_init: &mut DataInit<'_, D>,
) {
let instance = data_init.init(resource, ());
let instance = data_init.init(resource, GlobalData);
let state = state.foreign_toplevel_list_state();
@ -439,24 +451,24 @@ impl<D: ForeignToplevelListHandler> GlobalDispatch<ExtForeignToplevelListV1, For
state.list_instances.push(instance);
}
fn can_view(client: Client, global_data: &ForeignToplevelListGlobalData) -> bool {
(global_data.filter)(&client)
fn can_view(&self, client: &Client) -> bool {
(self.filter)(client)
}
}
impl<D: ForeignToplevelListHandler> Dispatch<ExtForeignToplevelListV1, (), D> for ForeignToplevelListState {
impl<D: ForeignToplevelListHandler> Dispatch2<ExtForeignToplevelListV1, D> for GlobalData {
fn request(
&self,
state: &mut D,
client: &wayland_server::Client,
manager: &ExtForeignToplevelListV1,
request: ext_foreign_toplevel_list_v1::Request,
data: &(),
_dh: &DisplayHandle,
_data_init: &mut wayland_server::DataInit<'_, D>,
) {
match request {
ext_foreign_toplevel_list_v1::Request::Stop => {
Self::destroyed(state, client.id(), manager, data);
self.destroyed(state, client.id(), manager);
manager.finished();
}
ext_foreign_toplevel_list_v1::Request::Destroy => {}
@ -464,7 +476,7 @@ impl<D: ForeignToplevelListHandler> Dispatch<ExtForeignToplevelListV1, (), D> fo
}
}
fn destroyed(state: &mut D, _client: ClientId, resource: &ExtForeignToplevelListV1, _data: &()) {
fn destroyed(&self, state: &mut D, _client: ClientId, resource: &ExtForeignToplevelListV1) {
state
.foreign_toplevel_list_state()
.list_instances
@ -472,15 +484,13 @@ impl<D: ForeignToplevelListHandler> Dispatch<ExtForeignToplevelListV1, (), D> fo
}
}
impl<D: ForeignToplevelListHandler> Dispatch<ExtForeignToplevelHandleV1, ForeignToplevelHandle, D>
for ForeignToplevelListState
{
impl<D: ForeignToplevelListHandler> Dispatch2<ExtForeignToplevelHandleV1, D> for ForeignToplevelHandle {
fn request(
&self,
_state: &mut D,
_client: &wayland_server::Client,
_context: &ExtForeignToplevelHandleV1,
request: ext_foreign_toplevel_handle_v1::Request,
_data: &ForeignToplevelHandle,
_dh: &DisplayHandle,
_data_init: &mut wayland_server::DataInit<'_, D>,
) {
@ -490,48 +500,7 @@ impl<D: ForeignToplevelListHandler> Dispatch<ExtForeignToplevelHandleV1, Foreign
}
}
fn destroyed(
_state: &mut D,
_client: ClientId,
resource: &ExtForeignToplevelHandleV1,
handle: &ForeignToplevelHandle,
) {
handle.remove_instance(resource);
fn destroyed(&self, _state: &mut D, _client: ClientId, resource: &ExtForeignToplevelHandleV1) {
self.remove_instance(resource);
}
}
/// Macro to delegate implementation of the xdg toplevel icon to [ForeignToplevelListState].
///
/// You must also implement [ForeignToplevelListHandler] to use this.
#[macro_export]
macro_rules! delegate_foreign_toplevel_list {
($(@<$( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+>)? $ty: ty) => {
const _: () = {
use $crate::{
reexports::{
wayland_protocols::ext::foreign_toplevel_list::v1::server::{
ext_foreign_toplevel_handle_v1::ExtForeignToplevelHandleV1,
ext_foreign_toplevel_list_v1::ExtForeignToplevelListV1,
},
wayland_server::{delegate_dispatch, delegate_global_dispatch},
},
wayland::foreign_toplevel_list::{
ForeignToplevelHandle, ForeignToplevelListGlobalData, ForeignToplevelListState,
},
};
delegate_global_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [ExtForeignToplevelListV1: ForeignToplevelListGlobalData] => ForeignToplevelListState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [ExtForeignToplevelListV1: ()] => ForeignToplevelListState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [ExtForeignToplevelHandleV1: ForeignToplevelHandle] => ForeignToplevelListState
);
};
};
}

View file

@ -8,7 +8,6 @@
//! and implement the [`FractionalScaleHandler`], as shown in this example:
//!
//! ```
//! use smithay::delegate_fractional_scale;
//! use smithay::wayland::compositor;
//! use smithay::reexports::wayland_server::protocol::wl_surface;
//! use smithay::wayland::fractional_scale::{
@ -34,7 +33,8 @@
//! // then you don't need to do anything here.
//! }
//! }
//! delegate_fractional_scale!(State);
//!
//! smithay::delegate_dispatch2!(State);
//!
//! // You're now ready to go!
//! ```
@ -71,6 +71,8 @@ use wayland_server::{
use super::compositor::{SurfaceData, with_states};
use crate::wayland::{Dispatch2, GlobalData, GlobalDispatch2};
/// State of the wp_fractional_scale_manager_v1 Global
#[derive(Debug)]
pub struct FractionalScaleManagerState {
@ -81,15 +83,17 @@ impl FractionalScaleManagerState {
/// Create new [`wp_fraction_scale_manager`](wayland_protocols::wp::fractional_scale::v1::server::wp_fractional_scale_manager_v1) global.
pub fn new<D>(display: &DisplayHandle) -> FractionalScaleManagerState
where
D: GlobalDispatch<wp_fractional_scale_manager_v1::WpFractionalScaleManagerV1, ()>
+ Dispatch<wp_fractional_scale_manager_v1::WpFractionalScaleManagerV1, ()>
+ Dispatch<wp_fractional_scale_v1::WpFractionalScaleV1, Weak<wl_surface::WlSurface>>
D: GlobalDispatch<wp_fractional_scale_manager_v1::WpFractionalScaleManagerV1, GlobalData>
+ Dispatch<wp_fractional_scale_manager_v1::WpFractionalScaleManagerV1, GlobalData>
+ Dispatch<wp_fractional_scale_v1::WpFractionalScaleV1, FractionalScaleData>
+ 'static,
D: FractionalScaleHandler,
{
FractionalScaleManagerState {
global: display
.create_global::<D, wp_fractional_scale_manager_v1::WpFractionalScaleManagerV1, ()>(1, ()),
.create_global::<D, wp_fractional_scale_manager_v1::WpFractionalScaleManagerV1, _>(
1, GlobalData,
),
}
}
@ -99,40 +103,35 @@ impl FractionalScaleManagerState {
}
}
impl<D> GlobalDispatch<wp_fractional_scale_manager_v1::WpFractionalScaleManagerV1, (), D>
for FractionalScaleManagerState
impl<D> GlobalDispatch2<wp_fractional_scale_manager_v1::WpFractionalScaleManagerV1, D> for GlobalData
where
D: GlobalDispatch<wp_fractional_scale_manager_v1::WpFractionalScaleManagerV1, ()>
+ Dispatch<wp_fractional_scale_manager_v1::WpFractionalScaleManagerV1, ()>
+ Dispatch<wp_fractional_scale_v1::WpFractionalScaleV1, Weak<wl_surface::WlSurface>>,
D: Dispatch<wp_fractional_scale_manager_v1::WpFractionalScaleManagerV1, GlobalData>
+ Dispatch<wp_fractional_scale_v1::WpFractionalScaleV1, FractionalScaleData>,
D: FractionalScaleHandler,
{
fn bind(
&self,
_state: &mut D,
_handle: &DisplayHandle,
_client: &wayland_server::Client,
resource: wayland_server::New<wp_fractional_scale_manager_v1::WpFractionalScaleManagerV1>,
_global_data: &(),
data_init: &mut wayland_server::DataInit<'_, D>,
) {
data_init.init(resource, ());
data_init.init(resource, GlobalData);
}
}
impl<D> Dispatch<wp_fractional_scale_manager_v1::WpFractionalScaleManagerV1, (), D>
for FractionalScaleManagerState
impl<D> Dispatch2<wp_fractional_scale_manager_v1::WpFractionalScaleManagerV1, D> for GlobalData
where
D: GlobalDispatch<wp_fractional_scale_manager_v1::WpFractionalScaleManagerV1, ()>
+ Dispatch<wp_fractional_scale_manager_v1::WpFractionalScaleManagerV1, ()>
+ Dispatch<wp_fractional_scale_v1::WpFractionalScaleV1, Weak<wl_surface::WlSurface>>,
D: Dispatch<wp_fractional_scale_v1::WpFractionalScaleV1, FractionalScaleData>,
D: FractionalScaleHandler,
{
fn request(
&self,
state: &mut D,
_client: &wayland_server::Client,
_resource: &wp_fractional_scale_manager_v1::WpFractionalScaleManagerV1,
request: <wp_fractional_scale_manager_v1::WpFractionalScaleManagerV1 as Resource>::Request,
_data: &(),
_dhandle: &DisplayHandle,
data_init: &mut wayland_server::DataInit<'_, D>,
) {
@ -158,7 +157,7 @@ where
}
let fractional_scale: wp_fractional_scale_v1::WpFractionalScaleV1 =
data_init.init(id, surface.downgrade());
data_init.init(id, FractionalScaleData(surface.downgrade()));
with_states(&surface, move |states| {
with_fractional_scale(states, move |data| {
@ -176,26 +175,26 @@ where
}
}
impl<D> Dispatch<wp_fractional_scale_v1::WpFractionalScaleV1, Weak<wl_surface::WlSurface>, D>
for FractionalScaleManagerState
#[doc(hidden)]
#[derive(Debug)]
pub struct FractionalScaleData(Weak<wl_surface::WlSurface>);
impl<D> Dispatch2<wp_fractional_scale_v1::WpFractionalScaleV1, D> for FractionalScaleData
where
D: GlobalDispatch<wp_fractional_scale_manager_v1::WpFractionalScaleManagerV1, ()>
+ Dispatch<wp_fractional_scale_manager_v1::WpFractionalScaleManagerV1, ()>
+ Dispatch<wp_fractional_scale_v1::WpFractionalScaleV1, Weak<wl_surface::WlSurface>>,
D: FractionalScaleHandler,
{
fn request(
&self,
_state: &mut D,
_client: &wayland_server::Client,
_resource: &wp_fractional_scale_v1::WpFractionalScaleV1,
request: <wp_fractional_scale_v1::WpFractionalScaleV1 as Resource>::Request,
data: &Weak<wl_surface::WlSurface>,
_dhandle: &DisplayHandle,
_data_init: &mut wayland_server::DataInit<'_, D>,
) {
match request {
wp_fractional_scale_v1::Request::Destroy => {
if let Ok(surface) = data.upgrade() {
if let Ok(surface) = self.0.upgrade() {
with_states(&surface, |states| {
states
.data_map
@ -262,39 +261,3 @@ where
f(&mut fractional_scale)
}
#[allow(missing_docs)] // TODO
#[macro_export]
macro_rules! delegate_fractional_scale {
($(@<$( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+>)? $ty: ty) => {
const _: () = {
use $crate::{
reexports::{
wayland_protocols::wp::fractional_scale::v1::server::{
wp_fractional_scale_manager_v1::WpFractionalScaleManagerV1,
wp_fractional_scale_v1::WpFractionalScaleV1,
},
wayland_server::{
delegate_dispatch, delegate_global_dispatch, protocol::wl_surface::WlSurface, Weak,
},
},
wayland::fractional_scale::FractionalScaleManagerState,
};
delegate_global_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [WpFractionalScaleManagerV1: ()] => FractionalScaleManagerState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [WpFractionalScaleManagerV1: ()] => FractionalScaleManagerState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [WpFractionalScaleV1: Weak<WlSurface>] => FractionalScaleManagerState
);
};
};
}

View file

@ -3,9 +3,10 @@
use _idle_inhibit::zwp_idle_inhibitor_v1::{Request, ZwpIdleInhibitorV1};
use wayland_protocols::wp::idle_inhibit::zv1::server as _idle_inhibit;
use wayland_server::protocol::wl_surface::WlSurface;
use wayland_server::{Client, DataInit, Dispatch, DisplayHandle};
use wayland_server::{Client, DataInit, DisplayHandle};
use crate::wayland::idle_inhibit::{IdleInhibitHandler, IdleInhibitManagerState};
use crate::wayland::Dispatch2;
use crate::wayland::idle_inhibit::IdleInhibitHandler;
/// State of zwp_idle_inhibitor_v1.
#[derive(Debug)]
@ -20,23 +21,22 @@ impl IdleInhibitorState {
}
}
impl<D> Dispatch<ZwpIdleInhibitorV1, IdleInhibitorState, D> for IdleInhibitManagerState
impl<D> Dispatch2<ZwpIdleInhibitorV1, D> for IdleInhibitorState
where
D: Dispatch<ZwpIdleInhibitorV1, IdleInhibitorState>,
D: IdleInhibitHandler,
D: 'static,
{
fn request(
&self,
state: &mut D,
_client: &Client,
_inhibitor: &ZwpIdleInhibitorV1,
request: Request,
data: &IdleInhibitorState,
_display: &DisplayHandle,
_data_init: &mut DataInit<'_, D>,
) {
match request {
Request::Destroy => state.uninhibit(data.surface.clone()),
Request::Destroy => state.uninhibit(self.surface.clone()),
_ => unreachable!(),
}
}

View file

@ -8,7 +8,6 @@
//! implement the [`IdleInhibitHandler`], as shown in this example:
//!
//! ```
//! use smithay::delegate_idle_inhibit;
//! use smithay::reexports::wayland_server::protocol::wl_surface::WlSurface;
//! use smithay::wayland::idle_inhibit::{IdleInhibitManagerState, IdleInhibitHandler};
//!
@ -27,7 +26,8 @@
//! // …
//! }
//! }
//! delegate_idle_inhibit!(State);
//!
//! smithay::delegate_dispatch2!(State);
//!
//! // You're now ready to go!
//! ```
@ -40,6 +40,7 @@ use wayland_server::protocol::wl_surface::WlSurface;
use wayland_server::{Client, DataInit, Dispatch, DisplayHandle, GlobalDispatch, New};
use crate::wayland::idle_inhibit::inhibitor::IdleInhibitorState;
use crate::wayland::{Dispatch2, GlobalData, GlobalDispatch2};
pub mod inhibitor;
@ -55,13 +56,11 @@ impl IdleInhibitManagerState {
/// Create new [`zwp_idle_inhibit_manager`](ZwpIdleInhibitManagerV1) global.
pub fn new<D>(display: &DisplayHandle) -> Self
where
D: GlobalDispatch<ZwpIdleInhibitManagerV1, ()>,
D: Dispatch<ZwpIdleInhibitManagerV1, ()>,
D: Dispatch<ZwpIdleInhibitorV1, IdleInhibitorState>,
D: GlobalDispatch<ZwpIdleInhibitManagerV1, GlobalData>,
D: IdleInhibitHandler,
D: 'static,
{
let global = display.create_global::<D, ZwpIdleInhibitManagerV1, _>(MANAGER_VERSION, ());
let global = display.create_global::<D, ZwpIdleInhibitManagerV1, _>(MANAGER_VERSION, GlobalData);
Self { global }
}
@ -72,40 +71,36 @@ impl IdleInhibitManagerState {
}
}
impl<D> GlobalDispatch<ZwpIdleInhibitManagerV1, (), D> for IdleInhibitManagerState
impl<D> GlobalDispatch2<ZwpIdleInhibitManagerV1, D> for GlobalData
where
D: GlobalDispatch<ZwpIdleInhibitManagerV1, ()>,
D: Dispatch<ZwpIdleInhibitManagerV1, ()>,
D: Dispatch<ZwpIdleInhibitorV1, IdleInhibitorState>,
D: Dispatch<ZwpIdleInhibitManagerV1, GlobalData>,
D: IdleInhibitHandler,
D: 'static,
{
fn bind(
&self,
_state: &mut D,
_display: &DisplayHandle,
_client: &Client,
manager: New<ZwpIdleInhibitManagerV1>,
_manager_state: &(),
data_init: &mut DataInit<'_, D>,
) {
data_init.init(manager, ());
data_init.init(manager, GlobalData);
}
}
impl<D> Dispatch<ZwpIdleInhibitManagerV1, (), D> for IdleInhibitManagerState
impl<D> Dispatch2<ZwpIdleInhibitManagerV1, D> for GlobalData
where
D: GlobalDispatch<ZwpIdleInhibitManagerV1, ()>,
D: Dispatch<ZwpIdleInhibitManagerV1, ()>,
D: Dispatch<ZwpIdleInhibitorV1, IdleInhibitorState>,
D: IdleInhibitHandler,
D: 'static,
{
fn request(
&self,
state: &mut D,
_client: &Client,
_manager: &ZwpIdleInhibitManagerV1,
request: Request,
_data: &(),
_display: &DisplayHandle,
data_init: &mut DataInit<'_, D>,
) {
@ -132,37 +127,3 @@ pub trait IdleInhibitHandler {
/// are invisible or dead.
fn uninhibit(&mut self, surface: WlSurface);
}
#[allow(missing_docs)]
#[macro_export]
macro_rules! delegate_idle_inhibit {
($(@<$( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+>)? $ty: ty) => {
const _: () = {
use $crate::{
reexports::{
wayland_protocols::wp::idle_inhibit::zv1::server::{
zwp_idle_inhibit_manager_v1::ZwpIdleInhibitManagerV1,
zwp_idle_inhibitor_v1::ZwpIdleInhibitorV1,
},
wayland_server::{delegate_dispatch, delegate_global_dispatch},
},
wayland::idle_inhibit::{inhibitor::IdleInhibitorState, IdleInhibitManagerState},
};
delegate_global_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [ZwpIdleInhibitManagerV1: ()] => IdleInhibitManagerState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [ZwpIdleInhibitManagerV1: ()] => IdleInhibitManagerState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [ZwpIdleInhibitorV1: IdleInhibitorState] => IdleInhibitManagerState
);
};
};
}

View file

@ -3,7 +3,6 @@
//! ```
//! # extern crate wayland_server;
//! # #[macro_use] extern crate smithay;
//! use smithay::delegate_idle_notify;
//! use smithay::wayland::idle_notify::{IdleNotifierState, IdleNotifierHandler};
//! # use smithay::input::{Seat, SeatHandler, SeatState, pointer::CursorImageStatus};
//! # use smithay::reexports::wayland_server::protocol::wl_surface::WlSurface;
@ -33,7 +32,8 @@
//! &mut self.idle_notifier
//! }
//! }
//! delegate_idle_notify!(State);
//!
//! smithay::delegate_dispatch2!(State);
//!
//! // On input you should notify the idle_notifier
//! // state.idle_notifier.notify_activity(&seat);
@ -59,7 +59,10 @@ use wayland_server::{
protocol::wl_seat::WlSeat,
};
use crate::input::{Seat, SeatHandler};
use crate::{
input::{Seat, SeatHandler},
wayland::{Dispatch2, GlobalData, GlobalDispatch2},
};
/// Handler trait for ext-idle-notify
pub trait IdleNotifierHandler: Sized {
@ -110,13 +113,11 @@ impl<D: IdleNotifierHandler> IdleNotifierState<D> {
/// Create new [`ExtIdleNotifierV1`] global.
pub fn new(display: &DisplayHandle, loop_handle: LoopHandle<'static, D>) -> Self
where
D: GlobalDispatch<ExtIdleNotifierV1, ()>,
D: Dispatch<ExtIdleNotifierV1, ()>,
D: Dispatch<ExtIdleNotificationV1, IdleNotificationUserData>,
D: GlobalDispatch<ExtIdleNotifierV1, GlobalData>,
D: IdleNotifierHandler,
D: 'static,
{
let global = display.create_global::<D, ExtIdleNotifierV1, _>(2, ());
let global = display.create_global::<D, ExtIdleNotifierV1, _>(2, GlobalData);
Self {
global,
notifications: HashMap::new(),
@ -235,40 +236,36 @@ impl<D: IdleNotifierHandler + SeatHandler> IdleNotifierState<D> {
}
}
impl<D> GlobalDispatch<ExtIdleNotifierV1, (), D> for IdleNotifierState<D>
impl<D> GlobalDispatch2<ExtIdleNotifierV1, D> for GlobalData
where
D: GlobalDispatch<ExtIdleNotifierV1, ()>,
D: Dispatch<ExtIdleNotifierV1, ()>,
D: Dispatch<ExtIdleNotificationV1, IdleNotificationUserData>,
D: Dispatch<ExtIdleNotifierV1, GlobalData>,
D: IdleNotifierHandler,
D: 'static,
{
fn bind(
&self,
_state: &mut D,
_handle: &DisplayHandle,
_client: &Client,
resource: New<ExtIdleNotifierV1>,
_global_data: &(),
data_init: &mut wayland_server::DataInit<'_, D>,
) {
data_init.init(resource, ());
data_init.init(resource, GlobalData);
}
}
impl<D> Dispatch<ExtIdleNotifierV1, (), D> for IdleNotifierState<D>
impl<D> Dispatch2<ExtIdleNotifierV1, D> for GlobalData
where
D: GlobalDispatch<ExtIdleNotifierV1, ()>,
D: Dispatch<ExtIdleNotifierV1, ()>,
D: Dispatch<ExtIdleNotificationV1, IdleNotificationUserData>,
D: IdleNotifierHandler,
D: 'static,
{
fn request(
&self,
state: &mut D,
_client: &Client,
_resource: &ExtIdleNotifierV1,
request: ext_idle_notifier_v1::Request,
_data: &(),
_dhandle: &DisplayHandle,
data_init: &mut DataInit<'_, D>,
) {
@ -329,17 +326,16 @@ where
}
}
impl<D> Dispatch<ExtIdleNotificationV1, IdleNotificationUserData, D> for IdleNotifierState<D>
impl<D> Dispatch2<ExtIdleNotificationV1, D> for IdleNotificationUserData
where
D: Dispatch<ExtIdleNotificationV1, IdleNotificationUserData>,
D: IdleNotifierHandler,
{
fn request(
&self,
_state: &mut D,
_client: &Client,
_resource: &ExtIdleNotificationV1,
request: ext_idle_notification_v1::Request,
_data: &IdleNotificationUserData,
_dhandle: &DisplayHandle,
_data_init: &mut DataInit<'_, D>,
) {
@ -349,14 +345,9 @@ where
}
}
fn destroyed(
state: &mut D,
_client: ClientId,
notification: &ExtIdleNotificationV1,
data: &IdleNotificationUserData,
) {
fn destroyed(&self, state: &mut D, _client: ClientId, notification: &ExtIdleNotificationV1) {
let state = state.idle_notifier_state();
if let Some(notifications) = state.notifications.get_mut(&data.seat) {
if let Some(notifications) = state.notifications.get_mut(&self.seat) {
notifications.retain(|x| x != notification);
}
@ -365,37 +356,3 @@ where
.retain(|seat, notifications| !notifications.is_empty() && seat.is_alive());
}
}
/// Macro to delegate implementation of the ext idle notify protocol
#[macro_export]
macro_rules! delegate_idle_notify {
($(@<$( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+>)? $ty: ty) => {
const _: () = {
use $crate::{
reexports::{
wayland_protocols::ext::idle_notify::v1::server::{
ext_idle_notification_v1::ExtIdleNotificationV1,
ext_idle_notifier_v1::ExtIdleNotifierV1,
},
wayland_server::{delegate_dispatch, delegate_global_dispatch},
},
wayland::idle_notify::{IdleNotificationUserData, IdleNotifierState},
};
delegate_global_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [ExtIdleNotifierV1: ()] => IdleNotifierState<$ty>
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [ExtIdleNotifierV1: ()] => IdleNotifierState<$ty>
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [ExtIdleNotificationV1: IdleNotificationUserData] => IdleNotifierState<$ty>
);
};
};
}

View file

@ -22,8 +22,6 @@
//! ### Output Capture Only
//!
//! ```no_run
//! use smithay::delegate_image_capture_source;
//! use smithay::delegate_output_capture_source;
//! use smithay::output::Output;
//! use smithay::wayland::image_capture_source::{
//! ImageCaptureSourceState, ImageCaptureSourceHandler, ImageCaptureSource,
@ -57,16 +55,12 @@
//! let image_capture_source = ImageCaptureSourceState::new();
//! let output_capture_source = OutputCaptureSourceState::new::<State>(&display_handle);
//!
//! delegate_image_capture_source!(State);
//! delegate_output_capture_source!(State);
//! smithay::delegate_dispatch2!(State);
//! ```
//!
//! ### With Toplevel Capture
//!
//! ```no_run
//! use smithay::delegate_image_capture_source;
//! use smithay::delegate_output_capture_source;
//! use smithay::delegate_toplevel_capture_source;
//! use smithay::output::Output;
//! use smithay::wayland::image_capture_source::{
//! ImageCaptureSourceState, ImageCaptureSourceHandler, ImageCaptureSource,
@ -114,9 +108,7 @@
//! let output_capture_source = OutputCaptureSourceState::new::<State>(&display_handle);
//! let toplevel_capture_source = ToplevelCaptureSourceState::new::<State>(&display_handle);
//!
//! delegate_image_capture_source!(State);
//! delegate_output_capture_source!(State);
//! delegate_toplevel_capture_source!(State);
//! smithay::delegate_dispatch2!(State);
//! ```
//!
//! ### Custom Capture Sources
@ -152,6 +144,7 @@ use wayland_server::{
use crate::output::Output;
use crate::utils::user_data::UserDataMap;
use crate::wayland::foreign_toplevel_list::ForeignToplevelHandle;
use crate::wayland::{Dispatch2, GlobalData, GlobalDispatch2};
// ============================================================================
// Core types
@ -317,16 +310,16 @@ pub trait ImageCaptureSourceHandler:
}
// Dispatch for the capture source resource
impl<D> Dispatch<ExtImageCaptureSourceV1, ImageCaptureSourceData, D> for ImageCaptureSourceState
impl<D> Dispatch2<ExtImageCaptureSourceV1, D> for ImageCaptureSourceData
where
D: ImageCaptureSourceHandler,
{
fn request(
&self,
_state: &mut D,
_client: &Client,
_resource: &ExtImageCaptureSourceV1,
request: ext_image_capture_source_v1::Request,
_data: &ImageCaptureSourceData,
_dh: &DisplayHandle,
_data_init: &mut DataInit<'_, D>,
) {
@ -339,13 +332,13 @@ where
}
fn destroyed(
&self,
state: &mut D,
_client: wayland_server::backend::ClientId,
_resource: &ExtImageCaptureSourceV1,
data: &ImageCaptureSourceData,
) {
data.source.mark_destroyed();
state.source_destroyed(data.source.clone());
self.source.mark_destroyed();
state.source_destroyed(self.source.clone());
}
}
@ -405,7 +398,7 @@ impl OutputCaptureSourceState {
pub trait OutputCaptureSourceHandler:
ImageCaptureSourceHandler
+ GlobalDispatch<ExtOutputImageCaptureSourceManagerV1, OutputCaptureSourceGlobalData>
+ Dispatch<ExtOutputImageCaptureSourceManagerV1, ()>
+ Dispatch<ExtOutputImageCaptureSourceManagerV1, GlobalData>
{
/// Returns a mutable reference to the [`OutputCaptureSourceState`].
fn output_capture_source_state(&mut self) -> &mut OutputCaptureSourceState;
@ -422,37 +415,36 @@ pub trait OutputCaptureSourceHandler:
}
}
impl<D> GlobalDispatch<ExtOutputImageCaptureSourceManagerV1, OutputCaptureSourceGlobalData, D>
for OutputCaptureSourceState
impl<D> GlobalDispatch2<ExtOutputImageCaptureSourceManagerV1, D> for OutputCaptureSourceGlobalData
where
D: OutputCaptureSourceHandler,
{
fn bind(
&self,
_state: &mut D,
_dh: &DisplayHandle,
_client: &Client,
resource: New<ExtOutputImageCaptureSourceManagerV1>,
_global_data: &OutputCaptureSourceGlobalData,
data_init: &mut DataInit<'_, D>,
) {
data_init.init(resource, ());
data_init.init(resource, GlobalData);
}
fn can_view(client: Client, global_data: &OutputCaptureSourceGlobalData) -> bool {
(global_data.filter)(&client)
fn can_view(&self, client: &Client) -> bool {
(self.filter)(client)
}
}
impl<D> Dispatch<ExtOutputImageCaptureSourceManagerV1, (), D> for OutputCaptureSourceState
impl<D> Dispatch2<ExtOutputImageCaptureSourceManagerV1, D> for GlobalData
where
D: OutputCaptureSourceHandler,
{
fn request(
&self,
state: &mut D,
_client: &Client,
_resource: &ExtOutputImageCaptureSourceManagerV1,
request: ext_output_image_capture_source_manager_v1::Request,
_data: &(),
_dh: &DisplayHandle,
data_init: &mut DataInit<'_, D>,
) {
@ -544,7 +536,7 @@ impl ToplevelCaptureSourceState {
pub trait ToplevelCaptureSourceHandler:
ImageCaptureSourceHandler
+ GlobalDispatch<ExtForeignToplevelImageCaptureSourceManagerV1, ToplevelCaptureSourceGlobalData>
+ Dispatch<ExtForeignToplevelImageCaptureSourceManagerV1, ()>
+ Dispatch<ExtForeignToplevelImageCaptureSourceManagerV1, GlobalData>
{
/// Returns a mutable reference to the [`ToplevelCaptureSourceState`].
fn toplevel_capture_source_state(&mut self) -> &mut ToplevelCaptureSourceState;
@ -561,37 +553,36 @@ pub trait ToplevelCaptureSourceHandler:
}
}
impl<D> GlobalDispatch<ExtForeignToplevelImageCaptureSourceManagerV1, ToplevelCaptureSourceGlobalData, D>
for ToplevelCaptureSourceState
impl<D> GlobalDispatch2<ExtForeignToplevelImageCaptureSourceManagerV1, D> for ToplevelCaptureSourceGlobalData
where
D: ToplevelCaptureSourceHandler,
{
fn bind(
&self,
_state: &mut D,
_dh: &DisplayHandle,
_client: &Client,
resource: New<ExtForeignToplevelImageCaptureSourceManagerV1>,
_global_data: &ToplevelCaptureSourceGlobalData,
data_init: &mut DataInit<'_, D>,
) {
data_init.init(resource, ());
data_init.init(resource, GlobalData);
}
fn can_view(client: Client, global_data: &ToplevelCaptureSourceGlobalData) -> bool {
(global_data.filter)(&client)
fn can_view(&self, client: &Client) -> bool {
(self.filter)(client)
}
}
impl<D> Dispatch<ExtForeignToplevelImageCaptureSourceManagerV1, (), D> for ToplevelCaptureSourceState
impl<D> Dispatch2<ExtForeignToplevelImageCaptureSourceManagerV1, D> for GlobalData
where
D: ToplevelCaptureSourceHandler,
{
fn request(
&self,
state: &mut D,
_client: &Client,
_resource: &ExtForeignToplevelImageCaptureSourceManagerV1,
request: ext_foreign_toplevel_image_capture_source_manager_v1::Request,
_data: &(),
_dh: &DisplayHandle,
data_init: &mut DataInit<'_, D>,
) {
@ -621,87 +612,3 @@ where
}
}
}
// ============================================================================
// Delegate macros
// ============================================================================
/// Delegate core image capture source handling to [`ImageCaptureSourceState`].
///
/// You must implement [`ImageCaptureSourceHandler`] to use this.
#[macro_export]
macro_rules! delegate_image_capture_source {
($(@<$( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+>)? $ty: ty) => {
const _: () = {
use $crate::reexports::wayland_protocols::ext::image_capture_source::v1::server::{
ext_image_capture_source_v1::ExtImageCaptureSourceV1,
};
use $crate::reexports::wayland_server::delegate_dispatch;
use $crate::wayland::image_capture_source::{
ImageCaptureSourceData, ImageCaptureSourceState,
};
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [ExtImageCaptureSourceV1: ImageCaptureSourceData] => ImageCaptureSourceState
);
};
};
}
/// Delegate output capture source management to [`OutputCaptureSourceState`].
///
/// You must implement [`OutputCaptureSourceHandler`] to use this.
#[macro_export]
macro_rules! delegate_output_capture_source {
($(@<$( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+>)? $ty: ty) => {
const _: () = {
use $crate::reexports::wayland_protocols::ext::image_capture_source::v1::server::{
ext_output_image_capture_source_manager_v1::ExtOutputImageCaptureSourceManagerV1,
};
use $crate::reexports::wayland_server::{delegate_dispatch, delegate_global_dispatch};
use $crate::wayland::image_capture_source::{
OutputCaptureSourceGlobalData, OutputCaptureSourceState,
};
delegate_global_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [ExtOutputImageCaptureSourceManagerV1: OutputCaptureSourceGlobalData] => OutputCaptureSourceState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [ExtOutputImageCaptureSourceManagerV1: ()] => OutputCaptureSourceState
);
};
};
}
/// Delegate toplevel capture source management to [`ToplevelCaptureSourceState`].
///
/// You must implement [`ToplevelCaptureSourceHandler`] to use this.
///
/// This uses Smithay's [`ForeignToplevelHandle`]. Compositors with custom
/// foreign-toplevel implementations should handle the protocol directly instead.
#[macro_export]
macro_rules! delegate_toplevel_capture_source {
($(@<$( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+>)? $ty: ty) => {
const _: () = {
use $crate::reexports::wayland_protocols::ext::image_capture_source::v1::server::{
ext_foreign_toplevel_image_capture_source_manager_v1::ExtForeignToplevelImageCaptureSourceManagerV1,
};
use $crate::reexports::wayland_server::{delegate_dispatch, delegate_global_dispatch};
use $crate::wayland::image_capture_source::{
ToplevelCaptureSourceGlobalData, ToplevelCaptureSourceState,
};
delegate_global_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [ExtForeignToplevelImageCaptureSourceManagerV1: ToplevelCaptureSourceGlobalData] => ToplevelCaptureSourceState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [ExtForeignToplevelImageCaptureSourceManagerV1: ()] => ToplevelCaptureSourceState
);
};
};
}

View file

@ -16,9 +16,6 @@
//! ## How to use it
//!
//! ```no_run
//! use smithay::delegate_image_copy_capture;
//! use smithay::delegate_image_capture_source;
//! use smithay::delegate_output_capture_source;
//! use smithay::wayland::image_copy_capture::{
//! ImageCopyCaptureState, ImageCopyCaptureHandler, BufferConstraints,
//! Session, SessionRef, Frame,
@ -65,14 +62,12 @@
//! # source.user_data().insert_if_missing(|| output.downgrade());
//! # }
//! # }
//! # smithay::delegate_image_capture_source!(State);
//! # smithay::delegate_output_capture_source!(State);
//!
//! # let mut display = wayland_server::Display::<State>::new().unwrap();
//! # let display_handle = display.handle();
//! let state = ImageCopyCaptureState::new::<State>(&display_handle);
//!
//! delegate_image_copy_capture!(State);
//! smithay::delegate_dispatch2!(State);
//! ```
//!
//! ## Session Lifecycle
@ -120,6 +115,7 @@ use crate::backend::renderer::{BufferType, buffer_type};
#[cfg(feature = "backend_drm")]
use crate::wayland::dmabuf::get_dmabuf;
use crate::wayland::shm::with_buffer_contents;
use crate::wayland::{Dispatch2, GlobalData, GlobalDispatch2};
// Re-export FailureReason for convenience
pub use wayland_protocols::ext::image_copy_capture::v1::server::ext_image_copy_capture_frame_v1::FailureReason as CaptureFailureReason;
@ -761,7 +757,7 @@ impl Drop for Frame {
/// Implement this on your compositor's state type to handle capture requests.
pub trait ImageCopyCaptureHandler:
GlobalDispatch<ExtImageCopyCaptureManagerV1, ImageCopyCaptureGlobalData>
+ Dispatch<ExtImageCopyCaptureManagerV1, ()>
+ Dispatch<ExtImageCopyCaptureManagerV1, GlobalData>
+ Dispatch<ExtImageCopyCaptureSessionV1, SessionData>
+ Dispatch<ExtImageCopyCaptureSessionV1, CursorSessionData>
+ Dispatch<ExtImageCopyCaptureCursorSessionV1, CursorSessionData>
@ -944,36 +940,36 @@ impl ImageCopyCaptureState {
// Dispatch implementations
// ============================================================================
impl<D> GlobalDispatch<ExtImageCopyCaptureManagerV1, ImageCopyCaptureGlobalData, D> for ImageCopyCaptureState
impl<D> GlobalDispatch2<ExtImageCopyCaptureManagerV1, D> for ImageCopyCaptureGlobalData
where
D: ImageCopyCaptureHandler,
{
fn bind(
&self,
_state: &mut D,
_dh: &DisplayHandle,
_client: &Client,
resource: New<ExtImageCopyCaptureManagerV1>,
_global_data: &ImageCopyCaptureGlobalData,
data_init: &mut DataInit<'_, D>,
) {
data_init.init(resource, ());
data_init.init(resource, GlobalData);
}
fn can_view(client: Client, global_data: &ImageCopyCaptureGlobalData) -> bool {
(global_data.filter)(&client)
fn can_view(&self, client: &Client) -> bool {
(self.filter)(client)
}
}
impl<D> Dispatch<ExtImageCopyCaptureManagerV1, (), D> for ImageCopyCaptureState
impl<D> Dispatch2<ExtImageCopyCaptureManagerV1, D> for GlobalData
where
D: ImageCopyCaptureHandler,
{
fn request(
&self,
state: &mut D,
_client: &Client,
_resource: &ExtImageCopyCaptureManagerV1,
request: ext_image_copy_capture_manager_v1::Request,
_data: &(),
_dh: &DisplayHandle,
data_init: &mut DataInit<'_, D>,
) {
@ -1097,25 +1093,25 @@ where
}
}
impl<D> Dispatch<ExtImageCopyCaptureSessionV1, SessionData, D> for ImageCopyCaptureState
impl<D> Dispatch2<ExtImageCopyCaptureSessionV1, D> for SessionData
where
D: ImageCopyCaptureHandler,
{
fn request(
&self,
_state: &mut D,
_client: &Client,
resource: &ExtImageCopyCaptureSessionV1,
request: ext_image_copy_capture_session_v1::Request,
data: &SessionData,
_dh: &DisplayHandle,
data_init: &mut DataInit<'_, D>,
) {
match request {
ext_image_copy_capture_session_v1::Request::CreateFrame { frame } => {
let constraints = data.inner.lock().unwrap().constraints.clone();
let constraints = self.inner.lock().unwrap().constraints.clone();
let inner = Arc::new(Mutex::new(FrameInner::new(resource.clone(), constraints)));
let obj = data_init.init(frame, FrameData { inner: inner.clone() });
data.inner
self.inner
.lock()
.unwrap()
.active_frames
@ -1127,40 +1123,40 @@ where
}
fn destroyed(
&self,
state: &mut D,
_client: wayland_server::backend::ClientId,
resource: &ExtImageCopyCaptureSessionV1,
data: &SessionData,
) {
let session_ref = SessionRef {
obj: resource.clone(),
inner: data.inner.clone(),
user_data: data.user_data.clone(),
inner: self.inner.clone(),
user_data: self.user_data.clone(),
};
state.session_destroyed(session_ref);
}
}
// Dispatch for session created from cursor session's get_capture_session
impl<D> Dispatch<ExtImageCopyCaptureSessionV1, CursorSessionData, D> for ImageCopyCaptureState
impl<D> Dispatch2<ExtImageCopyCaptureSessionV1, D> for CursorSessionData
where
D: ImageCopyCaptureHandler,
{
fn request(
&self,
_state: &mut D,
_client: &Client,
resource: &ExtImageCopyCaptureSessionV1,
request: ext_image_copy_capture_session_v1::Request,
data: &CursorSessionData,
_dh: &DisplayHandle,
data_init: &mut DataInit<'_, D>,
) {
match request {
ext_image_copy_capture_session_v1::Request::CreateFrame { frame } => {
let constraints = data.inner.lock().unwrap().constraints.clone();
let constraints = self.inner.lock().unwrap().constraints.clone();
let inner = Arc::new(Mutex::new(FrameInner::new(resource.clone(), constraints)));
let obj = data_init.init(frame, FrameData { inner: inner.clone() });
data.inner
self.inner
.lock()
.unwrap()
.active_frames
@ -1172,22 +1168,22 @@ where
}
}
impl<D> Dispatch<ExtImageCopyCaptureCursorSessionV1, CursorSessionData, D> for ImageCopyCaptureState
impl<D> Dispatch2<ExtImageCopyCaptureCursorSessionV1, D> for CursorSessionData
where
D: ImageCopyCaptureHandler,
{
fn request(
&self,
_state: &mut D,
_client: &Client,
_resource: &ExtImageCopyCaptureCursorSessionV1,
request: ext_image_copy_capture_cursor_session_v1::Request,
data: &CursorSessionData,
_dh: &DisplayHandle,
data_init: &mut DataInit<'_, D>,
) {
match request {
ext_image_copy_capture_cursor_session_v1::Request::GetCaptureSession { session } => {
let mut inner = data.inner.lock().unwrap();
let mut inner = self.inner.lock().unwrap();
if inner.session_obj.is_some() {
// Protocol error: only one session allowed
@ -1197,8 +1193,8 @@ where
let obj = data_init.init(
session,
CursorSessionData {
inner: data.inner.clone(),
user_data: data.user_data.clone(),
inner: self.inner.clone(),
user_data: self.user_data.clone(),
},
);
@ -1232,36 +1228,36 @@ where
}
fn destroyed(
&self,
state: &mut D,
_client: wayland_server::backend::ClientId,
resource: &ExtImageCopyCaptureCursorSessionV1,
data: &CursorSessionData,
) {
let session_ref = CursorSessionRef {
obj: resource.clone(),
inner: data.inner.clone(),
user_data: data.user_data.clone(),
inner: self.inner.clone(),
user_data: self.user_data.clone(),
};
state.cursor_session_destroyed(session_ref);
}
}
impl<D> Dispatch<ExtImageCopyCaptureFrameV1, FrameData, D> for ImageCopyCaptureState
impl<D> Dispatch2<ExtImageCopyCaptureFrameV1, D> for FrameData
where
D: ImageCopyCaptureHandler,
{
fn request(
&self,
state: &mut D,
_client: &Client,
resource: &ExtImageCopyCaptureFrameV1,
request: ext_image_copy_capture_frame_v1::Request,
data: &FrameData,
_dh: &DisplayHandle,
_data_init: &mut DataInit<'_, D>,
) {
match request {
ext_image_copy_capture_frame_v1::Request::AttachBuffer { buffer } => {
let mut inner = data.inner.lock().unwrap();
let mut inner = self.inner.lock().unwrap();
if inner.capture_requested {
// Protocol error: can't attach after capture
return;
@ -1269,7 +1265,7 @@ where
inner.buffer = Some(buffer);
}
ext_image_copy_capture_frame_v1::Request::DamageBuffer { x, y, width, height } => {
let mut inner = data.inner.lock().unwrap();
let mut inner = self.inner.lock().unwrap();
if inner.capture_requested {
return;
}
@ -1285,11 +1281,11 @@ where
ext_image_copy_capture_frame_v1::Request::Capture => {
let frame_ref = FrameRef {
obj: resource.clone(),
inner: data.inner.clone(),
inner: self.inner.clone(),
};
{
let mut inner = data.inner.lock().unwrap();
let mut inner = self.inner.lock().unwrap();
if inner.capture_requested || inner.failed.is_some() {
return;
}
@ -1352,7 +1348,7 @@ where
}
// Frame not found in any session
data.inner.lock().unwrap().fail(resource, FailureReason::Unknown);
self.inner.lock().unwrap().fail(resource, FailureReason::Unknown);
}
ext_image_copy_capture_frame_v1::Request::Destroy => {}
_ => unreachable!(),
@ -1360,14 +1356,14 @@ where
}
fn destroyed(
&self,
state: &mut D,
_client: wayland_server::backend::ClientId,
resource: &ExtImageCopyCaptureFrameV1,
data: &FrameData,
) {
let frame_ref = FrameRef {
obj: resource.clone(),
inner: data.inner.clone(),
inner: self.inner.clone(),
};
// Remove from active frames in sessions
@ -1391,54 +1387,3 @@ where
state.frame_aborted(frame_ref);
}
}
// ============================================================================
// Delegate macro
// ============================================================================
/// Macro to delegate implementation of the image copy capture protocol to [`ImageCopyCaptureState`].
///
/// You must also implement [`ImageCopyCaptureHandler`] to use this.
#[macro_export]
macro_rules! delegate_image_copy_capture {
($(@<$( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+>)? $ty: ty) => {
const _: () = {
use $crate::reexports::wayland_protocols::ext::image_copy_capture::v1::server::{
ext_image_copy_capture_cursor_session_v1::ExtImageCopyCaptureCursorSessionV1,
ext_image_copy_capture_frame_v1::ExtImageCopyCaptureFrameV1,
ext_image_copy_capture_manager_v1::ExtImageCopyCaptureManagerV1,
ext_image_copy_capture_session_v1::ExtImageCopyCaptureSessionV1,
};
use $crate::reexports::wayland_server::{delegate_dispatch, delegate_global_dispatch};
use $crate::wayland::image_copy_capture::{
ImageCopyCaptureGlobalData, ImageCopyCaptureState,
SessionData, CursorSessionData, FrameData,
};
delegate_global_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [ExtImageCopyCaptureManagerV1: ImageCopyCaptureGlobalData] => ImageCopyCaptureState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [ExtImageCopyCaptureManagerV1: ()] => ImageCopyCaptureState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [ExtImageCopyCaptureSessionV1: SessionData] => ImageCopyCaptureState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [ExtImageCopyCaptureSessionV1: CursorSessionData] => ImageCopyCaptureState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [ExtImageCopyCaptureCursorSessionV1: CursorSessionData] => ImageCopyCaptureState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [ExtImageCopyCaptureFrameV1: FrameData] => ImageCopyCaptureState
);
};
};
}

View file

@ -17,11 +17,11 @@ use wayland_server::{backend::ClientId, protocol::wl_surface::WlSurface};
use crate::{
input::{SeatHandler, keyboard::KeyboardHandle},
utils::{Logical, Rectangle, SERIAL_COUNTER, alive_tracker::AliveTracker},
wayland::{compositor, seat::WaylandFocus, text_input::TextInputHandle},
wayland::{Dispatch2, compositor, seat::WaylandFocus, text_input::TextInputHandle},
};
use super::{
INPUT_POPUP_SURFACE_ROLE, InputMethodHandler, InputMethodKeyboardUserData, InputMethodManagerState,
INPUT_POPUP_SURFACE_ROLE, InputMethodHandler, InputMethodKeyboardUserData,
InputMethodPopupSurfaceUserData,
input_method_keyboard_grab::InputMethodKeyboardGrab,
input_method_popup_surface::{PopupHandle, PopupParent, PopupSurface},
@ -185,9 +185,8 @@ impl<D: SeatHandler> fmt::Debug for InputMethodUserData<D> {
}
}
impl<D> Dispatch<ZwpInputMethodV2, InputMethodUserData<D>, D> for InputMethodManagerState
impl<D> Dispatch2<ZwpInputMethodV2, D> for InputMethodUserData<D>
where
D: Dispatch<ZwpInputMethodV2, InputMethodUserData<D>>,
D: Dispatch<ZwpInputPopupSurfaceV2, InputMethodPopupSurfaceUserData>,
D: Dispatch<ZwpInputMethodKeyboardGrabV2, InputMethodKeyboardUserData<D>>,
D: SeatHandler,
@ -196,17 +195,17 @@ where
D: 'static,
{
fn request(
&self,
state: &mut D,
_client: &Client,
seat: &ZwpInputMethodV2,
request: zwp_input_method_v2::Request,
data: &InputMethodUserData<D>,
_dh: &DisplayHandle,
data_init: &mut DataInit<'_, D>,
) {
match request {
zwp_input_method_v2::Request::CommitString { text } => {
data.text_input_handle.with_active_text_input(|ti, _surface| {
self.text_input_handle.with_active_text_input(|ti, _surface| {
ti.commit_string(Some(text.clone()));
});
}
@ -215,7 +214,7 @@ where
cursor_begin,
cursor_end,
} => {
data.text_input_handle.with_active_text_input(|ti, _surface| {
self.text_input_handle.with_active_text_input(|ti, _surface| {
ti.preedit_string(Some(text.clone()), cursor_begin, cursor_end);
});
}
@ -223,12 +222,12 @@ where
before_length,
after_length,
} => {
data.text_input_handle.with_active_text_input(|ti, _surface| {
self.text_input_handle.with_active_text_input(|ti, _surface| {
ti.delete_surrounding_text(before_length, after_length);
});
}
zwp_input_method_v2::Request::Commit { serial } => {
let current_serial = data
let current_serial = self
.handle
.inner
.lock()
@ -238,7 +237,7 @@ where
.map(|i| i.serial)
.unwrap_or(0);
data.text_input_handle.done(serial != current_serial);
self.text_input_handle.done(serial != current_serial);
}
zwp_input_method_v2::Request::GetInputPopupSurface { id, surface } => {
if compositor::give_role(&surface, INPUT_POPUP_SURFACE_ROLE).is_err()
@ -249,7 +248,7 @@ where
return;
}
let parent = match data.text_input_handle.focus().clone() {
let parent = match self.text_input_handle.focus().clone() {
Some(parent) => {
let location = state.parent_geometry(&parent);
Some(PopupParent {
@ -259,7 +258,7 @@ where
}
None => None,
};
let mut input_method = data.handle.inner.lock().unwrap();
let mut input_method = self.handle.inner.lock().unwrap();
let instance = data_init.init(
id,
@ -275,8 +274,8 @@ where
}
}
zwp_input_method_v2::Request::GrabKeyboard { keyboard } => {
let input_method = data.handle.inner.lock().unwrap();
data.keyboard_handle.set_grab(
let input_method = self.handle.inner.lock().unwrap();
self.keyboard_handle.set_grab(
state,
input_method.keyboard_grab.clone(),
SERIAL_COUNTER.next_serial(),
@ -285,15 +284,15 @@ where
keyboard,
InputMethodKeyboardUserData {
handle: input_method.keyboard_grab.clone(),
keyboard_handle: data.keyboard_handle.clone(),
keyboard_handle: self.keyboard_handle.clone(),
},
);
let mut keyboard = input_method.keyboard_grab.inner.lock().unwrap();
keyboard.grab = Some(instance.clone());
keyboard.text_input_handle = data.text_input_handle.clone();
let guard = data.keyboard_handle.arc.internal.lock().unwrap();
keyboard.text_input_handle = self.text_input_handle.clone();
let guard = self.keyboard_handle.arc.internal.lock().unwrap();
instance.repeat_info(guard.repeat_rate, guard.repeat_delay);
let keymap_file = data.keyboard_handle.arc.keymap.lock().unwrap();
let keymap_file = self.keyboard_handle.arc.keymap.lock().unwrap();
let res = keymap_file.with_fd(false, |fd, size| {
instance.keymap(KeymapFormat::XkbV1, fd, size as u32);
});
@ -320,13 +319,8 @@ where
}
}
fn destroyed(
_state: &mut D,
_client: ClientId,
_input_method: &ZwpInputMethodV2,
data: &InputMethodUserData<D>,
) {
data.handle.inner.lock().unwrap().instance = None;
data.text_input_handle.leave();
fn destroyed(&self, _state: &mut D, _client: ClientId, _input_method: &ZwpInputMethodV2) {
self.handle.inner.lock().unwrap().instance = None;
self.text_input_handle.leave();
}
}

View file

@ -6,7 +6,6 @@ use std::{
use wayland_protocols_misc::zwp_input_method_v2::server::zwp_input_method_keyboard_grab_v2::{
self, ZwpInputMethodKeyboardGrabV2,
};
use wayland_server::Dispatch;
use wayland_server::backend::ClientId;
use crate::input::{
@ -20,10 +19,9 @@ use crate::wayland::text_input::TextInputHandle;
use crate::{
backend::input::{KeyState, Keycode},
utils::Serial,
wayland::Dispatch2,
};
use super::InputMethodManagerState;
#[derive(Default, Debug)]
pub(crate) struct InputMethodKeyboard {
pub grab: Option<ZwpInputMethodKeyboardGrabV2>,
@ -100,25 +98,18 @@ impl<D: SeatHandler> fmt::Debug for InputMethodKeyboardUserData<D> {
}
}
impl<D: SeatHandler + 'static> Dispatch<ZwpInputMethodKeyboardGrabV2, InputMethodKeyboardUserData<D>, D>
for InputMethodManagerState
{
fn destroyed(
state: &mut D,
_client: ClientId,
_object: &ZwpInputMethodKeyboardGrabV2,
data: &InputMethodKeyboardUserData<D>,
) {
data.handle.inner.lock().unwrap().grab = None;
data.keyboard_handle.unset_grab(state);
impl<D: SeatHandler + 'static> Dispatch2<ZwpInputMethodKeyboardGrabV2, D> for InputMethodKeyboardUserData<D> {
fn destroyed(&self, state: &mut D, _client: ClientId, _object: &ZwpInputMethodKeyboardGrabV2) {
self.handle.inner.lock().unwrap().grab = None;
self.keyboard_handle.unset_grab(state);
}
fn request(
&self,
_state: &mut D,
_client: &wayland_server::Client,
_resource: &ZwpInputMethodKeyboardGrabV2,
request: zwp_input_method_keyboard_grab_v2::Request,
_data: &InputMethodKeyboardUserData<D>,
_dhandle: &wayland_server::DisplayHandle,
_data_init: &mut wayland_server::DataInit<'_, D>,
) {

View file

@ -3,15 +3,16 @@ use std::sync::{Arc, Mutex};
use wayland_protocols_misc::zwp_input_method_v2::server::zwp_input_popup_surface_v2::{
self, ZwpInputPopupSurfaceV2,
};
use wayland_server::{Dispatch, Resource, backend::ClientId, protocol::wl_surface::WlSurface};
use wayland_server::{Resource, backend::ClientId, protocol::wl_surface::WlSurface};
use crate::utils::{
Logical, Point, Rectangle,
alive_tracker::{AliveTracker, IsAlive},
use crate::{
utils::{
Logical, Point, Rectangle,
alive_tracker::{AliveTracker, IsAlive},
},
wayland::Dispatch2,
};
use super::InputMethodManagerState;
/// Handle to a popup surface
#[derive(Debug, Clone, Default)]
pub struct PopupHandle {
@ -129,13 +130,13 @@ pub struct InputMethodPopupSurfaceUserData {
pub(super) alive_tracker: AliveTracker,
}
impl<D> Dispatch<ZwpInputPopupSurfaceV2, InputMethodPopupSurfaceUserData, D> for InputMethodManagerState {
impl<D> Dispatch2<ZwpInputPopupSurfaceV2, D> for InputMethodPopupSurfaceUserData {
fn request(
&self,
_state: &mut D,
_client: &wayland_server::Client,
_resource: &ZwpInputPopupSurfaceV2,
request: zwp_input_popup_surface_v2::Request,
_data: &InputMethodPopupSurfaceUserData,
_dhandle: &wayland_server::DisplayHandle,
_data_init: &mut wayland_server::DataInit<'_, D>,
) {
@ -147,12 +148,7 @@ impl<D> Dispatch<ZwpInputPopupSurfaceV2, InputMethodPopupSurfaceUserData, D> for
}
}
fn destroyed(
_state: &mut D,
_client: ClientId,
_object: &ZwpInputPopupSurfaceV2,
data: &InputMethodPopupSurfaceUserData,
) {
data.alive_tracker.destroy_notify();
fn destroyed(&self, _state: &mut D, _client: ClientId, _object: &ZwpInputPopupSurfaceV2) {
self.alive_tracker.destroy_notify();
}
}

View file

@ -4,10 +4,6 @@
//! it must be used in conjunction with the text input module to work.
//!
//! ```
//! use smithay::{
//! delegate_seat, delegate_input_method_manager, delegate_text_input_manager,
//! # delegate_compositor,
//! };
//! use smithay::input::{Seat, SeatState, SeatHandler, pointer::CursorImageStatus};
//! # use smithay::wayland::compositor::{CompositorHandler, CompositorState, CompositorClientState};
//! use smithay::wayland::input_method::{InputMethodManagerState, InputMethodHandler, PopupSurface};
@ -18,9 +14,6 @@
//!
//! # struct State { seat_state: SeatState<Self> };
//!
//! delegate_seat!(State);
//! # delegate_compositor!(State);
//!
//! impl InputMethodHandler for State {
//! fn new_popup(&mut self, surface: PopupSurface) {}
//! fn dismiss_popup(&mut self, surface: PopupSurface) {}
@ -30,10 +23,7 @@
//! }
//! }
//!
//! // Delegate input method handling for State to InputMethodManagerState.
//! delegate_input_method_manager!(State);
//!
//! delegate_text_input_manager!(State);
//! smithay::delegate_dispatch2!(State);
//!
//! # let mut display = wayland_server::Display::<State>::new().unwrap();
//! # let display_handle = display.handle();
@ -78,6 +68,7 @@ use wayland_protocols_misc::zwp_input_method_v2::server::{
use crate::{
input::{Seat, SeatHandler},
utils::{Logical, Rectangle},
wayland::{Dispatch2, GlobalData, GlobalDispatch2},
};
pub use input_method_handle::{InputMethodHandle, InputMethodUserData};
@ -142,7 +133,7 @@ impl InputMethodManagerState {
pub fn new<D, F>(display: &DisplayHandle, filter: F) -> Self
where
D: GlobalDispatch<ZwpInputMethodManagerV2, InputMethodManagerGlobalData>,
D: Dispatch<ZwpInputMethodManagerV2, ()>,
D: Dispatch<ZwpInputMethodManagerV2, GlobalData>,
D: Dispatch<ZwpInputMethodV2, InputMethodUserData<D>>,
D: SeatHandler,
D: 'static,
@ -162,43 +153,41 @@ impl InputMethodManagerState {
}
}
impl<D> GlobalDispatch<ZwpInputMethodManagerV2, InputMethodManagerGlobalData, D> for InputMethodManagerState
impl<D> GlobalDispatch2<ZwpInputMethodManagerV2, D> for InputMethodManagerGlobalData
where
D: GlobalDispatch<ZwpInputMethodManagerV2, InputMethodManagerGlobalData>,
D: Dispatch<ZwpInputMethodManagerV2, ()>,
D: Dispatch<ZwpInputMethodManagerV2, GlobalData>,
D: Dispatch<ZwpInputMethodV2, InputMethodUserData<D>>,
D: SeatHandler,
D: 'static,
{
fn bind(
&self,
_: &mut D,
_: &DisplayHandle,
_: &Client,
resource: New<ZwpInputMethodManagerV2>,
_: &InputMethodManagerGlobalData,
data_init: &mut DataInit<'_, D>,
) {
data_init.init(resource, ());
data_init.init(resource, GlobalData);
}
fn can_view(client: Client, global_data: &InputMethodManagerGlobalData) -> bool {
(global_data.filter)(&client)
fn can_view(&self, client: &Client) -> bool {
(self.filter)(client)
}
}
impl<D> Dispatch<ZwpInputMethodManagerV2, (), D> for InputMethodManagerState
impl<D> Dispatch2<ZwpInputMethodManagerV2, D> for GlobalData
where
D: Dispatch<ZwpInputMethodManagerV2, ()>,
D: Dispatch<ZwpInputMethodV2, InputMethodUserData<D>>,
D: SeatHandler + InputMethodHandler,
D: 'static,
{
fn request(
&self,
_state: &mut D,
_client: &Client,
_: &ZwpInputMethodManagerV2,
request: zwp_input_method_manager_v2::Request,
_: &(),
_dh: &DisplayHandle,
data_init: &mut DataInit<'_, D>,
) {
@ -236,52 +225,3 @@ where
}
}
}
#[allow(missing_docs)] // TODO
#[macro_export]
macro_rules! delegate_input_method_manager {
($(@<$( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+>)? $ty: ty) => {
const _: () = {
use $crate::{
reexports::{
wayland_protocols_misc::zwp_input_method_v2::server::{
zwp_input_method_keyboard_grab_v2::ZwpInputMethodKeyboardGrabV2,
zwp_input_method_manager_v2::ZwpInputMethodManagerV2,
zwp_input_method_v2::ZwpInputMethodV2,
zwp_input_popup_surface_v2::ZwpInputPopupSurfaceV2,
},
wayland_server::{delegate_dispatch, delegate_global_dispatch},
},
wayland::input_method::{
InputMethodKeyboardUserData, InputMethodManagerGlobalData, InputMethodManagerState,
InputMethodPopupSurfaceUserData, InputMethodUserData,
},
};
delegate_global_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [ZwpInputMethodManagerV2: InputMethodManagerGlobalData] => InputMethodManagerState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [ZwpInputMethodManagerV2: ()] => InputMethodManagerState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [ZwpInputMethodV2: InputMethodUserData<Self>] => InputMethodManagerState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [ZwpInputMethodKeyboardGrabV2: InputMethodKeyboardUserData<Self>] => InputMethodManagerState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [ZwpInputPopupSurfaceV2: InputMethodPopupSurfaceUserData] => InputMethodManagerState
);
};
};
}

View file

@ -8,14 +8,17 @@ use wayland_protocols::wp::keyboard_shortcuts_inhibit::zv1::server::{
zwp_keyboard_shortcuts_inhibitor_v1::{self, ZwpKeyboardShortcutsInhibitorV1},
};
use wayland_server::{
Dispatch, GlobalDispatch, Resource,
Dispatch, Resource,
backend::{ClientId, ObjectId},
protocol::wl_surface::WlSurface,
};
use crate::input::{Seat, SeatHandler};
use crate::{
input::{Seat, SeatHandler},
wayland::{Dispatch2, GlobalData, GlobalDispatch2},
};
use super::{KeyboardShortcutsInhibitHandler, KeyboardShortcutsInhibitState};
use super::KeyboardShortcutsInhibitHandler;
/// User data of [ZwpKeyboardShortcutsInhibitorV1] object
#[derive(Debug)]
@ -27,37 +30,36 @@ pub struct KeyboardShortcutsInhibitorUserData {
pub(crate) is_active: AtomicBool,
}
impl<D> GlobalDispatch<ZwpKeyboardShortcutsInhibitManagerV1, (), D> for KeyboardShortcutsInhibitState
impl<D> GlobalDispatch2<ZwpKeyboardShortcutsInhibitManagerV1, D> for GlobalData
where
D: KeyboardShortcutsInhibitHandler,
D: Dispatch<ZwpKeyboardShortcutsInhibitManagerV1, ()>,
D: Dispatch<ZwpKeyboardShortcutsInhibitManagerV1, GlobalData>,
D: Dispatch<ZwpKeyboardShortcutsInhibitorV1, KeyboardShortcutsInhibitorUserData>,
{
fn bind(
&self,
_state: &mut D,
_handle: &wayland_server::DisplayHandle,
_client: &wayland_server::Client,
resource: wayland_server::New<ZwpKeyboardShortcutsInhibitManagerV1>,
_global_data: &(),
data_init: &mut wayland_server::DataInit<'_, D>,
) {
data_init.init(resource, ());
data_init.init(resource, GlobalData);
}
}
impl<D> Dispatch<ZwpKeyboardShortcutsInhibitManagerV1, (), D> for KeyboardShortcutsInhibitState
impl<D> Dispatch2<ZwpKeyboardShortcutsInhibitManagerV1, D> for GlobalData
where
D: KeyboardShortcutsInhibitHandler,
D: SeatHandler,
D: Dispatch<ZwpKeyboardShortcutsInhibitManagerV1, ()>,
D: Dispatch<ZwpKeyboardShortcutsInhibitorV1, KeyboardShortcutsInhibitorUserData>,
{
fn request(
&self,
handler: &mut D,
_client: &wayland_server::Client,
resource: &ZwpKeyboardShortcutsInhibitManagerV1,
request: zwp_keyboard_shortcuts_inhibit_manager_v1::Request,
_data: &(),
_dhandle: &wayland_server::DisplayHandle,
data_init: &mut wayland_server::DataInit<'_, D>,
) {
@ -109,17 +111,16 @@ where
}
}
impl<D> Dispatch<ZwpKeyboardShortcutsInhibitorV1, KeyboardShortcutsInhibitorUserData, D>
for KeyboardShortcutsInhibitState
impl<D> Dispatch2<ZwpKeyboardShortcutsInhibitorV1, D> for KeyboardShortcutsInhibitorUserData
where
D: KeyboardShortcutsInhibitHandler,
{
fn request(
&self,
_handler: &mut D,
_client: &wayland_server::Client,
_inhibitor: &ZwpKeyboardShortcutsInhibitorV1,
request: zwp_keyboard_shortcuts_inhibitor_v1::Request,
_data: &KeyboardShortcutsInhibitorUserData,
_dhandle: &wayland_server::DisplayHandle,
_data_init: &mut wayland_server::DataInit<'_, D>,
) {
@ -129,17 +130,12 @@ where
}
}
fn destroyed(
handler: &mut D,
_client: ClientId,
wl_inhibitor: &ZwpKeyboardShortcutsInhibitorV1,
data: &KeyboardShortcutsInhibitorUserData,
) {
data.is_active.store(false, atomic::Ordering::Release);
fn destroyed(&self, handler: &mut D, _client: ClientId, wl_inhibitor: &ZwpKeyboardShortcutsInhibitorV1) {
self.is_active.store(false, atomic::Ordering::Release);
let state = handler.keyboard_shortcuts_inhibit_state();
if let Entry::Occupied(mut entry) = state.inhibitors.entry(data.seat.clone()) {
if let Entry::Occupied(mut entry) = state.inhibitors.entry(self.seat.clone()) {
let inhibitor = entry.get_mut().borrow_mut().remove(wl_inhibitor.id());
if entry.get().borrow().is_empty() {

View file

@ -18,7 +18,10 @@ use wayland_server::{
mod dispatch;
pub use dispatch::KeyboardShortcutsInhibitorUserData;
use crate::input::{Seat, SeatHandler};
use crate::{
input::{Seat, SeatHandler},
wayland::GlobalData,
};
type SeatId = ObjectId;
@ -68,12 +71,13 @@ impl KeyboardShortcutsInhibitState {
/// Regiseter new [ZwpKeyboardShortcutsInhibitManagerV1] global
pub fn new<D>(display: &DisplayHandle) -> Self
where
D: GlobalDispatch<ZwpKeyboardShortcutsInhibitManagerV1, ()>,
D: Dispatch<ZwpKeyboardShortcutsInhibitManagerV1, ()>,
D: GlobalDispatch<ZwpKeyboardShortcutsInhibitManagerV1, GlobalData>,
D: Dispatch<ZwpKeyboardShortcutsInhibitManagerV1, GlobalData>,
D: Dispatch<ZwpKeyboardShortcutsInhibitorV1, KeyboardShortcutsInhibitorUserData>,
D: 'static,
{
let manager_global = display.create_global::<D, ZwpKeyboardShortcutsInhibitManagerV1, _>(1, ());
let manager_global =
display.create_global::<D, ZwpKeyboardShortcutsInhibitManagerV1, _>(1, GlobalData);
Self {
manager_global,
inhibitors: HashMap::new(),
@ -236,41 +240,3 @@ pub trait KeyboardShortcutsInhibitHandler {
/// Inhibitor got destroyed
fn inhibitor_destroyed(&mut self, inhibitor: KeyboardShortcutsInhibitor) {}
}
/// Macro to delegate implementation of the keyboard shortcuts inhibit protocol
///
/// You must also implement [`KeyboardShortcutsInhibitHandler`] to use this.
#[macro_export]
macro_rules! delegate_keyboard_shortcuts_inhibit {
($(@<$( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+>)? $ty: ty) => {
const _: () = {
use $crate::{
reexports::{
wayland_protocols::wp::keyboard_shortcuts_inhibit::zv1::server::{
zwp_keyboard_shortcuts_inhibit_manager_v1::ZwpKeyboardShortcutsInhibitManagerV1,
zwp_keyboard_shortcuts_inhibitor_v1::ZwpKeyboardShortcutsInhibitorV1,
},
wayland_server::{delegate_dispatch, delegate_global_dispatch},
},
wayland::keyboard_shortcuts_inhibit::{
KeyboardShortcutsInhibitState, KeyboardShortcutsInhibitorUserData,
},
};
delegate_global_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [ZwpKeyboardShortcutsInhibitManagerV1: ()] => KeyboardShortcutsInhibitState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [ZwpKeyboardShortcutsInhibitManagerV1: ()] => KeyboardShortcutsInhibitState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [ZwpKeyboardShortcutsInhibitorV1: KeyboardShortcutsInhibitorUserData] => KeyboardShortcutsInhibitState
);
};
};
}

View file

@ -54,6 +54,8 @@ pub mod commit_timing;
pub mod compositor;
pub mod content_type;
pub mod cursor_shape;
mod dispatch2;
pub use dispatch2::{Dispatch2, GlobalDispatch2};
pub mod dmabuf;
#[cfg(feature = "backend_drm")]
pub mod drm_lease;
@ -96,3 +98,7 @@ pub mod xdg_toplevel_tag;
pub mod xwayland_keyboard_grab;
#[cfg(feature = "xwayland")]
pub mod xwayland_shell;
/// Empty user-data
#[derive(Debug)]
pub struct GlobalData;

View file

@ -7,45 +7,44 @@ use wayland_protocols::xdg::xdg_output::zv1::server::{
zxdg_output_v1::{self, ZxdgOutputV1},
};
use wayland_server::{
Client, DataInit, Dispatch, DisplayHandle, GlobalDispatch, New, Resource,
Client, DataInit, Dispatch, DisplayHandle, New, Resource,
protocol::wl_output::{self, Mode as WMode, WlOutput},
};
use crate::wayland::compositor::CompositorHandler;
use crate::wayland::{Dispatch2, GlobalData, GlobalDispatch2, compositor::CompositorHandler};
use super::{Output, OutputHandler, OutputManagerState, OutputUserData, WlOutputData, xdg::XdgOutput};
use super::{Output, OutputHandler, OutputUserData, WlOutputData, xdg::XdgOutput};
/*
* Wl Output
*/
impl<D> GlobalDispatch<WlOutput, WlOutputData, D> for OutputManagerState
impl<D> GlobalDispatch2<WlOutput, D> for WlOutputData
where
D: GlobalDispatch<WlOutput, WlOutputData>,
D: Dispatch<WlOutput, OutputUserData>,
D: OutputHandler,
D: CompositorHandler,
D: 'static,
{
fn bind(
&self,
state: &mut D,
_dh: &DisplayHandle,
client: &Client,
resource: New<WlOutput>,
global_data: &WlOutputData,
data_init: &mut DataInit<'_, D>,
) {
let client_scale = state.client_compositor_state(client).clone_client_scale();
let output = data_init.init(
resource,
OutputUserData {
output: global_data.output.downgrade(),
output: self.output.downgrade(),
last_client_scale: AtomicF64::new(client_scale.load(Ordering::Acquire)),
client_scale,
},
);
let mut inner = global_data.output.inner.0.lock().unwrap();
let mut inner = self.output.inner.0.lock().unwrap();
let span = warn_span!("output_bind", name = inner.name);
let _enter = span.enter();
@ -97,32 +96,24 @@ where
inner.instances.push(output.downgrade());
drop(inner);
state.output_bound(global_data.output.clone(), output);
state.output_bound(self.output.clone(), output);
}
}
impl<D> Dispatch<WlOutput, OutputUserData, D> for OutputManagerState
where
D: Dispatch<WlOutput, OutputUserData>,
{
impl<D> Dispatch2<WlOutput, D> for OutputUserData {
fn request(
&self,
_state: &mut D,
_client: &Client,
_resource: &WlOutput,
_request: wl_output::Request,
_data: &OutputUserData,
_dhandle: &DisplayHandle,
_data_init: &mut DataInit<'_, D>,
) {
}
fn destroyed(
_state: &mut D,
_client_id: wayland_server::backend::ClientId,
output: &WlOutput,
data: &OutputUserData,
) {
if let Some(o) = data.output.upgrade() {
fn destroyed(&self, _state: &mut D, _client_id: wayland_server::backend::ClientId, output: &WlOutput) {
if let Some(o) = self.output.upgrade() {
o.inner
.0
.lock()
@ -137,38 +128,36 @@ where
* XDG Output
*/
impl<D> GlobalDispatch<ZxdgOutputManagerV1, (), D> for OutputManagerState
impl<D> GlobalDispatch2<ZxdgOutputManagerV1, D> for GlobalData
where
D: GlobalDispatch<ZxdgOutputManagerV1, ()>,
D: Dispatch<ZxdgOutputManagerV1, ()>,
D: Dispatch<ZxdgOutputManagerV1, GlobalData>,
D: Dispatch<ZxdgOutputV1, XdgOutputUserData>,
D: 'static,
{
fn bind(
&self,
_state: &mut D,
_handle: &DisplayHandle,
_client: &Client,
resource: New<ZxdgOutputManagerV1>,
_global_data: &(),
data_init: &mut DataInit<'_, D>,
) {
data_init.init(resource, ());
data_init.init(resource, GlobalData);
}
}
impl<D> Dispatch<ZxdgOutputManagerV1, (), D> for OutputManagerState
impl<D> Dispatch2<ZxdgOutputManagerV1, D> for GlobalData
where
D: Dispatch<ZxdgOutputManagerV1, ()>,
D: Dispatch<ZxdgOutputV1, XdgOutputUserData>,
D: CompositorHandler,
D: 'static,
{
fn request(
&self,
state: &mut D,
client: &Client,
_resource: &ZxdgOutputManagerV1,
request: zxdg_output_manager_v1::Request,
_data: &(),
_dh: &DisplayHandle,
data_init: &mut DataInit<'_, D>,
) {
@ -212,28 +201,25 @@ pub struct XdgOutputUserData {
pub(super) client_scale: Arc<AtomicF64>,
}
impl<D> Dispatch<ZxdgOutputV1, XdgOutputUserData, D> for OutputManagerState
where
D: Dispatch<ZxdgOutputV1, XdgOutputUserData>,
{
impl<D> Dispatch2<ZxdgOutputV1, D> for XdgOutputUserData {
fn request(
&self,
_state: &mut D,
_client: &Client,
_resource: &ZxdgOutputV1,
_request: zxdg_output_v1::Request,
_data: &XdgOutputUserData,
_dhandle: &DisplayHandle,
_data_init: &mut DataInit<'_, D>,
) {
}
fn destroyed(
&self,
_state: &mut D,
_client_id: wayland_server::backend::ClientId,
xdg_output: &ZxdgOutputV1,
data: &XdgOutputUserData,
) {
data.xdg_output
self.xdg_output
.inner
.lock()
.unwrap()

View file

@ -21,8 +21,6 @@
//! ```
//! # extern crate wayland_server;
//! # extern crate smithay;
//! use smithay::delegate_output;
//! # use smithay::delegate_compositor;
//! use smithay::output::{Output, PhysicalProperties, Scale, Mode, Subpixel};
//! use smithay::utils::Transform;
//! use smithay::wayland::output::OutputHandler;
@ -67,8 +65,7 @@
//! # fn commit(&mut self, surface: &WlSurface) {}
//! # }
//!
//! delegate_output!(State);
//! # delegate_compositor!(State);
//! smithay::delegate_dispatch2!(State);
//! ```
mod handlers;
@ -94,7 +91,10 @@ use wayland_server::{
},
};
use crate::utils::{Logical, Point};
use crate::{
utils::{Logical, Point},
wayland::GlobalData,
};
pub use self::handlers::XdgOutputUserData;
@ -128,10 +128,10 @@ impl OutputManagerState {
pub fn new_with_xdg_output<D>(display: &DisplayHandle) -> Self
where
D: GlobalDispatch<WlOutput, WlOutputData>,
D: GlobalDispatch<ZxdgOutputManagerV1, ()>,
D: GlobalDispatch<ZxdgOutputManagerV1, GlobalData>,
D: 'static,
{
let xdg_output_manager = display.create_global::<D, ZxdgOutputManagerV1, _>(3, ());
let xdg_output_manager = display.create_global::<D, ZxdgOutputManagerV1, _>(3, GlobalData);
Self {
xdg_output_manager: Some(xdg_output_manager),
@ -351,48 +351,3 @@ impl Output {
inner.surfaces.retain(|s| s.is_alive());
}
}
#[allow(missing_docs)] // TODO
#[macro_export]
macro_rules! delegate_output {
($(@<$( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+>)? $ty: ty) => {
const _: () = {
use $crate::{
reexports::{
wayland_protocols::xdg::xdg_output::zv1::server::{
zxdg_output_manager_v1::ZxdgOutputManagerV1, zxdg_output_v1::ZxdgOutputV1,
},
wayland_server::{
delegate_dispatch, delegate_global_dispatch, protocol::wl_output::WlOutput,
},
},
wayland::output::{OutputManagerState, OutputUserData, WlOutputData, XdgOutputUserData},
};
delegate_global_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [WlOutput: WlOutputData] => OutputManagerState
);
delegate_global_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [ZxdgOutputManagerV1: ()] => OutputManagerState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [WlOutput: OutputUserData] => OutputManagerState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [ZxdgOutputV1: XdgOutputUserData] => OutputManagerState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [ZxdgOutputManagerV1: ()] => OutputManagerState
);
};
};
}

View file

@ -25,7 +25,7 @@ use super::compositor::{self, RegionAttributes};
use crate::{
input::{SeatHandler, pointer::PointerHandle},
utils::{Logical, Point},
wayland::seat::PointerUserData,
wayland::{Dispatch2, GlobalData, GlobalDispatch2, seat::PointerUserData},
};
const VERSION: u32 = 1;
@ -220,14 +220,14 @@ impl PointerConstraintsState {
/// Create a new pointer constraints global
pub fn new<D>(display: &DisplayHandle) -> Self
where
D: GlobalDispatch<ZwpPointerConstraintsV1, ()>,
D: Dispatch<ZwpPointerConstraintsV1, ()>,
D: GlobalDispatch<ZwpPointerConstraintsV1, GlobalData>,
D: Dispatch<ZwpPointerConstraintsV1, GlobalData>,
D: Dispatch<ZwpConfinedPointerV1, PointerConstraintUserData<D>>,
D: Dispatch<ZwpLockedPointerV1, PointerConstraintUserData<D>>,
D: SeatHandler,
D: 'static,
{
let global = display.create_global::<D, ZwpPointerConstraintsV1, _>(VERSION, ());
let global = display.create_global::<D, ZwpPointerConstraintsV1, _>(VERSION, GlobalData);
Self { global }
}
@ -352,9 +352,8 @@ fn remove_constraint<D: SeatHandler + 'static>(surface: &WlSurface, pointer: &Po
});
}
impl<D> Dispatch<ZwpPointerConstraintsV1, (), D> for PointerConstraintsState
impl<D> Dispatch2<ZwpPointerConstraintsV1, D> for GlobalData
where
D: Dispatch<ZwpPointerConstraintsV1, ()>,
D: Dispatch<ZwpConfinedPointerV1, PointerConstraintUserData<D>>,
D: Dispatch<ZwpLockedPointerV1, PointerConstraintUserData<D>>,
D: SeatHandler,
@ -362,11 +361,11 @@ where
D: 'static,
{
fn request(
&self,
state: &mut D,
_client: &wayland_server::Client,
pointer_constraints: &ZwpPointerConstraintsV1,
request: zwp_pointer_constraints_v1::Request,
_data: &(),
_dh: &DisplayHandle,
data_init: &mut wayland_server::DataInit<'_, D>,
) {
@ -443,47 +442,43 @@ where
}
}
impl<D> GlobalDispatch<ZwpPointerConstraintsV1, (), D> for PointerConstraintsState
impl<D> GlobalDispatch2<ZwpPointerConstraintsV1, D> for GlobalData
where
D: GlobalDispatch<ZwpPointerConstraintsV1, ()>
+ Dispatch<ZwpPointerConstraintsV1, ()>
+ SeatHandler
+ 'static,
D: Dispatch<ZwpPointerConstraintsV1, GlobalData> + SeatHandler + 'static,
{
fn bind(
&self,
_state: &mut D,
_dh: &DisplayHandle,
_client: &Client,
resource: New<ZwpPointerConstraintsV1>,
_global_data: &(),
data_init: &mut DataInit<'_, D>,
) {
data_init.init(resource, ());
data_init.init(resource, GlobalData);
}
}
impl<D> Dispatch<ZwpConfinedPointerV1, PointerConstraintUserData<D>, D> for PointerConstraintsState
impl<D> Dispatch2<ZwpConfinedPointerV1, D> for PointerConstraintUserData<D>
where
D: Dispatch<ZwpConfinedPointerV1, PointerConstraintUserData<D>>,
D: SeatHandler,
D: 'static,
{
fn request(
&self,
_state: &mut D,
_client: &wayland_server::Client,
_confined_pointer: &ZwpConfinedPointerV1,
request: zwp_confined_pointer_v1::Request,
data: &PointerConstraintUserData<D>,
_dh: &DisplayHandle,
_data_init: &mut wayland_server::DataInit<'_, D>,
) {
let Some(pointer) = &data.pointer else {
let Some(pointer) = &self.pointer else {
return;
};
match request {
zwp_confined_pointer_v1::Request::SetRegion { region } => {
with_pointer_constraint(&data.surface, pointer, |constraint| {
with_pointer_constraint(&self.surface, pointer, |constraint| {
if let Some(PointerConstraint::Confined(confined)) =
constraint.map(|x| x.entry.into_mut())
{
@ -497,48 +492,47 @@ where
}
fn destroyed(
&self,
_state: &mut D,
_client: wayland_server::backend::ClientId,
_resource: &ZwpConfinedPointerV1,
data: &PointerConstraintUserData<D>,
) {
let Some(pointer) = &data.pointer else {
let Some(pointer) = &self.pointer else {
return;
};
remove_constraint(&data.surface, pointer);
remove_constraint(&self.surface, pointer);
}
}
impl<D> Dispatch<ZwpLockedPointerV1, PointerConstraintUserData<D>, D> for PointerConstraintsState
impl<D> Dispatch2<ZwpLockedPointerV1, D> for PointerConstraintUserData<D>
where
D: Dispatch<ZwpLockedPointerV1, PointerConstraintUserData<D>>,
D: SeatHandler,
D: 'static,
{
fn request(
&self,
_state: &mut D,
_client: &wayland_server::Client,
_locked_pointer: &ZwpLockedPointerV1,
request: zwp_locked_pointer_v1::Request,
data: &PointerConstraintUserData<D>,
_dh: &DisplayHandle,
_data_init: &mut wayland_server::DataInit<'_, D>,
) {
let Some(pointer) = &data.pointer else {
let Some(pointer) = &self.pointer else {
return;
};
match request {
zwp_locked_pointer_v1::Request::SetCursorPositionHint { surface_x, surface_y } => {
with_pointer_constraint(&data.surface, pointer, |constraint| {
with_pointer_constraint(&self.surface, pointer, |constraint| {
if let Some(PointerConstraint::Locked(locked)) = constraint.map(|x| x.entry.into_mut()) {
locked.pending_cursor_position_hint = Some((surface_x, surface_y).into());
}
});
}
zwp_locked_pointer_v1::Request::SetRegion { region } => {
with_pointer_constraint(&data.surface, pointer, |constraint| {
with_pointer_constraint(&self.surface, pointer, |constraint| {
if let Some(PointerConstraint::Locked(locked)) = constraint.map(|x| x.entry.into_mut()) {
locked.pending_region = region.as_ref().map(compositor::get_region_attributes);
}
@ -550,55 +544,15 @@ where
}
fn destroyed(
&self,
_state: &mut D,
_client: wayland_server::backend::ClientId,
_resource: &ZwpLockedPointerV1,
data: &PointerConstraintUserData<D>,
) {
let Some(pointer) = &data.pointer else {
let Some(pointer) = &self.pointer else {
return;
};
remove_constraint(&data.surface, pointer);
remove_constraint(&self.surface, pointer);
}
}
#[allow(missing_docs)]
#[macro_export]
macro_rules! delegate_pointer_constraints {
($(@<$( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+>)? $ty: ty) => {
const _: () = {
use $crate::{
reexports::{
wayland_protocols::wp::pointer_constraints::zv1::server::{
zwp_confined_pointer_v1::ZwpConfinedPointerV1,
zwp_locked_pointer_v1::ZwpLockedPointerV1,
zwp_pointer_constraints_v1::ZwpPointerConstraintsV1,
},
wayland_server::{delegate_dispatch, delegate_global_dispatch},
},
wayland::pointer_constraints::{PointerConstraintUserData, PointerConstraintsState},
};
delegate_global_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [ZwpPointerConstraintsV1: ()] => PointerConstraintsState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [ZwpPointerConstraintsV1: ()] => PointerConstraintsState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [ZwpConfinedPointerV1: PointerConstraintUserData<Self>] => PointerConstraintsState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [ZwpLockedPointerV1: PointerConstraintUserData<Self>] => PointerConstraintsState
);
};
};
}

View file

@ -20,7 +20,6 @@
//! extern crate smithay;
//!
//! use smithay::wayland::pointer_gestures::PointerGesturesState;
//! use smithay::delegate_pointer_gestures;
//! # use smithay::backend::input::KeyState;
//! # use smithay::input::{
//! # pointer::{PointerTarget, AxisFrame, MotionEvent, ButtonEvent, RelativeMotionEvent,
@ -93,7 +92,7 @@
//! # }
//! let state = PointerGesturesState::new::<State>(&display.handle());
//!
//! delegate_pointer_gestures!(State);
//! smithay::delegate_dispatch2!(State);
//! ```
use std::sync::{Arc, Mutex, atomic::Ordering};
@ -121,7 +120,7 @@ use crate::{
},
},
utils::{SERIAL_COUNTER, Serial},
wayland::seat::PointerUserData,
wayland::{Dispatch2, GlobalData, GlobalDispatch2, seat::PointerUserData},
};
const MANAGER_VERSION: u32 = 3;
@ -379,15 +378,15 @@ impl PointerGesturesState {
/// Register new [ZwpPointerGesturesV1] global
pub fn new<D>(display: &DisplayHandle) -> Self
where
D: GlobalDispatch<ZwpPointerGesturesV1, ()>,
D: Dispatch<ZwpPointerGesturesV1, ()>,
D: GlobalDispatch<ZwpPointerGesturesV1, GlobalData>,
D: Dispatch<ZwpPointerGesturesV1, GlobalData>,
D: Dispatch<ZwpPointerGestureSwipeV1, PointerGestureUserData<D>>,
D: Dispatch<ZwpPointerGesturePinchV1, PointerGestureUserData<D>>,
D: Dispatch<ZwpPointerGestureHoldV1, PointerGestureUserData<D>>,
D: SeatHandler,
D: 'static,
{
let global = display.create_global::<D, ZwpPointerGesturesV1, _>(MANAGER_VERSION, ());
let global = display.create_global::<D, ZwpPointerGesturesV1, _>(MANAGER_VERSION, GlobalData);
Self { global }
}
@ -398,9 +397,8 @@ impl PointerGesturesState {
}
}
impl<D> Dispatch<ZwpPointerGesturesV1, (), D> for PointerGesturesState
impl<D> Dispatch2<ZwpPointerGesturesV1, D> for GlobalData
where
D: Dispatch<ZwpPointerGesturesV1, ()>,
D: Dispatch<ZwpPointerGestureSwipeV1, PointerGestureUserData<D>>,
D: Dispatch<ZwpPointerGesturePinchV1, PointerGestureUserData<D>>,
D: Dispatch<ZwpPointerGestureHoldV1, PointerGestureUserData<D>>,
@ -408,11 +406,11 @@ where
D: 'static,
{
fn request(
&self,
_state: &mut D,
_client: &wayland_server::Client,
_pointer_gestures: &ZwpPointerGesturesV1,
request: zwp_pointer_gestures_v1::Request,
_data: &(),
_dh: &DisplayHandle,
data_init: &mut wayland_server::DataInit<'_, D>,
) {
@ -459,34 +457,33 @@ where
}
}
impl<D> GlobalDispatch<ZwpPointerGesturesV1, (), D> for PointerGesturesState
impl<D> GlobalDispatch2<ZwpPointerGesturesV1, D> for GlobalData
where
D: GlobalDispatch<ZwpPointerGesturesV1, ()> + Dispatch<ZwpPointerGesturesV1, ()> + SeatHandler + 'static,
D: Dispatch<ZwpPointerGesturesV1, GlobalData> + SeatHandler + 'static,
{
fn bind(
&self,
_state: &mut D,
_dh: &DisplayHandle,
_client: &Client,
resource: New<ZwpPointerGesturesV1>,
_global_data: &(),
data_init: &mut DataInit<'_, D>,
) {
data_init.init(resource, ());
data_init.init(resource, GlobalData);
}
}
impl<D> Dispatch<ZwpPointerGestureSwipeV1, PointerGestureUserData<D>, D> for PointerGesturesState
impl<D> Dispatch2<ZwpPointerGestureSwipeV1, D> for PointerGestureUserData<D>
where
D: Dispatch<ZwpPointerGestureSwipeV1, PointerGestureUserData<D>>,
D: SeatHandler,
D: 'static,
{
fn request(
&self,
_state: &mut D,
_client: &wayland_server::Client,
_gesture: &ZwpPointerGestureSwipeV1,
request: zwp_pointer_gesture_swipe_v1::Request,
_data: &PointerGestureUserData<D>,
_dh: &DisplayHandle,
_data_init: &mut wayland_server::DataInit<'_, D>,
) {
@ -496,13 +493,8 @@ where
}
}
fn destroyed(
_state: &mut D,
_: ClientId,
object: &ZwpPointerGestureSwipeV1,
data: &PointerGestureUserData<D>,
) {
if let Some(ref handle) = data.handle {
fn destroyed(&self, _state: &mut D, _: ClientId, object: &ZwpPointerGestureSwipeV1) {
if let Some(ref handle) = self.handle {
handle
.wp_pointer_gestures
.known_swipe_gestures
@ -513,18 +505,17 @@ where
}
}
impl<D> Dispatch<ZwpPointerGesturePinchV1, PointerGestureUserData<D>, D> for PointerGesturesState
impl<D> Dispatch2<ZwpPointerGesturePinchV1, D> for PointerGestureUserData<D>
where
D: Dispatch<ZwpPointerGesturePinchV1, PointerGestureUserData<D>>,
D: SeatHandler,
D: 'static,
{
fn request(
&self,
_state: &mut D,
_client: &wayland_server::Client,
_gesture: &ZwpPointerGesturePinchV1,
request: zwp_pointer_gesture_pinch_v1::Request,
_data: &PointerGestureUserData<D>,
_dh: &DisplayHandle,
_data_init: &mut wayland_server::DataInit<'_, D>,
) {
@ -534,13 +525,8 @@ where
}
}
fn destroyed(
_state: &mut D,
_: ClientId,
object: &ZwpPointerGesturePinchV1,
data: &PointerGestureUserData<D>,
) {
if let Some(ref handle) = data.handle {
fn destroyed(&self, _state: &mut D, _: ClientId, object: &ZwpPointerGesturePinchV1) {
if let Some(ref handle) = self.handle {
handle
.wp_pointer_gestures
.known_pinch_gestures
@ -551,18 +537,17 @@ where
}
}
impl<D> Dispatch<ZwpPointerGestureHoldV1, PointerGestureUserData<D>, D> for PointerGesturesState
impl<D> Dispatch2<ZwpPointerGestureHoldV1, D> for PointerGestureUserData<D>
where
D: Dispatch<ZwpPointerGestureHoldV1, PointerGestureUserData<D>>,
D: SeatHandler,
D: 'static,
{
fn request(
&self,
_state: &mut D,
_client: &wayland_server::Client,
_gesture: &ZwpPointerGestureHoldV1,
request: zwp_pointer_gesture_hold_v1::Request,
_data: &PointerGestureUserData<D>,
_dh: &DisplayHandle,
_data_init: &mut wayland_server::DataInit<'_, D>,
) {
@ -572,13 +557,8 @@ where
}
}
fn destroyed(
_state: &mut D,
_: ClientId,
object: &ZwpPointerGestureHoldV1,
data: &PointerGestureUserData<D>,
) {
if let Some(ref handle) = data.handle {
fn destroyed(&self, _state: &mut D, _: ClientId, object: &ZwpPointerGestureHoldV1) {
if let Some(ref handle) = self.handle {
handle
.wp_pointer_gestures
.known_hold_gestures
@ -588,49 +568,3 @@ where
}
}
}
/// Macro to delegate implementation of the pointer gestures protocol
#[macro_export]
macro_rules! delegate_pointer_gestures {
($(@<$( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+>)? $ty: ty) => {
const _: () = {
use $crate::{
reexports::{
wayland_protocols::wp::pointer_gestures::zv1::server::{
zwp_pointer_gesture_hold_v1::ZwpPointerGestureHoldV1,
zwp_pointer_gesture_pinch_v1::ZwpPointerGesturePinchV1,
zwp_pointer_gesture_swipe_v1::ZwpPointerGestureSwipeV1,
zwp_pointer_gestures_v1::ZwpPointerGesturesV1,
},
wayland_server::{delegate_dispatch, delegate_global_dispatch},
},
wayland::pointer_gestures::{PointerGestureUserData, PointerGesturesState},
};
delegate_global_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [ZwpPointerGesturesV1: ()] => PointerGesturesState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [ZwpPointerGesturesV1: ()] => PointerGesturesState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [ZwpPointerGestureSwipeV1: PointerGestureUserData<Self>] => PointerGesturesState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [ZwpPointerGesturePinchV1: PointerGestureUserData<Self>] => PointerGesturesState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [ZwpPointerGestureHoldV1: PointerGestureUserData<Self>] => PointerGesturesState
);
};
};
}

View file

@ -3,14 +3,12 @@
//! This global interface allows applications to request the pointer to be moved to a position
//! relative to a wl_surface.
//!
//! In order to advertise pointer warp global call [PointerWarpManager::new] and delegate
//! events to it with [`delegate_pointer_warp`](crate::delegate_pointer_warp).
//! In order to advertise pointer warp global call [PointerWarpManager::new].
//!
//! ```
//! use smithay::wayland::pointer_warp::{PointerWarpManager, PointerWarpHandler};
//! use wayland_server::protocol::wl_surface::WlSurface;
//! use wayland_server::protocol::wl_pointer::WlPointer;
//! use smithay::delegate_pointer_warp;
//! use smithay::utils::{Serial, Logical, Point};
//!
//! # struct State;
@ -23,7 +21,6 @@
//! # fn client_compositor_state<'a>(&self, client: &'a Client) -> &'a CompositorClientState { unimplemented!() }
//! # fn commit(&mut self, surface: &WlSurface) {}
//! # }
//! # smithay::delegate_compositor!(State);
//! #
//! # impl smithay::input::SeatHandler for State {
//! # type KeyboardFocus = WlSurface;
@ -33,7 +30,6 @@
//! # todo!()
//! # }
//! # }
//! # smithay::delegate_seat!(State);
//!
//! PointerWarpManager::new::<State>(
//! &display.handle(),
@ -45,7 +41,7 @@
//! }
//! }
//!
//! delegate_pointer_warp!(State);
//! smithay::delegate_dispatch2!(State);
//! ```
use std::sync::atomic::Ordering;
@ -60,13 +56,11 @@ use wayland_server::{
use crate::{
input::SeatHandler,
utils::{Client as ClientCords, Logical, Point, Serial},
wayland::seat::PointerUserData,
wayland::{Dispatch2, GlobalData, GlobalDispatch2, seat::PointerUserData},
};
/// Handler trait for pointer warp events.
pub trait PointerWarpHandler:
SeatHandler + GlobalDispatch<WpPointerWarpV1, ()> + Dispatch<WpPointerWarpV1, ()> + 'static
{
pub trait PointerWarpHandler: SeatHandler + 'static {
/// Request the compositor to move the pointer to a surface-local position.
/// Whether or not the compositor honors the request is implementation defined, but it should
/// - honor it if the surface has pointer focus, including when it has an implicit pointer grab
@ -95,8 +89,11 @@ pub struct PointerWarpManager {
impl PointerWarpManager {
/// Creates a new delegate type for handling [WpPointerWarpV1] events.
pub fn new<D: PointerWarpHandler>(display: &DisplayHandle) -> Self {
let global = display.create_global::<D, WpPointerWarpV1, _>(1, ());
pub fn new<D>(display: &DisplayHandle) -> Self
where
D: PointerWarpHandler + GlobalDispatch<WpPointerWarpV1, GlobalData>,
{
let global = display.create_global::<D, WpPointerWarpV1, _>(1, GlobalData);
Self { global }
}
@ -106,26 +103,29 @@ impl PointerWarpManager {
}
}
impl<D: PointerWarpHandler> GlobalDispatch<WpPointerWarpV1, (), D> for PointerWarpManager {
impl<D: PointerWarpHandler> GlobalDispatch2<WpPointerWarpV1, D> for GlobalData
where
D: Dispatch<WpPointerWarpV1, GlobalData>,
{
fn bind(
&self,
_state: &mut D,
_handle: &DisplayHandle,
_client: &Client,
resource: New<WpPointerWarpV1>,
_global_data: &(),
data_init: &mut DataInit<'_, D>,
) {
data_init.init(resource, ());
data_init.init(resource, GlobalData);
}
}
impl<D: PointerWarpHandler> Dispatch<WpPointerWarpV1, (), D> for PointerWarpManager {
impl<D: PointerWarpHandler> Dispatch2<WpPointerWarpV1, D> for GlobalData {
fn request(
&self,
state: &mut D,
_client: &Client,
_resource: &WpPointerWarpV1,
request: wp_pointer_warp_v1::Request,
_data: &(),
_dhandle: &DisplayHandle,
_data_init: &mut DataInit<'_, D>,
) {
@ -154,56 +154,3 @@ impl<D: PointerWarpHandler> Dispatch<WpPointerWarpV1, (), D> for PointerWarpMana
}
}
}
/// Macro to delegate implementation of the pointer warp protocol to [`PointerWarpManager`].
///
/// You must also implement [`PointerWarpHandler`] to use this.
#[macro_export]
macro_rules! delegate_pointer_warp {
($(@<$( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+>)? $ty: ty) => {
const _: () = {
use $crate::{
reexports::{
wayland_protocols::wp::pointer_warp::v1::server::wp_pointer_warp_v1::WpPointerWarpV1,
wayland_server::{delegate_dispatch, delegate_global_dispatch},
},
wayland::pointer_warp::PointerWarpManager,
};
delegate_global_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [WpPointerWarpV1: ()] => PointerWarpManager
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [WpPointerWarpV1: ()] => PointerWarpManager
);
};
};
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn delegate_pointer_warp_macro() {
struct State;
delegate_pointer_warp!(State);
impl SeatHandler for State {
type KeyboardFocus = WlSurface;
type PointerFocus = WlSurface;
type TouchFocus = WlSurface;
fn seat_state(&mut self) -> &mut crate::input::SeatState<Self> {
todo!()
}
}
// `PointerWarpHandler` can only be implemented if the macro works
impl PointerWarpHandler for State {}
fn is_delegated<T: PointerWarpHandler>() {}
is_delegated::<State>();
}
}

View file

@ -9,7 +9,6 @@
//!
//! ```
//! use smithay::wayland::presentation::PresentationState;
//! use smithay::delegate_presentation;
//!
//! # struct State;
//! # let mut display = wayland_server::Display::<State>::new().unwrap();
@ -19,8 +18,7 @@
//! 1 // the id of the clock
//! );
//!
//! // implement Dispatch for the Presentation types
//! delegate_presentation!(State);
//! smithay::delegate_dispatch2!(State);
//!
//! // You're now ready to go!
//! ```
@ -78,7 +76,10 @@ use wayland_server::{
Dispatch, DisplayHandle, GlobalDispatch, Resource, Weak, backend::GlobalId, protocol::wl_surface,
};
use crate::output::Output;
use crate::{
output::Output,
wayland::{Dispatch2, GlobalData, GlobalDispatch2},
};
use super::compositor::{Cacheable, with_states};
@ -97,13 +98,14 @@ impl PresentationState {
/// the event loop in the future.
pub fn new<D>(display: &DisplayHandle, clk_id: u32) -> Self
where
D: GlobalDispatch<wp_presentation::WpPresentation, u32>
+ Dispatch<wp_presentation::WpPresentation, u32>
+ Dispatch<wp_presentation_feedback::WpPresentationFeedback, ()>
D: GlobalDispatch<wp_presentation::WpPresentation, PresentationData>
+ Dispatch<wp_presentation::WpPresentation, PresentationData>
+ Dispatch<wp_presentation_feedback::WpPresentationFeedback, GlobalData>
+ 'static,
{
PresentationState {
global: display.create_global::<D, wp_presentation::WpPresentation, u32>(2, clk_id),
global: display
.create_global::<D, wp_presentation::WpPresentation, _>(2, PresentationData { clk_id }),
}
}
@ -113,43 +115,46 @@ impl PresentationState {
}
}
impl<D> GlobalDispatch<wp_presentation::WpPresentation, u32, D> for PresentationState
#[doc(hidden)]
#[derive(Copy, Clone, Debug)]
pub struct PresentationData {
clk_id: u32,
}
impl<D> GlobalDispatch2<wp_presentation::WpPresentation, D> for PresentationData
where
D: GlobalDispatch<wp_presentation::WpPresentation, u32>,
D: Dispatch<wp_presentation::WpPresentation, u32>,
D: Dispatch<wp_presentation_feedback::WpPresentationFeedback, ()>,
D: Dispatch<wp_presentation::WpPresentation, PresentationData>,
D: Dispatch<wp_presentation_feedback::WpPresentationFeedback, GlobalData>,
{
fn bind(
&self,
_state: &mut D,
_handle: &DisplayHandle,
_client: &wayland_server::Client,
resource: wayland_server::New<wp_presentation::WpPresentation>,
global_data: &u32,
data_init: &mut wayland_server::DataInit<'_, D>,
) {
let interface = data_init.init(resource, *global_data);
interface.clock_id(*global_data);
let interface = data_init.init(resource, *self);
interface.clock_id(self.clk_id);
}
}
impl<D> Dispatch<wp_presentation::WpPresentation, u32, D> for PresentationState
impl<D> Dispatch2<wp_presentation::WpPresentation, D> for PresentationData
where
D: GlobalDispatch<wp_presentation::WpPresentation, u32>,
D: Dispatch<wp_presentation::WpPresentation, u32>,
D: Dispatch<wp_presentation_feedback::WpPresentationFeedback, ()>,
D: Dispatch<wp_presentation_feedback::WpPresentationFeedback, GlobalData>,
{
fn request(
&self,
_state: &mut D,
_client: &wayland_server::Client,
_resource: &wp_presentation::WpPresentation,
request: <wp_presentation::WpPresentation as Resource>::Request,
data: &u32,
_dhandle: &DisplayHandle,
data_init: &mut wayland_server::DataInit<'_, D>,
) {
match request {
wp_presentation::Request::Feedback { surface, callback } => {
let callback = data_init.init(callback, ());
let callback = data_init.init(callback, GlobalData);
// TODO: Is there a better way to store the surface?
with_states(&surface, |states| {
@ -157,7 +162,7 @@ where
.cached_state
.get::<PresentationFeedbackCachedState>()
.pending()
.add_callback(&surface, *data, callback);
.add_callback(&surface, self.clk_id, callback);
});
}
wp_presentation::Request::Destroy => {
@ -168,18 +173,13 @@ where
}
}
impl<D> Dispatch<wp_presentation_feedback::WpPresentationFeedback, (), D> for PresentationFeedbackState
where
D: GlobalDispatch<wp_presentation::WpPresentation, u32>,
D: Dispatch<wp_presentation::WpPresentation, u32>,
D: Dispatch<wp_presentation_feedback::WpPresentationFeedback, ()>,
{
impl<D> Dispatch2<wp_presentation_feedback::WpPresentationFeedback, D> for GlobalData {
fn request(
&self,
_state: &mut D,
_client: &wayland_server::Client,
_resource: &wp_presentation_feedback::WpPresentationFeedback,
_request: <wp_presentation_feedback::WpPresentationFeedback as Resource>::Request,
_data: &(),
_dhandle: &DisplayHandle,
_data_init: &mut wayland_server::DataInit<'_, D>,
) {
@ -346,36 +346,3 @@ impl Drop for PresentationFeedbackCachedState {
}
}
}
#[allow(missing_docs)] // TODO
#[macro_export]
macro_rules! delegate_presentation {
($(@<$( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+>)? $ty: ty) => {
const _: () = {
use $crate::{
reexports::{
wayland_protocols::wp::presentation_time::server::{
wp_presentation::WpPresentation, wp_presentation_feedback::WpPresentationFeedback,
},
wayland_server::{delegate_dispatch, delegate_global_dispatch},
},
wayland::presentation::{PresentationFeedbackState, PresentationState},
};
delegate_global_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [WpPresentation: u32] => PresentationState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [WpPresentation: u32] => PresentationState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [WpPresentationFeedback: ()] => PresentationFeedbackState
);
};
};
}

View file

@ -8,7 +8,6 @@
//! extern crate smithay;
//!
//! use smithay::wayland::relative_pointer::RelativePointerManagerState;
//! use smithay::delegate_relative_pointer;
//! # use smithay::backend::input::KeyState;
//! # use smithay::input::{
//! # pointer::{PointerTarget, AxisFrame, MotionEvent, ButtonEvent, RelativeMotionEvent,
@ -81,7 +80,7 @@
//! # }
//! let state = RelativePointerManagerState::new::<State>(&display.handle());
//!
//! delegate_relative_pointer!(State);
//! smithay::delegate_dispatch2!(State);
//! ```
use std::sync::{Arc, Mutex, atomic::Ordering};
@ -102,7 +101,7 @@ use crate::{
SeatHandler,
pointer::{PointerHandle, RelativeMotionEvent},
},
wayland::seat::PointerUserData,
wayland::{Dispatch2, GlobalData, GlobalDispatch2, seat::PointerUserData},
};
const MANAGER_VERSION: u32 = 1;
@ -171,13 +170,13 @@ impl RelativePointerManagerState {
/// Register new [ZwpRelativePointerV1] global
pub fn new<D>(display: &DisplayHandle) -> Self
where
D: GlobalDispatch<ZwpRelativePointerManagerV1, ()>,
D: Dispatch<ZwpRelativePointerManagerV1, ()>,
D: GlobalDispatch<ZwpRelativePointerManagerV1, GlobalData>,
D: Dispatch<ZwpRelativePointerManagerV1, GlobalData>,
D: Dispatch<ZwpRelativePointerV1, RelativePointerUserData<D>>,
D: SeatHandler,
D: 'static,
{
let global = display.create_global::<D, ZwpRelativePointerManagerV1, _>(MANAGER_VERSION, ());
let global = display.create_global::<D, ZwpRelativePointerManagerV1, _>(MANAGER_VERSION, GlobalData);
Self { global }
}
@ -188,19 +187,18 @@ impl RelativePointerManagerState {
}
}
impl<D> Dispatch<ZwpRelativePointerManagerV1, (), D> for RelativePointerManagerState
impl<D> Dispatch2<ZwpRelativePointerManagerV1, D> for GlobalData
where
D: Dispatch<ZwpRelativePointerManagerV1, ()>,
D: Dispatch<ZwpRelativePointerV1, RelativePointerUserData<D>>,
D: SeatHandler,
D: 'static,
{
fn request(
&self,
_state: &mut D,
_client: &wayland_server::Client,
_relative_pointer_manager: &ZwpRelativePointerManagerV1,
request: zwp_relative_pointer_manager_v1::Request,
_data: &(),
_dh: &DisplayHandle,
data_init: &mut wayland_server::DataInit<'_, D>,
) {
@ -222,37 +220,33 @@ where
}
}
impl<D> GlobalDispatch<ZwpRelativePointerManagerV1, (), D> for RelativePointerManagerState
impl<D> GlobalDispatch2<ZwpRelativePointerManagerV1, D> for GlobalData
where
D: GlobalDispatch<ZwpRelativePointerManagerV1, ()>
+ Dispatch<ZwpRelativePointerManagerV1, ()>
+ SeatHandler
+ 'static,
D: Dispatch<ZwpRelativePointerManagerV1, GlobalData> + SeatHandler + 'static,
{
fn bind(
&self,
_state: &mut D,
_dh: &DisplayHandle,
_client: &Client,
resource: New<ZwpRelativePointerManagerV1>,
_global_data: &(),
data_init: &mut DataInit<'_, D>,
) {
data_init.init(resource, ());
data_init.init(resource, GlobalData);
}
}
impl<D> Dispatch<ZwpRelativePointerV1, RelativePointerUserData<D>, D> for RelativePointerManagerState
impl<D> Dispatch2<ZwpRelativePointerV1, D> for RelativePointerUserData<D>
where
D: Dispatch<ZwpRelativePointerV1, RelativePointerUserData<D>>,
D: SeatHandler,
D: 'static,
{
fn request(
&self,
_state: &mut D,
_client: &wayland_server::Client,
_relative_pointer: &ZwpRelativePointerV1,
request: zwp_relative_pointer_v1::Request,
_data: &RelativePointerUserData<D>,
_dh: &DisplayHandle,
_data_init: &mut wayland_server::DataInit<'_, D>,
) {
@ -262,13 +256,8 @@ where
}
}
fn destroyed(
_state: &mut D,
_: ClientId,
object: &ZwpRelativePointerV1,
data: &RelativePointerUserData<D>,
) {
if let Some(ref handle) = data.handle {
fn destroyed(&self, _state: &mut D, _: ClientId, object: &ZwpRelativePointerV1) {
if let Some(ref handle) = self.handle {
handle
.wp_relative
.known_relative_pointers
@ -278,37 +267,3 @@ where
}
}
}
/// Macro to delegate implementation of the relative pointer protocol
#[macro_export]
macro_rules! delegate_relative_pointer {
($(@<$( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+>)? $ty: ty) => {
const _: () = {
use $crate::{
reexports::{
wayland_protocols::wp::relative_pointer::zv1::server::{
zwp_relative_pointer_manager_v1::ZwpRelativePointerManagerV1,
zwp_relative_pointer_v1::ZwpRelativePointerV1,
},
wayland_server::{delegate_dispatch, delegate_global_dispatch},
},
wayland::relative_pointer::{RelativePointerManagerState, RelativePointerUserData},
};
delegate_global_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [ZwpRelativePointerManagerV1: ()] => RelativePointerManagerState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [ZwpRelativePointerManagerV1: ()] => RelativePointerManagerState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [ZwpRelativePointerV1: RelativePointerUserData<Self>] => RelativePointerManagerState
);
};
};
}

View file

@ -2,7 +2,7 @@ use std::{cell::RefCell, fmt};
use tracing::{instrument, trace, warn};
use wayland_server::{
Client, Dispatch, DisplayHandle, Resource,
Client, DisplayHandle, Resource,
backend::{ClientId, ObjectId},
protocol::{
wl_keyboard::{self, KeyState as WlKeyState, WlKeyboard},
@ -14,11 +14,12 @@ use super::WaylandFocus;
use crate::{
backend::input::{KeyState, Keycode},
input::{
Seat, SeatHandler, SeatState, WeakSeat,
Seat, SeatHandler, WeakSeat,
keyboard::{KeyboardHandle, KeyboardTarget, KeysymHandle, ModifiersState},
},
utils::{HookId, Serial, iter::new_locked_obj_iter_from_vec},
wayland::{
Dispatch2,
compositor::{add_destruction_hook, remove_destruction_hook, with_states},
input_method::InputMethodSeat,
text_input::TextInputSeat,
@ -116,24 +117,24 @@ impl<D: SeatHandler> fmt::Debug for KeyboardUserData<D> {
}
}
impl<D> Dispatch<WlKeyboard, KeyboardUserData<D>, D> for SeatState<D>
impl<D> Dispatch2<WlKeyboard, D> for KeyboardUserData<D>
where
D: 'static + Dispatch<WlKeyboard, KeyboardUserData<D>>,
D: 'static,
D: SeatHandler,
{
fn request(
&self,
_state: &mut D,
_client: &wayland_server::Client,
_resource: &WlKeyboard,
_request: wl_keyboard::Request,
_data: &KeyboardUserData<D>,
_dhandle: &DisplayHandle,
_data_init: &mut wayland_server::DataInit<'_, D>,
) {
}
fn destroyed(_state: &mut D, _client_id: ClientId, keyboard: &WlKeyboard, data: &KeyboardUserData<D>) {
if let Some(ref handle) = data.handle {
fn destroyed(&self, _state: &mut D, _client_id: ClientId, keyboard: &WlKeyboard) {
if let Some(ref handle) = self.handle {
handle
.arc
.known_kbds

View file

@ -8,8 +8,6 @@
//! ### Initialization
//!
//! ```
//! use smithay::delegate_seat;
//! # use smithay::delegate_compositor;
//! use smithay::input::{Seat, SeatState, SeatHandler, pointer::CursorImageStatus};
//! use smithay::reexports::wayland_server::{Display, protocol::wl_surface::WlSurface};
//! # use smithay::wayland::compositor::{CompositorHandler, CompositorState, CompositorClientState};
@ -44,14 +42,14 @@
//! // ...
//! }
//! }
//! delegate_seat!(State);
//!
//! smithay::delegate_dispatch2!(State);
//!
//! # impl CompositorHandler for State {
//! # fn compositor_state(&mut self) -> &mut CompositorState { unimplemented!() }
//! # fn client_compositor_state<'a>(&self, client: &'a Client) -> &'a CompositorClientState { unimplemented!() }
//! # fn commit(&mut self, surface: &WlSurface) {}
//! # }
//! # delegate_compositor!(State);
//! ```
//!
//! ### Run usage
@ -73,6 +71,7 @@ mod touch;
use std::{borrow::Cow, fmt, sync::Arc};
use crate::input::{Inner, Seat, SeatHandler, SeatRc, SeatState};
use crate::wayland::{Dispatch2, GlobalDispatch2};
pub use self::{
keyboard::KeyboardUserData,
@ -224,55 +223,8 @@ impl<D: SeatHandler> fmt::Debug for SeatUserData<D> {
}
}
#[allow(missing_docs)] // TODO
#[macro_export]
macro_rules! delegate_seat {
($(@<$( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+>)? $ty: ty) => {
const _: () = {
use $crate::{
input::SeatState,
reexports::wayland_server::{
delegate_dispatch, delegate_global_dispatch,
protocol::{
wl_keyboard::WlKeyboard, wl_pointer::WlPointer, wl_seat::WlSeat, wl_touch::WlTouch,
},
},
wayland::seat::{
KeyboardUserData, PointerUserData, SeatGlobalData, SeatUserData, TouchUserData,
},
};
delegate_global_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [WlSeat: SeatGlobalData<$ty>] => SeatState<$ty>
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [WlSeat: SeatUserData<$ty>] => SeatState<$ty>
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [WlPointer: PointerUserData<$ty>] => SeatState<$ty>
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [WlKeyboard: KeyboardUserData<$ty>] => SeatState<$ty>
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [WlTouch: TouchUserData<$ty>] => SeatState<$ty>
);
};
};
}
impl<D> Dispatch<WlSeat, SeatUserData<D>, D> for SeatState<D>
impl<D> Dispatch2<WlSeat, D> for SeatUserData<D>
where
D: Dispatch<WlSeat, SeatUserData<D>>,
D: Dispatch<WlKeyboard, KeyboardUserData<D>>,
D: Dispatch<WlPointer, PointerUserData<D>>,
D: Dispatch<WlTouch, TouchUserData<D>>,
@ -282,17 +234,17 @@ where
D: 'static,
{
fn request(
&self,
state: &mut D,
client: &wayland_server::Client,
_resource: &WlSeat,
request: wl_seat::Request,
data: &SeatUserData<D>,
_dh: &DisplayHandle,
data_init: &mut wayland_server::DataInit<'_, D>,
) {
match request {
wl_seat::Request::GetPointer { id } => {
let inner = data.arc.inner.lock().unwrap();
let inner = self.arc.inner.lock().unwrap();
let client_scale = state.client_compositor_state(client).clone_client_scale();
let pointer = data_init.init(
@ -311,7 +263,7 @@ where
}
}
wl_seat::Request::GetKeyboard { id } => {
let inner = data.arc.inner.lock().unwrap();
let inner = self.arc.inner.lock().unwrap();
let keyboard = data_init.init(
id,
@ -327,7 +279,7 @@ where
}
}
wl_seat::Request::GetTouch { id } => {
let inner = data.arc.inner.lock().unwrap();
let inner = self.arc.inner.lock().unwrap();
let client_scale = state.client_compositor_state(client).clone_client_scale();
let touch = data_init.init(
@ -351,8 +303,8 @@ where
}
}
fn destroyed(_state: &mut D, _: ClientId, seat: &WlSeat, data: &SeatUserData<D>) {
data.arc
fn destroyed(&self, _state: &mut D, _: ClientId, seat: &WlSeat) {
self.arc
.inner
.lock()
.unwrap()
@ -361,9 +313,8 @@ where
}
}
impl<D> GlobalDispatch<WlSeat, SeatGlobalData<D>, D> for SeatState<D>
impl<D> GlobalDispatch2<WlSeat, D> for SeatGlobalData<D>
where
D: GlobalDispatch<WlSeat, SeatGlobalData<D>>,
D: Dispatch<WlSeat, SeatUserData<D>>,
D: Dispatch<WlKeyboard, KeyboardUserData<D>>,
D: Dispatch<WlPointer, PointerUserData<D>>,
@ -372,24 +323,24 @@ where
D: 'static,
{
fn bind(
&self,
_state: &mut D,
_dh: &DisplayHandle,
_client: &wayland_server::Client,
resource: New<WlSeat>,
global_data: &SeatGlobalData<D>,
data_init: &mut DataInit<'_, D>,
) {
let data = SeatUserData {
arc: global_data.arc.clone(),
arc: self.arc.clone(),
};
let resource = data_init.init(resource, data);
if resource.version() >= 2 {
resource.name(global_data.arc.name.clone());
resource.name(self.arc.name.clone());
}
let mut inner = global_data.arc.inner.lock().unwrap();
let mut inner = self.arc.inner.lock().unwrap();
resource.capabilities(inner.compute_caps());
inner.known_seats.push(resource.downgrade());
}

View file

@ -2,7 +2,7 @@ use std::sync::{Arc, Mutex, atomic::Ordering};
use atomic_float::AtomicF64;
use wayland_server::{
Client, Dispatch, DisplayHandle, Resource, Weak,
Client, DisplayHandle, Resource, Weak,
backend::{ClientId, ObjectId},
protocol::{
wl_pointer::{
@ -25,10 +25,10 @@ use crate::{
},
},
utils::{Client as ClientCoords, Point, Serial, iter::new_locked_obj_iter_from_vec},
wayland::{compositor, pointer_constraints::with_pointer_constraint},
wayland::{Dispatch2, compositor, pointer_constraints::with_pointer_constraint},
};
use super::{SeatHandler, SeatState, WaylandFocus};
use super::{SeatHandler, WaylandFocus};
// Use to accumulate discrete values for `wl_pointer` < 8
#[derive(Default)]
@ -348,19 +348,18 @@ pub struct PointerUserData<D: SeatHandler> {
pub(crate) client_scale: Arc<AtomicF64>,
}
impl<D> Dispatch<WlPointer, PointerUserData<D>, D> for SeatState<D>
impl<D> Dispatch2<WlPointer, D> for PointerUserData<D>
where
D: Dispatch<WlPointer, PointerUserData<D>>,
D: SeatHandler,
<D as SeatHandler>::PointerFocus: WaylandFocus,
D: 'static,
{
fn request(
&self,
state: &mut D,
_client: &wayland_server::Client,
pointer: &WlPointer,
request: wl_pointer::Request,
data: &PointerUserData<D>,
_dh: &DisplayHandle,
_data_init: &mut wayland_server::DataInit<'_, D>,
) {
@ -371,7 +370,7 @@ where
hotspot_x,
hotspot_y,
} => {
let handle = match &data.handle {
let handle = match &self.handle {
Some(handle) => handle,
None => return,
};
@ -437,8 +436,8 @@ where
};
}
fn destroyed(_state: &mut D, _: ClientId, pointer: &WlPointer, data: &PointerUserData<D>) {
if let Some(ref handle) = data.handle {
fn destroyed(&self, _state: &mut D, _: ClientId, pointer: &WlPointer) {
if let Some(ref handle) = self.handle {
handle
.wl_pointer
.known_pointers

View file

@ -2,17 +2,18 @@ use std::sync::{Arc, atomic::Ordering};
use atomic_float::AtomicF64;
use wayland_server::{
Dispatch, DisplayHandle, Resource,
DisplayHandle, Resource,
backend::ClientId,
protocol::wl_touch::{self, WlTouch},
};
use super::{SeatHandler, SeatState};
use super::SeatHandler;
use crate::input::touch::TouchTarget;
use crate::input::{
Seat,
touch::{MotionEvent, OrientationEvent, ShapeEvent, UpEvent},
};
use crate::wayland::Dispatch2;
use crate::{input::touch::DownEvent, wayland::seat::wl_surface::WlSurface};
use crate::{input::touch::TouchHandle, utils::Serial};
@ -135,25 +136,24 @@ pub struct TouchUserData<D: SeatHandler> {
pub(crate) client_scale: Arc<AtomicF64>,
}
impl<D> Dispatch<WlTouch, TouchUserData<D>, D> for SeatState<D>
impl<D> Dispatch2<WlTouch, D> for TouchUserData<D>
where
D: Dispatch<WlTouch, TouchUserData<D>>,
D: SeatHandler,
D: 'static,
{
fn request(
&self,
_state: &mut D,
_client: &wayland_server::Client,
_resource: &WlTouch,
_request: wl_touch::Request,
_data: &TouchUserData<D>,
_dhandle: &DisplayHandle,
_data_init: &mut wayland_server::DataInit<'_, D>,
) {
}
fn destroyed(_state: &mut D, _client_id: ClientId, touch: &WlTouch, data: &TouchUserData<D>) {
if let Some(ref handle) = data.handle {
fn destroyed(&self, _state: &mut D, _client_id: ClientId, touch: &WlTouch) {
if let Some(ref handle) = self.handle {
handle
.known_instances
.lock()

View file

@ -14,6 +14,8 @@ use wayland_server::{
backend::{ClientId, GlobalId},
};
use crate::wayland::{Dispatch2, GlobalData, GlobalDispatch2};
mod listener_source;
pub use listener_source::SecurityContextListenerSource;
@ -68,7 +70,7 @@ impl SecurityContextState {
pub fn new<D, F>(display: &DisplayHandle, filter: F) -> Self
where
D: GlobalDispatch<WpSecurityContextManagerV1, SecurityContextGlobalData>,
D: Dispatch<WpSecurityContextManagerV1, ()>,
D: Dispatch<WpSecurityContextManagerV1, GlobalData>,
D: Dispatch<WpSecurityContextV1, SecurityContextUserData>,
D: 'static,
F: for<'c> Fn(&'c Client) -> bool + Send + Sync + 'static,
@ -93,40 +95,38 @@ pub struct SecurityContextGlobalData {
filter: Box<dyn for<'c> Fn(&'c Client) -> bool + Send + Sync>,
}
impl<D> GlobalDispatch<WpSecurityContextManagerV1, SecurityContextGlobalData, D> for SecurityContextState
impl<D> GlobalDispatch2<WpSecurityContextManagerV1, D> for SecurityContextGlobalData
where
D: GlobalDispatch<WpSecurityContextManagerV1, SecurityContextGlobalData>,
D: Dispatch<WpSecurityContextManagerV1, ()>,
D: Dispatch<WpSecurityContextManagerV1, GlobalData>,
D: 'static,
{
fn bind(
&self,
_state: &mut D,
_dh: &DisplayHandle,
_client: &Client,
resource: New<WpSecurityContextManagerV1>,
_global_data: &SecurityContextGlobalData,
data_init: &mut DataInit<'_, D>,
) {
data_init.init(resource, ());
data_init.init(resource, GlobalData);
}
fn can_view(client: Client, global_data: &SecurityContextGlobalData) -> bool {
(global_data.filter)(&client)
fn can_view(&self, client: &Client) -> bool {
(self.filter)(client)
}
}
impl<D> Dispatch<WpSecurityContextManagerV1, (), D> for SecurityContextState
impl<D> Dispatch2<WpSecurityContextManagerV1, D> for GlobalData
where
D: Dispatch<WpSecurityContextManagerV1, ()>,
D: Dispatch<WpSecurityContextV1, SecurityContextUserData>,
D: 'static,
{
fn request(
&self,
_state: &mut D,
_client: &wayland_server::Client,
_manager: &WpSecurityContextManagerV1,
request: wp_security_context_manager_v1::Request,
_data: &(),
_dh: &DisplayHandle,
data_init: &mut wayland_server::DataInit<'_, D>,
) {
@ -151,21 +151,20 @@ where
}
}
impl<D> Dispatch<WpSecurityContextV1, SecurityContextUserData, D> for SecurityContextState
impl<D> Dispatch2<WpSecurityContextV1, D> for SecurityContextUserData
where
D: Dispatch<WpSecurityContextV1, SecurityContextUserData> + 'static,
D: SecurityContextHandler,
D: SecurityContextHandler + 'static,
{
fn request(
&self,
state: &mut D,
client: &wayland_server::Client,
context: &WpSecurityContextV1,
request: wp_security_context_v1::Request,
data: &SecurityContextUserData,
_dh: &DisplayHandle,
_data_init: &mut wayland_server::DataInit<'_, D>,
) {
let mut data = data.0.lock().unwrap();
let mut data = self.0.lock().unwrap();
if matches!(request, wp_security_context_v1::Request::Destroy) {
return;
@ -227,39 +226,3 @@ where
}
}
}
/// Macro to delegate implementation of the security context protocol
#[macro_export]
macro_rules! delegate_security_context {
($(@<$( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+>)? $ty: ty) => {
const _: () = {
use $crate::{
reexports::{
wayland_protocols::wp::security_context::v1::server::{
wp_security_context_manager_v1::WpSecurityContextManagerV1,
wp_security_context_v1::WpSecurityContextV1,
},
wayland_server::{delegate_dispatch, delegate_global_dispatch},
},
wayland::security_context::{
SecurityContextGlobalData, SecurityContextState, SecurityContextUserData,
},
};
delegate_global_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [WpSecurityContextManagerV1: SecurityContextGlobalData] => SecurityContextState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [WpSecurityContextManagerV1: ()] => SecurityContextState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [WpSecurityContextV1: SecurityContextUserData] => SecurityContextState
);
};
};
}

View file

@ -2,7 +2,7 @@ use std::cell::RefCell;
use tracing::debug;
use wayland_server::{
Client, DataInit, Dispatch, DisplayHandle, Resource,
Client, DataInit, DisplayHandle, Resource,
protocol::{
wl_data_device::{self, WlDataDevice},
wl_seat::WlSeat,
@ -13,7 +13,7 @@ use crate::{
input::{Seat, SeatHandler, dnd::DndFocus},
utils::Serial,
wayland::{
compositor,
Dispatch2, compositor,
seat::WaylandFocus,
selection::{
SelectionTarget,
@ -25,7 +25,7 @@ use crate::{
},
};
use super::{DataDeviceHandler, DataDeviceState, GrabType};
use super::{DataDeviceHandler, GrabType};
/// WlSurface role of drag and drop icon
pub const DND_ICON_ROLE: &str = "dnd_icon";
@ -36,9 +36,8 @@ pub struct DataDeviceUserData {
pub(crate) wl_seat: WlSeat,
}
impl<D> Dispatch<WlDataDevice, DataDeviceUserData, D> for DataDeviceState
impl<D> Dispatch2<WlDataDevice, D> for DataDeviceUserData
where
D: Dispatch<WlDataDevice, DataDeviceUserData>,
D: DataDeviceHandler,
D: SeatHandler,
<D as SeatHandler>::PointerFocus: DndFocus<D>,
@ -47,15 +46,15 @@ where
D: 'static,
{
fn request(
&self,
handler: &mut D,
client: &Client,
resource: &WlDataDevice,
request: wl_data_device::Request,
data: &DataDeviceUserData,
dh: &DisplayHandle,
_data_init: &mut DataInit<'_, D>,
) {
let seat = match Seat::<D>::from_resource(&data.wl_seat) {
let seat = match Seat::<D>::from_resource(&self.wl_seat) {
Some(seat) => seat,
None => return,
};
@ -74,7 +73,7 @@ where
handler
.data_device_state()
.used_sources
.insert(source.clone(), data.wl_seat.clone());
.insert(source.clone(), self.wl_seat.clone());
}
let serial = Serial::from(serial);
@ -167,7 +166,7 @@ where
handler
.data_device_state()
.used_sources
.insert(source.clone(), data.wl_seat.clone());
.insert(source.clone(), self.wl_seat.clone());
}
let source = source.map(SelectionSourceProvider::DataDevice);
@ -197,13 +196,8 @@ where
}
}
fn destroyed(
_state: &mut D,
_client: wayland_server::backend::ClientId,
resource: &WlDataDevice,
data: &DataDeviceUserData,
) {
if let Some(seat) = Seat::<D>::from_resource(&data.wl_seat) {
fn destroyed(&self, _state: &mut D, _client: wayland_server::backend::ClientId, resource: &WlDataDevice) {
if let Some(seat) = Seat::<D>::from_resource(&self.wl_seat) {
if let Some(seat_data) = seat.user_data().get::<RefCell<SeatData<D::SelectionUserData>>>() {
seat_data.borrow_mut().retain_devices(|ndd| match ndd {
SelectionDevice::DataDevice(ndd) => ndd != resource,

View file

@ -27,7 +27,6 @@
//! ```
//! # extern crate wayland_server;
//! # #[macro_use] extern crate smithay;
//! use smithay::delegate_data_device;
//! use smithay::wayland::selection::SelectionHandler;
//! use smithay::wayland::selection::data_device::{WaylandDndGrabHandler, DataDeviceState, DataDeviceHandler};
//! # use smithay::input::{Seat, SeatState, SeatHandler, pointer::CursorImageStatus};
@ -62,7 +61,8 @@
//! fn data_device_state(&mut self) -> &mut DataDeviceState { &mut self.data_device_state }
//! // ... override default implementations here to customize handling ...
//! }
//! delegate_data_device!(State);
//!
//! smithay::delegate_dispatch2!(State);
//!
//! // You're now ready to go!
//! ```
@ -94,6 +94,7 @@ use crate::{
dnd::{DndAction, DndFocus, GrabType, OfferData, Source},
},
utils::{Logical, Point, Serial},
wayland::GlobalData,
};
mod device;
@ -566,10 +567,10 @@ impl DataDeviceState {
/// Regiseter new [WlDataDeviceManager] global
pub fn new<D>(display: &DisplayHandle) -> Self
where
D: GlobalDispatch<WlDataDeviceManager, ()> + 'static,
D: GlobalDispatch<WlDataDeviceManager, GlobalData> + 'static,
D: DataDeviceHandler,
{
let manager_global = display.create_global::<D, WlDataDeviceManager, _>(3, ());
let manager_global = display.create_global::<D, WlDataDeviceManager, _>(3, GlobalData);
Self {
manager_global,
@ -745,7 +746,7 @@ mod handlers {
use tracing::error;
use wayland_server::{
Dispatch, DisplayHandle, GlobalDispatch,
Dispatch, DisplayHandle,
protocol::{
wl_data_device::WlDataDevice,
wl_data_device_manager::{self, WlDataDeviceManager},
@ -756,46 +757,45 @@ mod handlers {
use crate::{
input::Seat,
wayland::selection::{device::SelectionDevice, seat_data::SeatData},
wayland::{Dispatch2, GlobalData, GlobalDispatch2},
};
use super::{DataDeviceHandler, DataDeviceState};
use super::DataDeviceHandler;
use super::{device::DataDeviceUserData, source::DataSourceUserData};
impl<D> GlobalDispatch<WlDataDeviceManager, (), D> for DataDeviceState
impl<D> GlobalDispatch2<WlDataDeviceManager, D> for GlobalData
where
D: GlobalDispatch<WlDataDeviceManager, ()>,
D: Dispatch<WlDataDeviceManager, ()>,
D: Dispatch<WlDataDeviceManager, GlobalData>,
D: Dispatch<WlDataSource, DataSourceUserData>,
D: Dispatch<WlDataDevice, DataDeviceUserData>,
D: DataDeviceHandler,
D: 'static,
{
fn bind(
&self,
_state: &mut D,
_handle: &DisplayHandle,
_client: &wayland_server::Client,
resource: wayland_server::New<WlDataDeviceManager>,
_global_data: &(),
data_init: &mut wayland_server::DataInit<'_, D>,
) {
data_init.init(resource, ());
data_init.init(resource, GlobalData);
}
}
impl<D> Dispatch<WlDataDeviceManager, (), D> for DataDeviceState
impl<D> Dispatch2<WlDataDeviceManager, D> for GlobalData
where
D: Dispatch<WlDataDeviceManager, ()>,
D: Dispatch<WlDataSource, DataSourceUserData>,
D: Dispatch<WlDataDevice, DataDeviceUserData>,
D: DataDeviceHandler,
D: 'static,
{
fn request(
&self,
_state: &mut D,
client: &wayland_server::Client,
_resource: &WlDataDeviceManager,
request: wl_data_device_manager::Request,
_data: &(),
dhandle: &DisplayHandle,
data_init: &mut wayland_server::DataInit<'_, D>,
) {
@ -829,42 +829,3 @@ mod handlers {
}
}
}
#[allow(missing_docs)] // TODO
#[macro_export]
macro_rules! delegate_data_device {
($(@<$( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+>)? $ty: ty) => {
const _: () = {
use $crate::{
reexports::wayland_server::{
delegate_dispatch, delegate_global_dispatch,
protocol::{
wl_data_device::WlDataDevice, wl_data_device_manager::WlDataDeviceManager,
wl_data_source::WlDataSource,
},
},
wayland::selection::data_device::{DataDeviceState, DataDeviceUserData, DataSourceUserData},
};
delegate_global_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [WlDataDeviceManager: ()] => DataDeviceState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [WlDataDeviceManager: ()] => DataDeviceState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [WlDataDevice: DataDeviceUserData] => DataDeviceState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [WlDataSource: DataSourceUserData] => DataDeviceState
);
};
};
}

View file

@ -7,7 +7,7 @@ use std::{
use tracing::{debug, error};
use wayland_server::{
Dispatch, DisplayHandle, Resource,
DisplayHandle, Resource,
backend::ClientId,
protocol::{
wl_data_source::{self, WlDataSource},
@ -20,11 +20,12 @@ use crate::input::{
dnd::{DndAction, Source, SourceMetadata},
};
use crate::utils::{IsAlive, alive_tracker::AliveTracker};
use crate::wayland::Dispatch2;
use crate::wayland::selection::offer::OfferReplySource;
use crate::wayland::selection::seat_data::SeatData;
use crate::wayland::selection::source::SelectionSourceProvider;
use super::{DataDeviceHandler, DataDeviceState};
use super::DataDeviceHandler;
#[doc(hidden)]
#[derive(Debug)]
@ -44,22 +45,21 @@ impl DataSourceUserData {
}
}
impl<D> Dispatch<WlDataSource, DataSourceUserData, D> for DataDeviceState
impl<D> Dispatch2<WlDataSource, D> for DataSourceUserData
where
D: Dispatch<WlDataSource, DataSourceUserData>,
D: DataDeviceHandler,
D: 'static,
{
fn request(
&self,
_state: &mut D,
_client: &wayland_server::Client,
_resource: &WlDataSource,
request: wl_data_source::Request,
data: &DataSourceUserData,
_dhandle: &DisplayHandle,
_data_init: &mut wayland_server::DataInit<'_, D>,
) {
let mut data = data.inner.lock().unwrap();
let mut data = self.inner.lock().unwrap();
match request {
wl_data_source::Request::Offer { mime_type } => {
@ -78,8 +78,8 @@ where
}
}
fn destroyed(state: &mut D, _client: ClientId, source: &WlDataSource, data: &DataSourceUserData) {
data.alive_tracker.destroy_notify();
fn destroyed(&self, state: &mut D, _client: ClientId, source: &WlDataSource) {
self.alive_tracker.destroy_notify();
// Remove the source from the used ones.
let seat = match state
@ -103,7 +103,7 @@ where
Some(OfferReplySource::Client(SelectionSourceProvider::DataDevice(set_source)))
if set_source == source =>
{
seat_data.set_clipboard_selection::<D>(&data.display_handle, None)
seat_data.set_clipboard_selection::<D>(&self.display_handle, None)
}
_ => (),
}

View file

@ -5,16 +5,17 @@ use wayland_protocols::ext::data_control::v1::server::ext_data_control_device_v1
};
use wayland_server::Resource;
use wayland_server::protocol::wl_seat::WlSeat;
use wayland_server::{Client, Dispatch, DisplayHandle};
use wayland_server::{Client, DisplayHandle};
use crate::input::Seat;
use crate::wayland::Dispatch2;
use crate::wayland::selection::device::SelectionDevice;
use crate::wayland::selection::offer::OfferReplySource;
use crate::wayland::selection::seat_data::SeatData;
use crate::wayland::selection::source::SelectionSourceProvider;
use crate::wayland::selection::{SelectionSource, SelectionTarget};
use super::{DataControlHandler, DataControlState};
use super::DataControlHandler;
#[doc(hidden)]
#[derive(Debug)]
@ -23,22 +24,21 @@ pub struct ExtDataControlDeviceUserData {
pub(crate) wl_seat: WlSeat,
}
impl<D> Dispatch<ExtDataControlDeviceV1, ExtDataControlDeviceUserData, D> for DataControlState
impl<D> Dispatch2<ExtDataControlDeviceV1, D> for ExtDataControlDeviceUserData
where
D: Dispatch<ExtDataControlDeviceV1, ExtDataControlDeviceUserData>,
D: DataControlHandler,
D: 'static,
{
fn request(
&self,
handler: &mut D,
_client: &Client,
resource: &ExtDataControlDeviceV1,
request: <ExtDataControlDeviceV1 as wayland_server::Resource>::Request,
data: &ExtDataControlDeviceUserData,
dh: &DisplayHandle,
_: &mut wayland_server::DataInit<'_, D>,
) {
let seat = match Seat::<D>::from_resource(&data.wl_seat) {
let seat = match Seat::<D>::from_resource(&self.wl_seat) {
Some(seat) => seat,
None => return,
};
@ -50,7 +50,7 @@ where
if handler
.data_control_state()
.used_sources
.insert(source.clone(), data.wl_seat.clone())
.insert(source.clone(), self.wl_seat.clone())
.is_some()
{
resource.post_error(
@ -80,7 +80,7 @@ where
}
ext_data_control_device_v1::Request::SetPrimarySelection { source, .. } => {
// When the primary selection is disabled, we should simply ignore the requests.
if !data.primary {
if !self.primary {
return;
}
@ -89,7 +89,7 @@ where
if handler
.data_control_state()
.used_sources
.insert(source.clone(), data.wl_seat.clone())
.insert(source.clone(), self.wl_seat.clone())
.is_some()
{
resource.post_error(
@ -132,12 +132,12 @@ where
}
fn destroyed(
&self,
_state: &mut D,
_client: wayland_server::backend::ClientId,
resource: &ExtDataControlDeviceV1,
data: &ExtDataControlDeviceUserData,
) {
if let Some(seat) = Seat::<D>::from_resource(&data.wl_seat) {
if let Some(seat) = Seat::<D>::from_resource(&self.wl_seat) {
if let Some(seat_data) = seat.user_data().get::<RefCell<SeatData<D::SelectionUserData>>>() {
seat_data.borrow_mut().retain_devices(|ndd| match ndd {
SelectionDevice::ExtDataControl(ndd) => ndd != resource,

View file

@ -39,7 +39,8 @@
//! fn data_control_state(&mut self) -> &mut DataControlState { &mut self.data_control_state }
//! // ... override default implementations here to customize handling ...
//! }
//! delegate_ext_data_control!(State);
//!
//! smithay::delegate_dispatch2!(State);
//!
//! // You're now ready to go!
//! ```
@ -137,64 +138,60 @@ mod handlers {
ext_data_control_manager_v1::{self, ExtDataControlManagerV1},
ext_data_control_source_v1::ExtDataControlSourceV1,
};
use wayland_server::{Client, Dispatch, DisplayHandle, GlobalDispatch};
use wayland_server::{Client, Dispatch, DisplayHandle};
use crate::input::Seat;
use crate::wayland::selection::SelectionTarget;
use crate::wayland::selection::device::SelectionDevice;
use crate::wayland::selection::seat_data::SeatData;
use crate::wayland::{Dispatch2, GlobalDispatch2};
use super::DataControlHandler;
use super::DataControlState;
use super::ExtDataControlDeviceUserData;
use super::ExtDataControlManagerGlobalData;
use super::ExtDataControlManagerUserData;
use super::ExtDataControlSourceUserData;
impl<D> GlobalDispatch<ExtDataControlManagerV1, ExtDataControlManagerGlobalData, D> for DataControlState
impl<D> GlobalDispatch2<ExtDataControlManagerV1, D> for ExtDataControlManagerGlobalData
where
D: GlobalDispatch<ExtDataControlManagerV1, ExtDataControlManagerGlobalData>,
D: Dispatch<ExtDataControlManagerV1, ExtDataControlManagerUserData>,
D: Dispatch<ExtDataControlDeviceV1, ExtDataControlDeviceUserData>,
D: Dispatch<ExtDataControlSourceV1, ExtDataControlSourceUserData>,
D: DataControlHandler,
D: 'static,
{
fn bind(
&self,
_state: &mut D,
_handle: &DisplayHandle,
_client: &wayland_server::Client,
resource: wayland_server::New<ExtDataControlManagerV1>,
global_data: &ExtDataControlManagerGlobalData,
data_init: &mut wayland_server::DataInit<'_, D>,
) {
data_init.init(
resource,
ExtDataControlManagerUserData {
primary: global_data.primary,
primary: self.primary,
},
);
}
fn can_view(client: Client, global_data: &ExtDataControlManagerGlobalData) -> bool {
(global_data.filter)(&client)
fn can_view(&self, client: &Client) -> bool {
(self.filter)(client)
}
}
impl<D> Dispatch<ExtDataControlManagerV1, ExtDataControlManagerUserData, D> for DataControlState
impl<D> Dispatch2<ExtDataControlManagerV1, D> for ExtDataControlManagerUserData
where
D: Dispatch<ExtDataControlManagerV1, ExtDataControlManagerUserData>,
D: Dispatch<ExtDataControlDeviceV1, ExtDataControlDeviceUserData>,
D: Dispatch<ExtDataControlSourceV1, ExtDataControlSourceUserData>,
D: DataControlHandler,
D: 'static,
{
fn request(
&self,
_handler: &mut D,
client: &wayland_server::Client,
_resource: &ExtDataControlManagerV1,
request: <ExtDataControlManagerV1 as wayland_server::Resource>::Request,
data: &ExtDataControlManagerUserData,
dh: &DisplayHandle,
data_init: &mut wayland_server::DataInit<'_, D>,
) {
@ -212,7 +209,7 @@ mod handlers {
id,
ExtDataControlDeviceUserData {
wl_seat,
primary: data.primary,
primary: self.primary,
},
));
@ -227,7 +224,7 @@ mod handlers {
// NOTE: broadcast selection only to the newly created device.
let device = Some(&device);
seat_data.send_selection::<D>(dh, SelectionTarget::Clipboard, device, true);
if data.primary {
if self.primary {
seat_data.send_selection::<D>(dh, SelectionTarget::Primary, device, true);
}
}
@ -246,46 +243,3 @@ mod handlers {
}
}
}
/// Macro to delegate implementation of the ext_data_control protocol
#[macro_export]
macro_rules! delegate_ext_data_control {
($(@<$( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+>)? $ty: ty) => {
const _: () = {
use $crate::{
reexports::{
wayland_protocols::ext::data_control::v1::server::{
ext_data_control_device_v1::ExtDataControlDeviceV1,
ext_data_control_manager_v1::ExtDataControlManagerV1,
ext_data_control_source_v1::ExtDataControlSourceV1,
},
wayland_server::{delegate_dispatch, delegate_global_dispatch},
},
wayland::selection::ext_data_control::{
DataControlState, ExtDataControlDeviceUserData, ExtDataControlManagerGlobalData,
ExtDataControlManagerUserData, ExtDataControlSourceUserData,
},
};
delegate_global_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [ExtDataControlManagerV1: ExtDataControlManagerGlobalData] => DataControlState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [ExtDataControlManagerV1: ExtDataControlManagerUserData] => DataControlState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [ExtDataControlDeviceV1: ExtDataControlDeviceUserData] => DataControlState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [ExtDataControlSourceV1: ExtDataControlSourceUserData] => DataControlState
);
};
};
}

View file

@ -1,10 +1,11 @@
use std::cell::RefCell;
use std::sync::Mutex;
use wayland_server::DisplayHandle;
use wayland_server::backend::ClientId;
use wayland_server::{Dispatch, DisplayHandle};
use crate::input::Seat;
use crate::wayland::Dispatch2;
use crate::wayland::selection::SelectionTarget;
use crate::wayland::selection::offer::OfferReplySource;
use crate::wayland::selection::seat_data::SeatData;
@ -14,7 +15,7 @@ use wayland_protocols::ext::data_control::v1::server::ext_data_control_source_v1
self, ExtDataControlSourceV1,
};
use super::{DataControlHandler, DataControlState};
use super::DataControlHandler;
#[doc(hidden)]
#[derive(Debug)]
@ -39,24 +40,23 @@ pub struct SourceMetadata {
pub mime_types: Vec<String>,
}
impl<D> Dispatch<ExtDataControlSourceV1, ExtDataControlSourceUserData, D> for DataControlState
impl<D> Dispatch2<ExtDataControlSourceV1, D> for ExtDataControlSourceUserData
where
D: Dispatch<ExtDataControlSourceV1, ExtDataControlSourceUserData>,
D: DataControlHandler,
D: 'static,
{
fn request(
&self,
_state: &mut D,
_client: &wayland_server::Client,
_resource: &ExtDataControlSourceV1,
request: <ExtDataControlSourceV1 as wayland_server::Resource>::Request,
data: &ExtDataControlSourceUserData,
_dhandle: &DisplayHandle,
_data_init: &mut wayland_server::DataInit<'_, D>,
) {
match request {
ext_data_control_source_v1::Request::Offer { mime_type } => {
let mut data = data.inner.lock().unwrap();
let mut data = self.inner.lock().unwrap();
data.mime_types.push(mime_type);
}
ext_data_control_source_v1::Request::Destroy => (),
@ -64,12 +64,7 @@ where
}
}
fn destroyed(
state: &mut D,
_client: ClientId,
source: &ExtDataControlSourceV1,
data: &ExtDataControlSourceUserData,
) {
fn destroyed(&self, state: &mut D, _client: ClientId, source: &ExtDataControlSourceV1) {
// Remove the source from the used ones.
let seat = match state
.data_control_state()
@ -100,10 +95,10 @@ where
{
match target {
SelectionTarget::Primary => {
seat_data.set_primary_selection::<D>(&data.display_handle, None)
seat_data.set_primary_selection::<D>(&self.display_handle, None)
}
SelectionTarget::Clipboard => {
seat_data.set_clipboard_selection::<D>(&data.display_handle, None)
seat_data.set_clipboard_selection::<D>(&self.display_handle, None)
}
}
}

View file

@ -4,11 +4,12 @@ use tracing::debug;
use wayland_protocols::wp::primary_selection::zv1::server::zwp_primary_selection_device_v1::{
self as primary_device, ZwpPrimarySelectionDeviceV1 as PrimaryDevice,
};
use wayland_server::{Client, DataInit, Dispatch, DisplayHandle, Resource, protocol::wl_seat::WlSeat};
use wayland_server::{Client, DataInit, DisplayHandle, Resource, protocol::wl_seat::WlSeat};
use crate::{
input::{Seat, SeatHandler},
wayland::{
Dispatch2,
seat::WaylandFocus,
selection::{
SelectionHandler, SelectionTarget,
@ -20,7 +21,7 @@ use crate::{
},
};
use super::{PrimarySelectionHandler, PrimarySelectionState};
use super::PrimarySelectionHandler;
#[doc(hidden)]
#[derive(Debug)]
@ -28,24 +29,24 @@ pub struct PrimaryDeviceUserData {
pub(crate) wl_seat: WlSeat,
}
impl<D> Dispatch<PrimaryDevice, PrimaryDeviceUserData, D> for PrimarySelectionState
impl<D> Dispatch2<PrimaryDevice, D> for PrimaryDeviceUserData
where
D: Dispatch<PrimaryDevice, PrimaryDeviceUserData> + PrimarySelectionHandler,
D: PrimarySelectionHandler,
D: SelectionHandler,
D: SeatHandler,
<D as SeatHandler>::KeyboardFocus: WaylandFocus,
D: 'static,
{
fn request(
&self,
handler: &mut D,
client: &Client,
resource: &PrimaryDevice,
request: primary_device::Request,
data: &PrimaryDeviceUserData,
dh: &DisplayHandle,
_data_init: &mut DataInit<'_, D>,
) {
let seat = match Seat::<D>::from_resource(&data.wl_seat) {
let seat = match Seat::<D>::from_resource(&self.wl_seat) {
Some(seat) => seat,
None => return,
};
@ -73,7 +74,7 @@ where
handler
.primary_selection_state()
.used_sources
.insert(source.clone(), data.wl_seat.clone());
.insert(source.clone(), self.wl_seat.clone());
}
let source = source.map(SelectionSourceProvider::Primary);
@ -103,12 +104,12 @@ where
}
fn destroyed(
&self,
_state: &mut D,
_client: wayland_server::backend::ClientId,
resource: &PrimaryDevice,
data: &PrimaryDeviceUserData,
) {
if let Some(seat) = Seat::<D>::from_resource(&data.wl_seat) {
if let Some(seat) = Seat::<D>::from_resource(&self.wl_seat) {
if let Some(seat_data) = seat.user_data().get::<RefCell<SeatData<D::SelectionUserData>>>() {
seat_data.borrow_mut().retain_devices(|ndd| match ndd {
SelectionDevice::Primary(ndd) => ndd != resource,

View file

@ -26,7 +26,6 @@
//! ```
//! # extern crate wayland_server;
//! # #[macro_use] extern crate smithay;
//! use smithay::delegate_primary_selection;
//! use smithay::wayland::selection::SelectionHandler;
//! use smithay::wayland::selection::primary_selection::{PrimarySelectionState, PrimarySelectionHandler};
//! # use smithay::input::{Seat, SeatHandler, SeatState, pointer::CursorImageStatus};
@ -58,7 +57,8 @@
//! fn primary_selection_state(&mut self) -> &mut PrimarySelectionState { &mut self.primary_selection_state }
//! // ... override default implementations here to customize handling ...
//! }
//! delegate_primary_selection!(State);
//!
//! delegate_dispatch2!(State);
//!
//! // You're now ready to go!
//! ```
@ -306,46 +306,47 @@ mod handlers {
zwp_primary_selection_device_v1::ZwpPrimarySelectionDeviceV1 as PrimaryDevice,
zwp_primary_selection_source_v1::ZwpPrimarySelectionSourceV1 as PrimarySource,
};
use wayland_server::{Dispatch, DisplayHandle, GlobalDispatch};
use wayland_server::{Dispatch, DisplayHandle};
use crate::{
input::{Seat, SeatHandler},
wayland::selection::{device::SelectionDevice, seat_data::SeatData},
wayland::{
Dispatch2, GlobalData, GlobalDispatch2,
selection::{device::SelectionDevice, seat_data::SeatData},
},
};
use super::PrimarySelectionHandler;
use super::{
PrimaryDeviceManagerGlobalData, device::PrimaryDeviceUserData, source::PrimarySourceUserData,
};
use super::{PrimarySelectionHandler, PrimarySelectionState};
impl<D> GlobalDispatch<PrimaryDeviceManager, PrimaryDeviceManagerGlobalData, D> for PrimarySelectionState
impl<D> GlobalDispatch2<PrimaryDeviceManager, D> for PrimaryDeviceManagerGlobalData
where
D: GlobalDispatch<PrimaryDeviceManager, PrimaryDeviceManagerGlobalData>,
D: Dispatch<PrimaryDeviceManager, ()>,
D: Dispatch<PrimaryDeviceManager, GlobalData>,
D: Dispatch<PrimarySource, PrimarySourceUserData>,
D: Dispatch<PrimaryDevice, PrimaryDeviceUserData>,
D: PrimarySelectionHandler,
D: 'static,
{
fn bind(
&self,
_state: &mut D,
_handle: &DisplayHandle,
_client: &wayland_server::Client,
resource: wayland_server::New<PrimaryDeviceManager>,
_global_data: &PrimaryDeviceManagerGlobalData,
data_init: &mut wayland_server::DataInit<'_, D>,
) {
data_init.init(resource, ());
data_init.init(resource, GlobalData);
}
fn can_view(client: wayland_server::Client, global_data: &PrimaryDeviceManagerGlobalData) -> bool {
(global_data.filter)(&client)
fn can_view(&self, client: &wayland_server::Client) -> bool {
(self.filter)(client)
}
}
impl<D> Dispatch<PrimaryDeviceManager, (), D> for PrimarySelectionState
impl<D> Dispatch2<PrimaryDeviceManager, D> for GlobalData
where
D: Dispatch<PrimaryDeviceManager, ()>,
D: Dispatch<PrimarySource, PrimarySourceUserData>,
D: Dispatch<PrimaryDevice, PrimaryDeviceUserData>,
D: PrimarySelectionHandler,
@ -353,11 +354,11 @@ mod handlers {
D: 'static,
{
fn request(
&self,
_state: &mut D,
client: &wayland_server::Client,
_resource: &PrimaryDeviceManager,
request: primary_device_manager::Request,
_data: &(),
dhandle: &DisplayHandle,
data_init: &mut wayland_server::DataInit<'_, D>,
) {
@ -397,46 +398,3 @@ mod handlers {
}
}
}
#[allow(missing_docs)] // TODO
#[macro_export]
macro_rules! delegate_primary_selection {
($(@<$( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+>)? $ty: ty) => {
const _: () = {
use $crate::{
reexports::{
wayland_protocols::wp::primary_selection::zv1::server::{
zwp_primary_selection_device_manager_v1::ZwpPrimarySelectionDeviceManagerV1,
zwp_primary_selection_device_v1::ZwpPrimarySelectionDeviceV1,
zwp_primary_selection_source_v1::ZwpPrimarySelectionSourceV1,
},
wayland_server::{delegate_dispatch, delegate_global_dispatch},
},
wayland::selection::primary_selection::{
PrimaryDeviceManagerGlobalData, PrimaryDeviceUserData, PrimarySelectionState,
PrimarySourceUserData,
},
};
delegate_global_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [ZwpPrimarySelectionDeviceManagerV1: PrimaryDeviceManagerGlobalData] => PrimarySelectionState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [ZwpPrimarySelectionDeviceManagerV1: ()] => PrimarySelectionState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [ZwpPrimarySelectionDeviceV1: PrimaryDeviceUserData] => PrimarySelectionState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [ZwpPrimarySelectionSourceV1: PrimarySourceUserData] => PrimarySelectionState
);
};
};
}

View file

@ -3,14 +3,17 @@ use std::{cell::RefCell, sync::Mutex};
use wayland_protocols::wp::primary_selection::zv1::server::zwp_primary_selection_source_v1::{
self as primary_source, ZwpPrimarySelectionSourceV1 as PrimarySource,
};
use wayland_server::{Dispatch, DisplayHandle, backend::ClientId};
use wayland_server::{DisplayHandle, backend::ClientId};
use crate::{
input::Seat,
wayland::selection::{offer::OfferReplySource, seat_data::SeatData, source::SelectionSourceProvider},
wayland::{
Dispatch2,
selection::{offer::OfferReplySource, seat_data::SeatData, source::SelectionSourceProvider},
},
};
use super::{PrimarySelectionHandler, PrimarySelectionState};
use super::PrimarySelectionHandler;
/// The metadata describing a data source
#[derive(Debug, Default, Clone)]
@ -35,23 +38,22 @@ impl PrimarySourceUserData {
}
}
impl<D> Dispatch<PrimarySource, PrimarySourceUserData, D> for PrimarySelectionState
impl<D> Dispatch2<PrimarySource, D> for PrimarySourceUserData
where
D: Dispatch<PrimarySource, PrimarySourceUserData>,
D: PrimarySelectionHandler,
D: 'static,
{
fn request(
&self,
state: &mut D,
_client: &wayland_server::Client,
_resource: &PrimarySource,
request: primary_source::Request,
data: &PrimarySourceUserData,
_dhandle: &DisplayHandle,
_data_init: &mut wayland_server::DataInit<'_, D>,
) {
let _primary_selection_state = state.primary_selection_state();
let mut data = data.inner.lock().unwrap();
let mut data = self.inner.lock().unwrap();
match request {
primary_source::Request::Offer { mime_type } => {
@ -62,7 +64,7 @@ where
}
}
fn destroyed(state: &mut D, _client: ClientId, source: &PrimarySource, data: &PrimarySourceUserData) {
fn destroyed(&self, state: &mut D, _client: ClientId, source: &PrimarySource) {
// Remove the source from the used ones.
let seat = match state
.primary_selection_state()
@ -85,7 +87,7 @@ where
Some(OfferReplySource::Client(SelectionSourceProvider::Primary(set_source)))
if set_source == source =>
{
seat_data.set_primary_selection::<D>(&data.display_handle, None)
seat_data.set_primary_selection::<D>(&self.display_handle, None)
}
_ => (),
}

View file

@ -5,16 +5,17 @@ use wayland_protocols_wlr::data_control::v1::server::zwlr_data_control_device_v1
self, ZwlrDataControlDeviceV1,
};
use wayland_server::protocol::wl_seat::WlSeat;
use wayland_server::{Client, Dispatch, DisplayHandle, Resource};
use wayland_server::{Client, DisplayHandle, Resource};
use crate::input::Seat;
use crate::wayland::Dispatch2;
use crate::wayland::selection::device::SelectionDevice;
use crate::wayland::selection::offer::OfferReplySource;
use crate::wayland::selection::seat_data::SeatData;
use crate::wayland::selection::source::SelectionSourceProvider;
use crate::wayland::selection::{SelectionSource, SelectionTarget};
use super::{DataControlHandler, DataControlState};
use super::DataControlHandler;
#[allow(missing_debug_implementations)]
#[doc(hidden)]
@ -23,22 +24,21 @@ pub struct DataControlDeviceUserData {
pub(crate) wl_seat: WlSeat,
}
impl<D> Dispatch<ZwlrDataControlDeviceV1, DataControlDeviceUserData, D> for DataControlState
impl<D> Dispatch2<ZwlrDataControlDeviceV1, D> for DataControlDeviceUserData
where
D: Dispatch<ZwlrDataControlDeviceV1, DataControlDeviceUserData>,
D: DataControlHandler,
D: 'static,
{
fn request(
&self,
handler: &mut D,
client: &Client,
resource: &ZwlrDataControlDeviceV1,
request: <ZwlrDataControlDeviceV1 as wayland_server::Resource>::Request,
data: &DataControlDeviceUserData,
dh: &DisplayHandle,
_: &mut wayland_server::DataInit<'_, D>,
) {
let seat = match Seat::<D>::from_resource(&data.wl_seat) {
let seat = match Seat::<D>::from_resource(&self.wl_seat) {
Some(seat) => seat,
None => return,
};
@ -50,7 +50,7 @@ where
if handler
.data_control_state()
.used_sources
.insert(source.clone(), data.wl_seat.clone())
.insert(source.clone(), self.wl_seat.clone())
.is_some()
{
resource.post_error(
@ -80,7 +80,7 @@ where
}
zwlr_data_control_device_v1::Request::SetPrimarySelection { source, .. } => {
// When the primary selection is disabled, we should simply ignore the requests.
if !(*data.primary_selection_filter)(client) {
if !(*self.primary_selection_filter)(client) {
return;
}
@ -89,7 +89,7 @@ where
if handler
.data_control_state()
.used_sources
.insert(source.clone(), data.wl_seat.clone())
.insert(source.clone(), self.wl_seat.clone())
.is_some()
{
resource.post_error(
@ -132,12 +132,12 @@ where
}
fn destroyed(
&self,
_state: &mut D,
_client: wayland_server::backend::ClientId,
resource: &ZwlrDataControlDeviceV1,
data: &DataControlDeviceUserData,
) {
if let Some(seat) = Seat::<D>::from_resource(&data.wl_seat) {
if let Some(seat) = Seat::<D>::from_resource(&self.wl_seat) {
if let Some(seat_data) = seat.user_data().get::<RefCell<SeatData<D::SelectionUserData>>>() {
seat_data.borrow_mut().retain_devices(|ndd| match ndd {
SelectionDevice::WlrDataControl(ndd) => ndd != resource,

View file

@ -39,7 +39,8 @@
//! fn data_control_state(&mut self) -> &mut DataControlState { &mut self.data_control_state }
//! // ... override default implementations here to customize handling ...
//! }
//! delegate_data_control!(State);
//!
//! smithay::delegate_dispatch2!(State);
//!
//! // You're now ready to go!
//! ```
@ -141,23 +142,22 @@ mod handlers {
use wayland_protocols_wlr::data_control::v1::server::zwlr_data_control_manager_v1;
use wayland_protocols_wlr::data_control::v1::server::zwlr_data_control_manager_v1::ZwlrDataControlManagerV1;
use wayland_protocols_wlr::data_control::v1::server::zwlr_data_control_source_v1::ZwlrDataControlSourceV1;
use wayland_server::{Client, Dispatch, DisplayHandle, GlobalDispatch};
use wayland_server::{Client, Dispatch, DisplayHandle};
use crate::input::Seat;
use crate::wayland::selection::SelectionTarget;
use crate::wayland::selection::device::SelectionDevice;
use crate::wayland::selection::seat_data::SeatData;
use crate::wayland::{Dispatch2, GlobalDispatch2};
use super::DataControlDeviceUserData;
use super::DataControlHandler;
use super::DataControlManagerGlobalData;
use super::DataControlManagerUserData;
use super::DataControlSourceUserData;
use super::DataControlState;
impl<D> GlobalDispatch<ZwlrDataControlManagerV1, DataControlManagerGlobalData, D> for DataControlState
impl<D> GlobalDispatch2<ZwlrDataControlManagerV1, D> for DataControlManagerGlobalData
where
D: GlobalDispatch<ZwlrDataControlManagerV1, DataControlManagerGlobalData>,
D: Dispatch<ZwlrDataControlManagerV1, DataControlManagerUserData>,
D: Dispatch<ZwlrDataControlDeviceV1, DataControlDeviceUserData>,
D: Dispatch<ZwlrDataControlSourceV1, DataControlSourceUserData>,
@ -165,40 +165,39 @@ mod handlers {
D: 'static,
{
fn bind(
&self,
_state: &mut D,
_handle: &DisplayHandle,
_client: &wayland_server::Client,
resource: wayland_server::New<ZwlrDataControlManagerV1>,
global_data: &DataControlManagerGlobalData,
data_init: &mut wayland_server::DataInit<'_, D>,
) {
data_init.init(
resource,
DataControlManagerUserData {
primary_selection_filter: Arc::clone(&global_data.primary_selection_filter),
primary_selection_filter: Arc::clone(&self.primary_selection_filter),
},
);
}
fn can_view(client: Client, global_data: &DataControlManagerGlobalData) -> bool {
(global_data.filter)(&client)
fn can_view(&self, client: &Client) -> bool {
(self.filter)(client)
}
}
impl<D> Dispatch<ZwlrDataControlManagerV1, DataControlManagerUserData, D> for DataControlState
impl<D> Dispatch2<ZwlrDataControlManagerV1, D> for DataControlManagerUserData
where
D: Dispatch<ZwlrDataControlManagerV1, DataControlManagerUserData>,
D: Dispatch<ZwlrDataControlDeviceV1, DataControlDeviceUserData>,
D: Dispatch<ZwlrDataControlSourceV1, DataControlSourceUserData>,
D: DataControlHandler,
D: 'static,
{
fn request(
&self,
_handler: &mut D,
client: &wayland_server::Client,
_resource: &ZwlrDataControlManagerV1,
request: <ZwlrDataControlManagerV1 as wayland_server::Resource>::Request,
data: &DataControlManagerUserData,
dh: &DisplayHandle,
data_init: &mut wayland_server::DataInit<'_, D>,
) {
@ -216,7 +215,7 @@ mod handlers {
id,
DataControlDeviceUserData {
wl_seat,
primary_selection_filter: Arc::clone(&data.primary_selection_filter),
primary_selection_filter: Arc::clone(&self.primary_selection_filter),
},
));
@ -231,7 +230,7 @@ mod handlers {
// NOTE: broadcast selection only to the newly created device.
let device = Some(&device);
seat_data.send_selection::<D>(dh, SelectionTarget::Clipboard, device, true);
if (*data.primary_selection_filter)(client) {
if (*self.primary_selection_filter)(client) {
seat_data.send_selection::<D>(dh, SelectionTarget::Primary, device, true);
}
}
@ -250,46 +249,3 @@ mod handlers {
}
}
}
#[allow(missing_docs)] // TODO
#[macro_export]
macro_rules! delegate_data_control {
($(@<$( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+>)? $ty: ty) => {
const _: () = {
use $crate::{
reexports::{
wayland_protocols_wlr::data_control::v1::server::{
zwlr_data_control_device_v1::ZwlrDataControlDeviceV1,
zwlr_data_control_manager_v1::ZwlrDataControlManagerV1,
zwlr_data_control_source_v1::ZwlrDataControlSourceV1,
},
wayland_server::{delegate_dispatch, delegate_global_dispatch},
},
wayland::selection::wlr_data_control::{
DataControlDeviceUserData, DataControlManagerGlobalData, DataControlManagerUserData,
DataControlSourceUserData, DataControlState,
},
};
delegate_global_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [ZwlrDataControlManagerV1: DataControlManagerGlobalData] => DataControlState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [ZwlrDataControlManagerV1: DataControlManagerUserData] => DataControlState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [ZwlrDataControlDeviceV1: DataControlDeviceUserData] => DataControlState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [ZwlrDataControlSourceV1: DataControlSourceUserData] => DataControlState
);
};
};
}

View file

@ -4,16 +4,17 @@ use std::sync::Mutex;
use wayland_protocols_wlr::data_control::v1::server::zwlr_data_control_source_v1::{
self, ZwlrDataControlSourceV1,
};
use wayland_server::DisplayHandle;
use wayland_server::backend::ClientId;
use wayland_server::{Dispatch, DisplayHandle};
use crate::input::Seat;
use crate::wayland::Dispatch2;
use crate::wayland::selection::SelectionTarget;
use crate::wayland::selection::offer::OfferReplySource;
use crate::wayland::selection::seat_data::SeatData;
use crate::wayland::selection::source::SelectionSourceProvider;
use super::{DataControlHandler, DataControlState};
use super::DataControlHandler;
#[doc(hidden)]
#[derive(Debug)]
@ -38,24 +39,23 @@ pub struct SourceMetadata {
pub mime_types: Vec<String>,
}
impl<D> Dispatch<ZwlrDataControlSourceV1, DataControlSourceUserData, D> for DataControlState
impl<D> Dispatch2<ZwlrDataControlSourceV1, D> for DataControlSourceUserData
where
D: Dispatch<ZwlrDataControlSourceV1, DataControlSourceUserData>,
D: DataControlHandler,
D: 'static,
{
fn request(
&self,
_state: &mut D,
_client: &wayland_server::Client,
_resource: &ZwlrDataControlSourceV1,
request: <ZwlrDataControlSourceV1 as wayland_server::Resource>::Request,
data: &DataControlSourceUserData,
_dhandle: &DisplayHandle,
_data_init: &mut wayland_server::DataInit<'_, D>,
) {
match request {
zwlr_data_control_source_v1::Request::Offer { mime_type } => {
let mut data = data.inner.lock().unwrap();
let mut data = self.inner.lock().unwrap();
data.mime_types.push(mime_type);
}
zwlr_data_control_source_v1::Request::Destroy => (),
@ -63,12 +63,7 @@ where
}
}
fn destroyed(
state: &mut D,
_client: ClientId,
source: &ZwlrDataControlSourceV1,
data: &DataControlSourceUserData,
) {
fn destroyed(&self, state: &mut D, _client: ClientId, source: &ZwlrDataControlSourceV1) {
// Remove the source from the used ones.
let seat = match state
.data_control_state()
@ -99,10 +94,10 @@ where
{
match target {
SelectionTarget::Primary => {
seat_data.set_primary_selection::<D>(&data.display_handle, None)
seat_data.set_primary_selection::<D>(&self.display_handle, None)
}
SelectionTarget::Clipboard => {
seat_data.set_clipboard_selection::<D>(&data.display_handle, None)
seat_data.set_clipboard_selection::<D>(&self.display_handle, None)
}
}
}

View file

@ -10,8 +10,9 @@ use _session_lock::ext_session_lock_v1::{Error, ExtSessionLockV1, Request};
use wayland_protocols::ext::session_lock::v1::server::{self as _session_lock};
use wayland_server::{Client, DataInit, Dispatch, DisplayHandle, Resource};
use crate::wayland::Dispatch2;
use crate::wayland::session_lock::SessionLockHandler;
use crate::wayland::session_lock::surface::{ExtLockSurfaceUserData, LockSurface, LockSurfaceAttributes};
use crate::wayland::session_lock::{SessionLockHandler, SessionLockManagerState};
/// Surface role for ext-session-lock surfaces.
const LOCK_SURFACE_ROLE: &str = "ext_session_lock_surface_v1";
@ -30,19 +31,18 @@ impl SessionLockState {
}
}
impl<D> Dispatch<ExtSessionLockV1, SessionLockState, D> for SessionLockManagerState
impl<D> Dispatch2<ExtSessionLockV1, D> for SessionLockState
where
D: Dispatch<ExtSessionLockV1, SessionLockState>,
D: Dispatch<ExtSessionLockSurfaceV1, ExtLockSurfaceUserData>,
D: SessionLockHandler,
D: 'static,
{
fn request(
&self,
state: &mut D,
_client: &Client,
lock: &ExtSessionLockV1,
request: Request,
data: &SessionLockState,
_display: &DisplayHandle,
data_init: &mut DataInit<'_, D>,
) {
@ -109,7 +109,7 @@ where
}
Request::UnlockAndDestroy => {
// Ensure session is locked.
if !data.lock_status.load(Ordering::Relaxed) {
if !self.lock_status.load(Ordering::Relaxed) {
lock.post_error(Error::InvalidUnlock, "Session is not locked.");
}
@ -118,7 +118,7 @@ where
}
Request::Destroy => {
// Ensure session is not locked.
if data.lock_status.load(Ordering::Relaxed) {
if self.lock_status.load(Ordering::Relaxed) {
lock.post_error(Error::InvalidDestroy, "Cannot destroy session lock while locked.");
}
}

View file

@ -8,7 +8,6 @@
//! implement the [`SessionLockHandler`], as shown in this example:
//!
//! ```
//! use smithay::delegate_session_lock;
//! use smithay::reexports::wayland_server::protocol::wl_output::WlOutput;
//! use smithay::wayland::session_lock::{
//! LockSurface, SessionLockManagerState, SessionLockHandler, SessionLocker,
@ -43,7 +42,8 @@
//! // Display `LockSurface` on `WlOutput`.
//! }
//! }
//! delegate_session_lock!(State);
//!
//! smithay::delegate_dispatch2!(State);
//!
//! // You're now ready to go!
//! ```
@ -58,6 +58,8 @@ use wayland_server::protocol::wl_output::WlOutput;
use wayland_server::protocol::wl_surface::WlSurface;
use wayland_server::{Client, DataInit, Dispatch, DisplayHandle, GlobalDispatch, New};
use crate::wayland::{Dispatch2, GlobalData, GlobalDispatch2};
mod lock;
mod surface;
@ -80,7 +82,7 @@ impl SessionLockManagerState {
pub fn new<D, F>(display: &DisplayHandle, filter: F) -> Self
where
D: GlobalDispatch<ExtSessionLockManagerV1, SessionLockManagerGlobalData>,
D: Dispatch<ExtSessionLockManagerV1, ()>,
D: Dispatch<ExtSessionLockManagerV1, GlobalData>,
D: Dispatch<ExtSessionLockV1, SessionLockState>,
D: SessionLockHandler,
D: 'static,
@ -104,44 +106,40 @@ pub struct SessionLockManagerGlobalData {
filter: Box<dyn for<'c> Fn(&'c Client) -> bool + Send + Sync>,
}
impl<D> GlobalDispatch<ExtSessionLockManagerV1, SessionLockManagerGlobalData, D> for SessionLockManagerState
impl<D> GlobalDispatch2<ExtSessionLockManagerV1, D> for SessionLockManagerGlobalData
where
D: GlobalDispatch<ExtSessionLockManagerV1, SessionLockManagerGlobalData>,
D: Dispatch<ExtSessionLockManagerV1, ()>,
D: Dispatch<ExtSessionLockV1, SessionLockState>,
D: Dispatch<ExtSessionLockManagerV1, GlobalData>,
D: SessionLockHandler,
D: 'static,
{
fn bind(
&self,
_state: &mut D,
_display: &DisplayHandle,
_client: &Client,
manager: New<ExtSessionLockManagerV1>,
_global_data: &SessionLockManagerGlobalData,
data_init: &mut DataInit<'_, D>,
) {
data_init.init(manager, ());
data_init.init(manager, GlobalData);
}
fn can_view(client: Client, global_data: &SessionLockManagerGlobalData) -> bool {
(global_data.filter)(&client)
fn can_view(&self, client: &Client) -> bool {
(self.filter)(client)
}
}
impl<D> Dispatch<ExtSessionLockManagerV1, (), D> for SessionLockManagerState
impl<D> Dispatch2<ExtSessionLockManagerV1, D> for GlobalData
where
D: GlobalDispatch<ExtSessionLockManagerV1, SessionLockManagerGlobalData>,
D: Dispatch<ExtSessionLockManagerV1, ()>,
D: Dispatch<ExtSessionLockV1, SessionLockState>,
D: SessionLockHandler,
D: 'static,
{
fn request(
&self,
state: &mut D,
_client: &Client,
_manager: &ExtSessionLockManagerV1,
request: Request,
_data: &(),
_display: &DisplayHandle,
data_init: &mut DataInit<'_, D>,
) {
@ -222,46 +220,3 @@ impl SessionLocker {
}
}
}
#[allow(missing_docs)]
#[macro_export]
macro_rules! delegate_session_lock {
($(@<$( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+>)? $ty: ty) => {
const _: () = {
use $crate::{
reexports::{
wayland_protocols::ext::session_lock::v1::server::{
ext_session_lock_manager_v1::ExtSessionLockManagerV1,
ext_session_lock_surface_v1::ExtSessionLockSurfaceV1,
ext_session_lock_v1::ExtSessionLockV1,
},
wayland_server::{delegate_dispatch, delegate_global_dispatch},
},
wayland::session_lock::{
ExtLockSurfaceUserData, SessionLockManagerGlobalData, SessionLockManagerState,
SessionLockState,
},
};
delegate_global_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [ExtSessionLockManagerV1: SessionLockManagerGlobalData] => SessionLockManagerState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [ExtSessionLockManagerV1: ()] => SessionLockManagerState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [ExtSessionLockV1: SessionLockState] => SessionLockManagerState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [ExtSessionLockSurfaceV1: ExtLockSurfaceUserData] => SessionLockManagerState
);
};
};
}

View file

@ -10,9 +10,10 @@ use _session_lock::ext_session_lock_surface_v1::{Error, ExtSessionLockSurfaceV1,
use tracing::trace_span;
use wayland_protocols::ext::session_lock::v1::server::{self as _session_lock, ext_session_lock_surface_v1};
use wayland_server::protocol::wl_surface::WlSurface;
use wayland_server::{Client, DataInit, Dispatch, DisplayHandle, Resource, Weak};
use wayland_server::{Client, DataInit, DisplayHandle, Resource, Weak};
use crate::wayland::session_lock::{SessionLockHandler, SessionLockManagerState};
use crate::wayland::Dispatch2;
use crate::wayland::session_lock::SessionLockHandler;
/// User data for ext-session-lock surfaces.
#[derive(Debug)]
@ -23,24 +24,23 @@ pub struct ExtLockSurfaceUserData {
pub(crate) surface: Weak<WlSurface>,
}
impl<D> Dispatch<ExtSessionLockSurfaceV1, ExtLockSurfaceUserData, D> for SessionLockManagerState
impl<D> Dispatch2<ExtSessionLockSurfaceV1, D> for ExtLockSurfaceUserData
where
D: Dispatch<ExtSessionLockSurfaceV1, ExtLockSurfaceUserData>,
D: SessionLockHandler,
D: 'static,
{
fn request(
&self,
state: &mut D,
_client: &Client,
lock_surface: &ExtSessionLockSurfaceV1,
request: Request,
data: &ExtLockSurfaceUserData,
_display: &DisplayHandle,
_data_init: &mut DataInit<'_, D>,
) {
match request {
Request::AckConfigure { serial } => {
let Ok(surface) = data.surface.upgrade() else {
let Ok(surface) = self.surface.upgrade() else {
return;
};
@ -65,12 +65,12 @@ where
}
fn destroyed(
&self,
_state: &mut D,
_client: wayland_server::backend::ClientId,
_resource: &ExtSessionLockSurfaceV1,
data: &ExtLockSurfaceUserData,
) {
if let Ok(surface) = data.surface.upgrade() {
if let Ok(surface) = self.surface.upgrade() {
compositor::with_states(&surface, |states| {
let mut attributes = states
.data_map

View file

@ -8,7 +8,6 @@
//! extern crate wayland_server;
//! extern crate smithay;
//!
//! use smithay::delegate_kde_decoration;
//! use smithay::wayland::shell::kde::decoration::{KdeDecorationHandler, KdeDecorationState};
//! use wayland_protocols_misc::server_decoration::server::org_kde_kwin_server_decoration_manager::Mode;
//!
@ -28,7 +27,7 @@
//! }
//! }
//!
//! delegate_kde_decoration!(State);
//! smithay::delegate_dispatch2!(State);
//! ```
use wayland_protocols_misc::server_decoration::server::org_kde_kwin_server_decoration::{
@ -41,6 +40,8 @@ use wayland_server::backend::GlobalId;
use wayland_server::protocol::wl_surface::WlSurface;
use wayland_server::{Client, Dispatch, DisplayHandle, GlobalDispatch, WEnum};
use crate::wayland::GlobalData;
/// KDE server decoration handler.
pub trait KdeDecorationHandler {
/// Return the KDE server decoration state.
@ -89,13 +90,17 @@ pub struct KdeDecorationManagerGlobalData {
pub(crate) filter: Box<dyn for<'c> Fn(&'c Client) -> bool + Send + Sync>,
}
#[doc(hidden)]
#[derive(Debug)]
pub struct KwinServerDecorationData(pub(crate) WlSurface);
impl KdeDecorationState {
/// Create a new KDE server decoration global.
pub fn new<D>(display: &DisplayHandle, default_mode: DefaultMode) -> Self
where
D: GlobalDispatch<OrgKdeKwinServerDecorationManager, KdeDecorationManagerGlobalData>
+ Dispatch<OrgKdeKwinServerDecorationManager, ()>
+ Dispatch<OrgKdeKwinServerDecoration, WlSurface>
+ Dispatch<OrgKdeKwinServerDecorationManager, GlobalData>
+ Dispatch<OrgKdeKwinServerDecoration, KwinServerDecorationData>
+ KdeDecorationHandler
+ 'static,
{
@ -108,8 +113,8 @@ impl KdeDecorationState {
pub fn new_with_filter<D, F>(display: &DisplayHandle, default_mode: DefaultMode, filter: F) -> Self
where
D: GlobalDispatch<OrgKdeKwinServerDecorationManager, KdeDecorationManagerGlobalData>
+ Dispatch<OrgKdeKwinServerDecorationManager, ()>
+ Dispatch<OrgKdeKwinServerDecoration, WlSurface>
+ Dispatch<OrgKdeKwinServerDecorationManager, GlobalData>
+ Dispatch<OrgKdeKwinServerDecoration, KwinServerDecorationData>
+ KdeDecorationHandler
+ 'static,
F: for<'c> Fn(&'c Client) -> bool + Send + Sync + 'static,
@ -139,38 +144,3 @@ impl KdeDecorationState {
self.default_mode = default_mode;
}
}
#[allow(missing_docs)] // TODO
#[macro_export]
macro_rules! delegate_kde_decoration {
($(@<$( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+>)? $ty: ty) => {
const _: () = {
use $crate::{
reexports::{
wayland_protocols_misc::server_decoration::server::{
org_kde_kwin_server_decoration::OrgKdeKwinServerDecoration,
org_kde_kwin_server_decoration_manager::OrgKdeKwinServerDecorationManager,
},
wayland_server::protocol::wl_surface::WlSurface,
wayland_server::{delegate_dispatch, delegate_global_dispatch},
},
wayland::shell::kde::decoration::{KdeDecorationManagerGlobalData, KdeDecorationState},
};
delegate_global_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [OrgKdeKwinServerDecorationManager: KdeDecorationManagerGlobalData] => KdeDecorationState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [OrgKdeKwinServerDecorationManager: ()] => KdeDecorationState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [OrgKdeKwinServerDecoration: WlSurface] => KdeDecorationState
);
};
};
}

View file

@ -7,31 +7,29 @@ use wayland_protocols_misc::server_decoration::server::org_kde_kwin_server_decor
use wayland_protocols_misc::server_decoration::server::org_kde_kwin_server_decoration_manager::{
OrgKdeKwinServerDecorationManager, Request as ManagerRequest,
};
use wayland_server::protocol::wl_surface::WlSurface;
use wayland_server::{Client, DataInit, Dispatch, DisplayHandle, GlobalDispatch, New, Resource};
use wayland_server::{Client, DataInit, Dispatch, DisplayHandle, New, Resource};
use crate::wayland::shell::kde::decoration::{KdeDecorationHandler, KdeDecorationState};
use crate::wayland::shell::kde::decoration::KdeDecorationHandler;
use crate::wayland::{Dispatch2, GlobalData, GlobalDispatch2};
use super::decoration::KdeDecorationManagerGlobalData;
use super::decoration::{KdeDecorationManagerGlobalData, KwinServerDecorationData};
impl<D> GlobalDispatch<OrgKdeKwinServerDecorationManager, KdeDecorationManagerGlobalData, D>
for KdeDecorationState
impl<D> GlobalDispatch2<OrgKdeKwinServerDecorationManager, D> for KdeDecorationManagerGlobalData
where
D: GlobalDispatch<OrgKdeKwinServerDecorationManager, KdeDecorationManagerGlobalData>
+ Dispatch<OrgKdeKwinServerDecorationManager, ()>
+ Dispatch<OrgKdeKwinServerDecoration, WlSurface>
D: Dispatch<OrgKdeKwinServerDecorationManager, GlobalData>
+ Dispatch<OrgKdeKwinServerDecoration, KwinServerDecorationData>
+ KdeDecorationHandler
+ 'static,
{
fn bind(
&self,
state: &mut D,
_dh: &DisplayHandle,
_client: &Client,
resource: New<OrgKdeKwinServerDecorationManager>,
_global_data: &KdeDecorationManagerGlobalData,
data_init: &mut DataInit<'_, D>,
) {
let kde_decoration_manager = data_init.init(resource, ());
let kde_decoration_manager = data_init.init(resource, GlobalData);
// Set default decoration mode.
let default_mode = state.kde_decoration_state().default_mode;
@ -40,25 +38,21 @@ where
trace!("Bound decoration manager global");
}
fn can_view(client: Client, global_data: &KdeDecorationManagerGlobalData) -> bool {
(global_data.filter)(&client)
fn can_view(&self, client: &Client) -> bool {
(self.filter)(client)
}
}
impl<D> Dispatch<OrgKdeKwinServerDecorationManager, (), D> for KdeDecorationState
impl<D> Dispatch2<OrgKdeKwinServerDecorationManager, D> for GlobalData
where
D: Dispatch<OrgKdeKwinServerDecorationManager, ()>
+ Dispatch<OrgKdeKwinServerDecorationManager, ()>
+ Dispatch<OrgKdeKwinServerDecoration, WlSurface>
+ KdeDecorationHandler
+ 'static,
D: Dispatch<OrgKdeKwinServerDecoration, KwinServerDecorationData> + KdeDecorationHandler + 'static,
{
fn request(
&self,
state: &mut D,
_client: &Client,
_kde_decoration_manager: &OrgKdeKwinServerDecorationManager,
request: ManagerRequest,
_data: &(),
_dh: &DisplayHandle,
data_init: &mut DataInit<'_, D>,
) {
@ -67,28 +61,30 @@ where
_ => unreachable!(),
};
let kde_decoration = data_init.init(id, surface);
let kde_decoration = data_init.init(id, KwinServerDecorationData(surface));
let surface = kde_decoration.data().unwrap();
let surface = &kde_decoration.data::<KwinServerDecorationData>().unwrap().0;
state.new_decoration(surface, &kde_decoration);
trace!(surface = ?surface, "Created decoration object for surface");
}
}
impl<D> Dispatch<OrgKdeKwinServerDecoration, WlSurface, D> for KdeDecorationState
impl<D> Dispatch2<OrgKdeKwinServerDecoration, D> for KwinServerDecorationData
where
D: Dispatch<OrgKdeKwinServerDecoration, WlSurface> + KdeDecorationHandler + 'static,
D: KdeDecorationHandler + 'static,
{
fn request(
&self,
state: &mut D,
_client: &Client,
kde_decoration: &OrgKdeKwinServerDecoration,
request: Request,
surface: &WlSurface,
_dh: &DisplayHandle,
_data_init: &mut DataInit<'_, D>,
) {
let surface = &self.0;
trace!(
surface = ?surface,
request = ?request,

View file

@ -4,14 +4,14 @@ use wayland_protocols_wlr::layer_shell::v1::server::zwlr_layer_shell_v1::{self,
use wayland_protocols_wlr::layer_shell::v1::server::zwlr_layer_surface_v1;
use wayland_protocols_wlr::layer_shell::v1::server::zwlr_layer_surface_v1::ZwlrLayerSurfaceV1;
use wayland_server::protocol::wl_surface;
use wayland_server::{Client, DataInit, Dispatch, DisplayHandle, GlobalDispatch, Resource, Weak};
use wayland_server::{Client, DataInit, Dispatch, DisplayHandle, Resource, Weak};
use crate::utils::{
Serial,
alive_tracker::{AliveTracker, IsAlive},
};
use crate::wayland::shell::xdg::XdgPopupSurfaceData;
use crate::wayland::{compositor, shell::wlr_layer::Layer};
use crate::wayland::{Dispatch2, GlobalData, GlobalDispatch2, compositor, shell::wlr_layer::Layer};
use super::{
Anchor, KeyboardInteractivity, LayerSurfaceAttributes, LayerSurfaceCachedState, LayerSurfaceData,
@ -24,43 +24,41 @@ use super::LAYER_SURFACE_ROLE;
* layer_shell
*/
impl<D> GlobalDispatch<ZwlrLayerShellV1, WlrLayerShellGlobalData, D> for WlrLayerShellState
impl<D> GlobalDispatch2<ZwlrLayerShellV1, D> for WlrLayerShellGlobalData
where
D: GlobalDispatch<ZwlrLayerShellV1, WlrLayerShellGlobalData>,
D: Dispatch<ZwlrLayerShellV1, ()>,
D: Dispatch<ZwlrLayerShellV1, GlobalData>,
D: Dispatch<ZwlrLayerSurfaceV1, WlrLayerSurfaceUserData>,
D: WlrLayerShellHandler,
D: 'static,
{
fn bind(
&self,
_state: &mut D,
_handle: &DisplayHandle,
_client: &Client,
resource: wayland_server::New<ZwlrLayerShellV1>,
_global_data: &WlrLayerShellGlobalData,
data_init: &mut DataInit<'_, D>,
) {
data_init.init(resource, ());
data_init.init(resource, GlobalData);
}
fn can_view(client: Client, global_data: &WlrLayerShellGlobalData) -> bool {
(global_data.filter)(&client)
fn can_view(&self, client: &Client) -> bool {
(self.filter)(client)
}
}
impl<D> Dispatch<ZwlrLayerShellV1, (), D> for WlrLayerShellState
impl<D> Dispatch2<ZwlrLayerShellV1, D> for GlobalData
where
D: Dispatch<ZwlrLayerShellV1, ()>,
D: Dispatch<ZwlrLayerSurfaceV1, WlrLayerSurfaceUserData>,
D: WlrLayerShellHandler,
D: 'static,
{
fn request(
&self,
state: &mut D,
_client: &Client,
shell: &ZwlrLayerShellV1,
request: zwlr_layer_shell_v1::Request,
_data: &(),
_dh: &DisplayHandle,
data_init: &mut DataInit<'_, D>,
) {
@ -173,17 +171,16 @@ impl IsAlive for ZwlrLayerSurfaceV1 {
}
}
impl<D> Dispatch<ZwlrLayerSurfaceV1, WlrLayerSurfaceUserData, D> for WlrLayerShellState
impl<D> Dispatch2<ZwlrLayerSurfaceV1, D> for WlrLayerSurfaceUserData
where
D: Dispatch<ZwlrLayerSurfaceV1, WlrLayerSurfaceUserData>,
D: WlrLayerShellHandler,
{
fn request(
&self,
state: &mut D,
_client: &Client,
layer_surface: &ZwlrLayerSurfaceV1,
request: zwlr_layer_surface_v1::Request,
data: &WlrLayerSurfaceUserData,
_dh: &DisplayHandle,
_data_init: &mut DataInit<'_, D>,
) {
@ -273,7 +270,7 @@ where
};
}
zwlr_layer_surface_v1::Request::GetPopup { popup } => {
let Ok(parent_surface) = data.wl_surface.upgrade() else {
let Ok(parent_surface) = self.wl_surface.upgrade() else {
return;
};
@ -298,7 +295,7 @@ where
);
}
zwlr_layer_surface_v1::Request::AckConfigure { serial } => {
let Ok(surface) = data.wl_surface.upgrade() else {
let Ok(surface) = self.wl_surface.upgrade() else {
return;
};
@ -335,15 +332,15 @@ where
}
fn destroyed(
&self,
state: &mut D,
_client_id: wayland_server::backend::ClientId,
layer_surface: &ZwlrLayerSurfaceV1,
data: &WlrLayerSurfaceUserData,
) {
data.alive_tracker.destroy_notify();
self.alive_tracker.destroy_notify();
// remove this surface from the known ones (as well as any leftover dead surface)
let mut layers = data.shell_data.known_layers.lock().unwrap();
let mut layers = self.shell_data.known_layers.lock().unwrap();
if let Some(index) = layers
.iter()
.position(|layer| layer.shell_surface.id() == layer_surface.id())

View file

@ -11,7 +11,6 @@
//! ```no_run
//! # extern crate wayland_server;
//! #
//! use smithay::delegate_layer_shell;
//! use smithay::wayland::shell::wlr_layer::{WlrLayerShellState, WlrLayerShellHandler, LayerSurface, Layer};
//! use smithay::reexports::wayland_server::protocol::wl_output::WlOutput;
//!
@ -39,8 +38,8 @@
//! // your implementation
//! }
//! }
//! // let smithay implement wayland_server::DelegateDispatch
//! delegate_layer_shell!(State);
//!
//! smithay::delegate_dispatch2!(State);
//!
//! // You're now ready to go!
//! ```
@ -583,40 +582,3 @@ pub struct LayerSurfaceConfigure {
/// serials.
pub serial: Serial,
}
/// Macro to delegate implementation of wlr layer shell to [`WlrLayerShellState`].
///
/// You must also implement [`WlrLayerShellHandler`] to use this.
#[macro_export]
macro_rules! delegate_layer_shell {
($(@<$( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+>)? $ty: ty) => {
const _: () = {
use $crate::{
reexports::{
wayland_protocols_wlr::layer_shell::v1::server::{
zwlr_layer_shell_v1::ZwlrLayerShellV1, zwlr_layer_surface_v1::ZwlrLayerSurfaceV1,
},
wayland_server::{delegate_dispatch, delegate_global_dispatch},
},
wayland::shell::wlr_layer::{
WlrLayerShellGlobalData, WlrLayerShellState, WlrLayerSurfaceUserData,
},
};
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [ZwlrLayerShellV1: ()] => WlrLayerShellState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [ZwlrLayerSurfaceV1: WlrLayerSurfaceUserData] => WlrLayerShellState
);
delegate_global_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [ZwlrLayerShellV1: WlrLayerShellGlobalData] => WlrLayerShellState
);
};
};
}

View file

@ -8,7 +8,6 @@
//! ```no_run
//! # extern crate wayland_server;
//! #
//! use smithay::{delegate_xdg_decoration, delegate_xdg_shell};
//! use smithay::wayland::shell::xdg::{ToplevelSurface, XdgShellHandler};
//! # use smithay::utils::Serial;
//! # use smithay::wayland::shell::xdg::{XdgShellState, PopupSurface, PositionerState};
@ -81,8 +80,8 @@
//! // handle new images for the cursor ...
//! }
//! }
//! delegate_xdg_shell!(State);
//! delegate_xdg_decoration!(State);
//!
//! smithay::delegate_dispatch2!(State);
//!
//! // You are ready to go!
// TODO: Describe how to change decoration mode.
@ -96,7 +95,7 @@ use wayland_server::{
};
use super::{ToplevelSurface, XdgShellHandler};
use crate::wayland::shell::xdg::XdgShellSurfaceUserData;
use crate::wayland::{Dispatch2, GlobalData, GlobalDispatch2, shell::xdg::XdgShellSurfaceUserData};
/// Delegate type for handling xdg decoration events.
#[derive(Debug)]
@ -119,7 +118,7 @@ impl XdgDecorationState {
D: GlobalDispatch<
zxdg_decoration_manager_v1::ZxdgDecorationManagerV1,
XdgDecorationManagerGlobalData,
> + Dispatch<zxdg_decoration_manager_v1::ZxdgDecorationManagerV1, ()>
> + Dispatch<zxdg_decoration_manager_v1::ZxdgDecorationManagerV1, GlobalData>
+ 'static,
{
Self::new_with_filter::<D, _>(display, |_| true)
@ -135,7 +134,7 @@ impl XdgDecorationState {
D: GlobalDispatch<
zxdg_decoration_manager_v1::ZxdgDecorationManagerV1,
XdgDecorationManagerGlobalData,
> + Dispatch<zxdg_decoration_manager_v1::ZxdgDecorationManagerV1, ()>
> + Dispatch<zxdg_decoration_manager_v1::ZxdgDecorationManagerV1, GlobalData>
+ 'static,
F: for<'c> Fn(&'c Client) -> bool + Send + Sync + 'static,
{
@ -166,25 +165,6 @@ pub trait XdgDecorationHandler {
fn unset_mode(&mut self, toplevel: ToplevelSurface);
}
/// Macro to delegate implementation of the xdg decoration to [`XdgDecorationState`].
///
/// You must also implement [`XdgDecorationHandler`] to use this.
#[macro_export]
macro_rules! delegate_xdg_decoration {
($(@<$( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+>)? $ty: ty) => {
$crate::reexports::wayland_server::delegate_global_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [
$crate::reexports::wayland_protocols::xdg::decoration::zv1::server::zxdg_decoration_manager_v1::ZxdgDecorationManagerV1: $crate::wayland::shell::xdg::decoration::XdgDecorationManagerGlobalData
] => $crate::wayland::shell::xdg::decoration::XdgDecorationState);
$crate::reexports::wayland_server::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [
$crate::reexports::wayland_protocols::xdg::decoration::zv1::server::zxdg_decoration_manager_v1::ZxdgDecorationManagerV1: ()
] => $crate::wayland::shell::xdg::decoration::XdgDecorationState);
$crate::reexports::wayland_server::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [
$crate::reexports::wayland_protocols::xdg::decoration::zv1::server::zxdg_toplevel_decoration_v1::ZxdgToplevelDecorationV1: $crate::wayland::shell::xdg::ToplevelSurface
] => $crate::wayland::shell::xdg::decoration::XdgDecorationState);
};
}
pub(super) fn send_decoration_configure(
id: &zxdg_toplevel_decoration_v1::ZxdgToplevelDecorationV1,
mode: Mode,
@ -192,46 +172,44 @@ pub(super) fn send_decoration_configure(
id.configure(mode)
}
impl<D> GlobalDispatch<zxdg_decoration_manager_v1::ZxdgDecorationManagerV1, XdgDecorationManagerGlobalData, D>
for XdgDecorationState
impl<D> GlobalDispatch2<zxdg_decoration_manager_v1::ZxdgDecorationManagerV1, D>
for XdgDecorationManagerGlobalData
where
D: GlobalDispatch<zxdg_decoration_manager_v1::ZxdgDecorationManagerV1, XdgDecorationManagerGlobalData>
+ Dispatch<zxdg_decoration_manager_v1::ZxdgDecorationManagerV1, ()>
D: Dispatch<zxdg_decoration_manager_v1::ZxdgDecorationManagerV1, GlobalData>
+ Dispatch<zxdg_toplevel_decoration_v1::ZxdgToplevelDecorationV1, ToplevelSurface>
+ XdgShellHandler
+ XdgDecorationHandler
+ 'static,
{
fn bind(
&self,
_: &mut D,
_: &DisplayHandle,
_: &Client,
resource: New<zxdg_decoration_manager_v1::ZxdgDecorationManagerV1>,
_: &XdgDecorationManagerGlobalData,
data_init: &mut DataInit<'_, D>,
) {
data_init.init(resource, ());
data_init.init(resource, GlobalData);
}
fn can_view(client: Client, global_data: &XdgDecorationManagerGlobalData) -> bool {
(global_data.filter)(&client)
fn can_view(&self, client: &Client) -> bool {
(self.filter)(client)
}
}
impl<D> Dispatch<zxdg_decoration_manager_v1::ZxdgDecorationManagerV1, (), D> for XdgDecorationState
impl<D> Dispatch2<zxdg_decoration_manager_v1::ZxdgDecorationManagerV1, D> for GlobalData
where
D: Dispatch<zxdg_decoration_manager_v1::ZxdgDecorationManagerV1, ()>
+ Dispatch<zxdg_toplevel_decoration_v1::ZxdgToplevelDecorationV1, ToplevelSurface>
D: Dispatch<zxdg_toplevel_decoration_v1::ZxdgToplevelDecorationV1, ToplevelSurface>
+ XdgShellHandler
+ XdgDecorationHandler
+ 'static,
{
fn request(
&self,
state: &mut D,
_: &Client,
resource: &zxdg_decoration_manager_v1::ZxdgDecorationManagerV1,
request: zxdg_decoration_manager_v1::Request,
_: &(),
_dh: &DisplayHandle,
data_init: &mut DataInit<'_, D>,
) {
@ -277,18 +255,16 @@ where
// zxdg_toplevel_decoration_v1
impl<D> Dispatch<zxdg_toplevel_decoration_v1::ZxdgToplevelDecorationV1, ToplevelSurface, D>
for XdgDecorationState
impl<D> Dispatch2<zxdg_toplevel_decoration_v1::ZxdgToplevelDecorationV1, D> for ToplevelSurface
where
D: Dispatch<zxdg_toplevel_decoration_v1::ZxdgToplevelDecorationV1, ToplevelSurface>
+ XdgDecorationHandler,
D: XdgDecorationHandler,
{
fn request(
&self,
state: &mut D,
_: &Client,
_: &zxdg_toplevel_decoration_v1::ZxdgToplevelDecorationV1,
request: zxdg_toplevel_decoration_v1::Request,
data: &ToplevelSurface,
_dh: &DisplayHandle,
_: &mut DataInit<'_, D>,
) {
@ -297,16 +273,16 @@ where
match request {
Request::SetMode { mode } => {
if let WEnum::Value(mode) = mode {
state.request_mode(data.clone(), mode);
state.request_mode(self.clone(), mode);
}
}
Request::UnsetMode => {
state.unset_mode(data.clone());
state.unset_mode(self.clone());
}
Request::Destroy => {
if let Some(data) = data.xdg_toplevel().data::<XdgShellSurfaceUserData>() {
if let Some(data) = self.xdg_toplevel().data::<XdgShellSurfaceUserData>() {
data.decoration.lock().unwrap().take();
}
}

View file

@ -5,7 +5,6 @@
//! ```no_run
//! # extern crate wayland_server;
//! #
//! use smithay::{delegate_xdg_dialog, delegate_xdg_shell};
//! use smithay::wayland::shell::xdg::{ToplevelSurface, XdgShellHandler};
//! # use smithay::utils::Serial;
//! # use smithay::wayland::shell::xdg::{XdgShellState, PopupSurface, PositionerState};
@ -69,8 +68,8 @@
//! // handle new images for the cursor ...
//! }
//! }
//! delegate_xdg_shell!(State);
//! delegate_xdg_dialog!(State);
//!
//! smithay::delegate_dispatch2!(State);
//!
//! // You are ready to go!
@ -85,7 +84,7 @@ use wayland_server::{
use super::{ToplevelSurface, XdgShellHandler};
use crate::wayland::{
compositor,
Dispatch2, GlobalData, GlobalDispatch2, compositor,
shell::xdg::{XdgShellSurfaceUserData, XdgToplevelSurfaceData},
};
@ -101,9 +100,9 @@ impl XdgDialogState {
/// A global id is also returned to allow destroying the global in the future.
pub fn new<D>(display: &DisplayHandle) -> XdgDialogState
where
D: GlobalDispatch<XdgWmDialogV1, ()> + Dispatch<XdgWmDialogV1, ()> + 'static,
D: GlobalDispatch<XdgWmDialogV1, GlobalData> + Dispatch<XdgWmDialogV1, GlobalData> + 'static,
{
let global = display.create_global::<D, XdgWmDialogV1, _>(1, ());
let global = display.create_global::<D, XdgWmDialogV1, _>(1, GlobalData);
XdgDialogState { global }
}
@ -114,12 +113,7 @@ impl XdgDialogState {
}
/// Handler trait for xdg dialog events.
pub trait XdgDialogHandler:
XdgShellHandler
+ GlobalDispatch<XdgWmDialogV1, ()>
+ Dispatch<XdgWmDialogV1, ()>
+ Dispatch<XdgDialogV1, ToplevelSurface>
{
pub trait XdgDialogHandler: XdgShellHandler {
/// The client has changed the dialog hint associated with the toplevel
fn dialog_hint_changed(&mut self, toplevel: ToplevelSurface, hint: ToplevelDialogHint) {
let _ = toplevel;
@ -127,47 +121,34 @@ pub trait XdgDialogHandler:
}
}
/// Macro to delegate implementation of the xdg dialog to [`XdgDialogState`].
///
/// You must also implement [`XdgDialogHandler`] to use this.
#[macro_export]
macro_rules! delegate_xdg_dialog {
($(@<$( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+>)? $ty: ty) => {
$crate::reexports::wayland_server::delegate_global_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [
$crate::reexports::wayland_protocols::xdg::dialog::v1::server::xdg_wm_dialog_v1::XdgWmDialogV1: ()
] => $crate::wayland::shell::xdg::dialog::XdgDialogState);
$crate::reexports::wayland_server::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [
$crate::reexports::wayland_protocols::xdg::dialog::v1::server::xdg_wm_dialog_v1::XdgWmDialogV1: ()
] => $crate::wayland::shell::xdg::dialog::XdgDialogState);
$crate::reexports::wayland_server::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [
$crate::reexports::wayland_protocols::xdg::dialog::v1::server::xdg_dialog_v1::XdgDialogV1: $crate::wayland::shell::xdg::ToplevelSurface
] => $crate::wayland::shell::xdg::dialog::XdgDialogState);
};
}
// xdg_wm_dialog_v1
impl<D: XdgDialogHandler> GlobalDispatch<XdgWmDialogV1, (), D> for XdgDialogState {
impl<D: XdgDialogHandler> GlobalDispatch2<XdgWmDialogV1, D> for GlobalData
where
D: Dispatch<XdgWmDialogV1, GlobalData>,
{
fn bind(
&self,
_: &mut D,
_: &DisplayHandle,
_: &Client,
resource: New<XdgWmDialogV1>,
_: &(),
data_init: &mut DataInit<'_, D>,
) {
data_init.init(resource, ());
data_init.init(resource, GlobalData);
}
}
impl<D: XdgDialogHandler> Dispatch<XdgWmDialogV1, (), D> for XdgDialogState {
impl<D: XdgDialogHandler> Dispatch2<XdgWmDialogV1, D> for GlobalData
where
D: Dispatch<XdgDialogV1, ToplevelSurface>,
{
fn request(
&self,
state: &mut D,
_: &Client,
resource: &XdgWmDialogV1,
request: xdg_wm_dialog_v1::Request,
_: &(),
_dh: &DisplayHandle,
data_init: &mut DataInit<'_, D>,
) {
@ -207,13 +188,13 @@ impl<D: XdgDialogHandler> Dispatch<XdgWmDialogV1, (), D> for XdgDialogState {
// xdg_dialog_v1
impl<D: XdgDialogHandler> Dispatch<XdgDialogV1, ToplevelSurface, D> for XdgDialogState {
impl<D: XdgDialogHandler> Dispatch2<XdgDialogV1, D> for ToplevelSurface {
fn request(
&self,
state: &mut D,
_: &Client,
_: &XdgDialogV1,
request: xdg_dialog_v1::Request,
toplevel: &ToplevelSurface,
_dh: &DisplayHandle,
_: &mut DataInit<'_, D>,
) {
@ -221,23 +202,23 @@ impl<D: XdgDialogHandler> Dispatch<XdgDialogV1, ToplevelSurface, D> for XdgDialo
match request {
Request::SetModal => {
if set_dialog_hint(toplevel.wl_surface(), ToplevelDialogHint::Modal) {
state.dialog_hint_changed(toplevel.clone(), ToplevelDialogHint::Modal);
if set_dialog_hint(self.wl_surface(), ToplevelDialogHint::Modal) {
state.dialog_hint_changed(self.clone(), ToplevelDialogHint::Modal);
}
}
Request::UnsetModal => {
if set_dialog_hint(toplevel.wl_surface(), ToplevelDialogHint::Dialog) {
state.dialog_hint_changed(toplevel.clone(), ToplevelDialogHint::Dialog);
if set_dialog_hint(self.wl_surface(), ToplevelDialogHint::Dialog) {
state.dialog_hint_changed(self.clone(), ToplevelDialogHint::Dialog);
}
}
Request::Destroy => {
if set_dialog_hint(toplevel.wl_surface(), ToplevelDialogHint::Unknown) {
state.dialog_hint_changed(toplevel.clone(), ToplevelDialogHint::Unknown);
if set_dialog_hint(self.wl_surface(), ToplevelDialogHint::Unknown) {
state.dialog_hint_changed(self.clone(), ToplevelDialogHint::Unknown);
}
if let Some(data) = toplevel.xdg_toplevel().data::<XdgShellSurfaceUserData>() {
if let Some(data) = self.xdg_toplevel().data::<XdgShellSurfaceUserData>() {
data.dialog.lock().unwrap().take();
}
}

View file

@ -1,6 +1,6 @@
use super::{
PopupConfigure, PositionerState, ShellClient, ShellClientData, SurfaceCachedState, ToplevelConfigure,
XdgPopupSurfaceRoleAttributes, XdgShellHandler, XdgShellState, XdgToplevelSurfaceRoleAttributes,
XdgPopupSurfaceRoleAttributes, XdgShellHandler, XdgToplevelSurfaceRoleAttributes,
};
mod wm_base;

View file

@ -1,12 +1,12 @@
use std::sync::Mutex;
use crate::{utils::Rectangle, utils::Serial};
use crate::{utils::Rectangle, utils::Serial, wayland::Dispatch2};
use wayland_protocols::xdg::shell::server::{xdg_positioner, xdg_positioner::XdgPositioner};
use wayland_server::{DataInit, Dispatch, DisplayHandle, Resource, WEnum};
use wayland_server::{DataInit, DisplayHandle, Resource, WEnum};
use super::{PositionerState, XdgShellHandler, XdgShellState};
use super::{PositionerState, XdgShellHandler};
/*
* xdg_positioner
@ -18,22 +18,21 @@ pub struct XdgPositionerUserData {
pub(crate) inner: Mutex<PositionerState>,
}
impl<D> Dispatch<XdgPositioner, XdgPositionerUserData, D> for XdgShellState
impl<D> Dispatch2<XdgPositioner, D> for XdgPositionerUserData
where
D: Dispatch<XdgPositioner, XdgPositionerUserData>,
D: XdgShellHandler,
D: 'static,
{
fn request(
&self,
_state: &mut D,
_client: &wayland_server::Client,
positioner: &XdgPositioner,
request: xdg_positioner::Request,
data: &XdgPositionerUserData,
_dh: &DisplayHandle,
_data_init: &mut DataInit<'_, D>,
) {
let mut state = data.inner.lock().unwrap();
let mut state = self.inner.lock().unwrap();
match request {
xdg_positioner::Request::SetSize { width, height } => {
if width < 1 || height < 1 {

View file

@ -9,8 +9,8 @@ use crate::wayland::shell::xdg::{XdgPopupSurfaceData, XdgToplevelSurfaceData};
use crate::{
utils::{Rectangle, Serial},
wayland::{
compositor,
shell::xdg::{PopupState, XDG_POPUP_ROLE, XDG_TOPLEVEL_ROLE, XdgShellState},
Dispatch2, compositor,
shell::xdg::{PopupState, XDG_POPUP_ROLE, XDG_TOPLEVEL_ROLE},
},
};
@ -45,44 +45,43 @@ pub struct XdgSurfaceUserData {
pub(crate) has_active_role: AtomicBool,
}
impl<D> Dispatch<XdgSurface, XdgSurfaceUserData, D> for XdgShellState
impl<D> Dispatch2<XdgSurface, D> for XdgSurfaceUserData
where
D: Dispatch<XdgSurface, XdgSurfaceUserData>,
D: Dispatch<XdgToplevel, XdgShellSurfaceUserData>,
D: Dispatch<XdgPopup, XdgShellSurfaceUserData>,
D: XdgShellHandler,
D: 'static,
{
fn request(
&self,
state: &mut D,
_client: &wayland_server::Client,
xdg_surface: &XdgSurface,
request: xdg_surface::Request,
data: &XdgSurfaceUserData,
_dh: &DisplayHandle,
data_init: &mut DataInit<'_, D>,
) {
match request {
xdg_surface::Request::Destroy => {
data.known_surfaces
self.known_surfaces
.lock()
.unwrap()
.swap_remove(&xdg_surface.downgrade());
if !data.wl_surface.alive() {
if !self.wl_surface.alive() {
// the wl_surface is destroyed, this means the client is not
// trying to change the role but it's a cleanup (possibly a
// disconnecting client), ignore the protocol check.
return;
}
if compositor::get_role(&data.wl_surface).is_none() {
if compositor::get_role(&self.wl_surface).is_none() {
// No role assigned to the surface, we can exit early.
return;
}
if data.has_active_role.load(Ordering::Acquire) {
data.wm_base.post_error(
if self.has_active_role.load(Ordering::Acquire) {
self.wm_base.post_error(
xdg_wm_base::Error::Role,
"xdg_surface was destroyed before its role object",
);
@ -90,15 +89,15 @@ where
}
xdg_surface::Request::GetToplevel { id } => {
// We now can assign a role to the surface
let surface = &data.wl_surface;
let shell = &data.wm_base;
let surface = &self.wl_surface;
let shell = &self.wm_base;
if compositor::give_role(surface, XDG_TOPLEVEL_ROLE).is_err() {
shell.post_error(xdg_wm_base::Error::Role, "Surface already has a role.");
return;
}
data.has_active_role.store(true, Ordering::Release);
self.has_active_role.store(true, Ordering::Release);
let initial = compositor::with_states(surface, |states| {
let initial = states.data_map.insert_if_missing_threadsafe(|| {
@ -133,9 +132,9 @@ where
let toplevel = data_init.init(
id,
XdgShellSurfaceUserData {
wl_surface: data.wl_surface.clone(),
wl_surface: self.wl_surface.clone(),
xdg_surface: xdg_surface.clone(),
wm_base: data.wm_base.clone(),
wm_base: self.wm_base.clone(),
decoration: Default::default(),
dialog: Default::default(),
alive_tracker: Default::default(),
@ -169,8 +168,8 @@ where
});
// We now can assign a role to the surface
let surface = &data.wl_surface;
let shell = &data.wm_base;
let surface = &self.wl_surface;
let shell = &self.wm_base;
let attributes = XdgPopupSurfaceRoleAttributes {
parent: parent_surface,
@ -186,7 +185,7 @@ where
return;
}
data.has_active_role.store(true, Ordering::Release);
self.has_active_role.store(true, Ordering::Release);
let initial = compositor::with_states(surface, |states| {
let inserted = states.data_map.insert_if_missing_threadsafe(|| {
@ -211,9 +210,9 @@ where
let popup = data_init.init(
id,
XdgShellSurfaceUserData {
wl_surface: data.wl_surface.clone(),
wl_surface: self.wl_surface.clone(),
xdg_surface: xdg_surface.clone(),
wm_base: data.wm_base.clone(),
wm_base: self.wm_base.clone(),
decoration: Default::default(),
dialog: Default::default(),
alive_tracker: Default::default(),
@ -233,7 +232,7 @@ where
// Check the role of the surface, this can be either xdg_toplevel
// or xdg_popup. If none of the role matches the xdg_surface has no role set
// which is a protocol error.
let surface = &data.wl_surface;
let surface = &self.wl_surface;
let role = compositor::get_role(surface);
@ -246,7 +245,7 @@ where
}
if role != Some(XDG_TOPLEVEL_ROLE) && role != Some(XDG_POPUP_ROLE) {
data.wm_base.post_error(
self.wm_base.post_error(
xdg_wm_base::Error::Role,
"xdg_surface must have a role of xdg_toplevel or xdg_popup.",
);
@ -267,7 +266,7 @@ where
}
xdg_surface::Request::AckConfigure { serial } => {
let serial = Serial::from(serial);
let surface = &data.wl_surface;
let surface = &self.wl_surface;
// Check the role of the surface, this can be either xdg_toplevel
// or xdg_popup. If none of the role matches the xdg_surface has no role set
@ -317,14 +316,14 @@ where
let configure = match found_configure {
Ok(Some(configure)) => configure,
Ok(None) => {
data.wm_base.post_error(
self.wm_base.post_error(
xdg_wm_base::Error::InvalidSurfaceState,
format!("wrong configure serial: {}", <u32>::from(serial)),
);
return;
}
Err(()) => {
data.wm_base.post_error(
self.wm_base.post_error(
xdg_wm_base::Error::Role as u32,
"xdg_surface must have a role of xdg_toplevel or xdg_popup.",
);

View file

@ -3,6 +3,7 @@ use std::sync::atomic::Ordering;
use crate::{
utils::Serial,
wayland::{
Dispatch2,
compositor::{self, with_states},
shell::xdg::{PopupCachedState, SurfaceCachedState, XdgPopupSurfaceData, XdgPositionerUserData},
},
@ -10,34 +11,33 @@ use crate::{
use wayland_protocols::xdg::shell::server::xdg_popup::{self, XdgPopup};
use wayland_server::{DataInit, Dispatch, DisplayHandle, Resource, backend::ClientId};
use wayland_server::{DataInit, DisplayHandle, Resource, backend::ClientId};
use super::{PopupConfigure, XdgShellHandler, XdgShellState, XdgShellSurfaceUserData, XdgSurfaceUserData};
use super::{PopupConfigure, XdgShellHandler, XdgShellSurfaceUserData, XdgSurfaceUserData};
impl<D> Dispatch<XdgPopup, XdgShellSurfaceUserData, D> for XdgShellState
impl<D> Dispatch2<XdgPopup, D> for XdgShellSurfaceUserData
where
D: Dispatch<XdgPopup, XdgShellSurfaceUserData>,
D: XdgShellHandler,
D: 'static,
{
fn request(
&self,
state: &mut D,
_client: &wayland_server::Client,
popup: &XdgPopup,
request: xdg_popup::Request,
data: &XdgShellSurfaceUserData,
_dh: &DisplayHandle,
_data_init: &mut DataInit<'_, D>,
) {
match request {
xdg_popup::Request::Destroy => {
if let Some(surface_data) = data.xdg_surface.data::<XdgSurfaceUserData>() {
if let Some(surface_data) = self.xdg_surface.data::<XdgSurfaceUserData>() {
surface_data.has_active_role.store(false, Ordering::Release);
}
}
xdg_popup::Request::Grab { seat, serial } => {
let handle = crate::wayland::shell::xdg::PopupSurface {
wl_surface: data.wl_surface.clone(),
wl_surface: self.wl_surface.clone(),
shell_surface: popup.clone(),
};
@ -55,7 +55,7 @@ where
}
xdg_popup::Request::Reposition { positioner, token } => {
let handle = crate::wayland::shell::xdg::PopupSurface {
wl_surface: data.wl_surface.clone(),
wl_surface: self.wl_surface.clone(),
shell_surface: popup.clone(),
};
@ -72,8 +72,8 @@ where
}
}
fn destroyed(state: &mut D, _client_id: ClientId, xdg_popup: &XdgPopup, data: &XdgShellSurfaceUserData) {
data.alive_tracker.destroy_notify();
fn destroyed(&self, state: &mut D, _client_id: ClientId, xdg_popup: &XdgPopup) {
self.alive_tracker.destroy_notify();
// remove this surface from the known ones (as well as any leftover dead surface)
if let Some(index) = state

View file

@ -3,7 +3,7 @@ use std::sync::atomic::Ordering;
use crate::{
utils::Serial,
wayland::{
compositor,
Dispatch2, compositor,
shell::{
is_valid_parent,
xdg::{ToplevelCachedState, XdgToplevelSurfaceData},
@ -16,37 +16,34 @@ use wayland_protocols::xdg::{
shell::server::xdg_toplevel::{self, XdgToplevel},
};
use wayland_server::{
DataInit, Dispatch, DisplayHandle, Resource, WEnum, backend::ClientId, protocol::wl_surface,
};
use wayland_server::{DataInit, DisplayHandle, Resource, WEnum, backend::ClientId, protocol::wl_surface};
use super::{
SurfaceCachedState, ToplevelConfigure, XdgShellHandler, XdgShellState, XdgShellSurfaceUserData,
XdgSurfaceUserData, XdgToplevelSurfaceRoleAttributes,
SurfaceCachedState, ToplevelConfigure, XdgShellHandler, XdgShellSurfaceUserData, XdgSurfaceUserData,
XdgToplevelSurfaceRoleAttributes,
};
impl<D> Dispatch<XdgToplevel, XdgShellSurfaceUserData, D> for XdgShellState
impl<D> Dispatch2<XdgToplevel, D> for XdgShellSurfaceUserData
where
D: Dispatch<XdgToplevel, XdgShellSurfaceUserData>,
D: XdgShellHandler,
D: 'static,
{
fn request(
&self,
state: &mut D,
_client: &wayland_server::Client,
toplevel: &XdgToplevel,
request: xdg_toplevel::Request,
data: &XdgShellSurfaceUserData,
_dh: &DisplayHandle,
_data_init: &mut DataInit<'_, D>,
) {
match request {
xdg_toplevel::Request::Destroy => {
if let Some(surface_data) = data.xdg_surface.data::<XdgSurfaceUserData>() {
if let Some(surface_data) = self.xdg_surface.data::<XdgSurfaceUserData>() {
surface_data.has_active_role.store(false, Ordering::Release);
}
if let Some(decoration) = data.decoration.lock().unwrap().clone() {
if let Some(decoration) = self.decoration.lock().unwrap().clone() {
decoration.post_error(
zxdg_toplevel_decoration_v1::Error::Orphaned,
"The xdg_toplevel_decoration object must be destroyed before its xdg_toplevel.",
@ -131,12 +128,12 @@ where
}
}
xdg_toplevel::Request::SetMaxSize { width, height } => {
with_toplevel_pending_state(data, |toplevel_data| {
with_toplevel_pending_state(self, |toplevel_data| {
toplevel_data.max_size = (width, height).into();
});
}
xdg_toplevel::Request::SetMinSize { width, height } => {
with_toplevel_pending_state(data, |toplevel_data| {
with_toplevel_pending_state(self, |toplevel_data| {
toplevel_data.min_size = (width, height).into();
});
}
@ -166,14 +163,9 @@ where
}
}
fn destroyed(
state: &mut D,
_client_id: ClientId,
xdg_toplevel: &XdgToplevel,
data: &XdgShellSurfaceUserData,
) {
data.alive_tracker.destroy_notify();
data.decoration.lock().unwrap().take();
fn destroyed(&self, state: &mut D, _client_id: ClientId, xdg_toplevel: &XdgToplevel) {
self.alive_tracker.destroy_notify();
self.decoration.lock().unwrap().take();
if let Some(index) = state
.xdg_shell_state()

View file

@ -4,22 +4,19 @@ use indexmap::IndexSet;
use crate::{
utils::{IsAlive, Serial, alive_tracker::AliveTracker},
wayland::shell::xdg::XdgShellState,
wayland::{Dispatch2, GlobalData, GlobalDispatch2},
};
use wayland_protocols::xdg::shell::server::{
xdg_positioner::XdgPositioner, xdg_surface, xdg_surface::XdgSurface, xdg_wm_base, xdg_wm_base::XdgWmBase,
};
use wayland_server::{
DataInit, Dispatch, DisplayHandle, GlobalDispatch, New, Resource, Weak, backend::ClientId,
};
use wayland_server::{DataInit, Dispatch, DisplayHandle, New, Resource, Weak, backend::ClientId};
use super::{ShellClient, ShellClientData, XdgPositionerUserData, XdgShellHandler, XdgSurfaceUserData};
impl<D> GlobalDispatch<XdgWmBase, (), D> for XdgShellState
impl<D> GlobalDispatch2<XdgWmBase, D> for GlobalData
where
D: GlobalDispatch<XdgWmBase, ()>,
D: Dispatch<XdgWmBase, XdgWmBaseUserData>,
D: Dispatch<XdgSurface, XdgSurfaceUserData>,
D: Dispatch<XdgPositioner, XdgPositionerUserData>,
@ -27,11 +24,11 @@ where
D: 'static,
{
fn bind(
&self,
state: &mut D,
_dh: &DisplayHandle,
_client: &wayland_server::Client,
resource: New<XdgWmBase>,
_global_data: &(),
data_init: &mut DataInit<'_, D>,
) {
let shell = data_init.init(resource, XdgWmBaseUserData::default());
@ -40,20 +37,19 @@ where
}
}
impl<D> Dispatch<XdgWmBase, XdgWmBaseUserData, D> for XdgShellState
impl<D> Dispatch2<XdgWmBase, D> for XdgWmBaseUserData
where
D: Dispatch<XdgWmBase, XdgWmBaseUserData>,
D: Dispatch<XdgSurface, XdgSurfaceUserData>,
D: Dispatch<XdgPositioner, XdgPositionerUserData>,
D: XdgShellHandler,
D: 'static,
{
fn request(
&self,
state: &mut D,
_client: &wayland_server::Client,
wm_base: &XdgWmBase,
request: xdg_wm_base::Request,
data: &XdgWmBaseUserData,
_dh: &DisplayHandle,
data_init: &mut DataInit<'_, D>,
) {
@ -68,13 +64,13 @@ where
let xdg_surface = data_init.init(
id,
XdgSurfaceUserData {
known_surfaces: data.known_surfaces.clone(),
known_surfaces: self.known_surfaces.clone(),
wl_surface: surface,
wm_base: wm_base.clone(),
has_active_role: AtomicBool::new(false),
},
);
data.known_surfaces
self.known_surfaces
.lock()
.unwrap()
.insert(xdg_surface.downgrade());
@ -82,7 +78,7 @@ where
xdg_wm_base::Request::Pong { serial } => {
let serial = Serial::from(serial);
let valid = {
let mut guard = data.client_data.lock().unwrap();
let mut guard = self.client_data.lock().unwrap();
if guard.pending_ping == Some(serial) {
guard.pending_ping = None;
true
@ -95,7 +91,7 @@ where
}
}
xdg_wm_base::Request::Destroy => {
if !data.known_surfaces.lock().unwrap().is_empty() {
if !self.known_surfaces.lock().unwrap().is_empty() {
wm_base.post_error(
xdg_wm_base::Error::DefunctSurfaces,
"xdg_wm_base was destroyed before children",
@ -106,9 +102,9 @@ where
}
}
fn destroyed(state: &mut D, _client_id: ClientId, wm_base: &XdgWmBase, data: &XdgWmBaseUserData) {
fn destroyed(&self, state: &mut D, _client_id: ClientId, wm_base: &XdgWmBase) {
XdgShellHandler::client_destroyed(state, ShellClient::new(wm_base));
data.alive_tracker.destroy_notify();
self.alive_tracker.destroy_notify();
}
}

View file

@ -25,7 +25,6 @@
//! ```no_run
//! # extern crate wayland_server;
//! #
//! use smithay::delegate_xdg_shell;
//! use smithay::reexports::wayland_server::protocol::{wl_seat, wl_surface};
//! use smithay::wayland::shell::xdg::{XdgShellState, XdgShellHandler, ToplevelSurface, PopupSurface, PositionerState};
//! use smithay::utils::Serial;
@ -94,7 +93,8 @@
//! // handle new images for the cursor ...
//! }
//! }
//! delegate_xdg_shell!(State);
//!
//! smithay::delegate_dispatch2!(State);
//!
//! // You're now ready to go!
//! ```
@ -121,6 +121,7 @@
use crate::utils::alive_tracker::IsAlive;
use crate::utils::{Logical, Point, Rectangle, Size, user_data::UserDataMap};
use crate::utils::{SERIAL_COUNTER, Serial};
use crate::wayland::GlobalData;
use crate::wayland::compositor::Cacheable;
use crate::wayland::compositor::{self, BufferAssignment, SurfaceAttributes};
use crate::wayland::shell::xdg::dialog::ToplevelDialogHint;
@ -1217,7 +1218,7 @@ impl XdgShellState {
/// Create a new `xdg_shell` global with all [`WmCapabilities`](xdg_toplevel::WmCapabilities)
pub fn new<D>(display: &DisplayHandle) -> XdgShellState
where
D: GlobalDispatch<XdgWmBase, ()> + 'static,
D: GlobalDispatch<XdgWmBase, GlobalData> + 'static,
{
Self::new_with_capabilities::<D>(
display,
@ -1236,9 +1237,9 @@ impl XdgShellState {
capabilities: impl Into<WmCapabilitySet>,
) -> XdgShellState
where
D: GlobalDispatch<XdgWmBase, ()> + 'static,
D: GlobalDispatch<XdgWmBase, GlobalData> + 'static,
{
let global = display.create_global::<D, XdgWmBase, _>(7, ());
let global = display.create_global::<D, XdgWmBase, _>(7, GlobalData);
XdgShellState {
known_toplevels: Vec::new(),
@ -2170,55 +2171,3 @@ impl From<PopupConfigure> for Configure {
Configure::Popup(configure)
}
}
#[allow(missing_docs)] // TODO
#[macro_export]
macro_rules! delegate_xdg_shell {
($(@<$( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+>)? $ty: ty) => {
const _: () = {
use $crate::{
reexports::{
wayland_protocols::xdg::shell::server::{
xdg_popup::XdgPopup, xdg_positioner::XdgPositioner, xdg_surface::XdgSurface,
xdg_toplevel::XdgToplevel, xdg_wm_base::XdgWmBase,
},
wayland_server::{delegate_dispatch, delegate_global_dispatch},
},
wayland::shell::xdg::{
XdgPositionerUserData, XdgShellState, XdgShellSurfaceUserData, XdgSurfaceUserData,
XdgWmBaseUserData,
},
};
delegate_global_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [XdgWmBase: ()] => XdgShellState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [XdgWmBase: XdgWmBaseUserData] => XdgShellState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [XdgPositioner: XdgPositionerUserData] => XdgShellState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [XdgPopup: XdgShellSurfaceUserData] => XdgShellState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [XdgSurface: XdgSurfaceUserData] => XdgShellState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [XdgToplevel: XdgShellSurfaceUserData] => XdgShellState
);
};
};
}

View file

@ -1,16 +1,17 @@
use crate::wayland::{
Dispatch2, GlobalData, GlobalDispatch2,
buffer::BufferHandler,
shm::{ShmBufferUserData, wl_bytes_per_pixel},
};
use super::{
BufferData, ShmHandler, ShmPoolUserData, ShmState,
BufferData, ShmHandler, ShmPoolUserData,
pool::{Pool, ResizeError},
};
use std::{num::NonZeroUsize, os::unix::io::AsRawFd, sync::Arc};
use wayland_server::{
DataInit, Dispatch, DisplayHandle, GlobalDispatch, New, Resource, WEnum,
DataInit, Dispatch, DisplayHandle, New, Resource, WEnum,
backend::ClientId,
protocol::{
wl_buffer,
@ -19,23 +20,22 @@ use wayland_server::{
},
};
impl<D> GlobalDispatch<WlShm, (), D> for ShmState
impl<D> GlobalDispatch2<WlShm, D> for GlobalData
where
D: GlobalDispatch<WlShm, ()>,
D: Dispatch<WlShm, ()>,
D: Dispatch<WlShm, GlobalData>,
D: Dispatch<WlShmPool, ShmPoolUserData>,
D: ShmHandler,
D: 'static,
{
fn bind(
&self,
state: &mut D,
_dh: &DisplayHandle,
_client: &wayland_server::Client,
resource: New<WlShm>,
_global_data: &(),
data_init: &mut DataInit<'_, D>,
) {
let shm = data_init.init(resource, ());
let shm = data_init.init(resource, GlobalData);
// send the formats
for &f in &state.shm_state().formats {
@ -44,16 +44,16 @@ where
}
}
impl<D> Dispatch<WlShm, (), D> for ShmState
impl<D> Dispatch2<WlShm, D> for GlobalData
where
D: Dispatch<WlShm, ()> + Dispatch<WlShmPool, ShmPoolUserData> + ShmHandler + 'static,
D: Dispatch<WlShmPool, ShmPoolUserData> + ShmHandler + 'static,
{
fn request(
&self,
_state: &mut D,
_client: &wayland_server::Client,
shm: &WlShm,
request: wl_shm::Request,
_data: &(),
_dh: &DisplayHandle,
data_init: &mut DataInit<'_, D>,
) {
@ -94,26 +94,22 @@ where
* wl_shm_pool
*/
impl<D> Dispatch<WlShmPool, ShmPoolUserData, D> for ShmState
impl<D> Dispatch2<WlShmPool, D> for ShmPoolUserData
where
D: Dispatch<WlShmPool, ShmPoolUserData>
+ Dispatch<wl_buffer::WlBuffer, ShmBufferUserData>
+ BufferHandler
+ ShmHandler
+ 'static,
D: Dispatch<wl_buffer::WlBuffer, ShmBufferUserData> + BufferHandler + ShmHandler + 'static,
{
fn request(
&self,
state: &mut D,
_client: &wayland_server::Client,
pool: &WlShmPool,
request: wl_shm_pool::Request,
data: &ShmPoolUserData,
_dh: &DisplayHandle,
data_init: &mut DataInit<'_, D>,
) {
use self::wl_shm_pool::Request;
let arc_pool = &data.inner;
let arc_pool = &self.inner;
match request {
Request::CreateBuffer {
@ -211,17 +207,17 @@ where
}
}
impl<D> Dispatch<wl_buffer::WlBuffer, ShmBufferUserData, D> for ShmState
impl<D> Dispatch2<wl_buffer::WlBuffer, D> for ShmBufferUserData
where
D: Dispatch<wl_buffer::WlBuffer, ShmBufferUserData> + BufferHandler,
D: BufferHandler,
D: 'static,
{
fn request(
&self,
_data: &mut D,
_client: &wayland_server::Client,
_buffer: &wl_buffer::WlBuffer,
request: wl_buffer::Request,
_udata: &ShmBufferUserData,
_dh: &DisplayHandle,
_data_init: &mut DataInit<'_, D>,
) {
@ -234,9 +230,9 @@ where
}
}
fn destroyed(data: &mut D, _client: ClientId, buffer: &wl_buffer::WlBuffer, udata: &ShmBufferUserData) {
fn destroyed(&self, data: &mut D, _client: ClientId, buffer: &wl_buffer::WlBuffer) {
// Clone to drop the mutex guard
let destruction_hooks = udata.destruction_hooks.lock().unwrap().clone();
let destruction_hooks = self.destruction_hooks.lock().unwrap().clone();
for hook in destruction_hooks.iter() {
(hook.cb)(data, buffer);
}

View file

@ -21,7 +21,6 @@
//!
//! use smithay::wayland::buffer::BufferHandler;
//! use smithay::wayland::shm::{ShmState, ShmHandler};
//! use smithay::delegate_shm;
//! use wayland_server::protocol::wl_shm::Format;
//!
//! # struct State { shm_state: ShmState };
@ -49,7 +48,8 @@
//! &self.shm_state
//! }
//! }
//! delegate_shm!(State);
//!
//! smithay::delegate_dispatch2!(State);
//! ```
//!
//! Then, when you have a [`WlBuffer`](wayland_server::protocol::wl_buffer::WlBuffer)
@ -117,6 +117,7 @@ mod pool;
use crate::{
backend::allocator::format::get_bpp,
utils::{HookId, UnmanagedResource, hook::Hook},
wayland::GlobalData,
};
use self::pool::Pool;
@ -141,8 +142,8 @@ impl ShmState {
/// remove this global in the future.
pub fn new<D>(display: &DisplayHandle, formats: impl IntoIterator<Item = wl_shm::Format>) -> ShmState
where
D: GlobalDispatch<WlShm, ()>
+ Dispatch<WlShm, ()>
D: GlobalDispatch<WlShm, GlobalData>
+ Dispatch<WlShm, GlobalData>
+ Dispatch<WlShmPool, ShmPoolUserData>
+ BufferHandler
+ ShmHandler
@ -154,7 +155,7 @@ impl ShmState {
formats.insert(wl_shm::Format::Argb8888);
formats.insert(wl_shm::Format::Xrgb8888);
let shm = display.create_global::<D, WlShm, _>(2, ());
let shm = display.create_global::<D, WlShm, _>(2, GlobalData);
ShmState { formats, shm }
}
@ -498,39 +499,3 @@ impl ShmBufferUserData {
}
}
}
#[allow(missing_docs)] // TODO
#[macro_export]
macro_rules! delegate_shm {
($(@<$( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+>)? $ty: ty) => {
const _: () = {
use $crate::{
reexports::{
wayland_server::protocol::{wl_buffer::WlBuffer, wl_shm::WlShm, wl_shm_pool::WlShmPool},
wayland_server::{delegate_dispatch, delegate_global_dispatch},
},
wayland::shm::{ShmBufferUserData, ShmPoolUserData, ShmState},
};
delegate_global_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [WlShm: ()] => ShmState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [WlShm: ()] => ShmState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [WlShmPool: ShmPoolUserData] => ShmState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [WlBuffer: ShmBufferUserData] => ShmState
);
};
};
}

View file

@ -1,44 +1,42 @@
use crate::wayland::buffer::BufferHandler;
use crate::wayland::{Dispatch2, GlobalData, GlobalDispatch2, buffer::BufferHandler};
use super::{SinglePixelBufferState, SinglePixelBufferUserData};
use super::SinglePixelBufferUserData;
use wayland_protocols::wp::single_pixel_buffer::v1::server::wp_single_pixel_buffer_manager_v1::{
self, WpSinglePixelBufferManagerV1,
};
use wayland_server::{
DataInit, Dispatch, DisplayHandle, GlobalDispatch, New,
DataInit, Dispatch, DisplayHandle, New,
protocol::wl_buffer::{self, WlBuffer},
};
impl<D> GlobalDispatch<WpSinglePixelBufferManagerV1, (), D> for SinglePixelBufferState
impl<D> GlobalDispatch2<WpSinglePixelBufferManagerV1, D> for GlobalData
where
D: GlobalDispatch<WpSinglePixelBufferManagerV1, ()>,
D: Dispatch<WpSinglePixelBufferManagerV1, ()>,
D: Dispatch<WpSinglePixelBufferManagerV1, GlobalData>,
D: 'static,
{
fn bind(
&self,
_state: &mut D,
_dh: &DisplayHandle,
_client: &wayland_server::Client,
resource: New<WpSinglePixelBufferManagerV1>,
_global_data: &(),
data_init: &mut DataInit<'_, D>,
) {
data_init.init(resource, ());
data_init.init(resource, GlobalData);
}
}
impl<D> Dispatch<WpSinglePixelBufferManagerV1, (), D> for SinglePixelBufferState
impl<D> Dispatch2<WpSinglePixelBufferManagerV1, D> for GlobalData
where
D: Dispatch<WpSinglePixelBufferManagerV1, ()>,
D: Dispatch<WlBuffer, SinglePixelBufferUserData>,
D: 'static,
{
fn request(
&self,
_state: &mut D,
_client: &wayland_server::Client,
_manager: &WpSinglePixelBufferManagerV1,
request: wp_single_pixel_buffer_manager_v1::Request,
_data: &(),
_dh: &DisplayHandle,
data_init: &mut DataInit<'_, D>,
) {
@ -58,17 +56,16 @@ where
}
}
impl<D> Dispatch<WlBuffer, SinglePixelBufferUserData, D> for SinglePixelBufferState
impl<D> Dispatch2<WlBuffer, D> for SinglePixelBufferUserData
where
D: Dispatch<WlBuffer, SinglePixelBufferUserData>,
D: BufferHandler,
{
fn request(
&self,
data: &mut D,
_client: &wayland_server::Client,
buffer: &wl_buffer::WlBuffer,
request: wl_buffer::Request,
_udata: &SinglePixelBufferUserData,
_dh: &DisplayHandle,
_data_init: &mut DataInit<'_, D>,
) {

View file

@ -12,7 +12,6 @@
//! buffer::BufferHandler,
//! single_pixel_buffer::SinglePixelBufferState
//! };
//! use smithay::delegate_single_pixel_buffer;
//!
//! # struct State;
//! # let mut display = wayland_server::Display::<State>::new().unwrap();
@ -31,8 +30,7 @@
//! }
//! }
//!
//! // implement Dispatch for the SinglePixelBuffer types
//! delegate_single_pixel_buffer!(State);
//! smithay::delegate_dispatch2!(State);
//!
//! // You're now ready to go!
//! ```
@ -52,6 +50,8 @@ use wayland_server::{
Dispatch, DisplayHandle, GlobalDispatch, Resource, backend::GlobalId, protocol::wl_buffer::WlBuffer,
};
use crate::wayland::GlobalData;
mod handlers;
/// Delegate state of WpSinglePixelBuffer protocol
@ -67,11 +67,11 @@ impl SinglePixelBufferState {
/// remove or disable this global in the future.
pub fn new<D>(display: &DisplayHandle) -> Self
where
D: GlobalDispatch<WpSinglePixelBufferManagerV1, ()>,
D: Dispatch<WpSinglePixelBufferManagerV1, ()>,
D: GlobalDispatch<WpSinglePixelBufferManagerV1, GlobalData>,
D: Dispatch<WpSinglePixelBufferManagerV1, GlobalData>,
D: 'static,
{
let global = display.create_global::<D, WpSinglePixelBufferManagerV1, _>(1, ());
let global = display.create_global::<D, WpSinglePixelBufferManagerV1, _>(1, GlobalData);
Self { global }
}
@ -142,35 +142,3 @@ pub fn get_single_pixel_buffer(buffer: &WlBuffer) -> Result<&SinglePixelBufferUs
.data::<SinglePixelBufferUserData>()
.ok_or(BufferAccessError::NotManaged)
}
/// Macro used to delegate `WpSinglePixelBuffer` events
#[macro_export]
macro_rules! delegate_single_pixel_buffer {
($(@<$( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+>)? $ty: ty) => {
const _: () = {
use $crate::{
reexports::{
wayland_server::{delegate_dispatch, delegate_global_dispatch},
wayland_server::protocol::wl_buffer::WlBuffer,
wayland_protocols::wp::single_pixel_buffer::v1::server::wp_single_pixel_buffer_manager_v1::WpSinglePixelBufferManagerV1,
},
wayland::single_pixel_buffer::{SinglePixelBufferState, SinglePixelBufferUserData},
};
delegate_global_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [WpSinglePixelBufferManagerV1: ()] => SinglePixelBufferState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [WpSinglePixelBufferManagerV1: ()] => SinglePixelBufferState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [WlBuffer: SinglePixelBufferUserData] => SinglePixelBufferState
);
};
};
}

View file

@ -3,8 +3,6 @@
//! This module provides helpers to handle graphics tablets.
//!
//! ```
//! use smithay::{delegate_seat, delegate_tablet_manager};
//! # use smithay::delegate_compositor;
//! use smithay::backend::input::TabletToolDescriptor;
//! use smithay::input::{Seat, SeatState, SeatHandler, pointer::CursorImageStatus};
//! # use smithay::wayland::compositor::{CompositorHandler, CompositorState, CompositorClientState};
@ -55,21 +53,20 @@
//! // ...
//! }
//! }
//! delegate_seat!(State);
//!
//! impl TabletSeatHandler for State {
//! fn tablet_tool_image(&mut self, tool: &TabletToolDescriptor, image: CursorImageStatus) {
//! // ...
//! }
//! }
//! delegate_tablet_manager!(State);
//!
//! # impl CompositorHandler for State {
//! # fn compositor_state(&mut self) -> &mut CompositorState { unimplemented!() }
//! # fn client_compositor_state<'a>(&self, client: &'a Client) -> &'a CompositorClientState { unimplemented!() }
//! # fn commit(&mut self, surface: &WlSurface) {}
//! # }
//! # delegate_compositor!(State);
//!
//! smithay::delegate_dispatch2!(State);
//! ```
//! ```ignore
//! // Init the manager global
@ -96,7 +93,10 @@
//! );
//! ```
use crate::input::{Seat, SeatHandler};
use crate::{
input::{Seat, SeatHandler},
wayland::{Dispatch2, GlobalData, GlobalDispatch2},
};
use wayland_protocols::wp::tablet::zv2::server::{
zwp_tablet_manager_v2::{self, ZwpTabletManagerV2},
zwp_tablet_seat_v2::ZwpTabletSeatV2,
@ -141,13 +141,13 @@ impl TabletManagerState {
/// Initialize a tablet manager global.
pub fn new<D>(display: &DisplayHandle) -> Self
where
D: GlobalDispatch<ZwpTabletManagerV2, ()>,
D: Dispatch<ZwpTabletManagerV2, ()>,
D: GlobalDispatch<ZwpTabletManagerV2, GlobalData>,
D: Dispatch<ZwpTabletManagerV2, GlobalData>,
D: Dispatch<ZwpTabletSeatV2, TabletSeatUserData>,
D: Dispatch<ZwpTabletToolV2, TabletToolUserData>,
D: 'static,
{
let global = display.create_global::<D, ZwpTabletManagerV2, _>(MANAGER_VERSION, ());
let global = display.create_global::<D, ZwpTabletManagerV2, _>(MANAGER_VERSION, GlobalData);
Self { global }
}
@ -158,28 +158,26 @@ impl TabletManagerState {
}
}
impl<D> GlobalDispatch<ZwpTabletManagerV2, (), D> for TabletManagerState
impl<D> GlobalDispatch2<ZwpTabletManagerV2, D> for GlobalData
where
D: GlobalDispatch<ZwpTabletManagerV2, ()>,
D: Dispatch<ZwpTabletManagerV2, ()>,
D: Dispatch<ZwpTabletManagerV2, GlobalData>,
D: Dispatch<ZwpTabletSeatV2, TabletSeatUserData>,
D: 'static,
{
fn bind(
&self,
_: &mut D,
_: &DisplayHandle,
_: &Client,
resource: New<ZwpTabletManagerV2>,
_: &(),
data_init: &mut DataInit<'_, D>,
) {
data_init.init(resource, ());
data_init.init(resource, GlobalData);
}
}
impl<D> Dispatch<ZwpTabletManagerV2, (), D> for TabletManagerState
impl<D> Dispatch2<ZwpTabletManagerV2, D> for GlobalData
where
D: Dispatch<ZwpTabletManagerV2, ()>,
D: Dispatch<ZwpTabletSeatV2, TabletSeatUserData>,
D: Dispatch<ZwpTabletV2, TabletUserData>,
D: Dispatch<ZwpTabletToolV2, TabletToolUserData>,
@ -187,11 +185,11 @@ where
D: CompositorHandler,
{
fn request(
&self,
state: &mut D,
client: &Client,
_: &ZwpTabletManagerV2,
request: zwp_tablet_manager_v2::Request,
_: &(),
dh: &DisplayHandle,
data_init: &mut DataInit<'_, D>,
) {
@ -219,49 +217,3 @@ where
}
}
}
#[allow(missing_docs)] // TODO
#[macro_export]
macro_rules! delegate_tablet_manager {
($(@<$( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+>)? $ty: ty) => {
const _: () = {
use $crate::{
reexports::{
wayland_protocols::wp::tablet::zv2::server::{
zwp_tablet_manager_v2::ZwpTabletManagerV2, zwp_tablet_seat_v2::ZwpTabletSeatV2,
zwp_tablet_tool_v2::ZwpTabletToolV2, zwp_tablet_v2::ZwpTabletV2,
},
wayland_server::{delegate_dispatch, delegate_global_dispatch},
},
wayland::tablet_manager::{
TabletManagerState, TabletSeatUserData, TabletToolUserData, TabletUserData,
},
};
delegate_global_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [ZwpTabletManagerV2: ()] => TabletManagerState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [ZwpTabletManagerV2: ()] => TabletManagerState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [ZwpTabletSeatV2: TabletSeatUserData] => TabletManagerState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [ZwpTabletToolV2: TabletToolUserData] => TabletManagerState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [ZwpTabletV2: TabletUserData] => TabletManagerState
);
};
};
}

View file

@ -12,9 +12,7 @@ use wayland_server::{
protocol::wl_surface::WlSurface,
};
use crate::backend::input::Device;
use super::TabletManagerState;
use crate::{backend::input::Device, wayland::Dispatch2};
/// Description of graphics tablet device
#[derive(Debug, Clone, Hash, Eq, PartialEq)]
@ -107,24 +105,23 @@ pub struct TabletUserData {
handle: TabletHandle,
}
impl<D> Dispatch<ZwpTabletV2, TabletUserData, D> for TabletManagerState
impl<D> Dispatch2<ZwpTabletV2, D> for TabletUserData
where
D: Dispatch<ZwpTabletV2, TabletUserData>,
D: 'static,
{
fn request(
&self,
_state: &mut D,
_client: &Client,
_tablet: &ZwpTabletV2,
_request: zwp_tablet_v2::Request,
_data: &TabletUserData,
_dh: &DisplayHandle,
_data_init: &mut DataInit<'_, D>,
) {
}
fn destroyed(_state: &mut D, _client: ClientId, tablet: &ZwpTabletV2, data: &TabletUserData) {
data.handle
fn destroyed(&self, _state: &mut D, _client: ClientId, tablet: &ZwpTabletV2) {
self.handle
.inner
.lock()
.unwrap()

View file

@ -6,12 +6,12 @@ use wayland_protocols::wp::tablet::zv2::server::{
use wayland_server::{Client, DataInit, Dispatch, DisplayHandle, Resource, Weak, backend::ClientId};
use crate::input::pointer::CursorImageStatus;
use crate::{backend::input::TabletToolDescriptor, wayland::compositor::CompositorHandler};
use super::{
TabletManagerState,
tablet::{TabletDescriptor, TabletHandle},
use crate::{
backend::input::TabletToolDescriptor,
wayland::{Dispatch2, compositor::CompositorHandler},
};
use super::tablet::{TabletDescriptor, TabletHandle};
use super::{
tablet::TabletUserData,
tablet_tool::{TabletToolHandle, TabletToolUserData},
@ -213,24 +213,23 @@ pub struct TabletSeatUserData {
pub(super) handle: TabletSeatHandle,
}
impl<D> Dispatch<ZwpTabletSeatV2, TabletSeatUserData, D> for TabletManagerState
impl<D> Dispatch2<ZwpTabletSeatV2, D> for TabletSeatUserData
where
D: Dispatch<ZwpTabletSeatV2, TabletSeatUserData>,
D: 'static,
{
fn request(
&self,
_state: &mut D,
_client: &Client,
_seat: &ZwpTabletSeatV2,
_request: zwp_tablet_seat_v2::Request,
_data: &TabletSeatUserData,
_dh: &DisplayHandle,
_data_init: &mut DataInit<'_, D>,
) {
}
fn destroyed(_state: &mut D, _client: ClientId, seat: &ZwpTabletSeatV2, data: &TabletSeatUserData) {
data.handle
fn destroyed(&self, _state: &mut D, _client: ClientId, seat: &ZwpTabletSeatV2) {
self.handle
.inner
.lock()
.unwrap()

View file

@ -16,9 +16,11 @@ use wayland_server::Weak;
use wayland_server::protocol::wl_surface::WlSurface;
use wayland_server::{Client, DataInit, Dispatch, DisplayHandle, Resource, backend::ClientId};
use crate::{utils::Serial, wayland::compositor};
use crate::{
utils::Serial,
wayland::{Dispatch2, compositor},
};
use super::TabletManagerState;
use super::tablet::TabletHandle;
use super::tablet_seat::TabletSeatHandler;
@ -468,17 +470,16 @@ impl fmt::Debug for TabletToolUserData {
}
}
impl<D> Dispatch<ZwpTabletToolV2, TabletToolUserData, D> for TabletManagerState
impl<D> Dispatch2<ZwpTabletToolV2, D> for TabletToolUserData
where
D: Dispatch<ZwpTabletToolV2, TabletToolUserData>,
D: TabletSeatHandler + 'static,
{
fn request(
&self,
state: &mut D,
_client: &Client,
tool: &ZwpTabletToolV2,
request: zwp_tablet_tool_v2::Request,
data: &TabletToolUserData,
_dh: &DisplayHandle,
_data_init: &mut DataInit<'_, D>,
) {
@ -489,7 +490,7 @@ where
hotspot_y,
..
} => {
let focus = data.handle.inner.lock().unwrap().focus.clone();
let focus = self.handle.inner.lock().unwrap().focus.clone();
if let Some(focus) = focus {
if focus.id().same_client_as(&tool.id()) {
@ -529,9 +530,9 @@ where
.hotspot = hotspot;
});
state.tablet_tool_image(&data.desc, CursorImageStatus::Surface(surface));
state.tablet_tool_image(&self.desc, CursorImageStatus::Surface(surface));
} else {
state.tablet_tool_image(&data.desc, CursorImageStatus::Hidden);
state.tablet_tool_image(&self.desc, CursorImageStatus::Hidden);
};
}
}
@ -543,8 +544,8 @@ where
}
}
fn destroyed(_state: &mut D, _client: ClientId, resource: &ZwpTabletToolV2, data: &TabletToolUserData) {
data.handle
fn destroyed(&self, _state: &mut D, _client: ClientId, resource: &ZwpTabletToolV2) {
self.handle
.inner
.lock()
.unwrap()

View file

@ -6,10 +6,6 @@
//! Text input focus is automatically set to the same surface that has keyboard focus.
//!
//! ```
//! use smithay::{
//! delegate_seat, delegate_text_input_manager,
//! # delegate_compositor,
//! };
//! use smithay::input::{Seat, SeatState, SeatHandler, pointer::CursorImageStatus};
//! # use smithay::wayland::compositor::{CompositorHandler, CompositorState, CompositorClientState};
//! use smithay::wayland::text_input::TextInputManagerState;
@ -18,9 +14,7 @@
//!
//! # struct State { seat_state: SeatState<Self> };
//!
//! delegate_seat!(State);
//! // Delegate text input handling for State to TextInputManagerState.
//! delegate_text_input_manager!(State);
//! smithay::delegate_dispatch2!(State);
//!
//! # let mut display = Display::<State>::new().unwrap();
//! # let display_handle = display.handle();
@ -47,7 +41,6 @@
//! # fn client_compositor_state<'a>(&self, client: &'a Client) -> &'a CompositorClientState { unimplemented!() }
//! # fn commit(&mut self, surface: &WlSurface) {}
//! # }
//! # delegate_compositor!(State);
//! ```
//!
@ -57,7 +50,10 @@ use wayland_protocols::wp::text_input::zv3::server::{
};
use wayland_server::{Client, DataInit, Dispatch, DisplayHandle, GlobalDispatch, New, backend::GlobalId};
use crate::input::{Seat, SeatHandler};
use crate::{
input::{Seat, SeatHandler},
wayland::{Dispatch2, GlobalData, GlobalDispatch2},
};
pub use text_input_handle::TextInputHandle;
pub use text_input_handle::TextInputUserData;
@ -92,12 +88,12 @@ impl TextInputManagerState {
/// Initialize a text input manager global.
pub fn new<D>(display: &DisplayHandle) -> Self
where
D: GlobalDispatch<ZwpTextInputManagerV3, ()>,
D: Dispatch<ZwpTextInputManagerV3, ()>,
D: GlobalDispatch<ZwpTextInputManagerV3, GlobalData>,
D: Dispatch<ZwpTextInputManagerV3, GlobalData>,
D: Dispatch<ZwpTextInputV3, TextInputUserData>,
D: 'static,
{
let global = display.create_global::<D, ZwpTextInputManagerV3, _>(MANAGER_VERSION, ());
let global = display.create_global::<D, ZwpTextInputManagerV3, _>(MANAGER_VERSION, GlobalData);
Self { global }
}
@ -108,38 +104,36 @@ impl TextInputManagerState {
}
}
impl<D> GlobalDispatch<ZwpTextInputManagerV3, (), D> for TextInputManagerState
impl<D> GlobalDispatch2<ZwpTextInputManagerV3, D> for GlobalData
where
D: GlobalDispatch<ZwpTextInputManagerV3, ()>,
D: Dispatch<ZwpTextInputManagerV3, ()>,
D: Dispatch<ZwpTextInputManagerV3, GlobalData>,
D: Dispatch<ZwpTextInputV3, TextInputUserData>,
D: 'static,
{
fn bind(
&self,
_: &mut D,
_: &DisplayHandle,
_: &Client,
resource: New<ZwpTextInputManagerV3>,
_: &(),
data_init: &mut DataInit<'_, D>,
) {
data_init.init(resource, ());
data_init.init(resource, GlobalData);
}
}
impl<D> Dispatch<ZwpTextInputManagerV3, (), D> for TextInputManagerState
impl<D> Dispatch2<ZwpTextInputManagerV3, D> for GlobalData
where
D: Dispatch<ZwpTextInputManagerV3, ()>,
D: Dispatch<ZwpTextInputV3, TextInputUserData>,
D: SeatHandler,
D: 'static,
{
fn request(
&self,
_state: &mut D,
_client: &Client,
_resource: &ZwpTextInputManagerV3,
request: zwp_text_input_manager_v3::Request,
_data: &(),
_dhandle: &DisplayHandle,
data_init: &mut DataInit<'_, D>,
) {
@ -171,36 +165,3 @@ where
}
}
}
#[allow(missing_docs)] // TODO
#[macro_export]
macro_rules! delegate_text_input_manager {
($(@<$( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+>)? $ty: ty) => {
const _: () = {
use $crate::{
reexports::{
wayland_protocols::wp::text_input::zv3::server::{
zwp_text_input_manager_v3::ZwpTextInputManagerV3, zwp_text_input_v3::ZwpTextInputV3,
},
wayland_server::{delegate_dispatch, delegate_global_dispatch},
},
wayland::text_input::{TextInputManagerState, TextInputUserData},
};
delegate_global_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [ZwpTextInputManagerV3: ()] => TextInputManagerState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [ZwpTextInputManagerV3: ()] => TextInputManagerState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [ZwpTextInputV3: TextInputUserData] => TextInputManagerState
);
};
};
}

View file

@ -6,13 +6,11 @@ use wayland_protocols::wp::text_input::zv3::server::zwp_text_input_v3::{
self, ChangeCause, ContentHint, ContentPurpose, ZwpTextInputV3,
};
use wayland_server::backend::{ClientId, ObjectId};
use wayland_server::{Dispatch, Resource, protocol::wl_surface::WlSurface};
use wayland_server::{Resource, protocol::wl_surface::WlSurface};
use crate::input::SeatHandler;
use crate::utils::{Logical, Rectangle};
use crate::wayland::input_method::InputMethodHandle;
use super::TextInputManagerState;
use crate::wayland::{Dispatch2, input_method::InputMethodHandle};
#[derive(Default, Debug)]
pub(crate) struct TextInput {
@ -188,33 +186,32 @@ pub struct TextInputUserData {
pub(crate) input_method_handle: InputMethodHandle,
}
impl<D> Dispatch<ZwpTextInputV3, TextInputUserData, D> for TextInputManagerState
impl<D> Dispatch2<ZwpTextInputV3, D> for TextInputUserData
where
D: Dispatch<ZwpTextInputV3, TextInputUserData>,
D: SeatHandler,
D: 'static,
{
fn request(
&self,
state: &mut D,
_client: &wayland_server::Client,
resource: &ZwpTextInputV3,
request: zwp_text_input_v3::Request,
data: &TextInputUserData,
_dhandle: &wayland_server::DisplayHandle,
_data_init: &mut wayland_server::DataInit<'_, D>,
) {
// Always increment serial to not desync with clients.
if matches!(request, zwp_text_input_v3::Request::Commit) {
data.handle.increment_serial(resource);
self.handle.increment_serial(resource);
}
// Discard requests without any active input method instance.
if !data.input_method_handle.has_instance() {
if !self.input_method_handle.has_instance() {
debug!("discarding text-input request without IME running");
return;
}
let focus = match data.handle.focus() {
let focus = match self.handle.focus() {
Some(focus) if focus.id().same_client_as(&resource.id()) => focus,
_ => {
debug!("discarding text-input request for unfocused client");
@ -222,7 +219,7 @@ where
}
};
let mut guard = data.handle.inner.lock().unwrap();
let mut guard = self.handle.inner.lock().unwrap();
let pending_state = match guard.instances.iter_mut().find_map(|instance| {
if instance.instance == *resource {
Some(&mut instance.pending_state)
@ -276,13 +273,13 @@ where
*active_text_input_id = Some(resource.id());
// Drop the guard before calling to other subsystem.
drop(guard);
data.input_method_handle.activate_input_method(state, &focus);
self.input_method_handle.activate_input_method(state, &focus);
}
Some(false) => {
*active_text_input_id = None;
// Drop the guard before calling to other subsystem.
drop(guard);
data.input_method_handle.deactivate_input_method(state);
self.input_method_handle.deactivate_input_method(state);
return;
}
None => {
@ -297,29 +294,29 @@ where
}
if let Some((text, cursor, anchor)) = new_state.surrounding_text.take() {
data.input_method_handle.with_instance(move |input_method| {
self.input_method_handle.with_instance(move |input_method| {
input_method.object.surrounding_text(text, cursor, anchor)
});
}
if let Some(cause) = new_state.text_change_cause.take() {
data.input_method_handle.with_instance(move |input_method| {
self.input_method_handle.with_instance(move |input_method| {
input_method.object.text_change_cause(cause);
});
}
if let Some((hint, purpose)) = new_state.content_type.take() {
data.input_method_handle.with_instance(move |input_method| {
self.input_method_handle.with_instance(move |input_method| {
input_method.object.content_type(hint, purpose);
});
}
if let Some(rect) = new_state.cursor_rectangle.take() {
data.input_method_handle
self.input_method_handle
.set_text_input_rectangle::<D>(state, rect);
}
data.input_method_handle.with_instance(|input_method| {
self.input_method_handle.with_instance(|input_method| {
input_method.done();
});
}
@ -330,10 +327,10 @@ where
}
}
fn destroyed(state: &mut D, _client: ClientId, text_input: &ZwpTextInputV3, data: &TextInputUserData) {
fn destroyed(&self, state: &mut D, _client: ClientId, text_input: &ZwpTextInputV3) {
let destroyed_id = text_input.id();
let deactivate_im = {
let mut inner = data.handle.inner.lock().unwrap();
let mut inner = self.handle.inner.lock().unwrap();
inner.instances.retain(|inst| inst.instance.id() != destroyed_id);
let destroyed_focused = inner
.focus
@ -351,7 +348,7 @@ where
};
if deactivate_im {
data.input_method_handle.deactivate_input_method(state);
self.input_method_handle.deactivate_input_method(state);
}
}
}

View file

@ -9,8 +9,6 @@
//!
//! ```
//! use smithay::wayland::viewporter::ViewporterState;
//! use smithay::delegate_viewporter;
//! # use smithay::delegate_compositor;
//! # use smithay::wayland::compositor::{CompositorHandler, CompositorState, CompositorClientState};
//! # use smithay::reexports::wayland_server::{Client, protocol::wl_surface::WlSurface};
//!
@ -22,15 +20,13 @@
//! &display.handle(), // the display
//! );
//!
//! // implement Dispatch for the Viewporter types
//! delegate_viewporter!(State);
//! smithay::delegate_dispatch2!(State);
//!
//! # impl CompositorHandler for State {
//! # fn compositor_state(&mut self) -> &mut CompositorState { unimplemented!() }
//! # fn client_compositor_state<'a>(&self, client: &'a Client) -> &'a CompositorClientState { unimplemented!() }
//! # fn commit(&mut self, surface: &WlSurface) {}
//! # }
//! # delegate_compositor!(State);
//!
//! // You're now ready to go!
//! ```
@ -61,7 +57,10 @@ use wayland_server::{
Dispatch, DisplayHandle, GlobalDispatch, Resource, Weak, backend::GlobalId, protocol::wl_surface,
};
use crate::utils::{Client, Logical, Rectangle, Size};
use crate::{
utils::{Client, Logical, Rectangle, Size},
wayland::{Dispatch2, GlobalData, GlobalDispatch2},
};
use super::compositor::{self, Cacheable, CompositorHandler, SurfaceData, with_states};
@ -80,13 +79,13 @@ impl ViewporterState {
/// the event loop in the future.
pub fn new<D>(display: &DisplayHandle) -> ViewporterState
where
D: GlobalDispatch<wp_viewporter::WpViewporter, ()>
+ Dispatch<wp_viewporter::WpViewporter, ()>
D: GlobalDispatch<wp_viewporter::WpViewporter, GlobalData>
+ Dispatch<wp_viewporter::WpViewporter, GlobalData>
+ Dispatch<wp_viewport::WpViewport, ViewportState>
+ 'static,
{
ViewporterState {
global: display.create_global::<D, wp_viewporter::WpViewporter, ()>(1, ()),
global: display.create_global::<D, wp_viewporter::WpViewporter, _>(1, GlobalData),
}
}
@ -96,36 +95,33 @@ impl ViewporterState {
}
}
impl<D> GlobalDispatch<wp_viewporter::WpViewporter, (), D> for ViewporterState
impl<D> GlobalDispatch2<wp_viewporter::WpViewporter, D> for GlobalData
where
D: GlobalDispatch<wp_viewporter::WpViewporter, ()>,
D: Dispatch<wp_viewporter::WpViewporter, ()>,
D: Dispatch<wp_viewporter::WpViewporter, GlobalData>,
D: Dispatch<wp_viewport::WpViewport, ViewportState>,
{
fn bind(
&self,
_state: &mut D,
_handle: &DisplayHandle,
_client: &wayland_server::Client,
resource: wayland_server::New<wp_viewporter::WpViewporter>,
_global_data: &(),
data_init: &mut wayland_server::DataInit<'_, D>,
) {
data_init.init(resource, ());
data_init.init(resource, GlobalData);
}
}
impl<D> Dispatch<wp_viewporter::WpViewporter, (), D> for ViewporterState
impl<D> Dispatch2<wp_viewporter::WpViewporter, D> for GlobalData
where
D: GlobalDispatch<wp_viewporter::WpViewporter, ()>,
D: Dispatch<wp_viewporter::WpViewporter, ()>,
D: Dispatch<wp_viewport::WpViewport, ViewportState>,
{
fn request(
&self,
_state: &mut D,
_client: &wayland_server::Client,
_resource: &wp_viewporter::WpViewporter,
request: <wp_viewporter::WpViewporter as wayland_server::Resource>::Request,
_data: &(),
_dhandle: &DisplayHandle,
data_init: &mut wayland_server::DataInit<'_, D>,
) {
@ -188,25 +184,22 @@ where
}
}
impl<D> Dispatch<wp_viewport::WpViewport, ViewportState, D> for ViewportState
impl<D> Dispatch2<wp_viewport::WpViewport, D> for ViewportState
where
D: GlobalDispatch<wp_viewporter::WpViewporter, ()>,
D: Dispatch<wp_viewporter::WpViewporter, ()>,
D: Dispatch<wp_viewport::WpViewport, ViewportState>,
D: CompositorHandler,
{
fn request(
&self,
state: &mut D,
client: &wayland_server::Client,
resource: &wp_viewport::WpViewport,
request: <wp_viewport::WpViewport as wayland_server::Resource>::Request,
data: &ViewportState,
_dhandle: &DisplayHandle,
_data_init: &mut wayland_server::DataInit<'_, D>,
) {
match request {
wp_viewport::Request::Destroy => {
if let Ok(surface) = data.surface.upgrade() {
if let Ok(surface) = self.surface.upgrade() {
with_states(&surface, |states| {
states
.data_map
@ -237,7 +230,7 @@ where
// If the wl_surface associated with the wp_viewport is destroyed,
// all wp_viewport requests except 'destroy' raise the protocol error no_surface.
let Ok(surface) = data.surface.upgrade() else {
let Ok(surface) = self.surface.upgrade() else {
resource.post_error(
wp_viewport::Error::NoSurface as u32,
"the wl_surface was destroyed".to_string(),
@ -275,7 +268,7 @@ where
// If the wl_surface associated with the wp_viewport is destroyed,
// all wp_viewport requests except 'destroy' raise the protocol error no_surface.
let Ok(surface) = data.surface.upgrade() else {
let Ok(surface) = self.surface.upgrade() else {
resource.post_error(
wp_viewport::Error::NoSurface as u32,
"the wl_surface was destroyed".to_string(),
@ -427,36 +420,3 @@ impl Cacheable for ViewportCachedState {
into.dst = self.dst;
}
}
#[allow(missing_docs)] // TODO
#[macro_export]
macro_rules! delegate_viewporter {
($(@<$( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+>)? $ty: ty) => {
const _: () = {
use $crate::{
reexports::{
wayland_protocols::wp::viewporter::server::{
wp_viewport::WpViewport, wp_viewporter::WpViewporter,
},
wayland_server::{delegate_dispatch, delegate_global_dispatch},
},
wayland::viewporter::{ViewportState, ViewporterState},
};
delegate_global_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [WpViewporter: ()] => ViewporterState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [WpViewporter: ()] => ViewporterState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [WpViewport: ViewportState] => ViewportState
);
};
};
}

View file

@ -5,10 +5,6 @@
//! an input method to pass through keys from the keyboard.
//!
//! ```
//! use smithay::{
//! delegate_seat, delegate_virtual_keyboard_manager,
//! # delegate_compositor
//! };
//! use smithay::input::{Seat, SeatState, SeatHandler, pointer::CursorImageStatus};
//! # use smithay::wayland::compositor::{CompositorHandler, CompositorState, CompositorClientState};
//! use smithay::wayland::virtual_keyboard::VirtualKeyboardManagerState;
@ -17,9 +13,7 @@
//!
//! # struct State { seat_state: SeatState<Self> };
//!
//! delegate_seat!(State);
//! // Delegate virtual keyboard handling for State to VirtualKeyboardManagerState.
//! delegate_virtual_keyboard_manager!(State);
//! smithay::delegate_dispatch2!(State);
//!
//! # let mut display = Display::<State>::new().unwrap();
//! # let display_handle = display.handle();
@ -47,7 +41,6 @@
//! # fn client_compositor_state<'a>(&self, client: &'a Client) -> &'a CompositorClientState { unimplemented!() }
//! # fn commit(&mut self, surface: &WlSurface) {}
//! # }
//! # delegate_compositor!(State);
//! ```
//!
@ -57,7 +50,10 @@ use wayland_protocols_misc::zwp_virtual_keyboard_v1::server::{
};
use wayland_server::{Client, DataInit, Dispatch, DisplayHandle, GlobalDispatch, New, backend::GlobalId};
use crate::input::{Seat, SeatHandler};
use crate::{
input::{Seat, SeatHandler},
wayland::{Dispatch2, GlobalData, GlobalDispatch2},
};
use self::virtual_keyboard_handle::VirtualKeyboardHandle;
@ -96,7 +92,7 @@ impl VirtualKeyboardManagerState {
pub fn new<D, F>(display: &DisplayHandle, filter: F) -> Self
where
D: GlobalDispatch<ZwpVirtualKeyboardManagerV1, VirtualKeyboardManagerGlobalData>,
D: Dispatch<ZwpVirtualKeyboardManagerV1, ()>,
D: Dispatch<ZwpVirtualKeyboardManagerV1, GlobalData>,
D: Dispatch<ZwpVirtualKeyboardV1, VirtualKeyboardUserData<D>>,
D: SeatHandler,
D: 'static,
@ -113,44 +109,41 @@ impl VirtualKeyboardManagerState {
}
}
impl<D> GlobalDispatch<ZwpVirtualKeyboardManagerV1, VirtualKeyboardManagerGlobalData, D>
for VirtualKeyboardManagerState
impl<D> GlobalDispatch2<ZwpVirtualKeyboardManagerV1, D> for VirtualKeyboardManagerGlobalData
where
D: GlobalDispatch<ZwpVirtualKeyboardManagerV1, VirtualKeyboardManagerGlobalData>,
D: Dispatch<ZwpVirtualKeyboardManagerV1, ()>,
D: Dispatch<ZwpVirtualKeyboardManagerV1, GlobalData>,
D: Dispatch<ZwpVirtualKeyboardV1, VirtualKeyboardUserData<D>>,
D: SeatHandler,
D: 'static,
{
fn bind(
&self,
_: &mut D,
_: &DisplayHandle,
_: &Client,
resource: New<ZwpVirtualKeyboardManagerV1>,
_: &VirtualKeyboardManagerGlobalData,
data_init: &mut DataInit<'_, D>,
) {
data_init.init(resource, ());
data_init.init(resource, GlobalData);
}
fn can_view(client: Client, global_data: &VirtualKeyboardManagerGlobalData) -> bool {
(global_data.filter)(&client)
fn can_view(&self, client: &Client) -> bool {
(self.filter)(client)
}
}
impl<D> Dispatch<ZwpVirtualKeyboardManagerV1, (), D> for VirtualKeyboardManagerState
impl<D> Dispatch2<ZwpVirtualKeyboardManagerV1, D> for GlobalData
where
D: Dispatch<ZwpVirtualKeyboardManagerV1, ()>,
D: Dispatch<ZwpVirtualKeyboardV1, VirtualKeyboardUserData<D>>,
D: SeatHandler,
D: 'static,
{
fn request(
&self,
_state: &mut D,
_client: &Client,
_resource: &ZwpVirtualKeyboardManagerV1,
request: zwp_virtual_keyboard_manager_v1::Request,
_data: &(),
_handle: &DisplayHandle,
data_init: &mut DataInit<'_, D>,
) {
@ -170,39 +163,3 @@ where
}
}
}
#[allow(missing_docs)] //TODO
#[macro_export]
macro_rules! delegate_virtual_keyboard_manager {
($(@<$( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+>)? $ty: ty) => {
const _: () = {
use $crate::{
reexports::{
wayland_protocols_misc::zwp_virtual_keyboard_v1::server::{
zwp_virtual_keyboard_manager_v1::ZwpVirtualKeyboardManagerV1,
zwp_virtual_keyboard_v1::ZwpVirtualKeyboardV1,
},
wayland_server::{delegate_dispatch, delegate_global_dispatch},
},
wayland::virtual_keyboard::{
VirtualKeyboardManagerGlobalData, VirtualKeyboardManagerState, VirtualKeyboardUserData,
},
};
delegate_global_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [ZwpVirtualKeyboardManagerV1: VirtualKeyboardManagerGlobalData] => VirtualKeyboardManagerState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [ZwpVirtualKeyboardManagerV1: ()] => VirtualKeyboardManagerState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [ZwpVirtualKeyboardV1: VirtualKeyboardUserData<Self>] => VirtualKeyboardManagerState
);
};
};
}

View file

@ -10,8 +10,7 @@ use wayland_protocols_misc::zwp_virtual_keyboard_v1::server::zwp_virtual_keyboar
self, ZwpVirtualKeyboardV1,
};
use wayland_server::{
Client, DataInit, Dispatch, DisplayHandle, Resource,
backend::ClientId,
Client, DataInit, DisplayHandle, Resource,
protocol::wl_keyboard::{KeyState, KeymapFormat},
};
use xkbcommon::xkb;
@ -20,11 +19,12 @@ use crate::input::keyboard::{KeyboardTarget, KeymapFile, ModifiersState};
use crate::{
input::{Seat, SeatHandler},
utils::SERIAL_COUNTER,
wayland::seat::{WaylandFocus, keyboard::for_each_focused_kbds},
wayland::{
Dispatch2,
seat::{WaylandFocus, keyboard::for_each_focused_kbds},
},
};
use super::VirtualKeyboardManagerState;
#[derive(Debug, Default)]
pub(crate) struct VirtualKeyboard {
state: Option<VirtualKeyboardState>,
@ -71,28 +71,27 @@ impl<D: SeatHandler> fmt::Debug for VirtualKeyboardUserData<D> {
}
}
impl<D> Dispatch<ZwpVirtualKeyboardV1, VirtualKeyboardUserData<D>, D> for VirtualKeyboardManagerState
impl<D> Dispatch2<ZwpVirtualKeyboardV1, D> for VirtualKeyboardUserData<D>
where
D: Dispatch<ZwpVirtualKeyboardV1, VirtualKeyboardUserData<D>>,
D: SeatHandler + 'static,
<D as SeatHandler>::KeyboardFocus: WaylandFocus,
{
fn request(
&self,
user_data: &mut D,
_client: &Client,
virtual_keyboard: &ZwpVirtualKeyboardV1,
request: zwp_virtual_keyboard_v1::Request,
data: &VirtualKeyboardUserData<D>,
_dh: &DisplayHandle,
_data_init: &mut DataInit<'_, D>,
) {
match request {
zwp_virtual_keyboard_v1::Request::Keymap { format, fd, size } => {
update_keymap(data, format, fd, size as usize);
update_keymap(self, format, fd, size as usize);
}
zwp_virtual_keyboard_v1::Request::Key { time, key, state } => {
// Ensure keymap was initialized.
let mut virtual_data = data.handle.inner.lock().unwrap();
let mut virtual_data = self.handle.inner.lock().unwrap();
let vk_state = match virtual_data.state.as_mut() {
Some(vk_state) => vk_state,
None => {
@ -102,13 +101,13 @@ where
};
// Ensure virtual keyboard's keymap is active.
let keyboard_handle = data.seat.get_keyboard().unwrap();
let keyboard_handle = self.seat.get_keyboard().unwrap();
let mut internal = keyboard_handle.arc.internal.lock().unwrap();
let focus = internal.focus.as_mut().map(|(focus, _)| focus);
keyboard_handle.send_keymap(user_data, &focus, &vk_state.keymap, vk_state.mods);
if let Some(wl_surface) = focus.and_then(|f| f.wl_surface()) {
for_each_focused_kbds(&data.seat, &wl_surface, |kbd| {
for_each_focused_kbds(&self.seat, &wl_surface, |kbd| {
// This should be wl_keyboard::KeyState, but the protocol does not state
// the parameter is an enum.
let key_state = if state == 1 {
@ -128,7 +127,7 @@ where
group,
} => {
// Ensure keymap was initialized.
let mut virtual_data = data.handle.inner.lock().unwrap();
let mut virtual_data = self.handle.inner.lock().unwrap();
let state = match virtual_data.state.as_mut() {
Some(state) => state,
None => {
@ -144,7 +143,7 @@ where
state.mods.update_with(&state.state);
// Ensure virtual keyboard's keymap is active.
let keyboard_handle = data.seat.get_keyboard().unwrap();
let keyboard_handle = self.seat.get_keyboard().unwrap();
let mut internal = keyboard_handle.arc.internal.lock().unwrap();
let focus = internal.focus.as_mut().map(|(focus, _)| focus);
let keymap_changed =
@ -153,7 +152,7 @@ where
// Report modifiers change to all keyboards.
if !keymap_changed {
if let Some(focus) = focus {
focus.modifiers(&data.seat, user_data, state.mods, SERIAL_COUNTER.next_serial());
focus.modifiers(&self.seat, user_data, state.mods, SERIAL_COUNTER.next_serial());
}
}
}
@ -163,14 +162,6 @@ where
_ => unreachable!(),
}
}
fn destroyed(
_state: &mut D,
_client: ClientId,
_virtual_keyboard: &ZwpVirtualKeyboardV1,
_data: &VirtualKeyboardUserData<D>,
) {
}
}
/// Handle the zwp_virtual_keyboard_v1::keymap request.

View file

@ -4,27 +4,24 @@ use std::sync::{
};
use wayland_protocols::xdg::activation::v1::server::{xdg_activation_token_v1, xdg_activation_v1};
use wayland_server::{
Client, DataInit, Dispatch, DisplayHandle, GlobalDispatch, New, Resource, backend::ClientId,
};
use wayland_server::{Client, DataInit, Dispatch, DisplayHandle, New, Resource};
use super::{
ActivationTokenData, TokenBuilder, XdgActivationHandler, XdgActivationState, XdgActivationTokenData,
};
use super::{ActivationTokenData, TokenBuilder, XdgActivationHandler, XdgActivationTokenData};
impl<D> Dispatch<xdg_activation_v1::XdgActivationV1, (), D> for XdgActivationState
use crate::wayland::{Dispatch2, GlobalData, GlobalDispatch2};
impl<D> Dispatch2<xdg_activation_v1::XdgActivationV1, D> for GlobalData
where
D: Dispatch<xdg_activation_v1::XdgActivationV1, ()>
+ Dispatch<xdg_activation_token_v1::XdgActivationTokenV1, ActivationTokenData>
D: Dispatch<xdg_activation_token_v1::XdgActivationTokenV1, ActivationTokenData>
+ XdgActivationHandler
+ 'static,
{
fn request(
&self,
state: &mut D,
_: &Client,
_: &xdg_activation_v1::XdgActivationV1,
request: xdg_activation_v1::Request,
_: &(),
_dh: &DisplayHandle,
data_init: &mut DataInit<'_, D>,
) {
@ -61,42 +58,41 @@ where
}
}
impl<D> GlobalDispatch<xdg_activation_v1::XdgActivationV1, (), D> for XdgActivationState
impl<D> GlobalDispatch2<xdg_activation_v1::XdgActivationV1, D> for GlobalData
where
D: GlobalDispatch<xdg_activation_v1::XdgActivationV1, ()>
+ Dispatch<xdg_activation_v1::XdgActivationV1, ()>
D: Dispatch<xdg_activation_v1::XdgActivationV1, GlobalData>
+ Dispatch<xdg_activation_token_v1::XdgActivationTokenV1, ActivationTokenData>
+ XdgActivationHandler
+ 'static,
{
fn bind(
&self,
_: &mut D,
_: &DisplayHandle,
_: &Client,
resource: New<xdg_activation_v1::XdgActivationV1>,
_: &(),
data_init: &mut DataInit<'_, D>,
) {
data_init.init(resource, ());
data_init.init(resource, GlobalData);
}
}
impl<D> Dispatch<xdg_activation_token_v1::XdgActivationTokenV1, ActivationTokenData, D> for XdgActivationState
impl<D> Dispatch2<xdg_activation_token_v1::XdgActivationTokenV1, D> for ActivationTokenData
where
D: Dispatch<xdg_activation_token_v1::XdgActivationTokenV1, ActivationTokenData> + XdgActivationHandler,
D: XdgActivationHandler,
{
fn request(
&self,
state: &mut D,
client: &Client,
token: &xdg_activation_token_v1::XdgActivationTokenV1,
request: xdg_activation_token_v1::Request,
data: &ActivationTokenData,
_dh: &DisplayHandle,
_: &mut DataInit<'_, D>,
) {
match request {
xdg_activation_token_v1::Request::SetSerial { serial, seat } => {
if data.constructed.load(Ordering::Relaxed) {
if self.constructed.load(Ordering::Relaxed) {
token.post_error(
xdg_activation_token_v1::Error::AlreadyUsed,
"The activation token has already been constructed",
@ -104,11 +100,11 @@ where
return;
}
data.build.lock().unwrap().serial = Some((serial.into(), seat));
self.build.lock().unwrap().serial = Some((serial.into(), seat));
}
xdg_activation_token_v1::Request::SetAppId { app_id } => {
if data.constructed.load(Ordering::Relaxed) {
if self.constructed.load(Ordering::Relaxed) {
token.post_error(
xdg_activation_token_v1::Error::AlreadyUsed,
"The activation token has already been constructed",
@ -116,11 +112,11 @@ where
return;
}
data.build.lock().unwrap().app_id = Some(app_id);
self.build.lock().unwrap().app_id = Some(app_id);
}
xdg_activation_token_v1::Request::SetSurface { surface } => {
if data.constructed.load(Ordering::Relaxed) {
if self.constructed.load(Ordering::Relaxed) {
token.post_error(
xdg_activation_token_v1::Error::AlreadyUsed,
"The activation token has already been constructed",
@ -128,11 +124,11 @@ where
return;
}
data.build.lock().unwrap().surface = Some(surface);
self.build.lock().unwrap().surface = Some(surface);
}
xdg_activation_token_v1::Request::Commit => {
if data.constructed.load(Ordering::Relaxed) {
if self.constructed.load(Ordering::Relaxed) {
token.post_error(
xdg_activation_token_v1::Error::AlreadyUsed,
"The activation token has already been constructed",
@ -140,10 +136,10 @@ where
return;
}
data.constructed.store(true, Ordering::Relaxed);
self.constructed.store(true, Ordering::Relaxed);
let (activation_token, token_data) = {
let mut guard = data.build.lock().unwrap();
let mut guard = self.build.lock().unwrap();
XdgActivationTokenData::new(
Some(client.id()),
@ -155,7 +151,7 @@ where
let valid = state.token_created(activation_token.clone(), token_data.clone());
*data.token.lock().unwrap() = Some(activation_token.clone());
*self.token.lock().unwrap() = Some(activation_token.clone());
if valid {
state
.activation_state()
@ -170,12 +166,4 @@ where
_ => unreachable!(),
}
}
fn destroyed(
_: &mut D,
_: ClientId,
_: &xdg_activation_token_v1::XdgActivationTokenV1,
_: &ActivationTokenData,
) {
}
}

View file

@ -7,7 +7,6 @@
//! #
//! use wayland_server::{protocol::wl_surface::WlSurface, DisplayHandle};
//! use smithay::{
//! delegate_xdg_activation,
//! wayland::xdg_activation::{XdgActivationHandler, XdgActivationState, XdgActivationToken, XdgActivationTokenData}
//! };
//!
@ -33,7 +32,7 @@
//! }
//!
//! // Delegate xdg activation handling for State to XdgActivationState.
//! delegate_xdg_activation!(State);
//! smithay::delegate_dispatch2!(State);
//!
//! # let mut display = wayland_server::Display::<State>::new().unwrap();
//! # let display_handle = display.handle();
@ -61,6 +60,7 @@ use wayland_server::{
use rand::distr::{Alphanumeric, SampleString};
use crate::utils::{Serial, user_data::UserDataMap};
use crate::wayland::GlobalData;
mod dispatch;
@ -179,12 +179,12 @@ impl XdgActivationState {
/// In order to use this abstraction, your `D` type needs to implement [`XdgActivationHandler`].
pub fn new<D>(display: &DisplayHandle) -> XdgActivationState
where
D: GlobalDispatch<xdg_activation_v1::XdgActivationV1, ()>
+ Dispatch<xdg_activation_v1::XdgActivationV1, ()>
D: GlobalDispatch<xdg_activation_v1::XdgActivationV1, GlobalData>
+ Dispatch<xdg_activation_v1::XdgActivationV1, GlobalData>
+ XdgActivationHandler
+ 'static,
{
let global = display.create_global::<D, xdg_activation_v1::XdgActivationV1, _>(1, ());
let global = display.create_global::<D, xdg_activation_v1::XdgActivationV1, _>(1, GlobalData);
XdgActivationState {
global,
@ -279,41 +279,6 @@ pub struct ActivationTokenData {
token: Mutex<Option<XdgActivationToken>>,
}
/// Macro to delegate implementation of the xdg activation to [`XdgActivationState`].
///
/// You must also implement [`XdgActivationHandler`] to use this.
#[macro_export]
macro_rules! delegate_xdg_activation {
($(@<$( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+>)? $ty: ty) => {
const _: () = {
use $crate::{
reexports::{
wayland_protocols::xdg::activation::v1::server::{
xdg_activation_token_v1::XdgActivationTokenV1, xdg_activation_v1::XdgActivationV1,
},
wayland_server::{delegate_dispatch, delegate_global_dispatch},
},
wayland::xdg_activation::{ActivationTokenData, XdgActivationState},
};
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [XdgActivationV1: ()] => XdgActivationState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [XdgActivationTokenV1: ActivationTokenData] => XdgActivationState
);
delegate_global_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [XdgActivationV1: ()] => XdgActivationState
);
};
};
}
#[derive(Debug)]
struct TokenBuilder {
serial: Option<(Serial, WlSeat)>,

View file

@ -6,54 +6,49 @@ use wayland_protocols::xdg::foreign::zv2::server::{
zxdg_imported_v2::{self, ZxdgImportedV2},
zxdg_importer_v2::{self, ZxdgImporterV2},
};
use wayland_server::{
Client, DataInit, Dispatch, DisplayHandle, GlobalDispatch, New, Resource, backend::ClientId,
};
use wayland_server::{Client, DataInit, Dispatch, DisplayHandle, New, Resource, backend::ClientId};
use crate::wayland::{
compositor,
Dispatch2, GlobalData, GlobalDispatch2, compositor,
shell::{
is_valid_parent,
xdg::{XDG_TOPLEVEL_ROLE, XdgShellHandler, XdgToplevelSurfaceData},
},
};
use super::{
ExportedState, XdgExportedUserData, XdgForeignHandle, XdgForeignHandler, XdgForeignState,
XdgImportedUserData,
};
use super::{ExportedState, XdgExportedUserData, XdgForeignHandle, XdgForeignHandler, XdgImportedUserData};
//
// Export
//
impl<D> GlobalDispatch<ZxdgExporterV2, (), D> for XdgForeignState
impl<D> GlobalDispatch2<ZxdgExporterV2, D> for GlobalData
where
D: Dispatch<ZxdgExporterV2, ()>,
D: Dispatch<ZxdgExporterV2, GlobalData>,
{
fn bind(
&self,
_state: &mut D,
_handle: &DisplayHandle,
_client: &Client,
resource: New<ZxdgExporterV2>,
_global_data: &(),
data_init: &mut DataInit<'_, D>,
) {
data_init.init(resource, ());
data_init.init(resource, GlobalData);
}
}
impl<D> Dispatch<ZxdgExporterV2, (), D> for XdgForeignState
impl<D> Dispatch2<ZxdgExporterV2, D> for GlobalData
where
D: Dispatch<ZxdgExportedV2, XdgExportedUserData>,
D: XdgForeignHandler,
{
fn request(
&self,
state: &mut D,
_client: &Client,
resource: &ZxdgExporterV2,
request: zxdg_exporter_v2::Request,
_data: &(),
_dhandle: &DisplayHandle,
data_init: &mut DataInit<'_, D>,
) {
@ -91,26 +86,26 @@ where
}
}
impl<D> Dispatch<ZxdgExportedV2, XdgExportedUserData, D> for XdgForeignState
impl<D> Dispatch2<ZxdgExportedV2, D> for XdgExportedUserData
where
D: XdgForeignHandler + XdgShellHandler,
{
fn request(
&self,
_state: &mut D,
_client: &Client,
_resource: &ZxdgExportedV2,
_request: zxdg_exported_v2::Request,
_data: &XdgExportedUserData,
_dhandle: &DisplayHandle,
_data_init: &mut DataInit<'_, D>,
) {
}
fn destroyed(state: &mut D, _client: ClientId, _resource: &ZxdgExportedV2, data: &XdgExportedUserData) {
fn destroyed(&self, state: &mut D, _client: ClientId, _resource: &ZxdgExportedV2) {
// Revoke the previously exported surface.
// This invalidates any relationship the importer may have set up using the xdg_imported created given the handle sent via xdg_exported.handle.
invalidate_all_relationships(state, &data.handle);
state.xdg_foreign_state().exported.remove(&data.handle);
invalidate_all_relationships(state, &self.handle);
state.xdg_foreign_state().exported.remove(&self.handle);
}
}
@ -118,32 +113,32 @@ where
// Import
//
impl<D> GlobalDispatch<ZxdgImporterV2, (), D> for XdgForeignState
impl<D> GlobalDispatch2<ZxdgImporterV2, D> for GlobalData
where
D: Dispatch<ZxdgImporterV2, ()>,
D: Dispatch<ZxdgImporterV2, GlobalData>,
{
fn bind(
&self,
_state: &mut D,
_handle: &DisplayHandle,
_client: &Client,
resource: New<ZxdgImporterV2>,
_global_data: &(),
data_init: &mut DataInit<'_, D>,
) {
data_init.init(resource, ());
data_init.init(resource, GlobalData);
}
}
impl<D: XdgForeignHandler> Dispatch<ZxdgImporterV2, (), D> for XdgForeignState
impl<D: XdgForeignHandler> Dispatch2<ZxdgImporterV2, D> for GlobalData
where
D: Dispatch<ZxdgImportedV2, XdgImportedUserData>,
{
fn request(
&self,
state: &mut D,
_client: &Client,
_resource: &ZxdgImporterV2,
request: zxdg_importer_v2::Request,
_data: &(),
_dhandle: &DisplayHandle,
data_init: &mut DataInit<'_, D>,
) {
@ -177,16 +172,16 @@ where
}
}
impl<D> Dispatch<ZxdgImportedV2, XdgImportedUserData, D> for XdgForeignState
impl<D> Dispatch2<ZxdgImportedV2, D> for XdgImportedUserData
where
D: XdgForeignHandler + XdgShellHandler,
{
fn request(
&self,
state: &mut D,
_client: &Client,
resource: &ZxdgImportedV2,
request: zxdg_imported_v2::Request,
data: &XdgImportedUserData,
_dhandle: &DisplayHandle,
_data_init: &mut DataInit<'_, D>,
) {
@ -196,7 +191,7 @@ where
.xdg_foreign_state()
.exported
.iter_mut()
.find(|(key, _)| key.as_str() == data.handle.as_str())
.find(|(key, _)| key.as_str() == self.handle.as_str())
{
let parent = &exported_state.exported_surface;
@ -242,17 +237,17 @@ where
}
}
fn destroyed(state: &mut D, _client: ClientId, resource: &ZxdgImportedV2, data: &XdgImportedUserData) {
fn destroyed(&self, state: &mut D, _client: ClientId, resource: &ZxdgImportedV2) {
if let Some((_, exported_state)) = state
.xdg_foreign_state()
.exported
.iter_mut()
.find(|(key, _)| key.as_str() == data.handle.as_str())
.find(|(key, _)| key.as_str() == self.handle.as_str())
{
exported_state.imported_by.remove(resource);
}
invalidate_relationship_for(state, &data.handle, Some(resource));
invalidate_relationship_for(state, &self.handle, Some(resource));
}
}

View file

@ -40,6 +40,8 @@ use wayland_protocols::xdg::foreign::zv2::server::{
};
use wayland_server::{DisplayHandle, GlobalDispatch, backend::GlobalId, protocol::wl_surface::WlSurface};
use crate::wayland::GlobalData;
mod handlers;
/// A trait implemented to be notified of activation requests using the xdg foreign protocol.
@ -105,11 +107,11 @@ impl XdgForeignState {
pub fn new<D>(display: &DisplayHandle) -> Self
where
D: XdgForeignHandler,
D: GlobalDispatch<ZxdgExporterV2, ()>,
D: GlobalDispatch<ZxdgImporterV2, ()>,
D: GlobalDispatch<ZxdgExporterV2, GlobalData>,
D: GlobalDispatch<ZxdgImporterV2, GlobalData>,
{
let exporter = display.create_global::<D, ZxdgExporterV2, _>(1, ());
let importer = display.create_global::<D, ZxdgImporterV2, _>(1, ());
let exporter = display.create_global::<D, ZxdgExporterV2, _>(1, GlobalData);
let importer = display.create_global::<D, ZxdgImporterV2, _>(1, GlobalData);
Self {
exported: HashMap::new(),
@ -128,55 +130,3 @@ impl XdgForeignState {
self.importer.clone()
}
}
/// Macro to delegate implementation of the xdg foreign to [`XdgForeignState`].
///
/// You must also implement [`XdgForeignHandler`] and
/// [`XdgShellHandler`](crate::wayland::shell::xdg::XdgShellHandler) to use this.
#[macro_export]
macro_rules! delegate_xdg_foreign {
($(@<$( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+>)? $ty: ty) => {
const _: () = {
use $crate::{
reexports::{
wayland_protocols::xdg::foreign::zv2::server::{
zxdg_exported_v2::ZxdgExportedV2, zxdg_exporter_v2::ZxdgExporterV2,
zxdg_imported_v2::ZxdgImportedV2, zxdg_importer_v2::ZxdgImporterV2,
},
wayland_server::{delegate_dispatch, delegate_global_dispatch},
},
wayland::xdg_foreign::{XdgExportedUserData, XdgForeignState, XdgImportedUserData},
};
delegate_global_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [ZxdgExporterV2: ()] => XdgForeignState
);
delegate_global_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [ZxdgImporterV2: ()] => XdgForeignState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [ZxdgExporterV2: ()] => XdgForeignState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [ZxdgImporterV2: ()] => XdgForeignState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [ZxdgExportedV2: XdgExportedUserData] => XdgForeignState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [ZxdgImportedV2: XdgImportedUserData] => XdgForeignState
);
};
};
}

View file

@ -2,13 +2,11 @@
//!
//! This protocol enables clients to ring the system bell.
//!
//! In order to advertise system bell global call [`XdgSystemBellState::new`] and delegate
//! events to it with [`delegate_xdg_system_bell`][crate::delegate_xdg_system_bell].
//! In order to advertise system bell global call [`XdgSystemBellState::new`].
//!
//! ```
//! use smithay::wayland::xdg_system_bell::{XdgSystemBellState, XdgSystemBellHandler};
//! use wayland_server::protocol::wl_surface::WlSurface;
//! use smithay::delegate_xdg_system_bell;
//!
//! # struct State;
//! # let mut display = wayland_server::Display::<State>::new().unwrap();
@ -24,7 +22,7 @@
//! }
//! }
//!
//! delegate_xdg_system_bell!(State);
//! smithay::delegate_dispatch2!(State);
//! ```
use wayland_protocols::xdg::system_bell::v1::server::xdg_system_bell_v1::{self, XdgSystemBellV1};
@ -33,10 +31,10 @@ use wayland_server::{
protocol::wl_surface::WlSurface,
};
use crate::wayland::{Dispatch2, GlobalData, GlobalDispatch2};
/// Handler for xdg ring request
pub trait XdgSystemBellHandler:
GlobalDispatch<XdgSystemBellV1, ()> + Dispatch<XdgSystemBellV1, ()> + 'static
{
pub trait XdgSystemBellHandler: 'static {
/// Ring the system bell
fn ring(&mut self, surface: Option<WlSurface>);
}
@ -49,8 +47,11 @@ pub struct XdgSystemBellState {
impl XdgSystemBellState {
/// Register new [XdgSystemBellV1] global
pub fn new<D: XdgSystemBellHandler>(display: &DisplayHandle) -> Self {
let global_id = display.create_global::<D, XdgSystemBellV1, ()>(1, ());
pub fn new<D>(display: &DisplayHandle) -> Self
where
D: XdgSystemBellHandler + GlobalDispatch<XdgSystemBellV1, GlobalData>,
{
let global_id = display.create_global::<D, XdgSystemBellV1, _>(1, GlobalData);
Self { global_id }
}
@ -60,26 +61,29 @@ impl XdgSystemBellState {
}
}
impl<D: XdgSystemBellHandler> GlobalDispatch<XdgSystemBellV1, (), D> for XdgSystemBellState {
impl<D: XdgSystemBellHandler> GlobalDispatch2<XdgSystemBellV1, D> for GlobalData
where
D: Dispatch<XdgSystemBellV1, GlobalData>,
{
fn bind(
&self,
_state: &mut D,
_handle: &DisplayHandle,
_client: &Client,
resource: New<XdgSystemBellV1>,
_global_data: &(),
data_init: &mut DataInit<'_, D>,
) {
data_init.init(resource, ());
data_init.init(resource, GlobalData);
}
}
impl<D: XdgSystemBellHandler> Dispatch<XdgSystemBellV1, (), D> for XdgSystemBellState {
impl<D: XdgSystemBellHandler> Dispatch2<XdgSystemBellV1, D> for GlobalData {
fn request(
&self,
state: &mut D,
_client: &wayland_server::Client,
_resource: &XdgSystemBellV1,
request: xdg_system_bell_v1::Request,
_data: &(),
_dhandle: &DisplayHandle,
_data_init: &mut DataInit<'_, D>,
) {
@ -92,31 +96,3 @@ impl<D: XdgSystemBellHandler> Dispatch<XdgSystemBellV1, (), D> for XdgSystemBell
}
}
}
/// Macro to delegate implementation of the xdg system bell to [`XdgSystemBellState`].
///
/// You must also implement [`XdgSystemBellHandler`] to use this.
#[macro_export]
macro_rules! delegate_xdg_system_bell {
($(@<$( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+>)? $ty: ty) => {
const _: () = {
use $crate::{
reexports::{
wayland_protocols::xdg::system_bell::v1::server::xdg_system_bell_v1::XdgSystemBellV1,
wayland_server::{delegate_dispatch, delegate_global_dispatch},
},
wayland::xdg_system_bell::XdgSystemBellState,
};
delegate_global_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [XdgSystemBellV1: ()] => XdgSystemBellState
);
delegate_dispatch!(
$(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
$ty: [XdgSystemBellV1: ()] => XdgSystemBellState
);
};
};
}

Some files were not shown because too many files have changed in this diff Show more