Live data from Hacker News

We rewrote the Ghostty GTK application

mitchellh.com

171–180 of 228 posts

Re: We rewrote the Ghostty GTK application

#171
post #23

Earlier quoted context omitted.

Hi @schmichael ;) Rust would've prevented one. The rest Rust wouldn't have prevented since as you already noticed, it was in the boundary layer and semantics of a C API. It would've only been as safe as the Rust wrapper. One argument is that the richer, more proven ecosystem of wrapper libraries may have prevented it versus my DIY wrappers. The one Rust would've prevented was a simple undefined memory access: https:/…

Rust has safe and reliable GTK bindings. They used gir to auto-generate the error-prone parts of the FFI based on schemas and introspection: https://gtk-rs.org/gir/book/ Rust's bindings fully embrace GTK's refcounting, so there's no mismatch in memory management.

But the GTK-rs stuff has already abandoned GTK3. Wait... I guess if the GTK-rs API doesn't change and it just uses GTK4 that's a good way to go? Everyone can install both 3 and 4 on their system and the rust apps will just migrate. Is that how they did it?

Re: We rewrote the Ghostty GTK application

#172

Earlier quoted context omitted.

It doesn't sound like they are talking about invalid states, more like they are taking about the kind of thing that in Rust would be represented by `Option >` or suchlike. Maybe your point is that in Rust much less ceremony is necessary to avoid hitting a null pointer when doing this. But still, in either language it's easy to end up with hard to follow logic when doing this.

not super familiar with Rust but isn't Option just an union type of null and T? I get the language has special semantics for this compared to a union type but it is conceptionally just an union. For example this is something you can do with typescript. function(args: Arguments) { ... } type Arguments = { a: number, b: number } | { a: number, b: string, c: number } the Arguments { a: 1, b: 1, c: 1 } is not representab…

I'm pretty sure they're talking about reference counting that depends on the arguments, not about optional arguments or invalid argument combinations.

Re: We rewrote the Ghostty GTK application

#173

Earlier quoted context omitted.

Titlebars are quite useful, I use them frequently to move, raise, lower, and maximize windows.

Many people use tiling window managers, so title bars become useless. The first thing I did in configuring ghostty was disabling window decoration for this reason.

Probably ten times more people don’t.

Re: We rewrote the Ghostty GTK application

#174

Earlier quoted context omitted.

