Years ago I wrote https://xcb.freedesktop.org/ for X Window System clients, and yesterday I wrote my first Wayland client. My goodness, I can see the impact of every lesson the Wayland designers learned from X, and for that matter from XCB. I'm honestly really impressed by the design of the Wayland protocol!
I saw somebody complaining the other day about how much code you have to write just to open a window in a Wayland client. I think it's important to understand going in that this is a protocol designed to make hard things possible, not to make easy things easy; if you want to do easy things, use a toolkit like Gtk or Qt or SDL. So my program may seem like a lot of code for what it does: it just opens a window, periodically flashes between white and black, and measures some timing statistics, and I wrote over 300 lines of Rust for that. (I chose not to use the wayland-client crate's helpers for binding globals, so it could have been shorter, but I wanted to see what working with the raw protocol felt like.) But I know from experience that if you cut out any of the steps I had to do, you cut off the ability to handle more complicated scenarios.
I believe Wayland made the right complexity tradeoff here: the low-level protocol is very flexible, and ease of use belongs in higher-level abstractions that can pick which aspects of that flexibility to discard for simplicity.