Objects
The Wayland protocol is an object-oriented protocol. This means that, as the client and server exchange messages, they build an abstract state made of several objects, which are represented by a numeric identifier. You can figure them as being scopes for messages: each message is associated with one of these protocol object. Each object has an "interface", which is a definition of which messages can be associated with it.
The messages are named "requests" when they are sent by the client to the server, and "events" when they are sent by the server to the client. An object interface is thus the list of which requests and which events can be associated with objects of this interface.
For example, an object representing a keyboard would receive the events from the server informing about which keys are pressed by the user. An object representing a window would send requests to update its content, and receive events informing about user interaction (such as resizing).
At the beginning, the protocol state contains a single object. Its identifier is 1, and its
interface is wl_display
. From this object the rest of the protocol state is setup by
the client.
Objects and proxies
The protocol objects are created and destroyed by messages. A request sent by the client can
have for effect the creation of a new object in the state, or the destruction of an object.
Most of the time, creation and destruction of objects is done by the client, but there are
exceptions. For this reason, protocol objects are not directly represented by Rust structs,
but instead one layer of indirection is added. wayland-client
provides you with Rust objects
that we call "proxies".
Each proxy represents a protocol object, but several proxies can represent the same object. You
can think of proxies as something akin Rc<_>
or Arc<_>
: they are an handle to the underlying
protocol object. Furthermore, their lifetime is not tied to the protocol object's lifetime: they
can outlive it. Once a protocol object has been destroyed, the proxies associated to it will
become inert.
Each kind of protocol object is represented by a different Rust type, all of them implementing the
Proxy
trait. Sending requests to the server is done by invoking methods on that object.
User data
wayland-client
makes it possible to associate some data with a protocol object. This data is set
when the object is created, and can be accessed from any proxy representing this object via the
Proxy::data()
method. This user data mechanism comes with two important limitations:
- You can only get an immutable
&
reference to the stored value. This means that if you need this value to be writable, you need to handle interior mutability by yourself. - The
Proxy::data()
is generic, and you need to know beforehand what is the type of the stored value. If the wrong type is provided as parameter, the function will returnNone
.
Lets now discuss the mechanism by which wayland-client
handles the stream of events from the server
and allows you to process it: event queues and dispatching.