© 2010-2019 by Zack Smith. All rights reserved.
Write one C++ GUI app and run it on any platform
FrugalWidgets is my GUI library that provides views, view controllers and other classes to build the user interface of an application. It supports animation, momentum and is meant to be touch-friendly i.e. not constained by the desktop or mouse input.
It presently runs on these platforms and graphics systems:
- iOS (UIKit)
- MacOS (OpenGL and X-Windows)
- GNU/Linux (OpenGL, X-Windows, framebuffer device)
- Android using NDK [work in progress]
I've begun support for:
- MacOS using AppKit
- Windows using GDI
Font support includes
- X-Windows BDF fonts
- TeX PK fonts
What problems does it solve?
Segregation of apps onto different platforms, each using different languages and OS libraries produces a huge problem for anyone who wants to create platform-agnostic code. FrugalWidgets directly addresses this by providing a UI library for C++ apps across multiple platforms.
Platform segregation, besides being a pain for the individual developer, also happens to create waste and expense for businesses, who have to maintain separate teams of specialists for each platform, such as:
- An iOS team coding in Swift and legacy Objective-C.
- An Android team coding in Java and slowing moving to Kotlin.
- Desktop OS team(s), which often never get hired because mobile is already eating up the software development budget.
To solve this...
- FrugalWidgets provides the freedom to run a native C++ app on any of the diverse supported platforms.
- Since FrugalWidgets is not a derivative of a desktop UI library, it bypasses the issue of inherited desktop UI technical debt and bloat.
- FrugalWidgets is both desktop- and mobile-friendly.
- FrugalWidgets is lightweight and takes mere seconds to compile.
While the user interface library is not all that is required to write a platform-agnostic application, because for instance classes are needed for networking, thread management and image manipulation, it is a key missing component.
The problem of non-portability
The ability to run native-code software that has a GUI on both desktop or mobile platforms remains elusive even in 2019.
There are partial solutions, such as Android on ChromeOS and soon, iPad apps on MacOS.
However to run the exact same native code on both mobile and desktop platforms and across manufacturers remains largely unheard of.
Sometimes it would just be nice for the individual to
take my code with me when
deciding to switch to a different platform.
Perhaps you have a desire to ditch the Mac and go back to Windows, or to ditch Windows and switch to BSD.
Perhaps you need to run your app on both the desktop, mobile, and even tiny computers like the Raspberry pi Zero.
It would be useful to never be
locked in to a particular OS or platform
just because of the UI or the language it's coded in,
especially if the creators of an OS make an unappealing change to it.
The problem of bloat
Over time, GUI libraries become bloated because of:
- Backward compatibility
- Creeping featureism
- Fragile technical debt
FrugalWidgets is meant to minimize these.
All GUI libraries should support the following basic UI pattern, as defined by Xerox PARC circa 1979:
- They present data (in
- They give you a place to put business logic (in a
- They expect you will store state and bulk data (in
My vision of a useful UI library is one offering a minimal feature set, not a library that tries to support every possible need, circumstance and resource type.
FrugalWidgets is thus not a totalizing solution, offering every
could ever need -- it's minimal, hence its name.
If it takes longer than a few minutes to compile FrugalWidgets, it is too large and has too many responsibilities.
The problem of complexity
Bloated software is bad because it leads to greater complexity:
- more lines of code means more bugs.
- more code means a need for more programmers to maintain the code.
- more time spent means technical debt.
- more code provides a larger attack surface for malware writers.
- more code inevitably leads to more security vulnerabilities.
All these are bad from the user's perspective. Complexity runs counter to the interests of the user.
Software bloat is analogous to belly fat, which is an unnecessary burden that both collects and excretes toxins and harms one's health.
The problem of desktop-only and mobile-only GUI toolkits
Before mobile phone and tablet platforms were a thing, a number of desktop GUI libraries were developed to a mature state that were unsuitable for touch interfaces and likely never will become suitable.
- Controls were too small by default.
- Responses were allowed to right-clicking, keyboard shortcuts, etc. that don't exist in touch interfaces.
- Scrolling was meant to use a narrow scrollbar, not fingers.
- Scroll direction was the reverse of hand motion.
- There was no on-screen keyboard or it was primitive.
- The mouse pointer was always visible.
- Different DPIs were either not considered or were an afterthought.
- Little support for animation or momentum scrolling.
- Multitouch was inconcievable.
Similarly mobile-only UI libraries have often been deemed unsuitable for running productivity apps because of the excessive reliance on touch.
With FrugalWidgets I'm trying to take these concerns into account from the outset to create a mobile+desktop UI library. Because I'm writing it from scratch, there is no technical debt to impede progress.
This project is the newest incarnation of an effort that goes back many years in various forms and for various platforms.
These have included:
- My C++ UI classes for Windows GDI.
- My C/C++ and Xlib-based library for my Pentium-based Linux laptop.
- My Borland C++-based library as part of an MSDOS application.
- My Objective-C and OpenGL-based library for MacOS and iOS.
- My C++ and OpenGL-based library for Linux.
- My C-based Linux framebuffer efforts.
- Basing a UI library on a particular low-level UI API (e.g. OpenGL) is pointless; API use is a separate concern that needs to be isolated. APIs also become deprecated, as OpenGL has on MacOS.
- Using one OpenGL texture per view worked fine on the desktop, but overwhelmed a mobile device. One pixel buffer per window is better and largely sufficient.
- Languages that only reached maturity on a few platforms, or that are owned/controlled by a particular company, must be avoided (e.g. Objective C, Go, Swift) as these issues impede portability.
iPhone 6S+ (iOS zoomed mode, DPI 250, BDF fonts)
iPhone SE (iOS non-zoomed mode, DPI 250, BDF fonts)
OpenGL (100 DPI, Freetype2)
NDK (250 DPI, TeX PK font)