Pick a platform and make the best application you can on that platform.
Most applications just pick Windows win32 API or MacOSX and forgets about everything else and are never released for Linux or other Unices, unless the application uses electron, Qt with C++, Qt with Python or Java SWING like JetBrains IDEA IDE family. The main problem of Linux desktop is the lack of a high level graphics library toolkit with a stable API, ABI and a C interface that does not introduce breaking changes on every release. Unlike Gtk, Qt is more stable, but it lacks a C API and C++ has a fragile ABI not friendly to foreign-function interface or cross-language linking.
True. But there are several entirely adequate cross-platform toolkits. Pick a toolkit, not a platform.
(GTK+ (via gtkmm) user for 23 years, on 3+ platforms)
X11 can work on Windows (many Xservers available, since forever), MacOS (used to ship with one, but now you've got to install one), and you can run an Xwayland in Wayland. So it's as cross platform as you can get. Might not look great, but then cross platform doesn't usually look great anyway.
If you're going to do X, avoid Xlib, it adds restrictive abstractions on top of X protocol and really confuses things. XCB is much closer to just reasonable interfaces to the protocol. Ultimately, X11 is a distributed systems communication protocol which happens to have graphical output as a side effect; understanding the communications part first lets you get the most out of it.
The following design patterns are widely used with graphical user interfaces: observer-design pattern; model-view-controller; model-view-presentation; two-way-data binding; property binding; command design pattern; and composite design patterns for representing a collection of objects as single object.
For understanding event loop it may be much easier to implement a Xterm or VT100 keyboard-driven terminal user interface TUI since this does not requiring dealing with too many backends.