I like writing in C (and C++) so much because it is a universally supported language: no matter the platform, you can compile and run C. The early Java pitch was all about promises of "write once, run anywhere" but of course it came with the huge catch of a heavy VM. With C you can get as close to the metal as is comfortable and the runtime is relatively small.
User interfaces are decidedly not cross-platform, though. Everywhere you go, UIs have some unique set of priorities or design constraints, or UI toolkits have their own not-invented-here APIs. From a UX perspective, the ideal solution would be to redesign the UI for each individual device/operating system separately. In practice, this is likely way too expensive. You'll end up choosing your favorites and the less popular platforms are left out in the cold.
(As an aside, it always vexes me that "popular" does not imply "good"; just look at Microsoft Windows.)
If one tries to make the user-facing portions of an app the same on all platforms, it'll just end up a lowest-common-denominator compromise that is equally foreign and/or disappointing on every device. Still, this is the most cost-effective approach, and one that is increasingly being employed for instance by Electron apps.
Truly native apps do have a special place in my heart, though. When software is lovingly crafted to work in perfect harmony with the operating system and its native UI, the user experience can be honed to perfection. Unfortunately, this also means that the app is excluded from other platforms in equal measure.
So how do you write a cross-platform app that still adapts in sufficient ways to the platforms it runs on? I suppose I'm on my way to find out with Lagrange. It is fortunately a simple app so it doesn't require many complicated system integrations. My approach is to use standard C11 and SDL as the common foundation for everything, and incorporate specific OS features to my custom dependency-free UI toolkit where it makes sense. For example, Lagrange has a few macOS-specific features, like system URL handlers, touch bar buttons, and trackpad scrolling. The UI has been designed for desktops (monitor & mouse) but there are obvious ways to adapt it for mobile. The advantage of a custom UI toolkit is that one has full control over modifications and overrides for system integrations.
In the end, it is a balancing act: one must choose which parts can work adequately as cross-platform code, and where costly OS-specific features are crucial for the UX.
🏷 Programming, Lagrange