apprt/gtk-ng: start basic window

This commit is contained in:
Mitchell Hashimoto
2025-07-16 09:29:33 -07:00
parent bb96388902
commit 3257203b6c
4 changed files with 101 additions and 7 deletions

View File

@ -29,12 +29,14 @@ pub const icon_sizes: []const comptime_int = &.{ 16, 32, 128, 256, 512, 1024 };
/// setup in the build system.
///
/// These will be asserted to exist at runtime.
pub const blueprints: []const struct {
pub const blueprints: []const Blueprint = &.{
.{ .major = 1, .minor = 5, .name = "window" },
};
pub const Blueprint = struct {
major: u16,
minor: u16,
name: []const u8,
} = &.{
.{ .major = 1, .minor = 5, .name = "window" },
};
/// The list of filepaths that we depend on. Used for the build
@ -60,6 +62,33 @@ pub const file_inputs = deps: {
break :deps deps;
};
/// Returns the matching blueprint resource path for the given blueprint
/// definition. This will fail at compile time if the blueprint is not
/// found.
///
/// Must be called at comptime.
pub fn blueprint(comptime bp: Blueprint) [:0]const u8 {
// The comptime block around this whole thing forces an error if
// the caller attempts to call this function at runtime.
comptime {
for (blueprints) |candidate| {
if (candidate.major == bp.major and
candidate.minor == bp.minor and
std.mem.eql(u8, candidate.name, bp.name))
{
return std.fmt.comptimePrint("{s}/ui/{d}.{d}/{s}.ui", .{
prefix,
candidate.major,
candidate.minor,
candidate.name,
});
}
}
@compileError("invalid blueprint");
}
}
pub fn main() !void {
var debug_allocator: std.heap.DebugAllocator(.{}) = .init;
defer _ = debug_allocator.deinit();

View File

@ -5,6 +5,7 @@ const adw = @import("adw");
const gio = @import("gio");
const glib = @import("glib");
const gobject = @import("gobject");
const gtk = @import("gtk");
const build_config = @import("../../../build_config.zig");
const apprt = @import("../../../apprt.zig");
@ -13,6 +14,8 @@ const CoreApp = @import("../../../App.zig");
const configpkg = @import("../../../config.zig");
const Config = configpkg.Config;
const GhosttyWindow = @import("window.zig").GhosttyWindow;
const log = std.log.scoped(.gtk_ghostty_application);
/// The primary entrypoint for the Ghostty GTK application.
@ -380,6 +383,9 @@ pub const GhosttyApplication = extern struct {
Class.parent,
self.as(Parent),
);
const win = GhosttyWindow.new(self);
gtk.Window.present(win.as(gtk.Window));
}
fn finalize(self: *GhosttyApplication) callconv(.C) void {

View File

@ -0,0 +1,59 @@
const std = @import("std");
const adw = @import("adw");
const gobject = @import("gobject");
const gtk = @import("gtk");
const gresource = @import("../build/gresource.zig");
const GhosttyApplication = @import("application.zig").GhosttyApplication;
const log = std.log.scoped(.gtk_ghostty_window);
pub const GhosttyWindow = extern struct {
const Self = @This();
parent_instance: Parent,
pub const Parent = adw.ApplicationWindow;
pub const getGObjectType = gobject.ext.defineClass(Self, .{
.instanceInit = &init,
.classInit = &Class.init,
.parent_class = &Class.parent,
.private = .{ .Type = Private, .offset = &Private.offset },
});
const Private = struct {
_todo: u8 = 0,
var offset: c_int = 0;
};
pub fn new(app: *GhosttyApplication) *Self {
return gobject.ext.newInstance(Self, .{ .application = app });
}
fn init(win: *GhosttyWindow, _: *Class) callconv(.C) void {
gtk.Widget.initTemplate(win.as(gtk.Widget));
}
pub fn as(win: *Self, comptime T: type) *T {
return gobject.ext.as(T, win);
}
pub const Class = extern struct {
parent_class: Parent.Class,
var parent: *Parent.Class = undefined;
pub const Instance = Self;
fn init(class: *Class) callconv(.C) void {
gtk.Widget.Class.setTemplateFromResource(
class.as(gtk.Widget.Class),
comptime gresource.blueprint(.{
.major = 1,
.minor = 5,
.name = "window",
}),
);
}
pub fn as(class: *Class, comptime T: type) *T {
return gobject.ext.as(T, class);
}
};
};

View File

@ -1,8 +1,8 @@
using Gtk 4.0;
using Adw 1;
Adw.Window {
Label {
label: "Hello";
}
template $GhosttyWindow: Adw.ApplicationWindow {
content: Label {
label: "Hello, Ghostty!";
};
}