Trait wayland_client::event_queue::Dispatch

source ·
pub trait Dispatch<I, UserData, State = Self>
where Self: Sized, I: Proxy, State: Dispatch<I, UserData, State>,
{ // Required method fn event( state: &mut State, proxy: &I, event: I::Event, data: &UserData, conn: &Connection, qhandle: &QueueHandle<State>, ); // Provided method fn event_created_child( opcode: u16, _qhandle: &QueueHandle<State>, ) -> Arc<dyn ObjectData> { ... } }
Expand description

A trait for handlers of proxies’ events delivered to an EventQueue.

§General usage

You need to implement this trait on your State for every type of Wayland object that will be processed by the EventQueue working with your State.

You can have different implementations of the trait for the same interface but different UserData type. This way the events for a given object will be processed by the adequate implementation depending on which UserData was assigned to it at creation.

The way this trait works is that the Dispatch::event() method will be invoked by the event queue for every event received by an object associated to this event queue. Your implementation can then match on the associated Proxy::Event enum and do any processing needed with that event.

In the rare case of an interface with events creating new objects (in the core protocol, the only instance of this is the wl_data_device.data_offer event), you’ll need to implement the Dispatch::event_created_child() method. See the event_created_child!() macro for a simple way to do this.

§Modularity

To provide generic handlers for downstream usage, it is possible to make an implementation of the trait that is generic over the last type argument, as illustrated below. Users will then be able to automatically delegate their implementation to yours using the delegate_dispatch!() macro.

As a result, when your implementation is instantiated, the last type parameter State will be the state struct of the app using your generic implementation. You can put additional trait constraints on it to specify an interface between your module and downstream code, as illustrated in this example:

use wayland_client::{protocol::wl_registry, Dispatch};

/// The type we want to delegate to
struct DelegateToMe;

/// The user data relevant for your implementation.
/// When providing a delegate implementation, it is recommended to use your own type here, even if it is
/// just a unit struct: using () would cause a risk of clashing with another such implementation.
struct MyUserData;

// Now a generic implementation of Dispatch, we are generic over the last type argument instead of using
// the default State=Self.
impl<State> Dispatch<wl_registry::WlRegistry, MyUserData, State> for DelegateToMe
where
    // State is the type which has delegated to this type, so it needs to have an impl of Dispatch itself
    State: Dispatch<wl_registry::WlRegistry, MyUserData>,
    // If your delegate type has some internal state, it'll need to access it, and you can
    // require it by adding custom trait bounds.
    // In this example, we just require an AsMut implementation
    State: AsMut<DelegateToMe>,
{
    fn event(
        state: &mut State,
        _proxy: &wl_registry::WlRegistry,
        _event: wl_registry::Event,
        _udata: &MyUserData,
        _conn: &wayland_client::Connection,
        _qhandle: &wayland_client::QueueHandle<State>,
    ) {
        // Here the delegate may handle incoming events as it pleases.

        // For example, it retrives its state and does some processing with it
        let me: &mut DelegateToMe = state.as_mut();
        // do something with `me` ...
    }
}

Note: Due to limitations in Rust’s trait resolution algorithm, a type providing a generic implementation of Dispatch cannot be used directly as the dispatching state, as rustc currently fails to understand that it also provides Dispatch<I, U, Self> (assuming all other trait bounds are respected as well).

Required Methods§

source

fn event( state: &mut State, proxy: &I, event: I::Event, data: &UserData, conn: &Connection, qhandle: &QueueHandle<State>, )

Called when an event from the server is processed

This method contains your logic for processing events, which can vary wildly from an object to the other. You are given as argument:

  • a proxy representing the object that received this event
  • the event itself as the Proxy::Event enum (which you’ll need to match against)
  • a reference to the UserData that was associated with that object on creation
  • a reference to the Connection in case you need to access it
  • a reference to a QueueHandle associated with the EventQueue currently processing events, in case you need to create new objects that you want associated to the same EventQueue.

Provided Methods§

source

fn event_created_child( opcode: u16, _qhandle: &QueueHandle<State>, ) -> Arc<dyn ObjectData>

Method used to initialize the user-data of objects created by events

If the interface does not have any such event, you can ignore it. If not, the event_created_child!() macro is provided for overriding it.

Object Safety§

This trait is not object safe.

Implementors§