mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-19 10:16:12 +03:00
apprt/gtk-ng: extract common methods into a mixin
Every GObject class we're ever going to make has the same handful of methods. This adds *just enough* noise to be annoying. This commit extracts the common ones so far into a central mixin. Since Zig is removing `usingnamespace` and has no other mixin mechanism, we must forward the decls, but this is still cleaner imo than what we did before. I suspect longer term we can probably abstract more of the `zig-gobject` boilerplate into a higher level abstraction but I'm not confident doing that yet across the 4 classes we have so far.
This commit is contained in:
@ -24,3 +24,45 @@ pub fn unrefLater(obj: anytype) void {
|
|||||||
}
|
}
|
||||||
}).callback, obj.as(gobject.Object));
|
}).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());
|
||||||
|
}
|
||||||
|
@ -20,6 +20,7 @@ const CoreConfig = configpkg.Config;
|
|||||||
const adw_version = @import("../adw_version.zig");
|
const adw_version = @import("../adw_version.zig");
|
||||||
const gtk_version = @import("../gtk_version.zig");
|
const gtk_version = @import("../gtk_version.zig");
|
||||||
const ApprtApp = @import("../App.zig");
|
const ApprtApp = @import("../App.zig");
|
||||||
|
const Common = @import("../class.zig").Common;
|
||||||
const WeakRef = @import("../weak_ref.zig").WeakRef;
|
const WeakRef = @import("../weak_ref.zig").WeakRef;
|
||||||
const Config = @import("config.zig").Config;
|
const Config = @import("config.zig").Config;
|
||||||
const Window = @import("window.zig").Window;
|
const Window = @import("window.zig").Window;
|
||||||
@ -84,7 +85,7 @@ pub const Application = extern struct {
|
|||||||
/// outside of our own lifecycle and that's okay.
|
/// outside of our own lifecycle and that's okay.
|
||||||
config_errors_dialog: WeakRef(ConfigErrorsDialog) = .{},
|
config_errors_dialog: WeakRef(ConfigErrorsDialog) = .{},
|
||||||
|
|
||||||
var offset: c_int = 0;
|
pub var offset: c_int = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Creates a new Application instance.
|
/// Creates a new Application instance.
|
||||||
@ -699,21 +700,11 @@ pub const Application = extern struct {
|
|||||||
return self.private().core_app.alloc;
|
return self.private().core_app.alloc;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as(app: *Self, comptime T: type) *T {
|
const C = Common(Self, Private);
|
||||||
return gobject.ext.as(T, app);
|
pub const as = C.as;
|
||||||
}
|
pub const ref = C.ref;
|
||||||
|
pub const unref = C.unref;
|
||||||
pub fn unref(self: *Self) void {
|
const private = C.private;
|
||||||
gobject.Object.unref(self.as(gobject.Object));
|
|
||||||
}
|
|
||||||
|
|
||||||
fn private(self: *Self) *Private {
|
|
||||||
return gobject.ext.impl_helpers.getPrivate(
|
|
||||||
self,
|
|
||||||
Private,
|
|
||||||
Private.offset,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub const Class = extern struct {
|
pub const Class = extern struct {
|
||||||
parent_class: Parent.Class,
|
parent_class: Parent.Class,
|
||||||
|
@ -9,6 +9,7 @@ const configpkg = @import("../../../config.zig");
|
|||||||
const CoreConfig = configpkg.Config;
|
const CoreConfig = configpkg.Config;
|
||||||
|
|
||||||
const unrefLater = @import("../class.zig").unrefLater;
|
const unrefLater = @import("../class.zig").unrefLater;
|
||||||
|
const Common = @import("../class.zig").Common;
|
||||||
|
|
||||||
const log = std.log.scoped(.gtk_ghostty_config);
|
const log = std.log.scoped(.gtk_ghostty_config);
|
||||||
|
|
||||||
@ -66,7 +67,7 @@ pub const Config = extern struct {
|
|||||||
const Private = struct {
|
const Private = struct {
|
||||||
config: CoreConfig,
|
config: CoreConfig,
|
||||||
|
|
||||||
var offset: c_int = 0;
|
pub var offset: c_int = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Create a new GhosttyConfig from a loaded configuration.
|
/// 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 {
|
const C = Common(Self, Private);
|
||||||
return gobject.ext.as(T, self);
|
pub const as = C.as;
|
||||||
}
|
pub const ref = C.ref;
|
||||||
|
pub const unref = C.unref;
|
||||||
pub fn ref(self: *Self) *Self {
|
const private = C.private;
|
||||||
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,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub const Class = extern struct {
|
pub const Class = extern struct {
|
||||||
parent_class: Parent.Class,
|
parent_class: Parent.Class,
|
||||||
|
@ -5,6 +5,7 @@ const gtk = @import("gtk");
|
|||||||
|
|
||||||
const gresource = @import("../build/gresource.zig");
|
const gresource = @import("../build/gresource.zig");
|
||||||
const adw_version = @import("../adw_version.zig");
|
const adw_version = @import("../adw_version.zig");
|
||||||
|
const Common = @import("../class.zig").Common;
|
||||||
const Config = @import("config.zig").Config;
|
const Config = @import("config.zig").Config;
|
||||||
|
|
||||||
const log = std.log.scoped(.gtk_ghostty_config_errors_dialog);
|
const log = std.log.scoped(.gtk_ghostty_config_errors_dialog);
|
||||||
@ -58,7 +59,7 @@ pub const ConfigErrorsDialog = extern struct {
|
|||||||
|
|
||||||
const Private = struct {
|
const Private = struct {
|
||||||
config: ?*Config,
|
config: ?*Config,
|
||||||
var offset: c_int = 0;
|
pub var offset: c_int = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn new(config: *Config) *Self {
|
pub fn new(config: *Config) *Self {
|
||||||
@ -129,25 +130,11 @@ pub const ConfigErrorsDialog = extern struct {
|
|||||||
priv.config = config;
|
priv.config = config;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as(win: *Self, comptime T: type) *T {
|
const C = Common(Self, Private);
|
||||||
return gobject.ext.as(T, win);
|
pub const as = C.as;
|
||||||
}
|
pub const ref = C.ref;
|
||||||
|
pub const unref = C.unref;
|
||||||
pub fn ref(self: *Self) *Self {
|
const private = C.private;
|
||||||
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,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub const Class = extern struct {
|
pub const Class = extern struct {
|
||||||
parent_class: Parent.Class,
|
parent_class: Parent.Class,
|
||||||
|
@ -4,6 +4,7 @@ const gobject = @import("gobject");
|
|||||||
const gtk = @import("gtk");
|
const gtk = @import("gtk");
|
||||||
|
|
||||||
const gresource = @import("../build/gresource.zig");
|
const gresource = @import("../build/gresource.zig");
|
||||||
|
const Common = @import("../class.zig").Common;
|
||||||
const Application = @import("application.zig").Application;
|
const Application = @import("application.zig").Application;
|
||||||
|
|
||||||
const log = std.log.scoped(.gtk_ghostty_window);
|
const log = std.log.scoped(.gtk_ghostty_window);
|
||||||
@ -22,7 +23,7 @@ pub const Window = extern struct {
|
|||||||
|
|
||||||
const Private = struct {
|
const Private = struct {
|
||||||
_todo: u8,
|
_todo: u8,
|
||||||
var offset: c_int = 0;
|
pub var offset: c_int = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn new(app: *Application) *Self {
|
pub fn new(app: *Application) *Self {
|
||||||
@ -45,17 +46,11 @@ pub const Window = extern struct {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as(self: *Self, comptime T: type) *T {
|
const C = Common(Self, Private);
|
||||||
return gobject.ext.as(T, self);
|
pub const as = C.as;
|
||||||
}
|
pub const ref = C.ref;
|
||||||
|
pub const unref = C.unref;
|
||||||
fn private(self: *Self) *Private {
|
const private = C.private;
|
||||||
return gobject.ext.impl_helpers.getPrivate(
|
|
||||||
self,
|
|
||||||
Private,
|
|
||||||
Private.offset,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub const Class = extern struct {
|
pub const Class = extern struct {
|
||||||
parent_class: Parent.Class,
|
parent_class: Parent.Class,
|
||||||
|
Reference in New Issue
Block a user