wayland_server

Trait Dispatch

source
pub trait Dispatch<I: Resource, UserData, State = Self>: Sized {
    // Required method
    fn request(
        state: &mut State,
        client: &Client,
        resource: &I,
        request: I::Request,
        data: &UserData,
        dhandle: &DisplayHandle,
        data_init: &mut DataInit<'_, State>,
    );

    // Provided method
    fn destroyed(
        _state: &mut State,
        _client: ClientId,
        _resource: &I,
        _data: &UserData,
    ) { ... }
}
Expand description

A trait which provides an implementation for handling a client’s requests from a resource with some type of associated user data.

§General usage

You need to implement this trait on your State for every type of Wayland object that will be processed by the Display 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::request() method will be invoked by the Display for every request received by an object. Your implementation can then match on the associated Resource::Request enum and do any processing needed with that event.

If the request being processed created a new object, you’ll receive it as a New<I>. When that is the case, you must initialize it using the DataInit argument. **Failing to do so will cause a panic.

§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 instanciated, 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_server::{protocol::wl_output, Dispatch};

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

/// The user data relevant for your implementation.
/// When providing 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 an other 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_output::WlOutput, 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_output::WlOutput, 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 request(
        state: &mut State,
        _client: &wayland_server::Client,
        _resource: &wl_output::WlOutput,
        _request: wl_output::Request,
        _udata: &MyUserData,
        _dhandle: &wayland_server::DisplayHandle,
        _data_init: &mut wayland_server::DataInit<'_, State>,
    ) {
        // Here the delegate may handle incoming requests 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 request( state: &mut State, client: &Client, resource: &I, request: I::Request, data: &UserData, dhandle: &DisplayHandle, data_init: &mut DataInit<'_, State>, )

Called when a request from a client is processed.

The implementation of this function will vary depending on what protocol is being implemented. Typically the server may respond to clients by sending events to the resource, or some other resource stored in the user data.

Provided Methods§

source

fn destroyed( _state: &mut State, _client: ClientId, _resource: &I, _data: &UserData, )

Called when the object this user data is associated with has been destroyed.

Note this type only provides an immutable reference to the user data, you will need to use interior mutability to change it.

Typically a Mutex would be used to have interior mutability.

You are given the ObjectId and ClientId associated with the destroyed object for cleanup convenience.

By default this method does nothing.

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.

Implementors§