
Boden cross-platform framework: Native C++11, native widgets, no JavaScript - gitoby
https://github.com/ashampoosystems/boden
======
int_19h
This does not appear to be idiomatic C++11. I mean:

    
    
        bdn::P<bdn::Button> button = bdn::newObj<bdn::Button>();
    

Idiomatic would be to use std::shared_ptr and std::make_shared, instead of
yet-another-custom-smart-pointer.

~~~
hduden
I am a member of the Boden dev team. The smart pointer system is actually
still a topic of discussion in the Boden team as well. It has a couple of nice
properties, like the fine grained control bdn::P gives us over the time when
an object is actually destructed. For example, these pointers provide an easy
way to ensure that destruction of our View objects happens only on the main
thread, no matter which thread released the last reference.

But on the other hand, not using the standard constructs definitely has a cost
associated with it. We are happy for your feedback on this issue.

Note that we also think about the idea of transforming P and making it a
specialization of std::shared_ptr for objects derived from bdn::Base. That
would give us the best of both worlds. Feel free to let us know what you
think.

~~~
int_19h
Deferring destructors is a suspicious pattern in general - in C++, I generally
expect them to not be async and unpredictable like that. What guarantees do
you make wrt destruction order? I hope it's not as complicated as finalizers
in Java and C#...

The more logical model, to me, would be to have child views owned by parent
views, and to only allow ownership-changing calls (i.e. adding or removing a
child) from the main thread. That way all you really need is unique_ptr (from
parent to children) and raw pointers (from children to parent, and from any
observers). Although it would probably still be better to use shared_ptr just
so that observers can use weak_ptr, since untangling lifetimes in callbacks
can be tricky, and often it's easier to just check if the object is still
there.

To give a specific code example, with unique_ptr, the same snippet would be:

    
    
        _window = std::make_unique<bdn::Window>();
        _window->setTitle("AwesomeApp");
    
        auto button = std::make_unique<bdn::Button>();
        button->setLabel("Hello World");
    
        // The following *moves* button, such that _window takes ownership over it.
        // It can only be called from the main thread.
        _window->setContentView(button); 
    
        _window->requestAutoSize();
        _window->requestCenter();
        _window->setVisible(true);
    

And furthermore, _window wouldn't have to be a pointer at all - it can just be
a member of MainViewController.

