Gtk4DotNet 7.0.33-beta-33

This is a prerelease version of Gtk4DotNet.
There is a newer prerelease version of this package available.
See the version list below for details.
dotnet add package Gtk4DotNet --version 7.0.33-beta-33
                    
NuGet\Install-Package Gtk4DotNet -Version 7.0.33-beta-33
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Gtk4DotNet" Version="7.0.33-beta-33" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Gtk4DotNet" Version="7.0.33-beta-33" />
                    
Directory.Packages.props
<PackageReference Include="Gtk4DotNet" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Gtk4DotNet --version 7.0.33-beta-33
                    
#r "nuget: Gtk4DotNet, 7.0.33-beta-33"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#addin nuget:?package=Gtk4DotNet&version=7.0.33-beta-33&prerelease
                    
Install Gtk4DotNet as a Cake Addin
#tool nuget:?package=Gtk4DotNet&version=7.0.33-beta-33&prerelease
                    
Install Gtk4DotNet as a Cake Tool

Gtk4DotNet

C# .NET 8 bindings for GTK4. You can create programs using the GTK4 UI system as a .NET 8 app.

In the following tutorial are (almost) all examples from the original GTK4 documentation as well as from the GUI development with Rust and GTK 4, all ported to C#. There is a Test project. In the terminal window, you can choose a certain example to run.

Gtk4DotNet uses a functional declarative approach to GTK4 similar to REACT or Kotlin Compose:

return Application
    .New("org.gtk.example")
    .OnActivate(app => 
        app
            .NewWindow()
            .Title("Hello Gtk👍")
            .SideEffect(win => win
            .Child(
                Grid
                    .New()
                    .Attach(                                
                        Button
                            .NewWithLabel("Button 1")
                            .OnClicked(() => WriteLine("Button1 clicked")), 
                        0, 0, 1, 1)
                    .Attach(                                
                        Button
                            .NewWithLabel("Button 2")
                            .OnClicked(() => WriteLine("Button2 clicked")), 
                        1, 0, 1, 1)
                    .Attach(                                
                        Button
                            .NewWithLabel("Quit")
                            .OnClicked(() => win.CloseWindow()), 
                        0, 1, 2, 1)))
            .Show())
    .Run(0, 0);
}

Table of contents

  1. Prerequisites
  2. Hello World (a minimal GTK4 app)
    1. Fluent syntax
    2. Using Adwaita

Prerequisites <a name="prerequisites"></a>

Necessary prerequisites only depending on the version of Linux

On modern Linux like Ubuntu 24.04 or Fedora 40 Gtk4DotNet apps will run out of the box (if you create a full contained single file exe), otherwise you have to install the necessary dotnet runtime.

libadwaita is only necessary if you want to create Adwaita apps, and webkitgtk6 you only need when integrating a webview.

On older/other Linux systems perhaps you have to install one of the following packages in order to make the app runnable.

sudo apt install libgtk-4-dev
sudo apt install libadwaita-1-dev
sudo apt install libwebkitgtk-6.0-dev

For example on Linux Mint 22 you only have to install

sudo apt install libwebkitgtk-6.0-dev

if you want to use webkit webview whereas for KDE neon 6.0 you have to install

sudo apt install libadwaita-1-dev
sudo apt install libwebkitgtk-6.0-dev

The necessary Gtk4DotNet Nuget package <a name="nuget"></a>

To use these features there is a nuget package Gtk4DotNet, which you have to include.

Hello World (a minimal GTK4 app) <a name="helloworld"></a>

In a newly created folder create a new console program with .NET (dotnet new console). Now add the necessary package: dotnet add package Gtk4DotNet.

In the created file Program.cs replace all code with:

using GtkDotNet;

static class First
{
    public static int Run()
    {
        var app = Application.New("de.uriegel.first");
        return app.Run(0, 0);
    }
}

It creates a GTK45 Application object and then runs the message loop. Compile the program and start it. It starts and ends immediately with the warning:

GLib-GIO-WARNING **: 08:27:42.149: Your application does not implement g_application_activate() and has no handlers connected to the 'activate' signal. It should do one of these.

When the app is being activated, you have to implement the activate method. You can do this with a injected C# callback with the help of Application.OnActivate. Let's do this:

    var app = Application.New("de.uriegel.first");  
    app.OnActivate(app => Console.WriteLine("App is being activated"));
    return app.Run(0, 0);

When you debug the program, OnActivate is being called and returns immediately. When app.Run() is being executed, the injected callback is being called and the text is being displayed in the terminal. However, the app also stops immediately. Of cource some kind of UI has to be created.

Let's create a window, this has to be done in the Application.OnActivate callback:

app.OnActivate(app =>
{
    var windows = app.NewWindow();
    windows.Show();
});

Now an empty default window is being shown and the function call Applicatio.Run() will only return when the window is being closed.

custom titlebar

Fluent syntax <a name="fluentsyntax"></a>

