Skip to content

Prototype a Dispatch2 trait to dispatch delegate macros to oblivion#519

Merged
wash2 merged 5 commits into
Smithay:masterfrom
ids1024:dispatch2
May 20, 2026
Merged

Prototype a Dispatch2 trait to dispatch delegate macros to oblivion#519
wash2 merged 5 commits into
Smithay:masterfrom
ids1024:dispatch2

Conversation

@ids1024
Copy link
Copy Markdown
Member

@ids1024 ids1024 commented Apr 3, 2026

I've though of some alternate ways to define Dispatch (as an alternative to the change in Smithay/smithay#1327). Today I had an idea for a way to prototype such a thing outside of wayland-rs. Due to the orphan rule, we can't create any blanket impls of Dispatch that are generic over the State the trait is implemented for (unless our crate is the one that defined the type I). But we can provide a delegate_dispatch2! macro that will add such a blanket impl for a particular concrete type.

Dispatch2 is similar to wayland_client::Dispatch, but it's now implemented for the object user data type instead of the state type, uses &self for the argument pointer to the user data, and removes the extra State = Self type bound.

Implementing this for the user data seems reasonable, since we already need to pass a user data when sending a request that creates an object. So the type passed there indicates what dispatch implementation to use. (It would also work to use State: Dispatch<UserData, I> instead of UserData: Dispatch<I, State>; but it would not work to use State: Dispatch<I, UserData> where I is a type from a different crate and State is generic. That isn't allowed under the orphan rule. So of the alternatives that work, this draft uses the one that seemed best to me.)

This draft uses Dispatch2 and eliminates the dispatch macros used in the simple_window example, except:

  • We can't make this generic over KeyboardDataExt, PointerDataExt, SurfaceDataExt, RequestDataExt (at least if this trait were part of wayland-rs, and not the same crate)
    • We can change the API to instead wrap the user data in a type provided by sctk. This would actually be potentially simpler anyway, since a trait impl wouldn't be needed. That isn't done here.
  • For registries, we likewise can't implement for the GlobalList type, since that is a wayland-client type, not an sctk one

event_created_child() is unchanged, but we should think of better ways to handle that too.

It is still necessary to have Dispatch bounds in methods of the *State types that create objects, but not in the implementations of Dispatch2. Though type bounds shouldn't be needed anymore if this were moved to wayland-rs and replaced Dispatch.

If an API change like this is good, it could be incorporated in the next breaking update to wayland-rs. Does anyone see non-obvious issues with this?

@ids1024
Copy link
Copy Markdown
Member Author

ids1024 commented May 13, 2026

Rebased on top of #524, so the *DataExt issue is addressed.

Not sure about how we want to handle GlobalList/delegate_registry!. It would okay to have a macro for just that, but a bit annoying.

ids1024 added 2 commits May 13, 2026 14:09
Presumably the type argument for the `LoopHandle` is expected to match
the the `D` type used for wayland-rs dispatch? Unless the calloop event
loop isn't being used to dispatch Wayland events.

Without `keyboard:` specified in `delegate_keyboard!`, this did use
`KeyboardData<$ty>`, so in that case these are assumed to match.
ids1024 added 2 commits May 19, 2026 10:41
For Smithay/wayland-rs#902, and eliminating
`delegate_!` macros, we won't be able to implement `Dispatch` for a
udata type that is not our own. So of letting the application define a
data type wrapping the sctk one with a trait, reverse that.

In some ways not having traits, etc. is a bit simpler here.

This opens up the possibility for things like keyboard to use the
builder pattern for all the various options that can be used when
binding a keyboard. But that isn't changed here.

Prior to this, `delegate_data_device!` doesn't seem to have had a way to
implement dispatch for a custom type, despite having an extension trait.
The input method code also seems to have been broken for custom types,
not handling it in the delegate macro, not providing a method to create
an instance with custom data, and assuming the default type in `.commit()`.
These things are fixed here.

`RequestDataExt` was defined a bit different from other things here,
with multiple methods instead of one returning a shared struct. But it
should still be fine to replace that with an immutable wrapper struct.
Smithay/wayland-rs#902 will replace `Dispatch`
with a trait defined this way. `Dispatch2` is a prototype to prove that
works, and an incremental change toward that.

I think for `delegate_registry!` we'll want a change to the API
wayland-client provides, so that is unchanged for now.

This makes it simpler to add protocols to sctk, and seems overall a
little bit better for client code using sctk. Once the wayland-rs update
is done, the `Dispatch` type bounds will be cleaner, and the compiler
should provide nicer error messages about missing `*Handler` traits.
@ids1024
Copy link
Copy Markdown
Member Author

ids1024 commented May 19, 2026

I've cleaned up the history, added detailed commit messages, and added changelog entries.

Along with the examples and tests, I think rust-windowing/winit#4567 verifies nothing seems to be wrong with how this works. And #525 confirms this seems to work smoothly with the wayland-rs release instead of providing a Dispatch2 macro here.

I think that confirms I can finish and merge Smithay/wayland-rs#902 and start moving towards actually releasing wayland-rs with these things.

delegate_registry! is kept here since I think that will be replaced using some change in wayland-rs (maybe a version of ProvidesRegistryState can be provided by wayland-client).

This could be left for merge until after wayland-rs is released if preferred, but I think this should be okay to merge now. I guess sctk does breaking API changes a bit less than smithay, but it should be probably sctk won't need to do a release before the wayland-rs update anyway.

@ids1024 ids1024 changed the title [WIP] Prototype a Dispatch2 trait to dispatch delegate macros to oblivion Prototype a Dispatch2 trait to dispatch delegate macros to oblivion May 19, 2026
@ids1024 ids1024 marked this pull request as ready for review May 19, 2026 19:48
@wash2 wash2 merged commit 70d6786 into Smithay:master May 20, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants