Dazzle spotlight – Multi Paned and Action Muxing

There really is a lot of code in libdazzle already. So occasionally it makes sense to spotlight some things you might be interested in using.

Action Muxing

Today, while working on various Builder redesigns, I got frustrated with a common downfall of GAction as used in Gtk applications. Say you have a UI split up into two sections: A Header Bar and Content Area. Very typical of a window. But it’s also very typical of an editor where you have the code editor below widgetry describing and performing actions on that view.

The way the GtkActionMuxer works is by following the widget hierarchy to resolve GActions. Since the HeaderBar is a sibling to the content area (and not a direct ancestor) you cannot activate those actions. It would be nice for the muxer to gain more complex support, but until then… Dazzle.

It does what most of us do already, copy the action groups between widgets so they can be activated.

// my_countainer should be either your headerbar or parent of it
// my_view is your view containing the attached action groups
// the mux key is used to remove old action groups
dzl_gtk_widget_mux_action_groups (my_container,
                                  my_view,
                                  "a mux key");

Exciting, I know.

Multi Paned

The number of times I’ve been asked if Gtk has a GtkPaned that can have multiple handles is pretty high. So last year, while working on Builder’s panel engine, I made one. It also gained some new features this week as part of our Builder redesign.

It knows how to handle minimum sizes, natural sizes, expanding, dragging, and lots of other tricky bits. There are lots of really annoying bits about GtkPaned from it’s early days that make it a pain when dealing with window resizes. MultiPaned tries to address many of those and do the right thing by default.

It should be strictly a step up from using GtkPaned of GtkPaned of GtkPaned.

Hello world in a handful of languages

The other day, Sri asked me for a quick Gtk example for a talk. Basically he just needed a window with a header bar. So I put together this repo on github with some examples in a variety of languages. After a few contributions from our community, we have even more examples.

I think it would be neat if people submitted pull requests for more languages. Take a peek and see if something you know about is missing. Ideally the example should use GtkApplication, Gtk templates (and resources if possible), and a window with a header bar.

Having these available will make it easier for me to make templates in Builder for more exotic languages.

Library Documentation

Now that gtk-doc is getting updates and integration with Meson, I decided to give it another shot. So here is some work-in-progress documentation for libdazzle, template-glib, and jsonrpc-glib.

There is plenty of work to do, but this makes it easier for others to come along and help me do the hard part, the documentation.

I’m sort of impressed, in hindsight, at the staggering amount of things we’ve built around Builder in the last couple of years.

This week in Builder

Given the success of this pattern of project-related updates in Gtk, maybe we can try to do this for Builder too. We’ve had lots of updates this past week in Builder and related projects.

  • Builder has switched to meson for building Builder. Autotools has been removed. This does NOT affect build systems supported by Builder.
  • Non-builder related widgets and utilities have moved into libdazzle. Roughly 50k fewer lines of code in Builder.
  • template-glib and jsonrpc-glib are now external projects. Our meson-based build system will automatically install them if necessary.
  • libdazzle’s DzlApplication now handles theme loading, menu merging, and icon loading. It also simplifies widget theming for non-Adwaita themes.
  • Builder’s panel engine was revamped and moved to libdazzle. Various CSS fallbacks were added, including Arc theme.
  • New releases (3.25.2) of gnome-builder, template-glib, jsonrpc-glib, and libdazzle.
  • Builder has switched to DzlSuggestionEntry for search. This design is not final by any means, so I expect further changes.
  • Shortcut engine development continues.
  • libdazzle’s fuzzy search has been vastly improved, while keeping overhead low.
  • Lots of widgets have been moved into libdazzle.
    • DzlThreeGrid — This is a three-column layout (with centered column) and rows.
    • Preferences ­— Copy the Builder style preferences in your app
    • Menu merging — Automatic menus.ui merging and management, handy for plugins.
    • StackList — Make your list boxes fly around
    • CPU graphs
    • Panels
    • MultiPaned — No more nested GtkPaned, deals with resizing, expanding, min and natural sizes appropriately.
    • RadioBox — Fancy joined buttons that act like radio boxes. Easily extendable for dynamic content.
    • Empty State ­— Your standard empty state helper
    • Progress Buttons — Both GNOME Software and Epiphany style animated download buttons.
    • Chromium and Firefox web-browser style auto-completion.
    • Lazy Tree Builders — These really simplify building large tree views with dynamic content.
    • Lots of utilities, data structures, and miscellaneous library glue.
  • A whole bunch of tests have been added to libdazzle. More are always needed.

If you’d like to help with the development of Builder or any of it’s associated libraries, come join us in #gnome-builder on irc.gnome.org.

3.26 Developments

My approach to development can often differ from my peers. I prefer to spend the early phase of a cycle doing lots of prototypes of various features we plan to implement. That allows me to have the confidence necessary to know early in the cycle what I can finish and where to ask for help.

We have some big stuff coming this cycle.

Panel Engine Revamp

Allan has been working on some major design work in how our panels and documents work. This has been needed for some time and things are looking good. To keep up with this, I’ve been doing some major improvements to panel-gtk, our panel engine. I managed to shake out a few bugs in the process and those fixes have made their way into the gnome-builder-3-24 branch.

The test program is not much to look at, but we have some necessary plumbing in place to do new things.

Shortcut Engine and Key Themes

Furthermore, I’ve been building a new shortcut engine to do the more advanced features we need. Gtk Shortcut Engine (GSE) provides plumbing for applications that need complex features such as multi-key “chords”, keyboard themes, and custom overrides by users. Many of you have asked for this in Builder, and I’m confident in saying it is coming for 3.26. You can find the work in progress in the shortcut-engine repository.