To avoid creating many variables only to set them as parameters in a function, Gtk4DotNet uses a functional builder approach to create a complicated ui with fluent syntax. Many setter function returns the same instance, so that builder functions can be assigned in a row.

The above sample can be written using this approach as:

static class First
{
    public static int Run()
        => Application
            .New("de.uriegel.first")
            .OnActivate(app =>
                app
                    .NewWindow()
                        .Show())
            .Run(0, IntPtr.Zero);
}

With this approach the hierarchy of the GTK4 application is being reflected in code.

The Window is very empty. Let's add a title and change the default size:

    .NewWindow()
        .Title("Hello Gtk👍")
        .DefaultSize(600, 200)
        .Show())

Now let's complete our Hello World program with a button and a click handler to maximize the window:

static class HelloWorld
{
    public static int Run()
        => Application
            .NewAdwaita("org.gtk.example")
            .OnActivate(app =>
                app
                    .SideEffect(_ => WriteLine($"Gkt theme: {GtkSettings.GetDefault().ThemeName}"))
                    .NewWindow()
                    .Title("Hello Gtk👍")
                    .DefaultSize(200, 200)
                    .Pipe(w => w.AddActions(
                        [new GtkAction("quit", () => w.SideEffect(_ => WriteLine("Close window from action")).CloseWindow(), "F4")]))
                    .OnClose(_ => false.SideEffect(_ => WriteLine("Window is closing")))
                    .Pipe(w => w
                        .Child(
                            Box
                                .New(Orientation.Vertical)
                                .HAlign(Align.Center)
                                .VAlign(Align.Center)
                                .Append(
                                    Button
                                        .NewWithLabel("Maximize Window")
                                        .OnClicked(() => w.Maximize())
                                        .Tooltip("This is a sample Button\tCtrl-H"))))

                    .Show())
            .AddActions([new GtkAction("appaction", () => WriteLine("appaction"), "F5")])
            .Run(0, IntPtr.Zero);
}

Detailed descriptions of the individual steps will follow in later sections.

Using Adwaita <a name="adwaita"></a>

The above HelloWorld example has another difference to the first ewample:

Application.NewAdwaita("de.uriegel.example") instead of Application.New("de.uriegel.example"). Here a new Adwaita window is being created. Adwaita is the design language of the GNOME desktop environment. It exists as the default theme and icon set of the GNOME Shell. When Adwaita is used, you can see a slightly different and more modern look and feel.

light version dark version

One differnce is a big one: as you can see in the images above, the window theme is adapted from the installed and selected Gnome theme. When a dark theme is selected, the window content uses a dark theme as well. This is not the case with a normal GTK Window.

  • Application.NewAdwaita creates a new Adw.Window
  • This is especially useful with AdwHeaderBar, see later section

Using Layouts and widgets

Lambdas in callbacks

Two convenience functions for extending the fluent syntax are used:

  • SideEffect
  • Pipe

These functions are from the contained nuget package CsTools.

SideEffect is used to return the input parameter but as it is called, it calls a sideeffect function so that you can do soemthing with the object, e.g. log the object state.

Pipe is similar, but it returns the result of the selector function which is being called on function invocation. This is necessary if you need a variable of the object chained though the function calls. In this example Window.Child is beeing called, but not directly but through the Pipe function so that you get an instance of the window object. It is needed in the following lambda that is used as action callback. A GTK Action is defined and on action the window should be closed so a window instance is needed.

// TODO short explanation of the single steps, especially the callback lambdas

// TODO explain static classes Object and ObjectHandle

DEPRECATED Part

Contained in this Repo are samples how to use Gtk4DotNet. All examples of the official GTK4 are transformed to C# with Gtk4DotNet.

If you want to use GTK resources

  • sudo apt install libglib2.0-dev-bin

Installation of GTK Schema

    sudo install -D ./Test/org.gtk.example.gschema.xml /usr/share/glib-2.0/schemas/
    sudo glib-compile-schemas /usr/share/glib-2.0/schemas/

Usage

