mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-09-05 19:08:17 +00:00
gtk: the Future is Now
This commit is contained in:
14
.github/workflows/test.yml
vendored
14
.github/workflows/test.yml
vendored
@@ -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
|
||||
|
@@ -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
|
||||
|
||||
|
@@ -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
|
||||
|
@@ -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.
|
||||
|
@@ -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" },
|
||||
),
|
||||
|
@@ -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");
|
||||
}
|
@@ -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
|
@@ -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" },
|
||||
),
|
||||
|
@@ -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" },
|
||||
|
@@ -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
|
||||
|
@@ -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,
|
||||
},
|
||||
};
|
||||
|
@@ -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);
|
||||
|
@@ -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" },
|
||||
),
|
||||
|
@@ -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
|
||||
|
@@ -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" },
|
||||
),
|
||||
|
@@ -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" },
|
||||
),
|
||||
|
@@ -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},
|
||||
|
@@ -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" },
|
||||
),
|
||||
|
@@ -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
|
||||
|
Reference in New Issue
Block a user