Ultimately I had to import a copy of the upstream’d GtkShortcutsWindow (based on what we wrote for Builder in 3.20) so that we could support chords. So the code-base looks bigger than it really is. The primary design (besides the keyboard themes) is the concept of a GseShortcutController and GseShortcutContext. These two things allow us to do some fun stuff like emacs-style “minor modes” as well as Vim-style modal keybindings.

I expect this to allow us to cleanup our Vim emulation quite a bit. It also solves some of our outstanding problems with keyboard shortcuts and unpredictable GAction activation. It’s really quite fundamental to how you’ll be interacting with Builder from a keyboard going forward.

Debugger

The big feature for 3.26 is the debugger. I have enough of a working prototype in place to have a reasonably good idea of what the moving parts are. As soon as we land the new shortcut engine and some of the panel updates I’ll be back finishing up that feature.

That’s it for now!

Rust’ic GNOME, Day 3

Today is day 3 of the GNOME+Rust hackfest in Mexico City at the beautiful new Red Hat office. We’ve been working on all sorts of stuff since we were graced with the presence of a few Rust hackers from Mozilla Research.

In particular, Niko and Federico have been working on a GObject plugin for Rust that allows us to have a nice, almost Vala-esque, syntax for writing GObjects. It’s pretty exciting to watch a compiler hacker at work. After lots of talks about GObject design internals, performance hacks, re-entrancy protections, and more, I think we’re headed down a solid path to enabling our Object Oriented style of development, but from Rust.

In addition to playing the code historian, I spent some time trying to get Builder’s support for the Rust Language Server up to snuff. It’s still a bit annoying to get rls installed¹, but it sounds like RustUp will support it soon which means we can make it seamless. Anyway, I fixed a bunch of little bugs that cropped up in the recent months as both Builder and rls projects churned like crazy.

I also implemented support for “Find all References” last night. In a Rust document, just Constrol+Shift+Space to get the list of references, followed by up/down, and return to jump. I’d like the IdeSymbolResolver’s for Clang and Vala to support this soon too.

¹ To install rls, start by installing the nightly toolchain from Builder’s Preferences → SDKs. If you’ve not done this before, you’ll need to first click the “Install” button for RustUp. Then add a new Rust Toolchain called “nightly” and set it as the default. Clone the rls repository and run ~/.cargo/bin/cargo install from within that project. The good news is we should be able to simplify this quite a bit in the near future.

Builder 3.24

I’m excited to announce that Builder 3.24 is here and ready for you to play with!

It should look familiar because most of the work this cycle was underneath the hood. I’m pretty happy with all the stabilization efforts from the past couple of weeks. I’d like to give a special thanks to everyone who took the time to file bugs, some of whom also filed patches.

With Outreachy and GSoC starting soon, I’m hoping that this will help reduce any difficulty for newcomers to start contributing to GNOME applications. I expect we’ll continue to polish that experience for our next couple of patch releases.

Under the hood: Runtimes

Now that 3.24 is almost here, I want to take a little downtime and write some information about pieces of the design underneath Builder. Today, let’s lift the hood and take a look at Runtimes.

In Builder, an IdeRuntime is an abstraction around an environment to run programs. That could be build tooling, SDK management, your application, unit tests, and more. Unsurprisingly, it’s naming is similar to Flatpak runtimes because they have a very 1:1 relationship in the Flatpak plugin. But it’s not an uncommon term by any means.

Today, Builder supports 3 types of runtimes: host, jhbuild, and flatpak.

The host runtime simply executes processes on the host system. This is as close to if you just opened a shell with gnome-terminal as we can give you. We actually go through great pains to do so when the application is distributed via Flatpak. For example, we use the HostCommand² developer-mode interface of Flatpak to execute the subprocess from the host session¹ yet using a PTY master/slave from within the sandbox.

The jhbuild runtime is similar to the host runtime except that we first enter the jhbuild environment using jhbuild run. This ensures that we are using dependencies that you may have built locally. Psuedo terminals are also run this way, so ctrl+alt+shift+t will naturally give you the equivalent of jhbuild shell inside a new embedded terminal.

The flatpak runtime uses flatpak build to enter the runtime environment. Our build pipeline will have had to advance to the point at least the IDE_BUILD_PHASE_PREPARE phase to ensure that the manifest and build directories are setup. So there is just a bit extra complexity involved here. But the result is pretty nice. Your subprocess will see /usr, /app and such just like during the application build process. This makes exploring the build environment very simple. Just open a new terminal with ctrl+alt+shift+t.

Running your application naturally uses runtimes too. This allows us to setup the environment, DBus, network namespaces, Wayland access, and more in the way your application needs. We use information from the build configuration (such as your org.gnome.Foo.json flatpak manifest) to determine what that is.

So what’s next?

I’m relatively happy with this design so far and I think it could work for a few more scenarios. One might be a runtime accessible via adb to your phone. Or possibly a remote container. Or far more interesting to me, inside a GNOME virtual machine providing a simulator with GNOME continuous.

Until next time…

  1. Obviously this means Builder has a more relaxed sandboxing story than a general purpose application. This comes with the territory of developer tooling of this magnitude.
  2. If you want to see this feature land in MonoDevelop/Xamarin Studio, go help fix https://github.com/mono/dbus-sharp/issues/57

Simplifying newcomer setup

One thing we are striving for in 3.24 is to make it as simple as possible for newcomers to get their development environment setup. Hopefully in time so that our next round of Outreachy and GSoC interns have an easier time getting started.

A common installation issue we’ve seen is that people have flatpak, but not flatpak-builder. Without it, Builder can’t do builds inside of the target mount namespace with all your proper dependencies. So now Builder will detect this and install it for you if you like.