diff --git a/src/apprt/gtk-ng/class.zig b/src/apprt/gtk-ng/class.zig index c0d3d7c7c..db403610e 100644 --- a/src/apprt/gtk-ng/class.zig +++ b/src/apprt/gtk-ng/class.zig @@ -24,3 +24,45 @@ pub fn unrefLater(obj: anytype) void { } }).callback, obj.as(gobject.Object)); } + +/// Common methods for all GObject classes we create. +pub fn Common( + comptime Self: type, + comptime Private: ?type, +) type { + return struct { + /// Upcast our type to a parent type or interface. This will fail at + /// compile time if the cast isn't 100% safe. For unsafe casts, + /// use `gobject.ext.cast` instead. We don't have a helper for that + /// because its uncommon and unsafe behavior should be noisier. + pub fn as(self: *Self, comptime T: type) *T { + return gobject.ext.as(T, self); + } + + /// Increase the reference count of the object. + pub fn ref(self: *Self) *Self { + return @ptrCast(@alignCast(gobject.Object.ref(self.as(gobject.Object)))); + } + + /// Decrease the reference count of the object. + pub fn unref(self: *Self) void { + gobject.Object.unref(self.as(gobject.Object)); + } + + /// Access the private data of the object. This should be forwarded + /// via a non-pub const usually. + pub const private = if (Private) |P| (struct { + fn private(self: *Self) *P { + return gobject.ext.impl_helpers.getPrivate( + self, + P, + P.offset, + ); + } + }).private else {}; + }; +} + +test { + @import("std").testing.refAllDecls(@This()); +} diff --git a/src/apprt/gtk-ng/class/application.zig b/src/apprt/gtk-ng/class/application.zig index fc6f574d5..da87ad193 100644 --- a/src/apprt/gtk-ng/class/application.zig +++ b/src/apprt/gtk-ng/class/application.zig @@ -20,6 +20,7 @@ const CoreConfig = configpkg.Config; const adw_version = @import("../adw_version.zig"); const gtk_version = @import("../gtk_version.zig"); const ApprtApp = @import("../App.zig"); +const Common = @import("../class.zig").Common; const WeakRef = @import("../weak_ref.zig").WeakRef; const Config = @import("config.zig").Config; const Window = @import("window.zig").Window; @@ -84,7 +85,7 @@ pub const Application = extern struct { /// outside of our own lifecycle and that's okay. config_errors_dialog: WeakRef(ConfigErrorsDialog) = .{}, - var offset: c_int = 0; + pub var offset: c_int = 0; }; /// Creates a new Application instance. @@ -699,21 +700,11 @@ pub const Application = extern struct { return self.private().core_app.alloc; } - pub fn as(app: *Self, comptime T: type) *T { - return gobject.ext.as(T, app); - } - - pub fn unref(self: *Self) void { - gobject.Object.unref(self.as(gobject.Object)); - } - - fn private(self: *Self) *Private { - return gobject.ext.impl_helpers.getPrivate( - self, - Private, - Private.offset, - ); - } + const C = Common(Self, Private); + pub const as = C.as; + pub const ref = C.ref; + pub const unref = C.unref; + const private = C.private; pub const Class = extern struct { parent_class: Parent.Class, diff --git a/src/apprt/gtk-ng/class/config.zig b/src/apprt/gtk-ng/class/config.zig index 68d3d9242..363a2e72e 100644 --- a/src/apprt/gtk-ng/class/config.zig +++ b/src/apprt/gtk-ng/class/config.zig @@ -9,6 +9,7 @@ const configpkg = @import("../../../config.zig"); const CoreConfig = configpkg.Config; const unrefLater = @import("../class.zig").unrefLater; +const Common = @import("../class.zig").Common; const log = std.log.scoped(.gtk_ghostty_config); @@ -66,7 +67,7 @@ pub const Config = extern struct { const Private = struct { config: CoreConfig, - var offset: c_int = 0; + pub var offset: c_int = 0; }; /// Create a new GhosttyConfig from a loaded configuration. @@ -141,25 +142,11 @@ pub const Config = extern struct { ); } - pub fn as(self: *Self, comptime T: type) *T { - return gobject.ext.as(T, self); - } - - pub fn ref(self: *Self) *Self { - return @ptrCast(@alignCast(gobject.Object.ref(self.as(gobject.Object)))); - } - - pub fn unref(self: *Self) void { - gobject.Object.unref(self.as(gobject.Object)); - } - - fn private(self: *Self) *Private { - return gobject.ext.impl_helpers.getPrivate( - self, - Private, - Private.offset, - ); - } + const C = Common(Self, Private); + pub const as = C.as; + pub const ref = C.ref; + pub const unref = C.unref; + const private = C.private; pub const Class = extern struct { parent_class: Parent.Class, diff --git a/src/apprt/gtk-ng/class/config_errors_dialog.zig b/src/apprt/gtk-ng/class/config_errors_dialog.zig index 13cc56026..765f4050f 100644 --- a/src/apprt/gtk-ng/class/config_errors_dialog.zig +++ b/src/apprt/gtk-ng/class/config_errors_dialog.zig @@ -5,6 +5,7 @@ const gtk = @import("gtk"); const gresource = @import("../build/gresource.zig"); const adw_version = @import("../adw_version.zig"); +const Common = @import("../class.zig").Common; const Config = @import("config.zig").Config; const log = std.log.scoped(.gtk_ghostty_config_errors_dialog); @@ -58,7 +59,7 @@ pub const ConfigErrorsDialog = extern struct { const Private = struct { config: ?*Config, - var offset: c_int = 0; + pub var offset: c_int = 0; }; pub fn new(config: *Config) *Self { @@ -129,25 +130,11 @@ pub const ConfigErrorsDialog = extern struct { priv.config = config; } - pub fn as(win: *Self, comptime T: type) *T { - return gobject.ext.as(T, win); - } - - pub fn ref(self: *Self) *Self { - return @ptrCast(@alignCast(gobject.Object.ref(self.as(gobject.Object)))); - } - - pub fn unref(self: *Self) void { - gobject.Object.unref(self.as(gobject.Object)); - } - - fn private(self: *Self) *Private { - return gobject.ext.impl_helpers.getPrivate( - self, - Private, - Private.offset, - ); - } + const C = Common(Self, Private); + pub const as = C.as; + pub const ref = C.ref; + pub const unref = C.unref; + const private = C.private; pub const Class = extern struct { parent_class: Parent.Class, diff --git a/src/apprt/gtk-ng/class/window.zig b/src/apprt/gtk-ng/class/window.zig index f6f71abb7..0eab18ee1 100644 --- a/src/apprt/gtk-ng/class/window.zig +++ b/src/apprt/gtk-ng/class/window.zig @@ -4,6 +4,7 @@ const gobject = @import("gobject"); const gtk = @import("gtk"); const gresource = @import("../build/gresource.zig"); +const Common = @import("../class.zig").Common; const Application = @import("application.zig").Application; const log = std.log.scoped(.gtk_ghostty_window); @@ -22,7 +23,7 @@ pub const Window = extern struct { const Private = struct { _todo: u8, - var offset: c_int = 0; + pub var offset: c_int = 0; }; pub fn new(app: *Application) *Self { @@ -45,17 +46,11 @@ pub const Window = extern struct { ); } - pub fn as(self: *Self, comptime T: type) *T { - return gobject.ext.as(T, self); - } - - fn private(self: *Self) *Private { - return gobject.ext.impl_helpers.getPrivate( - self, - Private, - Private.offset, - ); - } + const C = Common(Self, Private); + pub const as = C.as; + pub const ref = C.ref; + pub const unref = C.unref; + const private = C.private; pub const Class = extern struct { parent_class: Parent.Class,