apprt/gtk-ng: split zoom title

pull/8218/head
Mitchell Hashimoto 2025-08-12 15:37:53 -07:00
parent 12bc0d7b10
commit 798e872f48
No known key found for this signature in database
GPG Key ID: 523D5DC389D273BC
3 changed files with 53 additions and 23 deletions

View File

@ -70,6 +70,24 @@ pub const Tab = extern struct {
);
};
pub const @"split-tree" = struct {
pub const name = "split-tree";
const impl = gobject.ext.defineProperty(
name,
Self,
?*SplitTree,
.{
.accessor = gobject.ext.typedAccessor(
Self,
?*SplitTree,
.{
.getter = getSplitTree,
},
),
},
);
};
pub const @"surface-tree" = struct {
pub const name = "surface-tree";
const impl = gobject.ext.defineProperty(
@ -103,8 +121,6 @@ pub const Tab = extern struct {
pub const title = struct {
pub const name = "title";
pub const get = impl.get;
pub const set = impl.set;
const impl = gobject.ext.defineProperty(
name,
Self,
@ -135,13 +151,11 @@ pub const Tab = extern struct {
/// The configuration that this surface is using.
config: ?*Config = null,
/// The title to show for this tab. This is usually set to a binding
/// with the active surface but can be manually set to anything.
/// The title of this tab. This is usually bound to the active surface.
title: ?[:0]const u8 = null,
tooltip: ?[:0]const u8 = null,
/// The binding groups for the current active surface.
surface_bindings: *gobject.BindingGroup,
/// The tooltip of this tab. This is usually bound to the active surface.
tooltip: ?[:0]const u8 = null,
// Template bindings
split_tree: *SplitTree,
@ -169,15 +183,6 @@ pub const Tab = extern struct {
priv.config = app.getConfig();
}
// Setup binding groups for surface properties
priv.surface_bindings = gobject.BindingGroup.new();
priv.surface_bindings.bind(
"title",
self.as(gobject.Object),
"title",
.{},
);
// Create our initial surface in the split tree.
priv.split_tree.newSplit(.right, null) catch |err| switch (err) {
error.OutOfMemory => {
@ -227,7 +232,6 @@ pub const Tab = extern struct {
v.unref();
priv.config = null;
}
priv.surface_bindings.setSource(null);
gtk.Widget.disposeTemplate(
self.as(gtk.Widget),
@ -250,7 +254,6 @@ pub const Tab = extern struct {
glib.free(@constCast(@ptrCast(v)));
priv.title = null;
}
priv.surface_bindings.unref();
gobject.Object.virtual_methods.finalize.call(
Class.parent,
@ -285,13 +288,36 @@ pub const Tab = extern struct {
_: *gobject.ParamSpec,
self: *Self,
) callconv(.c) void {
const priv = self.private();
priv.surface_bindings.setSource(null);
if (self.getActiveSurface()) |surface| {
priv.surface_bindings.setSource(surface.as(gobject.Object));
self.as(gobject.Object).notifyByPspec(properties.@"active-surface".impl.param_spec);
}
self.as(gobject.Object).notifyByPspec(properties.@"active-surface".impl.param_spec);
fn closureComputedTitle(
_: *Self,
plain_: ?[*:0]const u8,
zoomed_: c_int,
) callconv(.c) ?[*:0]const u8 {
const zoomed = zoomed_ != 0;
const plain = plain: {
const default = "Ghostty";
const plain = plain_ orelse break :plain default;
break :plain std.mem.span(plain);
};
// If we're zoomed, prefix with the magnifying glass emoji.
if (zoomed) zoomed: {
// This results in an extra allocation (that we free), but I
// prefer using the Zig APIs so much more than the libc ones.
const alloc = Application.default().allocator();
const slice = std.fmt.allocPrint(
alloc,
"🔍 {s}",
.{plain},
) catch break :zoomed;
defer alloc.free(slice);
return glib.ext.dupeZ(u8, slice);
}
return glib.ext.dupeZ(u8, plain);
}
const C = Common(Self, Private);
@ -321,6 +347,7 @@ pub const Tab = extern struct {
gobject.ext.registerProperties(class, &.{
properties.@"active-surface".impl,
properties.config.impl,
properties.@"split-tree".impl,
properties.@"surface-tree".impl,
properties.title.impl,
properties.tooltip.impl,
@ -330,6 +357,7 @@ pub const Tab = extern struct {
class.bindTemplateChildPrivate("split_tree", .{});
// Template Callbacks
class.bindTemplateCallback("computed_title", &closureComputedTitle);
class.bindTemplateCallback("notify_active_surface", &propActiveSurface);
class.bindTemplateCallback("notify_tree", &propSplitTree);

View File

@ -1804,6 +1804,7 @@ pub const Window = extern struct {
fn init(class: *Class) callconv(.c) void {
gobject.ext.ensureType(DebugWarning);
gobject.ext.ensureType(SplitTree);
gobject.ext.ensureType(Surface);
gobject.ext.ensureType(Tab);
gtk.Widget.Class.setTemplateFromResource(

View File

@ -8,6 +8,7 @@ template $GhosttyTab: Box {
orientation: vertical;
hexpand: true;
vexpand: true;
title: bind $computed_title(split_tree.active-surface as <$GhosttySurface>.title, split_tree.is-zoomed) as <string>;
tooltip: bind split_tree.active-surface as <$GhosttySurface>.pwd;
$GhosttySplitTree split_tree {