From 793e2719891f985c27549fa9586822296652b47d Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Sun, 20 Jul 2025 15:02:49 -0700 Subject: [PATCH] apprt/gtk-ng: set pwd --- src/apprt/gtk-ng/class/application.zig | 21 +++++++++- src/apprt/gtk-ng/class/surface.zig | 53 ++++++++++++++++++++++++++ 2 files changed, 73 insertions(+), 1 deletion(-) diff --git a/src/apprt/gtk-ng/class/application.zig b/src/apprt/gtk-ng/class/application.zig index a170afc74..083c00e5a 100644 --- a/src/apprt/gtk-ng/class/application.zig +++ b/src/apprt/gtk-ng/class/application.zig @@ -416,6 +416,8 @@ pub const Application = extern struct { }, ), + .pwd => Action.pwd(target, value), + .quit_timer => try Action.quitTimer(self, value), .render => Action.render(self, target), @@ -439,7 +441,6 @@ pub const Application = extern struct { .show_gtk_inspector, .desktop_notification, .set_title, - .pwd, .present_terminal, .initial_size, .size_limit, @@ -937,6 +938,24 @@ const Action = struct { gtk.Window.present(win.as(gtk.Window)); } + pub fn pwd( + target: apprt.Target, + value: apprt.action.Pwd, + ) void { + switch (target) { + .app => log.warn("pwd to app is unexpected", .{}), + .surface => |surface| { + var v = gobject.ext.Value.newFrom(value.pwd); + defer v.unset(); + gobject.Object.setProperty( + surface.rt_surface.gobj().as(gobject.Object), + "pwd", + &v, + ); + }, + } + } + pub fn quitTimer( self: *Application, mode: apprt.action.QuitTimer, diff --git a/src/apprt/gtk-ng/class/surface.zig b/src/apprt/gtk-ng/class/surface.zig index 0100f61c4..bbd47e7ae 100644 --- a/src/apprt/gtk-ng/class/surface.zig +++ b/src/apprt/gtk-ng/class/surface.zig @@ -93,6 +93,30 @@ pub const Surface = extern struct { }, ); }; + + pub const pwd = struct { + pub const name = "pwd"; + const impl = gobject.ext.defineProperty( + name, + Self, + ?[:0]const u8, + .{ + .nick = "Working Directory", + .blurb = "The current working directory as reported by core.", + .default = null, + .accessor = gobject.ext.typedAccessor( + Self, + ?[:0]const u8, + .{ + .getter = getPwd, + .getter_transfer = .none, + .setter = setPwd, + .setter_transfer = .full, + }, + ), + }, + ); + }; }; pub const signals = struct { @@ -128,6 +152,11 @@ pub const Surface = extern struct { /// Whether the mouse should be hidden or not as requested externally. mouse_hidden: bool = false, + /// The current working directory. This has to be reported externally, + /// usually by shell integration which then talks to libghostty + /// which triggers this property. + pwd: ?[:0]const u8 = null, + /// The GLAarea that renders the actual surface. This is a binding /// to the template so it doesn't have to be unrefed manually. gl_area: *gtk.GLArea = undefined, @@ -820,6 +849,9 @@ pub const Surface = extern struct { priv.core_surface = null; } + if (priv.pwd != null) { + self.setPwd(null); + } gobject.Object.virtual_methods.finalize.call( Class.parent, @@ -830,6 +862,26 @@ pub const Surface = extern struct { //--------------------------------------------------------------- // 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 propMouseHidden( self: *Self, _: *gobject.ParamSpec, @@ -1512,6 +1564,7 @@ pub const Surface = extern struct { properties.config.impl, properties.@"mouse-shape".impl, properties.@"mouse-hidden".impl, + properties.pwd.impl, }); // Signals