Native applications and fragmentation

IME, GObject code does not lend itself to being either navigable or simulate-able.

2 Likes

Inheritance is not a blessing. C++ hiding the details of VTables and the performance regressions associated with them is just shorthand for bad C programming. There is modularity to be obtained by OOP but it also needs to be done differently. I may be new to Rust but it looks like traits and supertraits build more cleanly than vtable-based inheritance.

As for GUI development, the C interface for user-interfaces in AmigaOS was a C equivalence of SmallTalk called BOOPSI. Its plug-in interface made the Amiga able to develop frameworks just as tight as I’ve seen anywhere on most OS frameworks. It’s tighter and much smaller than any on Linux. C++ hides the inner-workings of Qt the same way Vala hides the inner workings of Gtk.

Whether writing a GUI from scratch or using an editor, I think the best way to implement it under-the-bonnet is to use the simplest type of plug-in work as possible. Avoid multiple layers of inheritance. If the layout engine could be compiled externally to the host programming language that would probably be quickest but a thread-pool to replace indirect recursion in the layout engine would be the next-best thing.

From a user point of view, people are already complaining about Haiku sliders, what should they think about GTK themes? Even if the result is shiny, they are awful to make, are often using engines not really maintained, and you need one for each version of the toolkit… Still, I can’t help myself and prefer the look of GTK apps over Qt ones.

Regarding Windows, several people say users don’t complain about different toolkits being in use. Ok, possibly. But the situation is still pretty bad. Over the years, Windows has accumulated several new ways to program an application, and they never remove the old ones. Even in things shipped with Windows, some were not updated since Windows 95 at least.

I can’t find it anymore, but there was a screenshot showing all the different toolkits in a single screenshot.

The situation is so ridiculous that no one cares anymore. Now, each application will come with its own branding and color scheme, and not use the standard Windows titlebar. Which is fine, because the Windows titlebar does not do a lot anyways: 3 buttons to maximize, close, minimize, and a titlebar you can drag to move the window. So they just gave up on having any kind of standardized look. The situation is similar on mobile phones, where apps will be strongly themed to the brand of their provider. There, they used a design language that’s very easy to adapt to different colors (mostly flat color areas, little to no gradients). But by doing so, they made things less discoverable, you can’t easily see what’s a textfield, or what’s a button.

Compare this to the Haiku one, which implement stack and tile. If someone was to implement their own window decorations in Haiku, Stack and Tile would not work with their app. Probably several keyboard shortcuts to move and resize windows would also not operate as expected, unless painstakingly reimplemented in each application (which would of course lead to larger executables, since the functions can’t be shared with other apps).

So that’s what we’re trying to avoid in Haiku. We would like to have a place where all apps use the same toolkit, and all look and behave the same. It is not an easy goal and it will probably not survive the inflow of ported apps and possibly later of apps developed by other companies who will just bring in their own look and feel and not care about integration with the other parts of the OS. But as a Haiku user, at some point you have to make a compromise: a ported app that doesn’t really fit with the OS is better than no app at all, and is possibly cheaper/easier than writing a new app from scratch (even if other UI toolkits are bad, they are not that bad).

I will not comment about GTK since I never really used it (the closest I got was using GStreamer, which I indeed found confusing and prone to memory leaks). However I have read a lot of MUI code (from Amiga/BOOPSI) which implements objects by using a lot of preprocessor macros, and seems to work reasonably well; and I have also used IUP which is designed for use with Lua but has a C API, in that case, the way to implement objects was by having a key-value attributre system, where the keys are strings. That’s a bit unusual at first, but it turns out it works very well, and provides something that allows for fully dynamic run-time things (you can easily change a callback, add or remove an attribute to an object, etc while the program is running).

Personally I found that at least as good as the C++/BeAPI combo. C being a low-level language opens way for experimenting different ways of doing object-oriented programming. C++ on the other hand forces you to use its own way (static vtables defined at compile time and that can’t be changed, fixed list of attributes, etc). IUP does objects in a similar way to what’s done in Lua (where objects are just a few syntax tricks in the language, and really are just implemented as key-value maps where the values can be attributes or functions). So it’s nice to see different approaches like that, and certainly it wouldn’t happen in the C++ world, because if you are going to ignore the existing classes in C++, why bother using C++?

3 Likes

VTable is just an implementation detail and it got baked in to C++ back in the time when all this was still being designed rather than “best practices”. But why do you need access to the VTable at runtime?

Something like this?

6 Likes

That is still pretty consistent. The main issue is Theme, so colours and Icons are not very consistent. But, every shortcut is always listed to the right, every menu item is to the left, when it opens a sub menu it has a >… I’ve seen much worse in Linux.

Update: and the additional images you added - that is a really old build of Windows 10. I’m on 19042. It changes over time.

More examples here https://www.askvg.com/too-much-inconsistency-in-windows-10-context-menus/

Yes, that’s so true. Just Windows users in the majority don’t care. There is clearly a different mindset to let’s say macOS users. As a maintainer of a Qt application I have seldom heard Windows people complain if things don’t look exactly like other apps. But on macOS users complain on small differences.

Now admittedly Qt does feel more native on Windows and has more small differences to native apps on macOS. But still macOS users (and also Apple) care more deeply about consistent look and feel, while on Windows as long as it is not terrible people seem to accept it :man_shrugging:

1 Like

The typical way to have this in C is using a struct to hold the data and a set of functions that work on this struct. I don’t know the GTK C sources very well, but AFAIK that’s basically how it handles that.

OOP has many shortcomings, but one of the few cases where it really has it’s place is representing a GUI. In all the GUIs you have usually a hierarchical set of objects (buttons, windows, labels etc.) with some properties and things they can perform. Any example of a widely used UI library, that does not work on such objects?

1 Like

My biggest annoyance, is when applications open detached external windows that then have yo be managed.

There’s a few times this is useful, productivity applications like a DAW where you have a multi head system and you can dedicate a screen to your vsti etc. But windows that detach from the application by defualt and exist only to be hidden under a different window, deserve a special place in hell if focus following behaviors are poor.

As to the UI look inconsistency, most people don’t care afaict. What is aggregating is when you have mystery meat navigatons that requires readong a manual to accomplish even basic tasks.

Anything that hampers performance and increases latency generally is rather annoying to

GTK uses GObject, and working with GObject is best left to the Vala compiler or some other code generator that uses GObject introspection.

Just like GObject uses introspection within Vala, some C++ frameworks use syntax candy in their implementations such as operator overloading (aka operator overriding) and inheritance to make bits of code look like a single operation like cin >> varname; and cout << var << endl; that produce a ton of heavy code and buffers on some operating systems and library dependencies on others. Mostly it’s just stuff you’re expected to know about the OS and runtimes along with documented and undocumented “features” about the frameworks themselves.

You cannot seriously compare needing an absurd amount of macros, structures and functions defined in a very strict format in order to extend a class equivalent to C++ operator overloading.

I just did. There may be differences in implementation between frameworks but ultimately macros and templates may make faster code than inheritance in the first place.

GObject does have inheritance and vtables (which every class struct starting from GObjectClass is), and they are implemented similarly to how C++ compilers implement them under-the-hood.

The difference is that C++ is infinitely easier to work with than GObject, at least with hand-written code.

If they are all the same under the hood, the differences are window dressing. Curtains don’t determine the differences between two windows.

If the curtains always get in your way when you’re trying to pull them apart, then it does.

I’m really fighting with myself not to respond to this… You are wrong in what you are concluding, but I don’t think arguing about it will change your opinion, so I will bite my tongue instead.

What I’m concluding is that I like Rust’s implementation of runtime support better than C++ or Vala.