Skip to content

pasgtk/pasgobject

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

pasgobject

Pascal bindings for GLib/GObject and GTK4, generated from GObject Introspection (GIR) data.

Repository: https://github.com/pasgtk/pasgobject

License: LGPL 3.0 or later

Successor to: pasgtk4 (no longer maintained)


Overview

pasgobject is a monorepo containing two layers:

gobject/   — GLib and GObject core (hand-written, stable)
gtk4/      — GTK4 bindings (auto-generated from Gtk-4.0.gir)
tools/
  gir2pas/ — GIR-to-Pascal code generator

The gobject/ layer provides the runtime foundation: ownership semantics (Take/Borrow), toggle-ref lifecycle, GValue, GParamSpec, signals with of object callbacks, and subclassing via lazy GType registration.

The gtk4/ layer is generated by gir2pas directly from /usr/share/gir-1.0/Gtk-4.0.gir — 265 classes and 3300+ methods, all with correct transfer semantics and floating-reference handling.


Requirements

Dependency Version Package (Arch)
Free Pascal ≥ 3.2 fpc
GLib / GObject ≥ 2.0 glib2
GTK4 ≥ 4.0 gtk4
Meson ≥ 1.0 meson
# Arch Linux
sudo pacman -S fpc glib2 gtk4 meson

# Debian / Ubuntu
sudo apt install fpc libglib2.0-dev libgtk-4-dev meson

# Fedora
sudo dnf install fpc glib2-devel gtk4-devel meson

Building

meson setup build
ninja -C build
ninja -C build test

Build options:

Option Default Description
build_tests true Build and register test programs
build_examples true Build example programs
build_gtk4 true Build GTK4 layer (skipped if GTK4 not found)
meson setup build -Dbuild_gtk4=false   # GObject only, no GTK4

Quick start — GObject

program HelloGObject;

{$mode objfpc}{$H+}

uses PasGObject, GSignal;

procedure OnNotify(ASender: TGObject; AUserData: Pointer);
begin
  WriteLn('notify fired');
end;

var
  Obj : TGObject;
  CB  : TGSignalCallback;
begin
  g_type_init;

  Obj := TGObject.Create;
  WriteLn(GTypeName(Obj.TypeID_));  { GObject }
  WriteLn(Obj.RefCount);            { 1 }

  CB := @OnNotify;
  SignalConnectMethod(Obj, 'notify', CB, nil);

  Obj.Free;
end.

Compile manually:

fpc -Fugobject/src -Fugobject/src/Internal hello.pas

Quick start — GTK4

program HelloWindow;

{$mode objfpc}{$H+}

uses GObject, GSignal, PasGTK;

type
  TApp = class
    procedure OnActivate(ASender: TGObject; AUserData: Pointer);
    function  Run: Integer;
  private
    FApp : TGtkApplication;
  end;

procedure TApp.OnActivate(ASender: TGObject; AUserData: Pointer);
var
  Win : TGtkApplicationWindow;
  Lbl : TGtkLabel;
begin
  Win := TGtkApplicationWindow.CreateFor(FApp);
  Win.SetTitle('Hello');
  Win.SetDefaultSize(400, 200);
  Lbl := TGtkLabel.NewWithLabel('Hello from Pascal!');
  Win.SetChild(Lbl);
  Win.Present;
end;

function TApp.Run: Integer;
var CB: TGSignalCallback;
begin
  FApp := TGtkApplication.New('org.example.Hello');
  CB   := @Self.OnActivate;
  SignalConnectMethod(FApp, 'activate', CB, nil);
  Result := FApp.Run;
  FApp.Free;
end;

var A: TApp;
begin
  A := TApp.Create;
  A.Run;
  A.Free;
end.

Compile manually:

fpc -Fugobject/src -Fugobject/src/Internal \
    -Fugtk4/src   -Fugtk4/src/Internal     \
    hello_window.pas

Subclassing GObject from Pascal

Derive from TGObject, override TypeName and ClassSetup, and the GType is registered lazily on the first call to TypeID:

type
  TCounter = class(TGObject)
  private
    FValue : Integer;
  protected
    class procedure ClassSetup(AClass: PGObjectClass); override;
    procedure DoGetProp(id: guint; val: TGValue; spec: PGParamSpec); override;
    procedure DoSetProp(id: guint; const val: TGValue; spec: PGParamSpec); override;
  public
    class function TypeName: string; override;  { 'PasCounter' }
  end;

class procedure TCounter.ClassSetup(AClass: PGObjectClass);
begin
  g_object_class_install_property(AClass, 1,
    ParamSpecInt('value', 'Value', 'Counter value',
      Low(Integer), High(Integer), 0,
      G_PARAM_READWRITE or G_PARAM_STATIC_STRINGS));
end;

Ownership semantics (GI spec)

Method GI transfer Behaviour
TGObject.Create Calls g_object_new, owns the result
TGObject.Take(ptr) transfer:full Takes ownership of an existing reference
TGObject.Borrow(ptr) transfer:none Adds a toggle ref; caller keeps their ref

Floating references (GInitiallyUnowned, i.e. all GTK widgets) are sunk automatically in Create and CreateFromHandle via g_object_ref_sink.


Regenerating GTK4 bindings

The files in gtk4/src/ are generated by gir2pas. To regenerate after a GTK update:

ninja -C build tools/gir2pas/gir2pas
./build/tools/gir2pas/gir2pas /usr/share/gir-1.0/Gtk-4.0.gir gtk4/src

gir2pas also works on any other GIR namespace:

./build/tools/gir2pas/gir2pas /usr/share/gir-1.0/Adw-1.gir adw/src

Tests

  gobject/TestGTypes    — type sizes, GType constants, GValue layout
  gobject/TestGObject   — TGObject lifecycle, ref counting, properties
  gobject/TestSignals   — connect/disconnect, block/unblock, method callbacks
  gtk4/TestGtk          — GTK4 GType queries, class hierarchy, TypeID overrides

License

Distributed under the GNU Lesser General Public License, version 3 or any later version.

About

Pascal bindings for GLib/GObject and GTK4, generated from GObject Introspection (GIR)

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Contributors