A set of .NET templates and build utilities for creating GTK4 / Libadwaita applications using Gir.Core and Blueprint UI files.
This project streamlines the development of Gir.Core applications by automating the compilation of Blueprint UI files, managing GResource bundling, and generating C# signal bindings at compile time.
- Automated Blueprint Compilation: MSBuild targets automatically discover and compile
.blpfiles to GTK.uifiles during the build process. - GResource Bundling and Embedding: Compiled UI files are automatically bundled into an
app.gresourcebinary and embedded into the .NET assembly. A runtime helper registers the resource stream with GIO automatically. - Compile-Time Signal Binding: A Roslyn Source Generator parses the generated UI XML and automatically creates strongly-typed C# code to wire GTK signals to your event handlers. This entirely eliminates the need for manual event subscription boilerplate and completely avoids Reflection, making the codebase Native AOT and Trimmer safe.
- Included Templates:
gircore-adw: Full application template with boilerplate for Adw.Application.gircore-adw-window: Item template for adding new GTK Windows to an active project.
To install the templates locally, execute test_and_install.sh
To create a new application, use the gircore-adw template:
dotnet new gircore-adw -n MyGtkApp
cd MyGtkApp
dotnet runTo add a new Window (including its backing C# class and .blp UI file) to an active project:
dotnet new gircore-adw-window -n SettingsWindowWhen you build the project, custom MSBuild targets execute the following workflow:
- Discovers all
**/*.blpfiles in the project. - Compiles them to standard GTK
.uifiles in the intermediate output directory usingblueprint-compiler. - Strips all
<signal>tags from the UI XML that is intended for GTK. This allows us to define signals in Blueprint without crashing GTK'sBuilder, which natively attempts to resolve signals to exported C functions (g_module_symbol). - Generates a
resources.xmlmanifest and runsglib-compile-resourcesto produce anapp.gresourcebundle. - Embeds the generated
app.gresourceinto the final assembly as an<EmbeddedResource>.
At runtime, the WindowBase class and GResourceLoader extract and register the embedded resource stream with GIO before GTK attempts to load the UI files.
The Roslyn generator analyzes the original un-stripped .ui files to handle the signals.
For each Blueprint file that defines a signal:
- The generator identifies the target widget IDs, their GTK class types (e.g.,
GtkButton), signal names, and the requested C# handler names. - It generates a partial class containing a strongly-typed
ConfigureSignals(Gtk.Builder builder)method. - This method uses the parsed class to cast the builder object statically (
as Gtk.Button) and natively binds the event (obj.OnClicked += this.MyHandler), entirely bypassing Reflection. This guarantees optimal performance and strict compatibility with the .NET Trimmer and Native AOT compilers.
To use this functionality, simply inherit from XSTH.Blueprint.Helpers.WindowBase, declare your class as partial, and call ConfigureSignals(Builder) in the constructor. The included templates are already configured to utilize this.
- .NET SDK (defaults to net10.0)
blueprint-compileravailable in your system PATHglib-compile-resourcesavailable in your system PATH- Gir.Core GTK4 and Libadwaita ecosystem packages
- https://github.com/TenderOwl/gircore-blueprint-template While i didn't take anything from them their project still helped me fix some problems
- https://gircore.github.io/ Obviously