gtk: the Future is Now

This commit is contained in:
Leah Amelia Chen
2025-09-05 10:07:36 +02:00
parent ac52af27d3
commit 93debc439c
77 changed files with 52 additions and 52 deletions

View File

@@ -22,7 +22,7 @@ jobs:
- build-macos-matrix
- build-windows
- test
- test-gtk-ng
- test-gtk
- test-sentry-linux
- test-macos
- pinact
@@ -491,14 +491,14 @@ jobs:
- name: test
run: nix develop -c zig build -Dapp-runtime=none test
- name: Test GTK-NG Build
run: nix develop -c zig build -Dapp-runtime=gtk-ng -Demit-docs -Demit-webdata
- name: Test GTK Build
run: nix develop -c zig build -Dapp-runtime=gtk -Demit-docs -Demit-webdata
# This relies on the cache being populated by the commands above.
- name: Test System Build
run: nix develop -c zig build --system ${ZIG_GLOBAL_CACHE_DIR}/p
test-gtk-ng:
test-gtk:
strategy:
fail-fast: false
matrix:
@@ -534,7 +534,7 @@ jobs:
run: |
nix develop -c \
zig build \
-Dapp-runtime=gtk-ng \
-Dapp-runtime=gtk \
-Dgtk-x11=${{ matrix.x11 }} \
-Dgtk-wayland=${{ matrix.wayland }} \
test
@@ -543,7 +543,7 @@ jobs:
run: |
nix develop -c \
zig build \
-Dapp-runtime=gtk-ng \
-Dapp-runtime=gtk \
-Dgtk-x11=${{ matrix.x11 }} \
-Dgtk-wayland=${{ matrix.wayland }}
@@ -1011,7 +1011,7 @@ jobs:
cd $GITHUB_WORKSPACE
zig build test
- name: Build GTK-NG app runtime
- name: Build GTK app runtime
shell: freebsd {0}
run: |
cd $GITHUB_WORKSPACE

View File