------
sovande
If you want to go down this road, doing mobile cross-platform native, Xamarin
seems much more compelling. It is supported by a very good IDE and has proper
licensing for distribution on the app stores.
[https://visualstudio.microsoft.com/xamarin/](https://visualstudio.microsoft.com/xamarin/)

~~~
je42
uhm. i tried it.

the example app you get out of the box. it didn't run the dummy tests
successfully on either ios or android side (forgot which one).

upgraded to the latest version other issues on the example app.

for me this was already a big no-no. if the tests are failing on the example
app.

------
Teknoman117
GPL means its pretty much unusable...

~~~
elteto
Why?

~~~
tom_
If you create a program that links with a GPL library, the program as a whole
must itself also be GPL - which is not always acceptable. See section 5 of the
GPL:
[https://www.gnu.org/licenses/gpl.html](https://www.gnu.org/licenses/gpl.html)

"You may convey a work based on the Program ... provided that you also meet
all of these conditions: ... c) You must license the entire work, as a whole,
under this License to anyone who comes into possession of a copy"

~~~
hak8or
Not always. I believe a common understanding is if it _statically_ links with
GPL code, then it spreads to your code. If it dynamically links then your
program is not hit with GPL, as the user is able to change the dynamic library
with their own. If what you dewxribed were the case, then the Tivoization
lawsuit would have went differently instead of GPLv3 coming out.

~~~
dragonwriter
> I believe a common understanding is if it statically links with GPL code,
> then it spreads to your code. If it dynamically links then your program is
> not hit with GPL

The FSF disagrees: [https://www.gnu.org/licenses/gpl-
faq.en.html#GPLStaticVsDyna...](https://www.gnu.org/licenses/gpl-
faq.en.html#GPLStaticVsDynamic)

> If what you dewxribed were the case, then the Tivoization lawsuit would have
> went differently instead of GPLv3 coming out.

The anti-Tivoization clause of GPLv3 doesn't deal with a linking issue, it
deals with the fact that even if the device maker releases code for
modifications under GPLv2, that doesn't let the user modify and replace the
code on the device if the device is locked down so as not to accept modified
code, and the user hasn't been provided with the appropriate incantations to
unlock it.

------
rhodysurf
This is pretty much all I want except for it being GPL

~~~
YetAnotherNick
Is there any reason why you don't want to publish your changes to the library?

~~~
jnbiche
It's GPL, not LGPL, so _your_ code will also have to be licensed GPL.

Which means that:

1\. you can't build proprietary apps with this framework, and;

2\. it's almost certain to be rejected by the Apple App Store, since they
typically reject GPL-licensed apps. A few might sneak through, but as a matter
of policy, Apple rejects GPL apps since the GPL conflicts with Apple's App
Store terms. (btw, this problem even exists with LGPL)

~~~
fermienrico
I like the spirit of open source but every time I see GPL, I feel like it is
an evil license that tries to consume everything it touches - even the stuff
it has absolutely no rights for. That is not the spirit of open source.

It has caused ages of headaches, law firms getting rich and unintentional
business losses.

How about a license that says "You cannot use it for any commercial use or
closed source projects" so then at least it doesn't claim rights to the rest
of the source code. GPL goes a notch beyond and claims rights to proprietary
code that so that community can enjoy the fruits of labor at the expense of a
small set of people developed without anything to return.

Copy-left licenses are overarching evil in my view.

~~~
zzo38computer
GPL is not meant to prevent commercial uses, as long as the commercial uses
are still with GPL.

What I generally do is release source code of my program as public domain,
even if it links with GPL libraries (it will be GPL if I am modifying an
existing GPL program though), although require that the combination is GPL
even though the files that are entirely my own writing will be public domain.
To distribute the combination or binaries requires distributing according to
GPL. Since public domain software with source code is compatible with GPL,
this is probably allowed, as long as the combination with the GPL libraries
are GPL. (Since I do not generally release binaries, and rather release them
as public domain source code, therefore it is probably allowed.)

[1] [http://www.gnu.org/licenses/gpl-
faq.html#DoesTheGPLAllowMone...](http://www.gnu.org/licenses/gpl-
faq.html#DoesTheGPLAllowMoney) [2] [http://www.gnu.org/licenses/gpl-
faq.html#CombinePublicDomain...](http://www.gnu.org/licenses/gpl-
faq.html#CombinePublicDomainWithGPL)

~~~
Cu3PO42
I would like to note that it is not possible to put works entirely into the
public domain in some jurisdictions. The only such legislation that I am
familiar with, is the German "Urheberrecht". In particular you cannot renounce
certain "moral rights" [1] you have to your works.

Since it is not possible to actually put the works into the public domain,
this typically means that you retain all rights and license no rights to user.
As such you should always include a fallback license, for example Apache or
MIT or whatever you feel comfortable with for these jurisdictions.

[1] [https://www.gesetze-im-
internet.de/englisch_urhg/englisch_ur...](https://www.gesetze-im-
internet.de/englisch_urhg/englisch_urhg.html) (Subchapter 2)

------
saagarjha
A couple of questions I had that I didn’t seem answered in the README:

* How is view positioning handled? Does Boden only allow for “list” layouts?

* Can I use my own native components?

* Can I call platform APIs?

~~~
hduden
Boden dev here. Boden currently supports linear layouts (horizontal and
vertical). We know that more is needed for a proper UI. Feedback is
appreciated - let us know what you would like to see regarding layout options.

Since all widgets are native, you can easily add your own child widgets to the
containers. You can gain access to the native view objects via the
"View::getCore" method. However, we do not have a good way yet to insert
custom widgets into the Boden layout system. That is an area where more work
is needed.

Regarding calling platform APIs: since the apps are written in C++ you can
call any platform API you like. On Android you can also use the Boden helper
classes (bdn::java::JClass, etc.) to make Java calls from C++. On iOS the
easiest way is to create an Objective C++ file (.mm file extension). In there
you can combine C++ and Objective C code freely.

~~~
saagarjha
I'm primarily an iOS developer (though, I've started looking into Android
recently), so my point of view will be skewed towards that platform. If you're
trying to write an iOS app, you probably want to expose AutoLayout, or at the
very least the API provided by UIStackView. Plus, you will need to handle
things like the navigation hierarchy, which on iOS does a lot of layout-
related things for you.

~~~
hduden
It is an interesting thought to also use the native layout system on each
platform. It might be challenging to provide an abstraction for the native
layout that behaves consistently on all platforms, though.

Can you elaborate on why you feel AutoLayout support is needed? If Boden had a
layout system of comparable power, would that solve this issue?

~~~
saagarjha
> Can you elaborate on why you feel AutoLayout support is needed?

That's simply how most apps are designed these days, since it makes it easy to
support the ever-growing list of device sizes that iOS apps need to support.

> If Boden had a layout system of comparable power, would that solve this
> issue?

Sure, but you might need to keep in mind that iOS developers are used to using
AutoLayout and need to learn how to do things in your new layout system.

------
simfoo
Why is it that nowadays all kinds of libraries go down the framework path by
forcing/encouraging the user to adapt their workflows to use some kind of
custom tooling?

I mean look at the readme: Getting Started? Just call "python boden.py new -n
AwesomeApp"

Just provide examples in source form with minimal and standard instrumentation
(like project files) and leave the rest to the user

~~~
zapzupnz
I rather like using the custom tooling. It means that if people are following
the prescribed procedure, they will always be using the latest version of a
project template or some such rather than duplicating a local copy of what
might be a hideously out-of-date template.

With Swift, for example, using Swift Package Manager (SPM) to initialise
templates means that the syntax in the newly-created project's files is up-to-
date, the Package.swift file follows the appropriate naming conventions for
whatever version of SPM it is, and it's much more convenient to do `swift
init` than to go clone a github repo manually then rename this or that.

It's basically a command-line version of project templates in Visual Studio or
whatever, and people generally like those. Sane defaults are nice, but sane
defaults with validation are nicer.

Though I agree that it would be nice to just have a blank template available
for those who don't want to use the tooling. There should always be a
subsection in the Getting Started section that says "clone this repo, and
you're good to go. Be sure to clone the repo again when you want to make
another project; don't just copy your existing clone!".

------
poidos
In step 6 here [0], `xcodeselect` doesn't work. It's `xcode-select` on my
machine (running Mojave 10.14.1 with XCode 10.1 (10B61))

[0]: [https://github.com/ashampoosystems/boden#1-install-
xcode](https://github.com/ashampoosystems/boden#1-install-xcode)

------
TheMagicHorsey
Flutter, out of Google is a solution for iOS and Android cross-platform
development that includes very fast UI primitives, a edit and continue
workflow, intuitive and reactive UI framework, and a nicer high-level language
to work with than C++ (Dart).

------
pritambarhate
Xamarin also follows a similar strategy of wrapping platform native widgets in
cross-platform widgets.

SWT project also does the same in Java Desktop World. But it never really
became widely used.

------
pabl0rg
Kotlin multi-platform also reuses native Widgets/UI but the DX doesn’t seem
very polished yet.

Does something like this exist in Crystal-lang or Nim? Using native widgets to
do cross-platform is appealing, but C++ ...?

~~~
dom96
For what it's worth, wrapping C++ in Nim is pretty trivial so you could use
this fairly easily with Nim.

------
z3t4
While I do see the potential, most people will probably look at the modest
design example and dismiss it.

------
GutenYe
Is `no JavaScript` a thing now?

~~~
nkozyra
It draws a comparison between electron, probably the leading contemporary
approach for cross platform (albeit not for mobile)

~~~
nicoburns
And ReactNative and Cordova which are probably the leading contemporary
approaches for cross platform mobile.

~~~
YetAnotherNick
I think it's written for ReactNative as no javascript is a strange wording. I
don't care as much for javascript as that for much less responsive webview.

------
setquk
Might want to check the name for trademark violation...

------
blueprint
Can it ensure full access to native SDKs?

~~~
YetAnotherNick
It's open source. You can add any SDK you want. "ensure": no.

------
esokullu
how is this different from qt-mobile?

~~~
rhodysurf
it uses C++ and not QML for the interface, the UI components are actually
native, you can use templates, etc.

~~~
k__
So it's like React-Native, but wirh C++ instead of JS?

~~~
rhodysurf
Yes exactly. If you look at the code, it basically is just using pure virtual
provider classes to allow JNI on android and OBJC++ on iOS to provide the
native system UI components. Its pretty elegant actually.

The only problem becomes that it is a lot of code to manually maintain or
bootstrap. And possibly a decent amount of effort to add new platform widgets,
but I didn't look very deeply into how exactly that would be done.

------
Signez
> Native widgets: Instead of drawing widgets that look nearly identical to the
> platform's design, Boden uses native OEM widgets ensuring that your app will
> always have a truly native look and feel.

While I fully understand the underlying concept, I don’t understand why so
many people seems to be bothered by that anymore; I used to care about that as
an Android user, but most of the apps I use everyday on my phone (Twitter,
Inbox, Slack, Youtube, even Google Photos or Maps) do not seems to use the
pure platform widgets anyway.

~~~
zapzupnz
Native widgets don't just mean "look". They can also mean "feel". This is
particularly true on macOS.

On macOS, I expect certain widgets in order to accomplish certain tasks. I
expect that they will respond to mouseover and button presses in a certain
way. I expect to be able to use certain key combinations to cause certain
widgets to do certain things, I expect keyboard combinations to be able to be
redefined in System Preferences.

On the accessibility front, I expect VoiceOver to be able to read what's on
screen, I expect it to be able to tell me what a widget's behaviour will be, I
expect to be able to get back to where I was using a standard key combo, I
expect images to respect colour inversion settings, I expect text to scale
according to the system's Dynamic Type settings.

When it comes to handling text; I expect fonts to have the system's native
rendering; I expect that Unicode support is complete, I expect macOS' emoji
picker to show up; I expect system-wide text replacements, smart quotes, and
orthography checking to work as expected, I expect selectable text to show a
list of system-wide Services in the context menu, I expect all text to be
draggable and handled correctly by the receiver of the drag action.

There are plenty of other things that I can't think of, but this list could
get quite long. Suffice to say, Apple put a _lot_ of default behaviours into
Cocoa, and apps that (A) don't use Cocoa, or (B) only use Cocoa for drawing
but not inheriting behaviours, they don't just look a bit off, they feel
_wrong_.

I think we may be immune to this to some extent on mobile, and Windows users
haven't known anything other than complete inconsistency, even with
Microsoft's own built-in interfaces. But for some of us, if the interface
feels wrong, the app goes straight into the Trash.

~~~
tom_
The takeaway here is that each OS trains you in its own way to look down at
all those morons using one of the other ones.

~~~
zapzupnz
I don't see that at all. Rather, each OS has its benefits, and if the person
who designs a toolkit doesn't account for them, you wind up with something
middling and foreign that takes advantage of nothing.

For able users, that can come down to minor irritations. For users with
special accessibility requirements, that's downright unacceptable.

If my listing of all the features of macOS might have come off as haughty,
it's simply because I'm one of the ones who has special accessibility
requirements, and the way macOS does things suits me well. Apps that don't use
Cocoa, therefore, can really screw me over.

~~~
mwcampbell
In your experience, how do web applications compare to native Mac apps? Of
course, a web app can be accessible with both VoiceOver and magnification
(based on all the features you listed, I'm guessing you're low-vision). But
are even the most accessible web applications noticeably less efficient for
you than native Cocoa apps?

~~~
zapzupnz
You're correct, I have low vision. Enough to code and read relatively
comfortably, but not for long; so I either make the text enormous or turn on
VoiceOver. Below, I'm talking about macOS; I don't use VoiceOver on iOS.

I tend to find with web apps that they're pretty inaccessible with VoiceOver,
depending on what they were made with. If it's Electron or React Native,
unusable. I just make the text huge. No good for blind users who shouldn't be
left out of the fun, but mightn't even be able to find the voice chat
controls.

Even when I'm not using VoiceOver, web apps tend not to respect system
accessibility settings like text size. When they have them built into the apps
as a setting, that's nice but rarely the case. It would still be better to
respect my accessibility preferences; I don't go to all the trouble of setting
them up for nothing. It's also not like Apple's accessibility APIs have
changed drastically over the years, they're pretty stable. I imagine this to
be the same for Windows.

In websites, it's usually a different matter, sometimes a bit better. In
general, the web version (that is, in a browser) version of a web app is
usable to a greater extent, though that doesn't necessarily mean anything,
because VoiceOver knows how to inspect the DOM — whereas it isn't expecting
that at all with 'native' web apps.

Proper Cocoa apps always win.

~~~
mwcampbell
Interesting. Based on your description, it seems that NVDA on Windows fares
better with Electron apps than does VoiceOver on Mac. NVDA's "browse mode"
features work equally well whether it's Electron, Chrome, or Firefox (and to a
lesser extent in IE and Edge).

In another thread, you wrote that Xcode is the best IDE you've found for Mac
simply because it's native to the Mac. Have you tried Eclipse? Given that
Eclipse's SWT widget toolkit is based largely on native widgets, it might be
native enough. Then again, the editor is custom, so it may still fall short.

I ask you these questions because I'm interested in the perspective of a Mac
user who has apparently learned to make very effective use of multiple Mac
accessibility features.

~~~
zapzupnz
I had to install Java and Eclipse to give it a try just to reply to this
comment.

I never liked Eclipse, it always felt extremely non-native to me. Nothing much
seems to have changed.

Right from the start, the Eclipse Installer (by Oomph, apparently) is a web
app that VoiceOver has difficulty with meaning I have to interact with it
using web navigation controls which is a pain when I'm not expecting it.

The rest of the interface was a bit hit and miss. Either VO could read what
was on screen, or it thought I was looking at a table that apparently had no
elements in it.

Turning VO off and clicking around, still definitely not a native experience,
though better than I remember it. Native-handling of text, access to macOS
Services… but only in certain parts of the program!

After poking around a bit more, it turns out the only places I could get
native handling of text were web views (of which there are many); most text
presents non-native controls to deal with things like copying and pasting,
precluding the ability to use built-in Services.

Besides that, the way the app is designed was just foreign. Non-native
paradigms for presenting information like those tear-off palettes (that turn
into weird, full windows when torn off, rather than inspector palette windows;
if you click the internal (non-macOS) minimize button on one of these windows,
the window itself stays the same size, but the UI inside gets smaller, leaving
this huge empty window with nothing in it.

I was curious to see what VO would say about this window. It was just as
confused as I was, thinking one of the two remaining on-screen buttons was a
checkbox. That's probably how it was implemented internally, but it was
certainly not a checkbox. Once I clicked on the internal restore button, the
rest of the UI came back, but VO couldn't tell me what it was looking at. I
had to Tab around blindly to get to a usable control, and even then, VO
couldn't tell me where it was or in what context.

I couldn't actually create a new project because the "Finish" button, when
creating a project, didn't seem to do anything, either through VO or using the
mouse pointer directly. The button was lit up and coloured as though it were
selectable, it just didn't do anything. So I couldn't actually play with the
IDE itself, but I knew I was done with it.

The design looks and feels like Windows in the late 90s/early 00s, from the
layout of various windows to those weird tear-off sidebar things. I especially
despised the tiny icons that all practically looked the same, conceptually
blurred together, and I couldn't find a clear way to make them bigger. VO saw
each draggable toolbar as separate, making the toolbar at the top
unnecessarily difficulty to navigate. Then those same icons infiltrated the
global menus, making those a mess to wade through.

I'm a great believer that there is absolutely nothing stopping cross-platform
desktop software being a first class citizen on, at the very least, the three
main players: Windows, macOS, and Linux. Sadly, Eclipse, like most Java
software, thinks it can get away with the last common denominator stuff and
force it on other systems. It just makes for a rather unpleasant time, whether
VO is on or not. Native widgets don't make up for non-native design patterns.

Sorry for the novel!

As to NVDA, I expect NVDA uses some heuristics to figure out how to read out
all the myriad types of interfaces there are on Windows. I remember one app
for vision impaired people, I can't remember it's name because I wound up
passing on actually buying it, that basically constantly scanned what was on
screen and made informed guesses. I'd say VoiceOver probably relies more on
well-made apps conforming to system guidelines; if so, it's somewhere between
naïve and brilliant, because I personally favour a system where accessibility
is a first-class citizen, not an afterthought for which we need to call upon
the powers of magic to figure things out.

------
k__
Rust plz.

~~~
rhodysurf
You could make this exact same framework with rust as the backend instead of
C++. I have made a proof of concept MVVM app in rust for iOS and Android.

Instead of binding view models and state you bind the entire platform with
bindings for every widget and control. Its not too much work but it is a lot
of boring code to write and maintain.

~~~
k__
Is this on GH or somewhere? :)

~~~
rhodysurf
Its not a complete product, just an exploration I am not done with but feel
free to look around
[https://github.com/mpiannucci/buoyfinder-v3](https://github.com/mpiannucci/buoyfinder-v3)

Ignore the generator folder haha

------
travisgriggs
“Boden is written in modern C++11 to make development easy...”

They lost me there. I admit I haven’t done any true C++ in the last few years,
bowing at the height of Boost. So I’m curious, did I miss something in the
next chapter of “modern” or perhaps the “11” that suddenly made C++
development “easy”?? It was quite capable for sure, but easy, no. Honestly
curious. Maybe I’m just not a good enough developer. :/

~~~
jhasse
Yes, C++11 added Smart Pointers and Lambdas, which made development a lot
easier, among other stuff.

~~~
77pt77
And threads and locking mechanisms.

And decent date and time management

