diff --git a/Cargo.toml b/Cargo.toml index 56430bae4..d1c6d81a7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -61,3 +61,12 @@ pollster = "0.3.0" [[example]] name = "wgpu" required-features = ["system"] + +[patch.crates-io] +wayland-client = { git = "https://github.com/smithay/wayland-rs" } +wayland-protocols = { git = "https://github.com/smithay/wayland-rs" } +wayland-protocols-wlr = { git = "https://github.com/smithay/wayland-rs" } +wayland-protocols-misc = { git = "https://github.com/smithay/wayland-rs" } +wayland-protocols-experimental = { git = "https://github.com/smithay/wayland-rs" } +wayland-cursor = { git = "https://github.com/smithay/wayland-rs" } +wayland-backend = { git = "https://github.com/smithay/wayland-rs" } diff --git a/src/activation.rs b/src/activation.rs index c0e37e114..d89b052a3 100644 --- a/src/activation.rs +++ b/src/activation.rs @@ -55,7 +55,7 @@ impl ActivationState { qh: &QueueHandle, ) -> Result where - State: Dispatch + 'static, + State: ActivationHandler + 'static, { let xdg_activation = globals.bind(qh, 1..=1, GlobalData)?; Ok(ActivationState { xdg_activation }) @@ -73,7 +73,7 @@ impl ActivationState { pub fn request_token(&self, qh: &QueueHandle, request_data: RequestData) where D: ActivationHandler, - D: Dispatch> + 'static, + D: 'static, U: Send + Sync + 'static, { let token = self.xdg_activation.get_activation_token(qh, request_data); diff --git a/src/background_effect.rs b/src/background_effect.rs index 8f06bb8ad..1924b15a3 100644 --- a/src/background_effect.rs +++ b/src/background_effect.rs @@ -1,5 +1,5 @@ use wayland_client::{ - globals::GlobalList, protocol::wl_surface, Connection, Dispatch, QueueHandle, WEnum, + globals::GlobalList, protocol::wl_surface, Connection, Dispatch, QueueHandle, }; use wayland_protocols::ext::background_effect::v1::client::{ ext_background_effect_manager_v1, ext_background_effect_surface_v1, @@ -16,8 +16,7 @@ pub struct BackgroundEffectState { impl BackgroundEffectState { pub fn new(globals: &GlobalList, qh: &QueueHandle) -> Self where - D: Dispatch - + 'static, + D: BackgroundEffectHandler + 'static, { let manager = GlobalProxy::from(globals.bind(qh, 1..=1, GlobalData)); Self { manager, capabilities: None } @@ -39,8 +38,7 @@ impl BackgroundEffectState { qh: &QueueHandle, ) -> Result where - D: Dispatch - + 'static, + D: BackgroundEffectHandler + 'static, { Ok(self.manager.get()?.get_background_effect(surface, qh, GlobalData)) } @@ -76,12 +74,6 @@ where ) { match event { ext_background_effect_manager_v1::Event::Capabilities { flags } => { - let flags = match flags { - WEnum::Value(value) => value, - WEnum::Unknown(value) => { - ext_background_effect_manager_v1::Capability::from_bits_retain(value) - } - }; data.background_effect_state().capabilities = Some(flags); data.update_capabilities(); } diff --git a/src/compositor.rs b/src/compositor.rs index 016db0f89..d91218c08 100644 --- a/src/compositor.rs +++ b/src/compositor.rs @@ -12,7 +12,7 @@ use wayland_client::{ wl_callback, wl_compositor, wl_output, wl_region, wl_surface::{self, WlSurface}, }, - Connection, Dispatch, Proxy, QueueHandle, WEnum, + Connection, Dispatch, Proxy, QueueHandle, }; use crate::{ @@ -95,7 +95,7 @@ impl CompositorState { qh: &QueueHandle, ) -> Result where - State: Dispatch + 'static, + State: CompositorHandler + 'static, { let wl_compositor = globals.bind(qh, 1..=Self::API_VERSION_MAX, GlobalData)?; Ok(CompositorState { wl_compositor }) @@ -107,7 +107,7 @@ impl CompositorState { pub fn create_surface(&self, qh: &QueueHandle) -> wl_surface::WlSurface where - D: Dispatch> + 'static, + D: CompositorHandler + OutputHandler + 'static, { self.create_surface_with_data(qh, None, 1, ()) } @@ -120,7 +120,7 @@ impl CompositorState { data: U, ) -> wl_surface::WlSurface where - D: Dispatch> + 'static, + D: CompositorHandler + OutputHandler + 'static, U: Send + Sync + 'static, { let data = SurfaceData::new(parent_surface, scale_factor, data); @@ -229,7 +229,7 @@ impl Surface { qh: &QueueHandle, ) -> Result where - D: Dispatch> + 'static, + D: CompositorHandler + OutputHandler + 'static, { Self::with_data(compositor, qh, None, 1, ()) } @@ -245,7 +245,7 @@ impl Surface { data: U, ) -> Result where - D: Dispatch> + 'static, + D: CompositorHandler + OutputHandler + 'static, U: Send + Sync + 'static, { let data = SurfaceData::new(parent_surface, scale_factor, data); @@ -306,7 +306,7 @@ where } wl_surface::Event::PreferredBufferTransform { transform } => { // Only handle known values. - if let WEnum::Value(transform) = transform { + if transform.available_since().is_some_and(|v| v <= surface.version()) { let old_transform = std::mem::replace(&mut inner.transform, transform); drop(inner); if old_transform != transform { diff --git a/src/data_device_manager/data_device.rs b/src/data_device_manager/data_device.rs index 82aef3c7b..d398070f2 100644 --- a/src/data_device_manager/data_device.rs +++ b/src/data_device_manager/data_device.rs @@ -105,13 +105,10 @@ impl Drop for DataDevice { impl Dispatch2 for DataDeviceData where - D: Dispatch - + DataDeviceHandler - + DataOfferHandler - + 'static, + D: DataDeviceHandler + DataOfferHandler + 'static, { event_created_child!(D, WlDataDevice, [ - 0 => (WlDataOffer, Default::default()) + 0 => (WlDataOffer, DataOfferData::default()) ]); fn event( diff --git a/src/data_device_manager/data_offer.rs b/src/data_device_manager/data_offer.rs index ad69c9257..3a4acd183 100644 --- a/src/data_device_manager/data_offer.rs +++ b/src/data_device_manager/data_offer.rs @@ -367,7 +367,7 @@ where fn event( &self, state: &mut D, - _offer: &wl_data_offer::WlDataOffer, + offer: &wl_data_offer::WlDataOffer, event: ::Event, conn: &wayland_client::Connection, qh: &wayland_client::QueueHandle, @@ -377,33 +377,27 @@ where self.push_mime_type(mime_type); } wl_data_offer::Event::SourceActions { source_actions } => { - match source_actions { - wayland_client::WEnum::Value(a) => { - self.set_source_action(a); - match &mut self.inner.lock().unwrap().offer { - DataDeviceOffer::Drag(o) => { - state.source_actions(conn, qh, o, a); - } - DataDeviceOffer::Selection(_) => {} - DataDeviceOffer::Undetermined(_) => {} + if source_actions.available_since().is_some_and(|v| v <= offer.version()) { + self.set_source_action(source_actions); + match &mut self.inner.lock().unwrap().offer { + DataDeviceOffer::Drag(o) => { + state.source_actions(conn, qh, o, source_actions); } + DataDeviceOffer::Selection(_) => {} + DataDeviceOffer::Undetermined(_) => {} } - wayland_client::WEnum::Unknown(_) => {} // Ignore } } wl_data_offer::Event::Action { dnd_action } => { - match dnd_action { - wayland_client::WEnum::Value(a) => { - self.set_selected_action(a); - match &mut self.inner.lock().unwrap().offer { - DataDeviceOffer::Drag(o) => { - state.selected_action(conn, qh, o, a); - } - DataDeviceOffer::Selection(_) => {} - DataDeviceOffer::Undetermined(_) => {} + if dnd_action.available_since().is_some_and(|v| v <= offer.version()) { + self.set_selected_action(dnd_action); + match &mut self.inner.lock().unwrap().offer { + DataDeviceOffer::Drag(o) => { + state.selected_action(conn, qh, o, dnd_action); } + DataDeviceOffer::Selection(_) => {} + DataDeviceOffer::Undetermined(_) => {} } - wayland_client::WEnum::Unknown(_) => {} // Ignore } } _ => unimplemented!(), diff --git a/src/data_device_manager/data_source.rs b/src/data_device_manager/data_source.rs index 01d6660c8..aa454a8de 100644 --- a/src/data_device_manager/data_source.rs +++ b/src/data_device_manager/data_source.rs @@ -5,7 +5,7 @@ use crate::reexports::client::{ wl_data_source::{self, WlDataSource}, wl_surface::WlSurface, }, - Connection, Proxy, QueueHandle, WEnum, + Connection, Proxy, QueueHandle, }; use super::{data_device::DataDevice, WritePipe}; @@ -103,12 +103,11 @@ where wl_data_source::Event::DndFinished => { state.dnd_finished(conn, qh, source); } - wl_data_source::Event::Action { dnd_action } => match dnd_action { - WEnum::Value(dnd_action) => { + wl_data_source::Event::Action { dnd_action } => { + if dnd_action.available_since().is_some_and(|v| v <= source.version()) { state.action(conn, qh, source, dnd_action); } - WEnum::Unknown(_) => {} - }, + } _ => unimplemented!(), }; } diff --git a/src/data_device_manager/mod.rs b/src/data_device_manager/mod.rs index 63697cc3c..4904d9e30 100644 --- a/src/data_device_manager/mod.rs +++ b/src/data_device_manager/mod.rs @@ -21,8 +21,9 @@ mod write_pipe; pub use read_pipe::*; pub use write_pipe::*; -use data_device::{DataDevice, DataDeviceData}; -use data_source::{CopyPasteSource, DataSourceData, DragSource}; +use data_device::{DataDevice, DataDeviceData, DataDeviceHandler}; +use data_offer::DataOfferHandler; +use data_source::{CopyPasteSource, DataSourceData, DataSourceHandler, DragSource}; #[derive(Debug)] pub struct DataDeviceManagerState { @@ -32,7 +33,7 @@ pub struct DataDeviceManagerState { impl DataDeviceManagerState { pub fn bind(globals: &GlobalList, qh: &QueueHandle) -> Result where - State: Dispatch + 'static, + State: 'static, { let manager = globals.bind(qh, 1..=3, GlobalData)?; Ok(Self { manager }) @@ -49,7 +50,7 @@ impl DataDeviceManagerState { mime_types: impl IntoIterator, ) -> CopyPasteSource where - D: Dispatch> + 'static, + D: DataSourceHandler + 'static, { CopyPasteSource { inner: self.create_data_source(qh, mime_types, None) } } @@ -62,7 +63,7 @@ impl DataDeviceManagerState { dnd_actions: DndAction, ) -> DragSource where - D: Dispatch> + 'static, + D: DataSourceHandler + 'static, { DragSource { inner: self.create_data_source(qh, mime_types, Some(dnd_actions)) } } @@ -75,9 +76,9 @@ impl DataDeviceManagerState { dnd_actions: Option, ) -> WlDataSource where - D: Dispatch> + 'static, + D: DataSourceHandler + 'static, { - let source = self.manager.create_data_source(qh, Default::default()); + let source = self.manager.create_data_source(qh, DataSourceData::new(())); for mime in mime_types { source.offer(mime.to_string()); @@ -95,7 +96,7 @@ impl DataDeviceManagerState { /// create a new data device for a given seat pub fn get_data_device(&self, qh: &QueueHandle, seat: &WlSeat) -> DataDevice where - D: Dispatch + 'static, + D: DataDeviceHandler + DataOfferHandler + 'static, { let data = DataDeviceData::new(seat.clone()); DataDevice { device: self.manager.get_data_device(seat, qh, data) } diff --git a/src/dispatch2.rs b/src/dispatch2.rs index a2082b3fe..9aa7b87f5 100644 --- a/src/dispatch2.rs +++ b/src/dispatch2.rs @@ -2,46 +2,9 @@ use std::sync::Arc; use wayland_client::backend::ObjectData; use wayland_client::{Connection, Proxy, QueueHandle}; -pub trait Dispatch2 { - fn event( - &self, - _: &mut State, - _: &I, - _: ::Event, - _: &Connection, - _: &QueueHandle, - ); - - fn event_created_child(opcode: u16, _qh: &QueueHandle) -> Arc { - panic!( - "Missing event_created_child specialization for event opcode {} of {}", - opcode, - I::interface().name - ); - } -} +pub use wayland_client::Dispatch as Dispatch2; #[macro_export] macro_rules! delegate_dispatch2 { - ($(@<$( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+>)? $ty: ty) => { - impl<$( $( $lt $( : $clt $(+ $dlt )* )? ),+, )? I, UserData> $crate::reexports::client::Dispatch for $ty - where - I: $crate::reexports::client::Proxy, - UserData: $crate::dispatch2::Dispatch2 { - fn event( - state: &mut $ty, - proxy: &I, - event: ::Event, - data: &UserData, - conn: &$crate::reexports::client::Connection, - qh: &$crate::reexports::client::QueueHandle<$ty>, - ) { - data.event(state, proxy, event, conn, qh); - } - - fn event_created_child(opcode: u16, qh: &$crate::reexports::client::QueueHandle<$ty>) -> ::std::sync::Arc { - UserData::event_created_child(opcode, qh) - } - } - }; + ($(@<$( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+>)? $ty: ty) => {}; } diff --git a/src/dmabuf.rs b/src/dmabuf.rs index b1e34769b..39f77a1bf 100644 --- a/src/dmabuf.rs +++ b/src/dmabuf.rs @@ -5,7 +5,7 @@ use std::{fmt, mem, os::unix::io::BorrowedFd, slice, sync::Mutex}; use wayland_client::{ globals::GlobalList, protocol::{wl_buffer, wl_surface}, - Connection, Dispatch, Proxy, QueueHandle, WEnum, + Connection, Dispatch, Proxy, QueueHandle, }; use wayland_protocols::wp::linux_dmabuf::zv1::client::{ zwp_linux_buffer_params_v1, @@ -20,18 +20,14 @@ pub struct DmabufFeedbackTranche { /// renderer device. pub device: dev_t, /// Flags for tranche - pub flags: WEnum, + pub flags: TrancheFlags, /// Indices of formats in the format table pub formats: Vec, } impl Default for DmabufFeedbackTranche { fn default() -> DmabufFeedbackTranche { - DmabufFeedbackTranche { - device: 0, - flags: WEnum::Value(TrancheFlags::empty()), - formats: Vec::new(), - } + DmabufFeedbackTranche { device: 0, flags: TrancheFlags::empty(), formats: Vec::new() } } } @@ -117,7 +113,7 @@ impl DmabufState { /// This does not fail if the global does not exist. pub fn new(globals: &GlobalList, qh: &QueueHandle) -> Self where - D: Dispatch + 'static, + D: DmabufHandler + 'static, { // Mesa (at least the latest version) also requires version 3 or 4 let zwp_linux_dmabuf = GlobalProxy::from(globals.bind(qh, 3..=5, GlobalData)); @@ -142,7 +138,7 @@ impl DmabufState { /// version. An application can then fallback to using `shm` buffers. pub fn create_params(&self, qh: &QueueHandle) -> Result where - D: Dispatch + 'static, + D: DmabufHandler + 'static, { let zwp_linux_dmabuf = self.zwp_linux_dmabuf.get()?; let params = zwp_linux_dmabuf.create_params(qh, GlobalData); @@ -157,8 +153,7 @@ impl DmabufState { qh: &QueueHandle, ) -> Result where - D: Dispatch - + 'static, + D: DmabufHandler + 'static, { let zwp_linux_dmabuf = self.zwp_linux_dmabuf.with_min_version(4)?; Ok(zwp_linux_dmabuf.get_default_feedback(qh, DmabufFeedbackData::default())) @@ -173,8 +168,7 @@ impl DmabufState { qh: &QueueHandle, ) -> Result where - D: Dispatch - + 'static, + D: DmabufHandler + 'static, { let zwp_linux_dmabuf = self.zwp_linux_dmabuf.with_min_version(4)?; Ok(zwp_linux_dmabuf.get_surface_feedback(surface, qh, DmabufFeedbackData::default())) @@ -263,7 +257,7 @@ impl DmabufParams { qh: &QueueHandle, ) -> (wl_buffer::WlBuffer, zwp_linux_buffer_params_v1::ZwpLinuxBufferParamsV1) where - D: Dispatch + 'static, + D: DmabufHandler + 'static, { let buffer = self.params.create_immed(width, height, format, flags, qh, DmaBufferData); (buffer, self.params) @@ -358,7 +352,7 @@ where impl Dispatch2 for GlobalData where - D: Dispatch + DmabufHandler + 'static, + D: DmabufHandler + 'static, { fn event( &self, diff --git a/src/foreign_toplevel_list.rs b/src/foreign_toplevel_list.rs index e94ade8bc..8ca6a2d0b 100644 --- a/src/foreign_toplevel_list.rs +++ b/src/foreign_toplevel_list.rs @@ -36,7 +36,7 @@ pub struct ForeignToplevelList { impl ForeignToplevelList { pub fn new(globals: &GlobalList, qh: &QueueHandle) -> Self where - D: Dispatch + 'static, + D: ForeignToplevelListHandler + 'static, { let foreign_toplevel_list = GlobalProxy::from(globals.bind(qh, 1..=1, GlobalData)); Self { foreign_toplevel_list, toplevels: Vec::new() } @@ -98,9 +98,7 @@ pub trait ForeignToplevelListHandler: Sized { impl Dispatch2 for GlobalData where - D: Dispatch - + ForeignToplevelListHandler - + 'static, + D: ForeignToplevelListHandler + 'static, { fn event( &self, @@ -121,7 +119,7 @@ where } wayland_client::event_created_child!(D, ext_foreign_toplevel_list_v1::ExtForeignToplevelListV1, [ - ext_foreign_toplevel_list_v1::EVT_TOPLEVEL_OPCODE => (ext_foreign_toplevel_handle_v1::ExtForeignToplevelHandleV1, Default::default()) + ext_foreign_toplevel_list_v1::EVT_TOPLEVEL_OPCODE => (ext_foreign_toplevel_handle_v1::ExtForeignToplevelHandleV1, ForeignToplevelData::default()) ]); } diff --git a/src/output.rs b/src/output.rs index 90d32e827..dfe6c1c5c 100644 --- a/src/output.rs +++ b/src/output.rs @@ -8,7 +8,7 @@ use log::warn; use wayland_client::{ globals::GlobalList, protocol::wl_output::{self, Subpixel, Transform}, - Connection, Dispatch, Proxy, QueueHandle, WEnum, + Connection, Dispatch, Proxy, QueueHandle, }; use wayland_protocols::xdg::xdg_output::zv1::client::{ zxdg_output_manager_v1::{self, ZxdgOutputManagerV1}, @@ -133,12 +133,7 @@ impl fmt::Debug for ScaleWatcherHandle { } impl OutputState { - pub fn new< - D: Dispatch - + Dispatch - + Dispatch - + 'static, - >( + pub fn new( global_list: &GlobalList, qh: &QueueHandle, ) -> OutputState { @@ -198,7 +193,7 @@ impl OutputState { fn setup(&mut self, wl_output: wl_output::WlOutput, qh: &QueueHandle) where - D: Dispatch + 'static, + D: OutputHandler + 'static, { let data = wl_output.data::().unwrap().clone(); @@ -430,15 +425,17 @@ where } => { inner.pending_info.location = (x, y); inner.pending_info.physical_size = (physical_width, physical_height); - inner.pending_info.subpixel = match subpixel { - WEnum::Value(subpixel) => subpixel, - WEnum::Unknown(_) => todo!("Warn about invalid subpixel value"), + inner.pending_info.subpixel = if subpixel.available_since().is_some() { + subpixel + } else { + todo!("Warn about invalid subpixel value") }; inner.pending_info.make = make; inner.pending_info.model = model; - inner.pending_info.transform = match transform { - WEnum::Value(subpixel) => subpixel, - WEnum::Unknown(_) => todo!("Warn about invalid transform value"), + inner.pending_info.transform = if transform.available_since().is_some() { + transform + } else { + todo!("Warn about invalid transform value") }; inner.pending_wl = true; } @@ -449,10 +446,8 @@ where mode.dimensions != (width, height) || mode.refresh_rate != refresh }); - let flags = match flags { - WEnum::Value(flags) => flags, - WEnum::Unknown(_) => panic!("Invalid flags"), - }; + let flags = + if flags.available_since().is_some() { flags } else { panic!("Invalid flags") }; let current = flags.contains(wl_output::Mode::Current); let preferred = flags.contains(wl_output::Mode::Preferred); @@ -644,12 +639,7 @@ where impl RegistryHandler for OutputState where - D: Dispatch - + Dispatch - + Dispatch - + OutputHandler - + ProvidesRegistryState - + 'static, + D: OutputHandler + ProvidesRegistryState + 'static, { fn new_global( data: &mut D, diff --git a/src/presentation_time.rs b/src/presentation_time.rs index 2c14c44ae..70d84337a 100644 --- a/src/presentation_time.rs +++ b/src/presentation_time.rs @@ -2,7 +2,7 @@ use std::{mem, sync::Mutex}; use wayland_client::{ globals::GlobalList, protocol::{wl_output, wl_surface}, - Connection, Dispatch, QueueHandle, WEnum, + Connection, Dispatch, QueueHandle, }; use wayland_protocols::wp::presentation_time::client::{wp_presentation, wp_presentation_feedback}; @@ -25,7 +25,7 @@ impl PresentationTimeState { /// Bind `wp_presentation` global, if it exists pub fn bind(globals: &GlobalList, qh: &QueueHandle) -> Self where - D: Dispatch + 'static, + D: PresentationTimeHandler + 'static, { let presentation = GlobalProxy::from(globals.bind(qh, 1..=1, GlobalData)); Self { presentation, clk_id: None } @@ -38,8 +38,7 @@ impl PresentationTimeState { qh: &QueueHandle, ) -> Result where - D: Dispatch - + 'static, + D: PresentationTimeHandler + 'static, { let udata = PresentationTimeData { wl_surface: surface.clone(), @@ -64,7 +63,7 @@ pub trait PresentationTimeHandler: Sized { time: PresentTime, refresh: u32, seq: u64, - flags: WEnum, + flags: wp_presentation_feedback::Kind, ); /// Content update not displayed diff --git a/src/primary_selection/device.rs b/src/primary_selection/device.rs index 1389c9c71..f86c00ef0 100644 --- a/src/primary_selection/device.rs +++ b/src/primary_selection/device.rs @@ -55,9 +55,7 @@ impl Drop for PrimarySelectionDevice { impl Dispatch2 for PrimarySelectionDeviceData where - State: Dispatch - + PrimarySelectionDeviceHandler - + 'static, + State: PrimarySelectionDeviceHandler + 'static, { event_created_child!(State, ZwpPrimarySelectionDeviceV1, [ 0 => (ZwpPrimarySelectionOfferV1, PrimarySelectionOfferData::default()) diff --git a/src/primary_selection/mod.rs b/src/primary_selection/mod.rs index a46a8fdb1..7d2cc3c5f 100644 --- a/src/primary_selection/mod.rs +++ b/src/primary_selection/mod.rs @@ -12,11 +12,12 @@ use crate::reexports::protocols::wp::primary_selection::zv1::client::{ }; pub mod device; +use device::PrimarySelectionDeviceHandler; pub mod offer; pub mod selection; use self::device::{PrimarySelectionDevice, PrimarySelectionDeviceData}; -use selection::PrimarySelectionSource; +use selection::{PrimarySelectionSource, PrimarySelectionSourceHandler}; #[derive(Debug)] pub struct PrimarySelectionManagerState { @@ -26,7 +27,7 @@ pub struct PrimarySelectionManagerState { impl PrimarySelectionManagerState { pub fn bind(globals: &GlobalList, qh: &QueueHandle) -> Result where - State: Dispatch + 'static, + State: 'static, { let manager = globals.bind(qh, 1..=1, GlobalData)?; Ok(Self { manager }) @@ -44,7 +45,7 @@ impl PrimarySelectionManagerState { mime_types: I, ) -> PrimarySelectionSource where - State: Dispatch + 'static, + State: PrimarySelectionSourceHandler + 'static, I: IntoIterator, T: ToString, { @@ -64,7 +65,7 @@ impl PrimarySelectionManagerState { seat: &WlSeat, ) -> PrimarySelectionDevice where - State: Dispatch + 'static, + State: PrimarySelectionDeviceHandler + 'static, { PrimarySelectionDevice { device: self.manager.get_device( diff --git a/src/registry.rs b/src/registry.rs index e41335282..c4db62747 100644 --- a/src/registry.rs +++ b/src/registry.rs @@ -207,9 +207,9 @@ impl RegistryState { udata: U, ) -> Result where - D: Dispatch + 'static, + D: 'static, I: Proxy + 'static, - U: Send + Sync + 'static, + U: Dispatch + Send + Sync + 'static, { bind_one(&self.registry, &self.globals, qh, version, udata) } @@ -226,9 +226,9 @@ impl RegistryState { udata: U, ) -> Result where - D: Dispatch + 'static, + D: 'static, I: Proxy + 'static, - U: Send + Sync + 'static, + U: Dispatch + Send + Sync + 'static, { let iface = I::interface(); if *version.end() > iface.version { @@ -242,7 +242,11 @@ impl RegistryState { continue; } if global.version < *version.start() { - return Err(BindError::UnsupportedVersion); + return Err(BindError::UnsupportedVersion { + interface: iface.name, + requested: *version.start(), + available: global.version, + }); } let version = global.version.min(*version.end()); let proxy = self.registry.bind(global.name, version, qh, udata); @@ -250,7 +254,7 @@ impl RegistryState { return Ok(proxy); } - Err(BindError::NotPresent) + Err(BindError::NotPresent(iface.name)) } /// Binds all globals with a given interface. @@ -261,10 +265,10 @@ impl RegistryState { make_udata: F, ) -> Result, BindError> where - D: Dispatch + 'static, + D: 'static, I: Proxy + 'static, F: FnMut(u32) -> U, - U: Send + Sync + 'static, + U: Dispatch + Send + Sync + 'static, { bind_all(&self.registry, &self.globals, qh, version, make_udata) } @@ -305,34 +309,28 @@ macro_rules! delegate_registry { }; } -impl Dispatch for RegistryState -where - D: Dispatch + ProvidesRegistryState, -{ - fn event( - state: &mut D, - _: &wl_registry::WlRegistry, - event: wl_registry::Event, - _: &GlobalListContents, - conn: &Connection, - qh: &QueueHandle, - ) { - match event { - wl_registry::Event::Global { name, interface, version } => { - let iface = interface.clone(); - state.registry().globals.push(Global { name, interface, version }); - state.runtime_add_global(conn, qh, name, &iface, version); - } +#[doc(hidden)] +pub fn dispatch_registry( + state: &mut D, + event: wl_registry::Event, + conn: &Connection, + qh: &QueueHandle, +) { + match event { + wl_registry::Event::Global { name, interface, version } => { + let iface = interface.clone(); + state.registry().globals.push(Global { name, interface, version }); + state.runtime_add_global(conn, qh, name, &iface, version); + } - wl_registry::Event::GlobalRemove { name } => { - if let Some(i) = state.registry().globals.iter().position(|g| g.name == name) { - let global = state.registry().globals.swap_remove(i); - state.runtime_remove_global(conn, qh, name, &global.interface); - } + wl_registry::Event::GlobalRemove { name } => { + if let Some(i) = state.registry().globals.iter().position(|g| g.name == name) { + let global = state.registry().globals.swap_remove(i); + state.runtime_remove_global(conn, qh, name, &global.interface); } - - _ => unreachable!("wl_registry is frozen"), } + + _ => unreachable!("wl_registry is frozen"), } } @@ -388,7 +386,8 @@ pub struct SimpleGlobal { impl SimpleGlobal { pub fn bind(globals: &GlobalList, qh: &QueueHandle) -> Result where - State: Dispatch + 'static, + State: 'static, + (): Dispatch + 'static, { let proxy = globals.bind(qh, 0..=MAX_VERSION, ())?; Ok(Self { proxy: GlobalProxy::Bound(proxy) }) @@ -427,10 +426,10 @@ pub(crate) fn bind_all( mut make_udata: F, ) -> Result, BindError> where - D: Dispatch + 'static, + D: 'static, I: Proxy + 'static, F: FnMut(u32) -> U, - U: Send + Sync + 'static, + U: Dispatch + Send + Sync + 'static, { let iface = I::interface(); if *version.end() > iface.version { @@ -444,7 +443,11 @@ where continue; } if global.version < *version.start() { - return Err(BindError::UnsupportedVersion); + return Err(BindError::UnsupportedVersion { + interface: iface.name, + requested: *version.start(), + available: global.version, + }); } let version = global.version.min(*version.end()); let udata = make_udata(global.name); @@ -465,9 +468,9 @@ pub(crate) fn bind_one( udata: U, ) -> Result where - D: Dispatch + 'static, + D: 'static, I: Proxy + 'static, - U: Send + Sync + 'static, + U: Dispatch + Send + Sync + 'static, { let iface = I::interface(); if *version.end() > iface.version { @@ -485,7 +488,11 @@ where continue; } if global.version < *version.start() { - return Err(BindError::UnsupportedVersion); + return Err(BindError::UnsupportedVersion { + interface: iface.name, + requested: *version.start(), + available: global.version, + }); } let version = global.version.min(*version.end()); let proxy = registry.bind(global.name, version, qh, udata); @@ -493,7 +500,7 @@ where return Ok(proxy); } - Err(BindError::NotPresent) + Err(BindError::NotPresent(iface.name)) } /// A helper macro for implementing [`ProvidesRegistryState`]. diff --git a/src/seat/input_method.rs b/src/seat/input_method.rs index bff553b32..075ff6668 100644 --- a/src/seat/input_method.rs +++ b/src/seat/input_method.rs @@ -14,7 +14,6 @@ use std::sync::Mutex; use wayland_client::globals::{BindError, GlobalList}; use wayland_client::protocol::wl_seat::WlSeat; -use wayland_client::WEnum; use wayland_client::{Connection, Dispatch, Proxy, QueueHandle}; use wayland_protocols::wp::text_input::zv3::client::zwp_text_input_v3::{ @@ -37,7 +36,7 @@ impl InputMethodManager { /// Bind `zwp_input_method_v2` global, if it exists pub fn bind(globals: &GlobalList, qh: &QueueHandle) -> Result where - D: Dispatch + 'static, + D: InputMethodHandler + 'static, { let manager = globals.bind(qh, 1..=1, GlobalData)?; Ok(Self { manager }) @@ -47,7 +46,7 @@ impl InputMethodManager { /// seat. pub fn get_input_method(&self, qh: &QueueHandle, seat: &WlSeat) -> InputMethod where - State: Dispatch, State> + 'static, + State: InputMethodHandler + 'static, { self.get_input_method_with_data(qh, seat, ()) } @@ -59,7 +58,7 @@ impl InputMethodManager { udata: U, ) -> InputMethod where - State: Dispatch, State> + 'static, + State: InputMethodHandler + 'static, U: Send + Sync + 'static, { InputMethod { @@ -314,15 +313,17 @@ where } Event::TextChangeCause { cause } => { imdata.pending_state = InputMethodEventState { - text_change_cause: match cause { - WEnum::Value(cause) => cause, - WEnum::Unknown(value) => { - warn!( - "Unknown `text_change_cause`: {}. Assuming not input method.", - value - ); - ChangeCause::Other - } + text_change_cause: if cause + .available_since() + .is_some_and(|v| v <= input_method.version()) + { + cause + } else { + warn!( + "Unknown `text_change_cause`: {:?}. Assuming not input method.", + cause + ); + ChangeCause::Other }, ..imdata.pending_state.clone() } @@ -330,23 +331,26 @@ where Event::ContentType { hint, purpose } => { imdata.pending_state = InputMethodEventState { active: imdata.pending_state.active.with_content_type(), - content_hint: match hint { - WEnum::Value(hint) => hint, - WEnum::Unknown(value) => { - warn!( - "Unknown content hints: 0b{:b}, ignoring.", - ContentHint::from_bits_retain(value) - - ContentHint::from_bits_truncate(value) - ); - ContentHint::from_bits_truncate(value) - } + content_hint: if hint + .available_since() + .is_some_and(|v| v <= input_method.version()) + { + hint + } else { + let unknown_bits = ContentHint::from_iter(hint.iter().filter(|h| { + h.available_since().is_none_or(|v| v > input_method.version()) + })); + warn!("Unknown content hints: {:?}, ignoring.", unknown_bits); + hint - unknown_bits }, - content_purpose: match purpose { - WEnum::Value(v) => v, - WEnum::Unknown(value) => { - warn!("Unknown `content_purpose`: {}. Assuming `normal`.", value); - ContentPurpose::Normal - } + content_purpose: if purpose + .available_since() + .is_some_and(|v| v <= input_method.version()) + { + purpose + } else { + warn!("Unknown `content_purpose`: {:?}. Assuming `normal`.", purpose); + ContentPurpose::Normal }, ..imdata.pending_state.clone() } diff --git a/src/seat/input_method_v3.rs b/src/seat/input_method_v3.rs index cf74a430a..77aac4b93 100644 --- a/src/seat/input_method_v3.rs +++ b/src/seat/input_method_v3.rs @@ -25,7 +25,6 @@ use crate::reexports::protocols_experimental::text_input::v3::client::xx_text_in use wayland_client::globals::{BindError, GlobalList}; use wayland_client::protocol::wl_seat::WlSeat; use wayland_client::protocol::wl_surface; -use wayland_client::WEnum; use wayland_client::{Connection, Dispatch, Proxy, QueueHandle}; use crate::reexports::protocols_experimental::input_method::v1::client as protocol; @@ -66,7 +65,7 @@ impl InputMethodManager { /// Bind the input_method global, if it exists pub fn bind(globals: &GlobalList, qh: &QueueHandle) -> Result where - D: Dispatch + 'static, + D: InputMethodHandler + 'static, { let manager = globals.bind(qh, 2..=3, GlobalData)?; Ok(Self { manager }) @@ -76,7 +75,7 @@ impl InputMethodManager { /// seat. pub fn get_input_method(&self, qh: &QueueHandle, seat: &WlSeat) -> InputMethod where - State: Dispatch, State> + 'static, + State: InputMethodHandler + 'static, { self.get_input_method_with_data(qh, seat, ()) } @@ -88,7 +87,7 @@ impl InputMethodManager { udata: U, ) -> InputMethod where - State: Dispatch, State> + 'static, + State: InputMethodHandler + 'static, U: Send + Sync + 'static, { InputMethod { @@ -102,7 +101,7 @@ impl InputMethodManager { pub fn get_positioner(&self, qh: &QueueHandle) -> PopupPositioner where - State: Dispatch + 'static, + State: InputMethodHandler + 'static, { PopupPositioner(self.manager.get_positioner(qh, PositionerData)) } @@ -255,7 +254,7 @@ impl InputMethod { positioner: &PopupPositioner, ) -> Popup where - D: Dispatch + 'static, + D: InputMethodHandler + 'static, U: Send + Sync + 'static, { let data = self.input_method.data::>().unwrap(); @@ -666,15 +665,14 @@ where } Event::TextChangeCause { cause } => { imdata.pending_state = InputMethodEventState { - text_change_cause: match cause { - WEnum::Value(cause) => cause, - WEnum::Unknown(value) => { + text_change_cause: if cause.available_since().is_some_and(|v| v <= input_method.version()) { + cause + } else { warn!( - "Unknown `text_change_cause`: {}. Assuming not input method.", - value + "Unknown `text_change_cause`: {:?}. Assuming not input method.", + cause ); ChangeCause::Other - } }, ..imdata.pending_state.clone() } @@ -682,23 +680,21 @@ where Event::ContentType { hint, purpose } => { imdata.pending_state = InputMethodEventState { active: imdata.pending_state.active.clone().with_content_type(), - content_hint: match hint { - WEnum::Value(hint) => hint, - WEnum::Unknown(value) => { + content_hint: if hint.available_since().is_some_and(|v| v <= input_method.version()) { + hint + } else { + let unknown_bits = ContentHint::from_iter(hint.iter().filter(|h| h.available_since().is_none_or(|v|v > input_method.version()))); warn!( - "Unknown content hints: 0b{:b}, ignoring.", - ContentHint::from_bits_retain(value) - - ContentHint::from_bits_truncate(value) + "Unknown content hints: {:?}, ignoring.", + unknown_bits ); - ContentHint::from_bits_truncate(value) - } + hint - unknown_bits }, - content_purpose: match purpose { - WEnum::Value(v) => v, - WEnum::Unknown(value) => { - warn!("Unknown `content_purpose`: {}. Assuming `normal`.", value); - ContentPurpose::Normal - } + content_purpose: if purpose.available_since().is_some_and(|v| v <= input_method.version()) { + purpose + } else { + warn!("Unknown `content_purpose`: {:?}. Assuming `normal`.", purpose); + ContentPurpose::Normal }, ..imdata.pending_state.clone() } @@ -718,12 +714,11 @@ where Event::AnnounceSupportedFeatures { features } => { imdata.pending_state = InputMethodEventState { active: imdata.pending_state.active.clone().with_extra_features( - match features { - WEnum::Value(v) => v, - WEnum::Unknown(value) => { - warn!("Unknown `features`: {value}. Assuming no extra features supported."); - SupportedFeatures::empty() - } + if features.available_since().is_some_and(|v| v <= input_method.version()) { + features + } else { + warn!("Unknown `features`: {features:?}. Assuming no extra features supported."); + SupportedFeatures::empty() } ), ..imdata.pending_state.clone() diff --git a/src/seat/keyboard/mod.rs b/src/seat/keyboard/mod.rs index 666f155c6..a9a7b18f8 100644 --- a/src/seat/keyboard/mod.rs +++ b/src/seat/keyboard/mod.rs @@ -18,7 +18,7 @@ pub use xkeysym::{KeyCode, Keysym}; use calloop::timer::{TimeoutAction, Timer}; use wayland_client::{ protocol::{wl_keyboard, wl_seat, wl_surface}, - Connection, Dispatch, Proxy, QueueHandle, WEnum, + Connection, Dispatch, Proxy, QueueHandle, }; use xkbcommon::xkb; @@ -67,10 +67,7 @@ impl SeatState { rmlvo: Option, ) -> Result where - D: Dispatch> - + SeatHandler - + KeyboardHandler - + 'static, + D: SeatHandler + KeyboardHandler + 'static, { let udata = match rmlvo { Some(rmlvo) => KeyboardData::from_rmlvo(seat.clone(), rmlvo, ())?, @@ -104,10 +101,7 @@ impl SeatState { udata: U, ) -> Result where - D: Dispatch> - + SeatHandler - + KeyboardHandler - + 'static, + D: SeatHandler + KeyboardHandler + 'static, U: Send + Sync + 'static, { let inner = @@ -522,62 +516,56 @@ where match event { wl_keyboard::Event::Keymap { format, fd, size } => { match format { - WEnum::Value(format) => match format { - wl_keyboard::KeymapFormat::NoKeymap => { - log::warn!(target: "sctk", "non-xkb compatible keymap"); - } + wl_keyboard::KeymapFormat::NoKeymap => { + log::warn!(target: "sctk", "non-xkb compatible keymap"); + } - wl_keyboard::KeymapFormat::XkbV1 => { - if self.user_specified_rmlvo { - // state is locked, ignore keymap updates - return; - } + wl_keyboard::KeymapFormat::XkbV1 => { + if self.user_specified_rmlvo { + // state is locked, ignore keymap updates + return; + } - let context = self.xkb_context.lock().unwrap(); - - // 0.5.0-beta.0 does not mark this function as unsafe but upstream rightly makes - // this function unsafe. - // - // Version 7 of wl_keyboard requires the file descriptor to be mapped using - // MAP_PRIVATE. xkbcommon-rs does mmap the file descriptor properly. - // - // SAFETY: - // - wayland-client guarantees we have received a valid file descriptor. - #[allow(unused_unsafe)] // Upstream release will change this - match unsafe { - xkb::Keymap::new_from_fd( - &context, - fd, - size as usize, - xkb::KEYMAP_FORMAT_TEXT_V1, - xkb::COMPILE_NO_FLAGS, - ) - } { - Ok(Some(keymap)) => { - let state = xkb::State::new(&keymap); - { - let mut state_guard = self.xkb_state.lock().unwrap(); - *state_guard = Some(state); - } - data.update_keymap(conn, qh, keyboard, Keymap(&keymap)); + let context = self.xkb_context.lock().unwrap(); + + // 0.5.0-beta.0 does not mark this function as unsafe but upstream rightly makes + // this function unsafe. + // + // Version 7 of wl_keyboard requires the file descriptor to be mapped using + // MAP_PRIVATE. xkbcommon-rs does mmap the file descriptor properly. + // + // SAFETY: + // - wayland-client guarantees we have received a valid file descriptor. + #[allow(unused_unsafe)] // Upstream release will change this + match unsafe { + xkb::Keymap::new_from_fd( + &context, + fd, + size as usize, + xkb::KEYMAP_FORMAT_TEXT_V1, + xkb::COMPILE_NO_FLAGS, + ) + } { + Ok(Some(keymap)) => { + let state = xkb::State::new(&keymap); + { + let mut state_guard = self.xkb_state.lock().unwrap(); + *state_guard = Some(state); } + data.update_keymap(conn, qh, keyboard, Keymap(&keymap)); + } - Ok(None) => { - log::error!(target: "sctk", "invalid keymap"); - } + Ok(None) => { + log::error!(target: "sctk", "invalid keymap"); + } - Err(err) => { - log::error!(target: "sctk", "{}", err); - } + Err(err) => { + log::error!(target: "sctk", "{}", err); } } - - _ => unreachable!(), - }, - - WEnum::Unknown(value) => { - log::warn!(target: "sctk", "unknown keymap format 0x{:x}", value) } + + _ => log::warn!(target: "sctk", "unknown keymap format {:?}", format), } } @@ -633,7 +621,9 @@ where } wl_keyboard::Event::Key { serial, time, key, state } => match state { - WEnum::Value(state) => { + wl_keyboard::KeyState::Pressed + | wl_keyboard::KeyState::Released + | wl_keyboard::KeyState::Repeated => { let state_guard = self.xkb_state.lock().unwrap(); if let Some(guard) = state_guard.as_ref() { @@ -794,8 +784,8 @@ where }; } - WEnum::Unknown(unknown) => { - log::warn!(target: "sctk", "{}: compositor sends invalid key state: {:x}", keyboard.id(), unknown); + _ => { + log::warn!(target: "sctk", "{}: compositor sends invalid key state: {:?}", keyboard.id(), state); } }, diff --git a/src/seat/keyboard/repeat.rs b/src/seat/keyboard/repeat.rs index 3160315f2..13af5f5b4 100644 --- a/src/seat/keyboard/repeat.rs +++ b/src/seat/keyboard/repeat.rs @@ -64,7 +64,7 @@ impl SeatState { callback: RepeatCallback, ) -> Result where - D: Dispatch> + KeyboardHandler + 'static, + D: KeyboardHandler + 'static, { let udata = match rmlvo { Some(rmlvo) => KeyboardData::from_rmlvo(seat.clone(), rmlvo, ())?, @@ -113,7 +113,7 @@ impl SeatState { callback: RepeatCallback, ) -> Result where - D: Dispatch> + KeyboardHandler + 'static, + D: KeyboardHandler + 'static, U: Send + Sync + 'static, { let inner = diff --git a/src/seat/keyboard_filter.rs b/src/seat/keyboard_filter.rs index b460b5abf..9cff2f5be 100644 --- a/src/seat/keyboard_filter.rs +++ b/src/seat/keyboard_filter.rs @@ -23,7 +23,7 @@ impl KeyboardFilterManager { /// Bind the input_method global, if it exists pub fn bind(globals: &GlobalList, qh: &QueueHandle) -> Result where - D: Dispatch + 'static, + D: 'static, { let manager = globals.bind(qh, 1..=1, GlobalData)?; Ok(Self { manager }) @@ -43,7 +43,7 @@ impl KeyboardFilterManager { surface: &WlSurface, ) -> KeyboardFilter where - D: Dispatch + 'static, + D: 'static, { KeyboardFilter(self.manager.bind_to_input_method( keyboard, diff --git a/src/seat/mod.rs b/src/seat/mod.rs index 97aac1667..45da85a00 100644 --- a/src/seat/mod.rs +++ b/src/seat/mod.rs @@ -81,7 +81,7 @@ enum CursorShapeManagerState { } impl SeatState { - pub fn new + 'static>( + pub fn new( global_list: &GlobalList, qh: &QueueHandle, ) -> SeatState { @@ -153,7 +153,7 @@ impl SeatState { seat: &wl_seat::WlSeat, ) -> Result where - D: Dispatch> + PointerHandler + 'static, + D: PointerHandler + 'static, { self.get_pointer_with_data(qh, seat, ()) } @@ -174,12 +174,7 @@ impl SeatState { theme: ThemeSpec, ) -> Result, SeatError> where - D: Dispatch> - + Dispatch> - + Dispatch - + Dispatch - + PointerHandler - + 'static, + D: PointerHandler + 'static, { self.get_pointer_with_theme_and_data(qh, seat, shm, surface, theme, ()) } @@ -196,7 +191,7 @@ impl SeatState { pointer_data: U, ) -> Result where - D: Dispatch> + PointerHandler + 'static, + D: PointerHandler + 'static, U: Send + Sync + 'static, { let inner = @@ -225,11 +220,7 @@ impl SeatState { pointer_data: U, ) -> Result, SeatError> where - D: Dispatch> - + Dispatch - + Dispatch - + PointerHandler - + 'static, + D: PointerHandler + 'static, U: Send + Sync + 'static, { let inner = @@ -288,7 +279,7 @@ impl SeatState { seat: &wl_seat::WlSeat, ) -> Result where - D: Dispatch> + TouchHandler + 'static, + D: TouchHandler + 'static, { self.get_touch_with_data(qh, seat, ()) } @@ -305,7 +296,7 @@ impl SeatState { udata: U, ) -> Result where - D: Dispatch> + TouchHandler + 'static, + D: TouchHandler + 'static, U: Send + Sync + 'static, { let inner = @@ -492,7 +483,7 @@ where impl RegistryHandler for SeatState where - D: Dispatch + SeatHandler + ProvidesRegistryState + 'static, + D: SeatHandler + ProvidesRegistryState + 'static, { fn new_global( state: &mut D, diff --git a/src/seat/pointer/cursor_shape.rs b/src/seat/pointer/cursor_shape.rs index f4be25808..778f0b707 100644 --- a/src/seat/pointer/cursor_shape.rs +++ b/src/seat/pointer/cursor_shape.rs @@ -20,7 +20,7 @@ impl CursorShapeManager { queue_handle: &QueueHandle, ) -> Result where - State: Dispatch + 'static, + State: 'static, { let cursor_shape_manager = globals.bind(queue_handle, 1..=2, GlobalData)?; Ok(Self { cursor_shape_manager }) @@ -36,7 +36,7 @@ impl CursorShapeManager { queue_handle: &QueueHandle, ) -> WpCursorShapeDeviceV1 where - State: Dispatch + 'static, + State: 'static, { self.cursor_shape_manager.get_pointer(pointer, queue_handle, GlobalData) } diff --git a/src/seat/pointer/mod.rs b/src/seat/pointer/mod.rs index e4c455f95..1f1631419 100644 --- a/src/seat/pointer/mod.rs +++ b/src/seat/pointer/mod.rs @@ -12,7 +12,7 @@ use wayland_client::{ wl_shm::WlShm, wl_surface::WlSurface, }, - Connection, Proxy, QueueHandle, WEnum, + Connection, Proxy, QueueHandle, }; use wayland_cursor::{Cursor, CursorTheme}; use wayland_protocols::wp::cursor_shape::v1::client::wp_cursor_shape_device_v1::WpCursorShapeDeviceV1; @@ -248,56 +248,53 @@ where wl_pointer::Event::Button { time, button, state, serial } => { guard.latest_btn.replace(serial); match state { - WEnum::Value(wl_pointer::ButtonState::Pressed) => { + wl_pointer::ButtonState::Pressed => { PointerEventKind::Press { time, button, serial } } - WEnum::Value(wl_pointer::ButtonState::Released) => { + wl_pointer::ButtonState::Released => { PointerEventKind::Release { time, button, serial } } - WEnum::Unknown(unknown) => { - log::warn!(target: "sctk", "{}: invalid pointer button state: {:x}", pointer.id(), unknown); + _ => { + log::warn!(target: "sctk", "{}: invalid pointer button state: {:?}", pointer.id(), state); return; } - _ => unreachable!(), } } // Axis logical events. - wl_pointer::Event::Axis { time, axis, value } => match axis { - WEnum::Value(axis) => { - let (mut horizontal, mut vertical) = <(AxisScroll, AxisScroll)>::default(); - match axis { - wl_pointer::Axis::VerticalScroll => { - vertical.absolute = value; - } - wl_pointer::Axis::HorizontalScroll => { - horizontal.absolute = value; - } - _ => unreachable!(), - }; - - PointerEventKind::Axis { time, horizontal, vertical, source: None } - } - WEnum::Unknown(unknown) => { - log::warn!(target: "sctk", "{}: invalid pointer axis: {:x}", pointer.id(), unknown); - return; + wl_pointer::Event::Axis { time, axis, value } => { + let (mut horizontal, mut vertical) = <(AxisScroll, AxisScroll)>::default(); + match axis { + wl_pointer::Axis::VerticalScroll => { + vertical.absolute = value; + } + wl_pointer::Axis::HorizontalScroll => { + horizontal.absolute = value; + } + _ => { + log::warn!(target: "sctk", "{}: invalid pointer axis: {:?}", pointer.id(), axis); + return; + } } - }, - - wl_pointer::Event::AxisSource { axis_source } => match axis_source { - WEnum::Value(source) => PointerEventKind::Axis { - horizontal: AxisScroll::default(), - vertical: AxisScroll::default(), - source: Some(source), - time: 0, - }, - WEnum::Unknown(unknown) => { - log::warn!(target: "sctk", "unknown pointer axis source: {:x}", unknown); + + PointerEventKind::Axis { time, horizontal, vertical, source: None } + } + + wl_pointer::Event::AxisSource { axis_source } => { + if axis_source.available_since().is_some_and(|v| v <= pointer.version()) { + PointerEventKind::Axis { + horizontal: AxisScroll::default(), + vertical: AxisScroll::default(), + source: Some(axis_source), + time: 0, + } + } else { + log::warn!(target: "sctk", "unknown pointer axis source: {:?}", axis_source); return; } - }, + } - wl_pointer::Event::AxisStop { time, axis } => match axis { - WEnum::Value(axis) => { + wl_pointer::Event::AxisStop { time, axis } => { + if axis.available_since().is_some_and(|v| v <= pointer.version()) { let (mut horizontal, mut vertical) = <(AxisScroll, AxisScroll)>::default(); match axis { wl_pointer::Axis::VerticalScroll => vertical.stop = true, @@ -307,16 +304,14 @@ where } PointerEventKind::Axis { time, horizontal, vertical, source: None } - } - - WEnum::Unknown(unknown) => { - log::warn!(target: "sctk", "{}: invalid pointer axis: {:x}", pointer.id(), unknown); + } else { + log::warn!(target: "sctk", "{}: invalid pointer axis: {:?}", pointer.id(), axis); return; } - }, + } - wl_pointer::Event::AxisDiscrete { axis, discrete } => match axis { - WEnum::Value(axis) => { + wl_pointer::Event::AxisDiscrete { axis, discrete } => { + if axis.available_since().is_some_and(|v| v <= pointer.version()) { let (mut horizontal, mut vertical) = <(AxisScroll, AxisScroll)>::default(); match axis { wl_pointer::Axis::VerticalScroll => { @@ -331,16 +326,14 @@ where }; PointerEventKind::Axis { time: 0, horizontal, vertical, source: None } - } - - WEnum::Unknown(unknown) => { - log::warn!(target: "sctk", "{}: invalid pointer axis: {:x}", pointer.id(), unknown); + } else { + log::warn!(target: "sctk", "{}: invalid pointer axis: {:?}", pointer.id(), axis); return; } - }, + } - wl_pointer::Event::AxisValue120 { axis, value120 } => match axis { - WEnum::Value(axis) => { + wl_pointer::Event::AxisValue120 { axis, value120 } => { + if axis.available_since().is_some_and(|v| v <= pointer.version()) { let (mut horizontal, mut vertical) = <(AxisScroll, AxisScroll)>::default(); match axis { wl_pointer::Axis::VerticalScroll => { @@ -355,43 +348,40 @@ where }; PointerEventKind::Axis { time: 0, horizontal, vertical, source: None } - } - WEnum::Unknown(unknown) => { - log::warn!(target: "sctk", "{}: invalid pointer axis: {:x}", pointer.id(), unknown); + } else { + log::warn!(target: "sctk", "{}: invalid pointer axis: {:?}", pointer.id(), axis); return; } - }, + } wl_pointer::Event::AxisRelativeDirection { axis, direction } => { - let direction = match direction { - WEnum::Value(dir) => Some(dir), - WEnum::Unknown(unknown) => { - log::warn!(target: "sctk", "{}: invalid axis direction: {:x}", pointer.id(), unknown); - return; - } + let direction = if direction + .available_since() + .is_some_and(|v| v <= pointer.version()) + { + Some(direction) + } else { + log::warn!(target: "sctk", "{}: invalid axis direction: {:?}", pointer.id(), direction); + return; }; - match axis { - WEnum::Value(axis) => { - let (mut horizontal, mut vertical) = <(AxisScroll, AxisScroll)>::default(); - match axis { - wl_pointer::Axis::VerticalScroll => { - vertical.relative_direction = direction; - } - - wl_pointer::Axis::HorizontalScroll => { - horizontal.relative_direction = direction; - } + if axis.available_since().is_some_and(|v| v <= pointer.version()) { + let (mut horizontal, mut vertical) = <(AxisScroll, AxisScroll)>::default(); + match axis { + wl_pointer::Axis::VerticalScroll => { + vertical.relative_direction = direction; + } - _ => unreachable!(), - }; + wl_pointer::Axis::HorizontalScroll => { + horizontal.relative_direction = direction; + } - PointerEventKind::Axis { time: 0, horizontal, vertical, source: None } - } + _ => unreachable!(), + }; - WEnum::Unknown(unknown) => { - log::warn!(target: "sctk", "{}: invalid pointer axis: {:x}", pointer.id(), unknown); - return; - } + PointerEventKind::Axis { time: 0, horizontal, vertical, source: None } + } else { + log::warn!(target: "sctk", "{}: invalid pointer axis: {:?}", pointer.id(), axis); + return; } } diff --git a/src/seat/pointer_constraints.rs b/src/seat/pointer_constraints.rs index 9923becff..4c1c319b3 100644 --- a/src/seat/pointer_constraints.rs +++ b/src/seat/pointer_constraints.rs @@ -23,7 +23,7 @@ impl PointerConstraintsState { /// Bind `zwp_pointer_constraints_v1` global, if it exists pub fn bind(globals: &GlobalList, qh: &QueueHandle) -> Self where - D: Dispatch + 'static, + D: PointerConstraintsHandler + 'static, { let pointer_constraints = GlobalProxy::from(globals.bind(qh, 1..=1, GlobalData)); Self { pointer_constraints } @@ -41,7 +41,7 @@ impl PointerConstraintsState { qh: &QueueHandle, ) -> Result where - D: Dispatch + 'static, + D: PointerConstraintsHandler + 'static, { let udata = PointerConstraintData { surface: surface.clone(), pointer: pointer.clone() }; Ok(self @@ -62,7 +62,7 @@ impl PointerConstraintsState { qh: &QueueHandle, ) -> Result where - D: Dispatch + 'static, + D: PointerConstraintsHandler + 'static, { let udata = PointerConstraintData { surface: surface.clone(), pointer: pointer.clone() }; Ok(self diff --git a/src/seat/relative_pointer.rs b/src/seat/relative_pointer.rs index cc68202f1..a557f8424 100644 --- a/src/seat/relative_pointer.rs +++ b/src/seat/relative_pointer.rs @@ -17,8 +17,7 @@ impl RelativePointerState { /// Bind `zwp_relative_pointer_manager_v1` global, if it exists pub fn bind(globals: &GlobalList, qh: &QueueHandle) -> Self where - D: Dispatch - + 'static, + D: RelativePointerHandler + 'static, { let relative_pointer_manager = GlobalProxy::from(globals.bind(qh, 1..=1, GlobalData)); Self { relative_pointer_manager } @@ -30,7 +29,7 @@ impl RelativePointerState { qh: &QueueHandle, ) -> Result where - D: Dispatch + 'static, + D: RelativePointerHandler + 'static, { let udata = RelativePointerData { wl_pointer: pointer.clone() }; Ok(self.relative_pointer_manager.get()?.get_relative_pointer(pointer, qh, udata)) diff --git a/src/seat/touch.rs b/src/seat/touch.rs index 3bbd8a658..cb7459876 100644 --- a/src/seat/touch.rs +++ b/src/seat/touch.rs @@ -136,7 +136,7 @@ pub trait TouchHandler: Sized { impl Dispatch2 for TouchData where - D: Dispatch> + TouchHandler, + D: TouchHandler, { fn event( &self, diff --git a/src/session_lock/mod.rs b/src/session_lock/mod.rs index d05e2f574..909135f43 100644 --- a/src/session_lock/mod.rs +++ b/src/session_lock/mod.rs @@ -133,8 +133,7 @@ impl SessionLock { qh: &QueueHandle, ) -> SessionLockSurface where - D: Dispatch - + 'static, + D: SessionLockHandler + 'static, { // Freeze the queue during the creation of the Arc to avoid a race between events on the // new objects being processed and the Weak in the SessionLockSurfaceData becoming usable. @@ -166,7 +165,7 @@ pub struct SessionLockState { impl SessionLockState { pub fn new(globals: &GlobalList, qh: &QueueHandle) -> Self where - D: Dispatch + 'static, + D: SessionLockHandler + 'static, { let session_lock_manager = GlobalProxy::from(globals.bind(qh, 1..=1, GlobalData)); Self { session_lock_manager } @@ -174,7 +173,7 @@ impl SessionLockState { pub fn lock(&self, qh: &QueueHandle) -> Result where - D: Dispatch + 'static, + D: SessionLockHandler + 'static, { let session_lock_manager = self.session_lock_manager.get()?; diff --git a/src/shell/wlr_layer/mod.rs b/src/shell/wlr_layer/mod.rs index 6a673eda6..b98342db0 100644 --- a/src/shell/wlr_layer/mod.rs +++ b/src/shell/wlr_layer/mod.rs @@ -34,9 +34,7 @@ impl LayerShell { qh: &QueueHandle, ) -> Result where - State: Dispatch - + LayerShellHandler - + 'static, + State: LayerShellHandler + 'static, { let wlr_layer_shell = globals.bind(qh, 1..=4, GlobalData)?; Ok(LayerShell { wlr_layer_shell }) @@ -52,7 +50,7 @@ impl LayerShell { output: Option<&wl_output::WlOutput>, ) -> LayerSurface where - State: Dispatch + 'static, + State: LayerShellHandler + 'static, { // Freeze the queue during the creation of the Arc to avoid a race between events on the // new objects being processed and the Weak in the LayerSurfaceData becoming usable. diff --git a/src/shell/xdg/fallback_frame.rs b/src/shell/xdg/fallback_frame.rs index 2ff34dc6b..646b26e71 100644 --- a/src/shell/xdg/fallback_frame.rs +++ b/src/shell/xdg/fallback_frame.rs @@ -14,7 +14,8 @@ use crate::reexports::csd_frame::{ }; use crate::{ - compositor::SurfaceData, + compositor::{CompositorHandler, SurfaceData}, + output::OutputHandler, seat::pointer::CursorIcon, shell::WaylandSurface, shm::{slot::SlotPool, Shm}, @@ -91,7 +92,7 @@ pub struct FallbackFrame { impl FallbackFrame where - State: Dispatch> + Dispatch + 'static, + State: CompositorHandler + OutputHandler + 'static, { pub fn new( parent: &impl WaylandSurface, @@ -327,7 +328,7 @@ where impl DecorationsFrame for FallbackFrame where - State: Dispatch> + Dispatch + 'static, + State: CompositorHandler + OutputHandler + 'static, { fn set_scaling_factor(&mut self, scale_factor: f64) { self.scale_factor = scale_factor; @@ -621,8 +622,7 @@ impl FrameRenderData { queue_handle: &QueueHandle, ) -> Self where - State: - Dispatch> + Dispatch + 'static, + State: CompositorHandler + OutputHandler + 'static, { let parts = [ // Header. diff --git a/src/shell/xdg/mod.rs b/src/shell/xdg/mod.rs index 65a454cb3..9a6cc9b89 100644 --- a/src/shell/xdg/mod.rs +++ b/src/shell/xdg/mod.rs @@ -57,9 +57,7 @@ impl XdgShell { /// This function will return [`Err`] if the `xdg_wm_base` global is not available. pub fn bind(globals: &GlobalList, qh: &QueueHandle) -> Result where - State: Dispatch - + Dispatch - + 'static, + State: WindowHandler + 'static, { let xdg_wm_base = globals.bind(qh, 1..=Self::API_VERSION_MAX, GlobalData)?; let xdg_decoration_manager = GlobalProxy::from(globals.bind(qh, 1..=1, GlobalData)); @@ -87,11 +85,7 @@ impl XdgShell { qh: &QueueHandle, ) -> Window where - State: Dispatch - + Dispatch - + Dispatch - + WindowHandler - + 'static, + State: WindowHandler + 'static, { let decoration_manager = self.xdg_decoration_manager.get().ok(); let surface = surface.into(); @@ -253,8 +247,8 @@ impl XdgShellSurface { udata: U, ) -> Result where - D: Dispatch + 'static, - U: Send + Sync + 'static, + D: 'static, + U: Dispatch + Send + Sync + 'static, { let surface = surface.into(); let xdg_surface = wm_base.bound_global()?.get_xdg_surface(surface.wl_surface(), qh, udata); diff --git a/src/shell/xdg/popup.rs b/src/shell/xdg/popup.rs index 243dd7a00..47bfa9889 100644 --- a/src/shell/xdg/popup.rs +++ b/src/shell/xdg/popup.rs @@ -1,8 +1,9 @@ use crate::{ - compositor::{Surface, SurfaceData}, + compositor::{CompositorHandler, Surface, SurfaceData}, dispatch2::Dispatch2, error::GlobalError, globals::ProvidesBoundGlobal, + output::OutputHandler, shell::xdg::XdgShellSurface, }; use std::sync::{ @@ -55,11 +56,7 @@ impl Popup { wm_base: &impl ProvidesBoundGlobal, ) -> Result where - D: Dispatch> - + Dispatch - + Dispatch - + PopupHandler - + 'static, + D: CompositorHandler + OutputHandler + PopupHandler + 'static, { let surface = Surface::new(compositor, qh)?; let popup = Self::from_surface(Some(parent), position, qh, surface, wm_base)?; @@ -82,9 +79,7 @@ impl Popup { wm_base: &impl ProvidesBoundGlobal, ) -> Result where - D: Dispatch - + Dispatch - + 'static, + D: PopupHandler + 'static, { let surface = surface.into(); let wm_base = wm_base.bound_global()?; diff --git a/src/shell/xdg/window/inner.rs b/src/shell/xdg/window/inner.rs index 96a276a73..7e35b5890 100644 --- a/src/shell/xdg/window/inner.rs +++ b/src/shell/xdg/window/inner.rs @@ -4,7 +4,7 @@ use std::{ sync::Mutex, }; -use wayland_client::{Connection, QueueHandle}; +use wayland_client::{Connection, Proxy, QueueHandle}; use wayland_protocols::{ xdg::decoration::zv1::client::{ zxdg_decoration_manager_v1, @@ -210,8 +210,8 @@ where ) { if let Some(window) = Window::from_toplevel_decoration(decoration) { match event { - zxdg_toplevel_decoration_v1::Event::Configure { mode } => match mode { - wayland_client::WEnum::Value(mode) => { + zxdg_toplevel_decoration_v1::Event::Configure { mode } => { + if mode.available_since().is_some_and(|v| v <= decoration.version()) { let mode = match mode { Mode::ClientSide => DecorationMode::Client, Mode::ServerSide => DecorationMode::Server, @@ -220,12 +220,10 @@ where }; window.0.pending_configure.lock().unwrap().decoration_mode = mode; + } else { + log::error!(target: "sctk", "unknown decoration mode {:?}", mode); } - - wayland_client::WEnum::Unknown(unknown) => { - log::error!(target: "sctk", "unknown decoration mode 0x{:x}", unknown); - } - }, + } _ => unreachable!(), } diff --git a/src/shm/mod.rs b/src/shm/mod.rs index 0a3997568..52c7f52bd 100644 --- a/src/shm/mod.rs +++ b/src/shm/mod.rs @@ -7,7 +7,7 @@ use std::io; use wayland_client::{ globals::{BindError, GlobalList}, protocol::wl_shm, - Connection, Dispatch, QueueHandle, WEnum, + Connection, Dispatch, QueueHandle, }; use crate::{ @@ -35,7 +35,7 @@ impl From for Shm { impl Shm { pub fn bind(globals: &GlobalList, qh: &QueueHandle) -> Result where - State: Dispatch + ShmHandler + 'static, + State: ShmHandler + 'static, { let wl_shm = globals.bind(qh, 1..=1, GlobalData)?; // Compositors must advertise Argb8888 and Xrgb8888, so let's reserve space for those formats. @@ -84,17 +84,8 @@ where ) { match event { wl_shm::Event::Format { format } => { - match format { - WEnum::Value(format) => { - state.shm_state().formats.push(format); - log::debug!(target: "sctk", "supported wl_shm format {:?}", format); - } - - // Ignore formats we don't know about. - WEnum::Unknown(raw) => { - log::debug!(target: "sctk", "Unknown supported wl_shm format {:x}", raw); - } - }; + state.shm_state().formats.push(format); + log::debug!(target: "sctk", "supported wl_shm format {:?}", format); } _ => unreachable!(), diff --git a/src/shm/raw.rs b/src/shm/raw.rs index 8c767a3c1..61d335a40 100644 --- a/src/shm/raw.rs +++ b/src/shm/raw.rs @@ -20,12 +20,12 @@ use memmap2::MmapMut; use wayland_client::{ backend::ObjectData, protocol::{wl_buffer, wl_shm, wl_shm_pool}, - Dispatch, Proxy, QueueHandle, WEnum, + Dispatch, Proxy, QueueHandle, }; use crate::globals::ProvidesBoundGlobal; -use super::CreatePoolError; +use super::{CreatePoolError, ShmHandler}; /// A raw handler for file backed shared memory pools. /// @@ -112,8 +112,8 @@ impl RawPool { qh: &QueueHandle, ) -> wl_buffer::WlBuffer where - D: Dispatch + 'static, - U: Send + Sync + 'static, + D: 'static, + U: Dispatch + Send + Sync + 'static, { self.pool.create_buffer(offset, width, height, stride, format, qh, udata) } @@ -134,13 +134,7 @@ impl RawPool { ) -> wl_buffer::WlBuffer { self.pool .send_constructor( - wl_shm_pool::Request::CreateBuffer { - offset, - width, - height, - stride, - format: WEnum::Value(format), - }, + wl_shm_pool::Request::CreateBuffer { offset, width, height, stride, format }, data, ) .unwrap_or_else(|_| Proxy::inert(self.pool.backend().clone())) diff --git a/src/shm/slot.rs b/src/shm/slot.rs index 5e68872be..a44a51611 100644 --- a/src/shm/slot.rs +++ b/src/shm/slot.rs @@ -2,7 +2,8 @@ use std::io; use std::{ - os::unix::io::{AsRawFd, OwnedFd}, + any::Any, + os::unix::io::{AsFd, OwnedFd}, sync::{ atomic::{AtomicU8, AtomicUsize, Ordering}, Arc, Mutex, Weak, @@ -10,6 +11,7 @@ use std::{ }; use wayland_client::{ + backend::protocol::Message, protocol::{wl_buffer, wl_shm, wl_surface}, Proxy, }; @@ -415,7 +417,7 @@ impl Buffer { } fn data(&self) -> Option<&BufferData> { - self.buffer.object_data()?.downcast_ref() + (self.buffer.object_data()? as &dyn Any).downcast_ref() } /// Get the bytes corresponding to this buffer if drawing is permitted. @@ -527,7 +529,11 @@ impl wayland_client::backend::ObjectData for BufferData { // The Destroy message is identical to Release message (no args, same ID), so just reply handle - .send_request(msg.map_fd(|x| x.as_raw_fd()), None, None) + .send_request( + Message { sender_id: msg.sender_id, opcode: 0, args: Default::default() }, + None, + None, + ) .expect("Unexpected invalid ID"); } BufferData::DEAD => { diff --git a/src/subcompositor.rs b/src/subcompositor.rs index c1c14ba4d..f992ea3d8 100644 --- a/src/subcompositor.rs +++ b/src/subcompositor.rs @@ -5,9 +5,10 @@ use crate::reexports::client::protocol::wl_subsurface::WlSubsurface; use crate::reexports::client::protocol::wl_surface::WlSurface; use crate::reexports::client::{Connection, Dispatch, Proxy, QueueHandle}; -use crate::compositor::SurfaceData; +use crate::compositor::{CompositorHandler, SurfaceData}; use crate::dispatch2::Dispatch2; use crate::globals::GlobalData; +use crate::output::OutputHandler; #[derive(Debug)] pub struct SubcompositorState { @@ -22,7 +23,7 @@ impl SubcompositorState { queue_handle: &QueueHandle, ) -> Result where - State: Dispatch + 'static, + State: 'static, { let subcompositor = globals.bind(queue_handle, 1..=1, GlobalData)?; Ok(SubcompositorState { compositor, subcompositor }) @@ -34,8 +35,7 @@ impl SubcompositorState { queue_handle: &QueueHandle, ) -> (WlSubsurface, WlSurface) where - State: - Dispatch> + Dispatch + 'static, + State: CompositorHandler + OutputHandler + 'static, { let surface_data = SurfaceData::new(Some(parent.clone()), 1, ()); let surface = self.compositor.create_surface(queue_handle, surface_data); @@ -51,8 +51,7 @@ impl SubcompositorState { queue_handle: &QueueHandle, ) -> Option where - State: - Dispatch> + Dispatch + 'static, + State: 'static, { let parent = surface.data::>().unwrap().parent_surface(); let subsurface_data = SubsurfaceData::new(surface.clone());