apprt/gtk-ng: abstract helper for private string fields

This commit is contained in:
Mitchell Hashimoto
2025-07-21 06:52:23 -07:00
parent 9440c775c7
commit cd82a610c3
2 changed files with 52 additions and 57 deletions

View File

@ -46,6 +46,48 @@ pub fn Common(
} }
}).private else {}; }).private else {};
/// A helper that can be used to create a property that reads and
/// writes a private `?[:0]const u8` field type.
///
/// This helper helps properly manage the memory to avoid memory leaks.
///
/// The object class (Self) must still free the private field
/// in finalize!
pub fn privateStringFieldAccessor(
comptime name: []const u8,
) gobject.ext.Accessor(
Self,
@FieldType(Private.?, name),
) {
const S = struct {
fn getter(self: *Self) ?[:0]const u8 {
return @field(private(self), name);
}
fn setter(self: *Self, value: ?[:0]const u8) void {
const priv = private(self);
if (@field(priv, name)) |v| {
glib.free(@constCast(@ptrCast(v)));
}
// We don't need to copy this because it was already
// copied by the typedAccessor.
@field(priv, name) = value;
}
};
return gobject.ext.typedAccessor(
Self,
?[:0]const u8,
.{
.getter = S.getter,
.getter_transfer = .none,
.setter = S.setter,
.setter_transfer = .full,
},
);
}
/// Common class functions. /// Common class functions.
pub const Class = struct { pub const Class = struct {
pub fn as(class: *Self.Class, comptime T: type) *T { pub fn as(class: *Self.Class, comptime T: type) *T {

View File

@ -96,6 +96,8 @@ pub const Surface = extern struct {
pub const pwd = struct { pub const pwd = struct {
pub const name = "pwd"; pub const name = "pwd";
pub const get = impl.get;
pub const set = impl.set;
const impl = gobject.ext.defineProperty( const impl = gobject.ext.defineProperty(
name, name,
Self, Self,
@ -104,22 +106,15 @@ pub const Surface = extern struct {
.nick = "Working Directory", .nick = "Working Directory",
.blurb = "The current working directory as reported by core.", .blurb = "The current working directory as reported by core.",
.default = null, .default = null,
.accessor = gobject.ext.typedAccessor( .accessor = C.privateStringFieldAccessor("pwd"),
Self,
?[:0]const u8,
.{
.getter = getPwd,
.getter_transfer = .none,
.setter = setPwd,
.setter_transfer = .full,
},
),
}, },
); );
}; };
pub const title = struct { pub const title = struct {
pub const name = "title"; pub const name = "title";
pub const get = impl.get;
pub const set = impl.set;
const impl = gobject.ext.defineProperty( const impl = gobject.ext.defineProperty(
name, name,
Self, Self,
@ -128,16 +123,7 @@ pub const Surface = extern struct {
.nick = "Title", .nick = "Title",
.blurb = "The title of the surface.", .blurb = "The title of the surface.",
.default = null, .default = null,
.accessor = gobject.ext.typedAccessor( .accessor = C.privateStringFieldAccessor("title"),
Self,
?[:0]const u8,
.{
.getter = getTitle,
.getter_transfer = .none,
.setter = setTitle,
.setter_transfer = .full,
},
),
}, },
); );
}; };
@ -876,8 +862,10 @@ pub const Surface = extern struct {
priv.core_surface = null; priv.core_surface = null;
} }
if (priv.pwd != null) self.setPwd(null);
if (priv.title != null) self.setTitle(null); var @"null": gobject.Value = undefined;
if (priv.pwd != null) properties.pwd.set(self, &@"null");
if (priv.title != null) properties.pwd.set(self, &@"null");
gobject.Object.virtual_methods.finalize.call( gobject.Object.virtual_methods.finalize.call(
Class.parent, Class.parent,
@ -888,41 +876,6 @@ pub const Surface = extern struct {
//--------------------------------------------------------------- //---------------------------------------------------------------
// Properties // Properties
fn getPwd(
self: *Self,
) ?[:0]const u8 {
return self.private().pwd;
}
fn setPwd(
self: *Self,
value: ?[:0]const u8,
) void {
const priv = self.private();
// Free the previous value
if (priv.pwd) |v| glib.free(@constCast(@ptrCast(v.ptr)));
// Set the new value, which is already copied since we
// set our setter_transfer value to full.
priv.pwd = value;
}
fn getTitle(
self: *Self,
) ?[:0]const u8 {
return self.private().title;
}
fn setTitle(
self: *Self,
value: ?[:0]const u8,
) void {
const priv = self.private();
if (priv.title) |v| glib.free(@constCast(@ptrCast(v.ptr)));
priv.title = value;
}
fn propMouseHidden( fn propMouseHidden(
self: *Self, self: *Self,
_: *gobject.ParamSpec, _: *gobject.ParamSpec,