Slightly unrelated, but I wonder why the "Linux desktop maintainers" (whoever that is - and that this is even a question is probably the main problem) haven't come up yet with a minimal shared 'interface library' that's mandatory on each Linux desktop installation, and which provides a standard API (but no implementation) to create a window, get input events and probably also a set of simple UI widgets (buttons, slid…

I’m not a maintainer, but IMO, it may be the different design systems. Yes there are common elements like buttons and scrolled view. But the whole selling point of a toolkit is consistency, especially around more advanced widgets.

> But the whole selling point of a toolkit is consistency, especially around more advanced widgets.

In theory yeah, but that consistency is out the window anyway when some apps I'm using are GTK, others Qt, and yet others Electron with the JS framework flavour of the week.

A standard shim library which would map to the user's preferred framework (e.g. GTK or Qt) would at least be visually consistent between GTK and Qt - and not just for the window chrome) - even if it only offers a common subset of GTK vs Qt vs ... features.

Re: We rewrote the Ghostty GTK application

#175

Earlier quoted context omitted.

> That lead me to think that GTK and the GObject system is opinionated in a way that are not terribly compatible with my own opinions. This might be amusing for me to say but... I also feel this way. I disagree a lot with the Gnome ecosystem's point of view. Funny! Using GTK for Linux was a pragmatic choice. A goal of Ghostty is to be "platform-native" (defined here because there's no such thing on Linux: https://gho…

> GTK is by various definitions the most popular, widespread GUI toolkit on Linux that makes your app fit into _most_ ecosystems. I disagree. Qt is also quite popular and much better at adapting to the environment it runs in.

Gtk is more than Gnome. It is also used by Xfce and other DEs. So while Qt is also popular, I think it's fair to call it the most popular.

Re: We rewrote the Ghostty GTK application

#176

Earlier quoted context omitted.

> That lead me to think that GTK and the GObject system is opinionated in a way that are not terribly compatible with my own opinions. This might be amusing for me to say but... I also feel this way. I disagree a lot with the Gnome ecosystem's point of view. Funny! Using GTK for Linux was a pragmatic choice. A goal of Ghostty is to be "platform-native" (defined here because there's no such thing on Linux: https://gho…

I like Linux because it gives me the freedom to make my system behave how I want. The GNOME devs seem to think that GNOME should only behave how they want. For example, last time I checked, GNOME required a third-party plugin just to move the clock from the center of the status bar to the side. I'm not at all surprised to see that this mindset extends to GTK.

Gnome shell is designed in a way so that users can configure basically everything using plugins. That way everything does not have to go through the Gnome Shell developers and much more specific and esoteric functionality can be added.

Re: We rewrote the Ghostty GTK application

#177
post #73
post #3

Nice example of how good programming is often about meeting systems where they are: Whatever your feelings are about OOP and memory management, the reality is that if you choose GTK, you're forced into interfacing in some way with the GObject type system. You can't avoid it. Well you can avoid it and we did avoid it. And it leads to a mess trying to tie the lifetimes of your non-reference-counted objects to the refer…

Giving in a bad system is more pragmatic rather than good

Kinda reminds me of a quote attributed to Bjarne Stroustrup:

"There are only two kinds of programming languages: those people always bitch about and those nobody uses"

I feel there are no absolutely "good" systems, only the ones with added compromises over time. Battle scars on a beautiful body.

Re: We rewrote the Ghostty GTK application

#178

Earlier quoted context omitted.

It doesn't sound like they are talking about invalid states, more like they are taking about the kind of thing that in Rust would be represented by `Option >` or suchlike. Maybe your point is that in Rust much less ceremony is necessary to avoid hitting a null pointer when doing this. But still, in either language it's easy to end up with hard to follow logic when doing this.

not super familiar with Rust but isn't Option just an union type of null and T? I get the language has special semantics for this compared to a union type but it is conceptionally just an union. For example this is something you can do with typescript. function(args: Arguments) { ... } type Arguments = { a: number, b: number } | { a: number, b: string, c: number } the Arguments { a: 1, b: 1, c: 1 } is not representab…

> not super familiar with Rust but isn't Option just an union type of null and T?

Only if there is a niche optimization happens if T is never null, otherwise it's a tagged union.

That's not what you're replying to is about.

Re: We rewrote the Ghostty GTK application

#179

Earlier quoted context omitted.

> GTK is by various definitions the most popular, widespread GUI toolkit on Linux that makes your app fit into _most_ ecosystems. I disagree. Qt is also quite popular and much better at adapting to the environment it runs in.

I just use the default terminal, konsole, in kubuntu. Is Ghostty that much better?

No, Konsole is awesome.

Re: We rewrote the Ghostty GTK application

#180
post #15

I haven't worked with GTK, but what you are describing here sounds reminiscent of what we have been dealing with trying to build Godot bindings in Zig with a nice API. the project is in mid-flight, but Godot: - has tons of OOP concepts: classes, virtual methods, properties, signals, etc - a C API to work with all of those concepts, define your own objects, properties, and so on - manages the lifetimes of any engine o…

Thx for the work you're doing! Just out of curiosity, I sometimes struggle to write performant C# Godot code because it's hard to interface with the engine without doing a lot of back and forth conversions to engine types. You end up doing a lot of allocations. Did you run into that kind of stuff while creating your bindings?

My understanding may be out of date, but the C# support was created before GDExtension existed. The team has been working hard on porting it over to GDExtension. Once they are done, it should be much more performant, and they will finally be able to ship only one version of the editor. I believe the original C# bindings do a lot of unnecessary marshaling at the ABI.

With GDExtension, the core builtin types like `Vector3` are passed by value. Avoid unnecessarily wrapping them in Variant, a specialized tagged union, where you can. You can see the documentation here; you have direct access to the float fields: https://gdzig.github.io/gdzig/#gdzig.builtin.vector3.Vector3

Engine objects are passed around as opaque pointers into engine managed memory. The memory for your custom types is managed by you. You allocate the engine object and essentially attach userdata to it, tagged with a unique token provided to your extension. You can see the header functions that manage this: https://github.com/godotengine/godot/blob/e67074d0abe9b69f3d...

But, this is how the lifetimes for the objects gets slightly hairy (for us, the people creating the language bindings). Our goal with the Zig bindings is to make the allocations and lifetimes extremely obvious, a la Zig's philosophy of "No hidden memory allocations". It is proving somewhat challenging, but I think we can get there.

There's still a lot of surprising or unintuitive allocations that can happen when calling into Godot, but we hope to expose those. My current idea is to accept a `GodotAllocator` on those functions (and do nothing with it; just use it to signal the allocation). You can read the code for the `GodotAllocator` implementation: https://github.com/gdzig/gdzig/blob/master/gdzig/heap.zig#L8...

If we succeed, I think Zig can become the best language to write highly performant Godot extensions in.

Post reply on HN