@@ -15,7 +15,7 @@ A file for [guiding coding agents](https://agents.md/).
- Shared Zig core: `src/`
- C API: `include/ghostty.h`
- macOS app: `macos/`
- GTK (Linux and FreeBSD) app: `src/apprt/gtk-ng`
- GTK (Linux and FreeBSD) app: `src/apprt/gtk`
## macOS App

View File

@@ -118,7 +118,7 @@
/pkg/harfbuzz/ @ghostty-org/font
# GTK
/src/apprt/gtk-ng/ @ghostty-org/gtk
/src/apprt/gtk/ @ghostty-org/gtk
/src/os/cgroup.zig @ghostty-org/gtk
/src/os/flatpak.zig @ghostty-org/gtk
/dist/linux/ @ghostty-org/gtk

View File

@@ -16,7 +16,7 @@ const structs = @import("apprt/structs.zig");
pub const action = @import("apprt/action.zig");
pub const ipc = @import("apprt/ipc.zig");
pub const gtk_ng = @import("apprt/gtk-ng.zig");
pub const gtk = @import("apprt/gtk.zig");
pub const none = @import("apprt/none.zig");
pub const browser = @import("apprt/browser.zig");
pub const embedded = @import("apprt/embedded.zig");
@@ -42,7 +42,7 @@ pub const SurfaceSize = structs.SurfaceSize;
pub const runtime = switch (build_config.artifact) {
.exe => switch (build_config.app_runtime) {
.none => none,
.@"gtk-ng" => gtk_ng,
.gtk => gtk,
},
.lib => embedded,
.wasm_module => browser,
@@ -60,13 +60,13 @@ pub const Runtime = enum {
/// GTK4. Rich windowed application. This uses a full GObject-based
/// approach to building the application.
@"gtk-ng",
gtk,
pub fn default(target: std.Target) Runtime {
return switch (target.os.tag) {
// The Linux and FreeBSD default is GTK because it is a full
// featured application.
.linux, .freebsd => .@"gtk-ng",
.linux, .freebsd => .gtk,
// Otherwise, we do NONE so we don't create an exe and we create
// libghostty. On macOS, Xcode is used to build the app that links
// to libghostty.

View File

@@ -542,7 +542,7 @@ pub const InitialSize = extern struct {
/// Make this a valid gobject if we're in a GTK environment.
pub const getGObjectType = switch (build_config.app_runtime) {
.@"gtk-ng" => @import("gobject").ext.defineBoxed(
.gtk => @import("gobject").ext.defineBoxed(
InitialSize,
.{ .name = "GhosttyApprtInitialSize" },
),

View File

@@ -1,15 +1,15 @@
const internal_os = @import("../os/main.zig");
// The required comptime API for any apprt.
pub const App = @import("gtk-ng/App.zig");
pub const Surface = @import("gtk-ng/Surface.zig");
pub const App = @import("gtk/App.zig");
pub const Surface = @import("gtk/Surface.zig");
pub const resourcesDir = internal_os.resourcesDir;
// The exported API, custom for the apprt.
pub const class = @import("gtk-ng/class.zig");
pub const WeakRef = @import("gtk-ng/weak_ref.zig").WeakRef;
pub const class = @import("gtk/class.zig");
pub const WeakRef = @import("gtk/weak_ref.zig").WeakRef;
test {
@import("std").testing.refAllDecls(@This());
_ = @import("gtk-ng/ext.zig");
_ = @import("gtk/ext.zig");
}

View File

@@ -14,10 +14,10 @@ pub const app_id = "com.mitchellh.ghostty";
/// The path to the Blueprint files. The folder structure is expected to be
/// `{version}/{name}.blp` where `version` is the major and minor
/// minimum adwaita version.
pub const ui_path = "src/apprt/gtk-ng/ui";
pub const ui_path = "src/apprt/gtk/ui";
/// The path to the CSS files.
pub const css_path = "src/apprt/gtk-ng/css";
pub const css_path = "src/apprt/gtk/css";
/// The possible icon sizes we'll embed into the gresource file.
/// If any size doesn't exist then it will be an error. We could

View File

@@ -39,13 +39,13 @@ pub const Clipboard = enum(Backing) {
// Our backing isn't is as small as we can in Zig, but a full
// C int if we're binding to C APIs.
const Backing = switch (build_config.app_runtime) {
.@"gtk-ng" => c_int,
.gtk => c_int,
else => u2,
};
/// Make this a valid gobject if we're in a GTK environment.
pub const getGObjectType = switch (build_config.app_runtime) {
.@"gtk-ng" => @import("gobject").ext.defineEnum(
.gtk => @import("gobject").ext.defineEnum(
Clipboard,
.{ .name = "GhosttyApprtClipboard" },
),
@@ -74,7 +74,7 @@ pub const ClipboardRequest = union(ClipboardRequestType) {
/// Make this a valid gobject if we're in a GTK environment.
pub const getGObjectType = switch (build_config.app_runtime) {
.@"gtk-ng" => @import("gobject").ext.defineBoxed(
.gtk => @import("gobject").ext.defineBoxed(
ClipboardRequest,
.{ .name = "GhosttyClipboardRequest" },
),

View File

@@ -111,7 +111,7 @@ pub const Message = union(enum) {
/// Make this a valid gobject if we're in a GTK environment.
pub const getGObjectType = switch (build_config.app_runtime) {
.@"gtk-ng",
.gtk,
=> @import("gobject").ext.defineBoxed(
ChildExited,
.{ .name = "GhosttyApprtChildExited" },

View File

@@ -3,7 +3,7 @@ const GhosttyI18n = @This();
const std = @import("std");
const builtin = @import("builtin");
const Config = @import("Config.zig");
const gresource = @import("../apprt/gtk-ng/build/gresource.zig");
const gresource = @import("../apprt/gtk/build/gresource.zig");
const internal_os = @import("../os/main.zig");
const domain = "com.mitchellh.ghostty";
@@ -80,7 +80,7 @@ fn createUpdateStep(b: *std.Build) !*std.Build.Step {
inline for (gresource.blueprints) |blp| {
const path = std.fmt.comptimePrint(
"src/apprt/gtk-ng/ui/{[major]}.{[minor]}/{[name]s}.blp",
"src/apprt/gtk/ui/{[major]}.{[minor]}/{[name]s}.blp",
blp,
);
// The arguments to xgettext must be the relative path in the build root
@@ -105,7 +105,7 @@ fn createUpdateStep(b: *std.Build) !*std.Build.Step {
}
var gtk_dir = try b.build_root.handle.openDir(
"src/apprt/gtk-ng",
"src/apprt/gtk",
.{ .iterate = true },
);
defer gtk_dir.close();
@@ -138,7 +138,7 @@ fn createUpdateStep(b: *std.Build) !*std.Build.Step {
);
for (gtk_files.items) |item| {
const path = b.pathJoin(&.{ "src/apprt/gtk-ng", item });
const path = b.pathJoin(&.{ "src/apprt/gtk", item });
// The arguments to xgettext must be the relative path in the build root
// or the resulting files will contain the absolute path. This will
// cause a lot of churn because not everyone has the Ghostty code

View File

@@ -550,7 +550,7 @@ pub fn add(
switch (self.config.app_runtime) {
.none => {},
.@"gtk-ng" => try self.addGtkNg(step),
.gtk => try self.addGtkNg(step),
}
}
@@ -701,11 +701,11 @@ pub fn gtkNgDistResources(
resources_c: DistResource,
resources_h: DistResource,
} {
const gresource = @import("../apprt/gtk-ng/build/gresource.zig");
const gresource = @import("../apprt/gtk/build/gresource.zig");
const gresource_xml = gresource_xml: {
const xml_exe = b.addExecutable(.{
.name = "generate_gresource_xml",
.root_source_file = b.path("src/apprt/gtk-ng/build/gresource.zig"),
.root_source_file = b.path("src/apprt/gtk/build/gresource.zig"),
.target = b.graph.host,
});
const xml_run = b.addRunArtifact(xml_exe);
@@ -713,7 +713,7 @@ pub fn gtkNgDistResources(
// Run our blueprint compiler across all of our blueprint files.
const blueprint_exe = b.addExecutable(.{
.name = "gtk_blueprint_compiler",
.root_source_file = b.path("src/apprt/gtk-ng/build/blueprint.zig"),
.root_source_file = b.path("src/apprt/gtk/build/blueprint.zig"),
.target = b.graph.host,
});
blueprint_exe.linkLibC();
@@ -778,11 +778,11 @@ pub fn gtkNgDistResources(
return .{
.resources_c = .{
.dist = "src/apprt/gtk-ng/ghostty_resources.c",
.dist = "src/apprt/gtk/ghostty_resources.c",
.generated = resources_c,
},
.resources_h = .{
.dist = "src/apprt/gtk-ng/ghostty_resources.h",
.dist = "src/apprt/gtk/ghostty_resources.h",
.generated = resources_h,
},
};

View File

@@ -7,8 +7,8 @@ const internal_os = @import("../os/main.zig");
const xev = @import("../global.zig").xev;
const renderer = @import("../renderer.zig");
const gtk_version = @import("../apprt/gtk-ng/gtk_version.zig");
const adw_version = @import("../apprt/gtk-ng/adw_version.zig");
const gtk_version = @import("../apprt/gtk/gtk_version.zig");
const adw_version = @import("../apprt/gtk/adw_version.zig");
pub const Options = struct {};
@@ -38,7 +38,7 @@ pub fn run(alloc: Allocator) !u8 {
try stdout.print(" - font engine : {}\n", .{build_config.font_backend});
try stdout.print(" - renderer : {}\n", .{renderer.Renderer});
try stdout.print(" - libxev : {s}\n", .{@tagName(xev.backend)});
if (comptime build_config.app_runtime == .@"gtk-ng") {
if (comptime build_config.app_runtime == .gtk) {
if (comptime builtin.os.tag == .linux) {
const kernel_info = internal_os.getKernelInfo(alloc);
defer if (kernel_info) |k| alloc.free(k);

View File

@@ -7149,7 +7149,7 @@ pub const GtkTitlebarStyle = enum(c_int) {
tabs,
pub const getGObjectType = switch (build_config.app_runtime) {
.@"gtk-ng" => @import("gobject").ext.defineEnum(
.gtk => @import("gobject").ext.defineEnum(
GtkTitlebarStyle,
.{ .name = "GhosttyGtkTitlebarStyle" },
),
@@ -7717,7 +7717,7 @@ pub const WindowDecoration = enum(c_int) {
/// Make this a valid gobject if we're in a GTK environment.
pub const getGObjectType = switch (build_config.app_runtime) {
.@"gtk-ng" => @import("gobject").ext.defineEnum(
.gtk => @import("gobject").ext.defineEnum(
WindowDecoration,
.{ .name = "GhosttyConfigWindowDecoration" },
),

View File

@@ -1266,7 +1266,7 @@ pub fn SplitTree(comptime V: type) type {
/// Make this a valid gobject if we're in a GTK environment.
pub const getGObjectType = switch (build_config.app_runtime) {
.@"gtk-ng" => @import("gobject").ext.defineBoxed(
.gtk => @import("gobject").ext.defineBoxed(
Self,
.{
// To get the type name we get the non-qualified type name

View File

@@ -59,7 +59,7 @@ pub const DesiredSize = struct {
/// Make this a valid gobject if we're in a GTK environment.
pub const getGObjectType = switch (build_config.app_runtime) {
.@"gtk-ng" => @import("gobject").ext.defineBoxed(
.gtk => @import("gobject").ext.defineBoxed(
DesiredSize,
.{ .name = "GhosttyFontDesiredSize" },
),

View File

@@ -744,7 +744,7 @@ pub const Action = union(enum) {
/// Make this a valid gobject if we're in a GTK environment.
pub const getGObjectType = switch (build_config.app_runtime) {
.@"gtk-ng" => @import("gobject").ext.defineBoxed(
.gtk => @import("gobject").ext.defineBoxed(
Action,
.{ .name = "GhosttyBindingAction" },
),

View File

@@ -165,7 +165,7 @@ pub fn surfaceInit(surface: *apprt.Surface) !void {
else => @compileError("unsupported app runtime for OpenGL"),
// GTK uses global OpenGL context so we load from null.
apprt.gtk_ng,
apprt.gtk,
=> try prepareContext(null),
apprt.embedded => {
@@ -200,7 +200,7 @@ pub fn threadEnter(self: *const OpenGL, surface: *apprt.Surface) !void {
switch (apprt.runtime) {
else => @compileError("unsupported app runtime for OpenGL"),
apprt.gtk_ng => {
apprt.gtk => {
// GTK doesn't support threaded OpenGL operations as far as I can
// tell, so we use the renderer thread to setup all the state
// but then do the actual draws and texture syncs and all that
@@ -222,7 +222,7 @@ pub fn threadExit(self: *const OpenGL) void {
switch (apprt.runtime) {
else => @compileError("unsupported app runtime for OpenGL"),
apprt.gtk_ng => {
apprt.gtk => {
// We don't need to do any unloading for GTK because we may
// be sharing the global bindings with other windows.
},
@@ -237,7 +237,7 @@ pub fn displayRealized(self: *const OpenGL) void {
_ = self;
switch (apprt.runtime) {
apprt.gtk_ng => prepareContext(null) catch |err| {
apprt.gtk => prepareContext(null) catch |err| {
log.warn(
"Error preparing GL context in displayRealized, err={}",
.{err},

View File

@@ -49,7 +49,7 @@ pub const MouseShape = enum(c_int) {
/// Make this a valid gobject if we're in a GTK environment.
pub const getGObjectType = switch (build_config.app_runtime) {
.@"gtk-ng" => @import("gobject").ext.defineEnum(
.gtk => @import("gobject").ext.defineEnum(
MouseShape,
.{ .name = "GhosttyMouseShape" },
),

View File

@@ -143,8 +143,8 @@
fun:g_main_context_dispatch_unlocked
fun:g_main_context_iterate_unlocked.isra.0
fun:g_main_context_iteration
fun:apprt.gtk-ng.class.application.Application.run
fun:apprt.gtk-ng.App.run
fun:apprt.gtk.class.application.Application.run
fun:apprt.gtk.App.run
fun:main_ghostty.main
fun:callMain
fun:callMainWithArgs
@@ -177,8 +177,8 @@
fun:g_main_context_dispatch_unlocked
fun:g_main_context_iterate_unlocked.isra.0
fun:g_main_context_iteration
fun:apprt.gtk-ng.class.application.Application.run
fun:apprt.gtk-ng.App.run
fun:apprt.gtk.class.application.Application.run
fun:apprt.gtk.App.run
fun:main_ghostty.main
fun:callMain
fun:callMainWithArgs