Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions wayland-client/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@

## Unreleased

#### Breaking changes
- Define `Dispatch` to be implemented on udata type
- Remove `delegate_dispatch!` in favor of implementation that is generic over
`D` for a particular user data type
- Replace `delegate_noop!` with `Noop` and `NoopIgnore` types providing generic
dispatch implementations

## 0.31.14-- 2026-03-30

- Updated Wayland core protocol to 1.25
Expand Down
6 changes: 3 additions & 3 deletions wayland-client/examples/list_globals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@ struct AppData;
//
// In this example, we just use () as we don't have any value to associate. See
// the `Dispatch` documentation for more details about this.
impl Dispatch<wl_registry::WlRegistry, ()> for AppData {
impl Dispatch<wl_registry::WlRegistry, AppData> for () {
fn event(
_: &mut Self,
&self,
_: &mut AppData,
_: &wl_registry::WlRegistry,
event: wl_registry::Event,
_: &(),
_: &Connection,
_: &QueueHandle<AppData>,
) {
Expand Down
88 changes: 41 additions & 47 deletions wayland-client/examples/simple_window.rs
Original file line number Diff line number Diff line change
@@ -1,23 +1,22 @@
use std::{fs::File, os::unix::io::AsFd};

use wayland_client::{
Connection, Dispatch, QueueHandle, WEnum, delegate_noop,
protocol::{
wl_buffer, wl_compositor, wl_keyboard, wl_registry, wl_seat, wl_shm, wl_shm_pool,
wl_surface,
},
Connection, Dispatch, NoopIgnore, QueueHandle, WEnum,
protocol::{wl_buffer, wl_compositor, wl_keyboard, wl_registry, wl_seat, wl_shm, wl_surface},
};

use wayland_protocols::xdg::shell::client::{xdg_surface, xdg_toplevel, xdg_wm_base};

struct GlobalData;

fn main() {
let conn = Connection::connect_to_env().unwrap();

let mut event_queue = conn.new_event_queue();
let qhandle = event_queue.handle();

let display = conn.display();
display.get_registry(&qhandle, ());
display.get_registry(&qhandle, GlobalData);

let mut state = State {
running: true,
Expand All @@ -44,43 +43,44 @@ struct State {
configured: bool,
}

impl Dispatch<wl_registry::WlRegistry, ()> for State {
impl Dispatch<wl_registry::WlRegistry, State> for GlobalData {
fn event(
state: &mut Self,
&self,
state: &mut State,
registry: &wl_registry::WlRegistry,
event: wl_registry::Event,
_: &(),
_: &Connection,
qh: &QueueHandle<Self>,
qh: &QueueHandle<State>,
) {
if let wl_registry::Event::Global { name, interface, .. } = event {
match &interface[..] {
"wl_compositor" => {
let compositor =
registry.bind::<wl_compositor::WlCompositor, _, _>(name, 1, qh, ());
let surface = compositor.create_surface(qh, ());
registry.bind::<wl_compositor::WlCompositor, _, _>(name, 1, qh, NoopIgnore);
let surface = compositor.create_surface(qh, NoopIgnore);
state.base_surface = Some(surface);

if state.wm_base.is_some() && state.xdg_surface.is_none() {
state.init_xdg_surface(qh);
}
}
"wl_shm" => {
let shm = registry.bind::<wl_shm::WlShm, _, _>(name, 1, qh, ());
let shm = registry.bind::<wl_shm::WlShm, _, _>(name, 1, qh, NoopIgnore);

let (init_w, init_h) = (320, 240);

let mut file = tempfile::tempfile().unwrap();
draw(&mut file, (init_w, init_h));
let pool = shm.create_pool(file.as_fd(), (init_w * init_h * 4) as i32, qh, ());
let pool =
shm.create_pool(file.as_fd(), (init_w * init_h * 4) as i32, qh, NoopIgnore);
let buffer = pool.create_buffer(
0,
init_w as i32,
init_h as i32,
(init_w * 4) as i32,
wl_shm::Format::Argb8888,
qh,
(),
NoopIgnore,
);
state.buffer = Some(buffer.clone());

Expand All @@ -91,10 +91,11 @@ impl Dispatch<wl_registry::WlRegistry, ()> for State {
}
}
"wl_seat" => {
registry.bind::<wl_seat::WlSeat, _, _>(name, 1, qh, ());
registry.bind::<wl_seat::WlSeat, _, _>(name, 1, qh, GlobalData);
}
"xdg_wm_base" => {
let wm_base = registry.bind::<xdg_wm_base::XdgWmBase, _, _>(name, 1, qh, ());
let wm_base =
registry.bind::<xdg_wm_base::XdgWmBase, _, _>(name, 1, qh, GlobalData);
state.wm_base = Some(wm_base);

if state.base_surface.is_some() && state.xdg_surface.is_none() {
Expand All @@ -107,13 +108,6 @@ impl Dispatch<wl_registry::WlRegistry, ()> for State {
}
}

// Ignore events from these object types in this example.
delegate_noop!(State: ignore wl_compositor::WlCompositor);
delegate_noop!(State: ignore wl_surface::WlSurface);
delegate_noop!(State: ignore wl_shm::WlShm);
delegate_noop!(State: ignore wl_shm_pool::WlShmPool);
delegate_noop!(State: ignore wl_buffer::WlBuffer);

fn draw(tmp: &mut File, (buf_x, buf_y): (u32, u32)) {
use std::{cmp::min, io::Write};
let mut buf = std::io::BufWriter::new(tmp);
Expand All @@ -134,8 +128,8 @@ impl State {
let wm_base = self.wm_base.as_ref().unwrap();
let base_surface = self.base_surface.as_ref().unwrap();

let xdg_surface = wm_base.get_xdg_surface(base_surface, qh, ());
let toplevel = xdg_surface.get_toplevel(qh, ());
let xdg_surface = wm_base.get_xdg_surface(base_surface, qh, GlobalData);
let toplevel = xdg_surface.get_toplevel(qh, GlobalData);
toplevel.set_title("A fantastic window!".into());

base_surface.commit();
Expand All @@ -144,29 +138,29 @@ impl State {
}
}

impl Dispatch<xdg_wm_base::XdgWmBase, ()> for State {
impl Dispatch<xdg_wm_base::XdgWmBase, State> for GlobalData {
fn event(
_: &mut Self,
&self,
_: &mut State,
wm_base: &xdg_wm_base::XdgWmBase,
event: xdg_wm_base::Event,
_: &(),
_: &Connection,
_: &QueueHandle<Self>,
_: &QueueHandle<State>,
) {
if let xdg_wm_base::Event::Ping { serial } = event {
wm_base.pong(serial);
}
}
}

impl Dispatch<xdg_surface::XdgSurface, ()> for State {
impl Dispatch<xdg_surface::XdgSurface, State> for GlobalData {
fn event(
state: &mut Self,
&self,
state: &mut State,
xdg_surface: &xdg_surface::XdgSurface,
event: xdg_surface::Event,
_: &(),
_: &Connection,
_: &QueueHandle<Self>,
_: &QueueHandle<State>,
) {
if let xdg_surface::Event::Configure { serial, .. } = event {
xdg_surface.ack_configure(serial);
Expand All @@ -180,46 +174,46 @@ impl Dispatch<xdg_surface::XdgSurface, ()> for State {
}
}

impl Dispatch<xdg_toplevel::XdgToplevel, ()> for State {
impl Dispatch<xdg_toplevel::XdgToplevel, State> for GlobalData {
fn event(
state: &mut Self,
&self,
state: &mut State,
_: &xdg_toplevel::XdgToplevel,
event: xdg_toplevel::Event,
_: &(),
_: &Connection,
_: &QueueHandle<Self>,
_: &QueueHandle<State>,
) {
if let xdg_toplevel::Event::Close = event {
state.running = false;
}
}
}

impl Dispatch<wl_seat::WlSeat, ()> for State {
impl Dispatch<wl_seat::WlSeat, State> for GlobalData {
fn event(
_: &mut Self,
&self,
_: &mut State,
seat: &wl_seat::WlSeat,
event: wl_seat::Event,
_: &(),
_: &Connection,
qh: &QueueHandle<Self>,
qh: &QueueHandle<State>,
) {
if let wl_seat::Event::Capabilities { capabilities: WEnum::Value(capabilities) } = event {
if capabilities.contains(wl_seat::Capability::Keyboard) {
seat.get_keyboard(qh, ());
seat.get_keyboard(qh, GlobalData);
}
}
}
}

impl Dispatch<wl_keyboard::WlKeyboard, ()> for State {
impl Dispatch<wl_keyboard::WlKeyboard, State> for GlobalData {
fn event(
state: &mut Self,
&self,
state: &mut State,
_: &wl_keyboard::WlKeyboard,
event: wl_keyboard::Event,
_: &(),
_: &Connection,
_: &QueueHandle<Self>,
_: &QueueHandle<State>,
) {
if let wl_keyboard::Event::Key { key, .. } = event {
if key == 1 {
Expand Down
Loading
Loading