In general, the right way is to handle things that affect a window in the thread that owns the window, then no locking is necessary. That happens automatically for anything triggered by a window message. For other things, usually we send an internal message to switch processing to the right thread.
In previous MR discussions I touched on some aspects of why the driver is using the current design (separate dispatch thread), but I would like to use this opportunity to present some additional justification.
In contrast with, e.g., X11, mouse events in Wayland are emitted as part of the `wl_pointer` global object, rather than any `wl_surface` object. Since the association of `wl_pointer` with any `wl_surface`/`HWND` is ephemeral, we can't assign the dispatch of `wl_pointer` events to any particular window thread beforehand. Also due to how dispatching works we would not able to safely change the target event queue dynamically in this case (e.g., imagine if on each `enter` we could specify a new thread event queue for further input events to be queued to). The same stands for `wl_keyboard` objects (coming in the future).
For all its drawbacks (i.e., not ideal in terms of Wine integration, and requiring additional thread synchronization) I have found that a separate Wayland dispatch thread is much simpler to reason about and deal with compared to other alternatives I have experimented with. And, as you mention, if we really need something to happen in the context of the window thread message loop, we have the escape hatch of a using an internal window message.
Note, however, that using an internal message wouldn't help with our current concern, since it wouldn't mitigate the problem of ensuring that any stored HWND remains valid and has not been recycled during the event dispatch.
If you are accessing the window from a different thread, then of course proper locking is needed. If you have to do that a lot, it's probably a sign that the design is wrong though.
Do I understand correctly then, that robustness against HWND invalidation/recycling, in the context that @rbernon mentioned, is considered a requirement for the driver?