Look at the sample programs (https://github.com/uriegel/Gtk4DotNet/tree/Main/Test)

Checking if memory is being freed

To check if GObjects are being freed, just run

Widget.AddWeakRef(() => Console.WriteLine("... is being freed));

If this object is finalized, then the callback will be called.

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (3)

Showing the top 3 NuGet packages that depend on Gtk4DotNet:

Package Downloads
WebWindowNetCore

A C# Webview Application for Windows and Linux similar to Electron based on WebView2 (Windows) and GTK WebKit (Linux)

WebWindowNetCore.Linux

A C# Webview Application for Linux similar to Electron based on GTK WebKit

Gtk4DotNet.FSharp

.NET 8 F# Bindings for GTK 4, functional declarative similar to REACT or Kotlin Compose

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
7.0.58-beta-58 132 10 days ago
7.0.57-beta-57 173 15 days ago
7.0.56-beta-56 115 16 days ago
7.0.55-beta-55 112 16 days ago
7.0.54-beta-54 112 16 days ago
7.0.53-beta-53 114 16 days ago
7.0.52-beta-52 74 17 days ago
7.0.51-beta-51 108 17 days ago
7.0.50-beta-50 142 18 days ago
7.0.49-beta-49 148 18 days ago
7.0.48-beta-48 140 18 days ago
7.0.47-beta-47 145 18 days ago
7.0.46-beta-46 145 19 days ago
7.0.45-beta-45 133 19 days ago
7.0.44-beta-44 140 20 days ago
7.0.43-beta-43 139 20 days ago
7.0.42-beta-42 145 22 days ago
7.0.41-beta-41 140 22 days ago
7.0.40-beta-40 115 23 days ago
7.0.39-beta-39 86 23 days ago
7.0.38-beta-38 73 23 days ago
7.0.37-beta-37 68 23 days ago
7.0.36-beta-36 139 25 days ago
7.0.35-beta-35 142 25 days ago
7.0.34-beta-34 137 25 days ago
7.0.33-beta-33 144 a month ago
7.0.32-beta-32 138 a month ago
7.0.31-beta-31 139 a month ago
7.0.30-beta-30 140 a month ago
7.0.29-beta-29 142 a month ago
7.0.28-beta-28 131 a month ago
7.0.27-beta-27 458 a month ago
7.0.26-beta-26 444 a month ago
7.0.25-beta-25 387 a month ago
7.0.24-beta-24 388 a month ago
7.0.23-beta-23 253 a month ago
7.0.22-beta-22 61 a month ago
7.0.21-beta-21 59 a month ago
7.0.20-beta-20 78 a month ago
7.0.19-beta-19 112 a month ago
7.0.18-beta-18 128 a month ago
7.0.17-beta-17 129 a month ago
7.0.16-beta-16 131 a month ago
7.0.15-beta-15 129 a month ago
7.0.14-beta-14 125 a month ago
7.0.13-beta-13 126 a month ago
7.0.12-beta-12 129 a month ago
7.0.11-beta-11 129 a month ago
7.0.10-beta-10 72 a month ago
7.0.9-beta-9 70 a month ago
7.0.8-beta-8 102 a month ago
7.0.7-beta-7 77 2 months ago
7.0.6-beta-6 102 2 months ago
7.0.5-beta-5 90 2 months ago
7.0.4-beta-4 83 2 months ago
7.0.3-beta-3 93 2 months ago
7.0.2-beta-2 87 2 months ago
7.0.1-beta-1 78 2 months ago
7.0.0-beta-0 91 2 months ago
6.8.1 172 2 months ago
6.8.0 95 2 months ago
6.7.1 178 3 months ago
6.7.0 100 3 months ago
6.6.1 94 3 months ago
6.6.0 169 3 months ago
6.5.6 110 3 months ago
6.5.5 184 8 months ago
6.5.4 233 8 months ago
6.5.4-beta6 99 8 months ago
6.5.4-beta5 100 8 months ago
6.5.4-beta4 95 8 months ago
6.5.4-beta3 100 8 months ago
6.5.3 296 8 months ago
6.5.3-beta3 98 8 months ago
6.5.3-beta2 101 8 months ago
6.5.3-beta1 95 8 months ago
6.5.2 151 8 months ago
6.5.1 131 8 months ago
6.5.0 146 8 months ago
6.4.0 150 9 months ago
6.3.0 140 9 months ago
6.2.1 151 9 months ago
6.2.0 132 9 months ago
6.1.3 143 9 months ago
6.1.2 138 9 months ago
6.1.1 127 9 months ago
6.1.0 316 4/29/2024
6.0.0 136 4/27/2024
5.4.0 159 4/20/2024
5.3.11 135 4/20/2024
5.3.10 126 4/20/2024
5.3.9 137 4/19/2024
5.3.8 147 3/26/2024
5.3.7 146 3/13/2024
5.3.6 210 1/20/2024
5.3.5 136 1/20/2024
5.3.4 190 1/7/2024
5.3.3 162 1/3/2024
5.3.2 161 1/2/2024
5.3.1 143 1/2/2024
5.3.0 150 1/2/2024
5.2.0 164 12/22/2023
5.1.0 142 12/22/2023
5.0.0 219 12/14/2023
4.0.0 139 12/13/2023
3.4.0 141 12/10/2023
3.3.1 148 12/10/2023
3.3.0 130 12/10/2023
3.2.0 138 12/9/2023
3.1.1 137 12/9/2023
3.1.0 133 12/9/2023
3.0.0 151 12/9/2023
2.0.0 146 11/28/2023
1.4.0 207 11/17/2023
1.3.3 115 11/16/2023
1.3.2 140 11/16/2023
1.3.1 124 11/16/2023
1.3.0 147 11/16/2023
1.2.1 153 10/29/2023
1.2.0 149 10/22/2023
1.1.0 213 4/24/2023
1.0.0 183 4/23/2023

ListView, ColumnView