diff options
Diffstat (limited to 'src/apprt/gtk-ng/class')
| -rw-r--r-- | src/apprt/gtk-ng/class/application.zig | 17 | ||||
| -rw-r--r-- | src/apprt/gtk-ng/class/config.zig | 25 | ||||
| -rw-r--r-- | src/apprt/gtk-ng/class/surface.zig | 31 | ||||
| -rw-r--r-- | src/apprt/gtk-ng/class/window.zig | 125 |
4 files changed, 183 insertions, 15 deletions
diff --git a/src/apprt/gtk-ng/class/application.zig b/src/apprt/gtk-ng/class/application.zig index d3e02e28d..41b550c7e 100644 --- a/src/apprt/gtk-ng/class/application.zig +++ b/src/apprt/gtk-ng/class/application.zig @@ -1086,6 +1086,7 @@ const Action = struct { const win = Window.new(self); gtk.Window.present(win.as(gtk.Window)); + win.setupInitialFocus(); } pub fn pwd( @@ -1095,13 +1096,7 @@ const Action = struct { 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, - ); + surface.rt_surface.setPwd(value.pwd); }, } } @@ -1130,13 +1125,7 @@ const Action = struct { switch (target) { .app => log.warn("set_title to app is unexpected", .{}), .surface => |surface| { - var v = gobject.ext.Value.newFrom(value.title); - defer v.unset(); - gobject.Object.setProperty( - surface.rt_surface.gobj().as(gobject.Object), - "title", - &v, - ); + surface.rt_surface.setTitle(value.title); }, } } diff --git a/src/apprt/gtk-ng/class/config.zig b/src/apprt/gtk-ng/class/config.zig index e40602f47..ace1c7bc1 100644 --- a/src/apprt/gtk-ng/class/config.zig +++ b/src/apprt/gtk-ng/class/config.zig @@ -52,6 +52,24 @@ pub const Config = extern struct { }, ); + pub const @"gtk-wide-tabs" = gobject.ext.defineProperty( + "gtk-wide-tabs", + Self, + bool, + .{ + .nick = "gtk-wide-tabs", + .blurb = null, + .default = false, + .accessor = gobject.ext.typedAccessor( + Self, + bool, + .{ + .getter = Self.gtkWideTabs, + }, + ), + }, + ); + pub const @"has-diagnostics" = gobject.ext.defineProperty( "has-diagnostics", Self, @@ -105,6 +123,12 @@ pub const Config = extern struct { return &self.private().config; } + /// Returns the current value of gtk-wide-tabs. + pub fn gtkWideTabs(self: *Self) bool { + const config = self.get(); + return config.@"gtk-wide-tabs"; + } + /// Returns whether this configuration has any diagnostics. pub fn hasDiagnostics(self: *Self) bool { const config = self.get(); @@ -163,6 +187,7 @@ pub const Config = extern struct { gobject.Object.virtual_methods.finalize.implement(class, &finalize); gobject.ext.registerProperties(class, &.{ properties.@"diagnostics-buffer", + properties.@"gtk-wide-tabs", properties.@"has-diagnostics", }); } diff --git a/src/apprt/gtk-ng/class/surface.zig b/src/apprt/gtk-ng/class/surface.zig index 9a64cd101..7d7482436 100644 --- a/src/apprt/gtk-ng/class/surface.zig +++ b/src/apprt/gtk-ng/class/surface.zig @@ -1085,11 +1085,42 @@ pub const Surface = extern struct { //--------------------------------------------------------------- // Properties + /// Returns the pwd property without a copy. + pub fn getPwd(self: *Self) ?[:0]const u8 { + return self.private().pwd; + } + + /// Set the pwd property. + pub fn setPwd(self: *Self, pwd: [:0]const u8) void { + const priv = self.private(); + + if (priv.title) |v| { + glib.free(@constCast(@ptrCast(v))); + priv.title = null; + } + + priv.pwd = std.mem.span(glib.strdup(pwd)); + self.as(gobject.Object).notifyByPspec(properties.pwd.impl.param_spec); + } + /// Returns the title property without a copy. pub fn getTitle(self: *Self) ?[:0]const u8 { return self.private().title; } + /// Set the title property. + pub fn setTitle(self: *Self, title: [:0]const u8) void { + const priv = self.private(); + + if (priv.title) |v| { + glib.free(@constCast(@ptrCast(v))); + priv.title = null; + } + + priv.title = std.mem.span(glib.strdup(title)); + self.as(gobject.Object).notifyByPspec(properties.title.impl.param_spec); + } + fn propConfig( self: *Self, _: *gobject.ParamSpec, diff --git a/src/apprt/gtk-ng/class/window.zig b/src/apprt/gtk-ng/class/window.zig index 6e30389a0..6e0fcf375 100644 --- a/src/apprt/gtk-ng/class/window.zig +++ b/src/apprt/gtk-ng/class/window.zig @@ -8,6 +8,7 @@ const gresource = @import("../build/gresource.zig"); const Common = @import("../class.zig").Common; const Application = @import("application.zig").Application; const Surface = @import("surface.zig").Surface; +const Config = @import("config.zig").Config; const log = std.log.scoped(.gtk_ghostty_window); @@ -23,7 +24,34 @@ pub const Window = extern struct { .private = .{ .Type = Private, .offset = &Private.offset }, }); + pub const properties = struct { + pub const config = struct { + pub const name = "config"; + const impl = gobject.ext.defineProperty( + name, + Self, + ?*Config, + .{ + .nick = "Config", + .blurb = "The configuration that this window is using.", + .accessor = gobject.ext.privateFieldAccessor( + Self, + Private, + &Private.offset, + "config", + ), + }, + ); + }; + }; + const Private = struct { + /// The configuration that this window is using. + config: ?*Config = null, + + /// The window title widget. + window_title: *adw.WindowTitle = undefined, + /// The surface in the view. surface: *Surface = undefined, @@ -34,10 +62,19 @@ pub const Window = extern struct { return gobject.ext.newInstance(Self, .{ .application = app }); } + pub fn setupInitialFocus(self: *Self) void { + _ = self.private().surface.as(gtk.Widget).grabFocus(); + } + fn init(self: *Self, _: *Class) callconv(.C) void { gtk.Widget.initTemplate(self.as(gtk.Widget)); - const surface = self.private().surface; + const priv = self.private(); + + const app = Application.default(); + priv.config = app.getConfig(); + + const surface = priv.surface; _ = Surface.signals.@"close-request".connect( surface, *Self, @@ -45,6 +82,32 @@ pub const Window = extern struct { self, .{}, ); + _ = gobject.Object.signals.notify.connect( + surface, + *Self, + &surfaceNotifyHasFocus, + self, + .{ .detail = "has-focus" }, + ); + self.setupSurfacePropertyConnections(surface); + } + + fn setupSurfacePropertyConnections(self: *Self, surface: *Surface) void { + _ = gobject.Object.signals.notify.connect( + surface, + *Self, + &surfaceNotifyTitle, + self, + .{ .detail = "title" }, + ); + + _ = gobject.Object.signals.notify.connect( + surface, + *Self, + &surfaceNotifyPwd, + self, + .{ .detail = "pwd" }, + ); } //--------------------------------------------------------------- @@ -56,12 +119,30 @@ pub const Window = extern struct { getGObjectType(), ); + const priv = self.private(); + if (priv.config) |v| { + v.unref(); + priv.config = null; + } + gobject.Object.virtual_methods.dispose.call( Class.parent, self.as(Parent), ); } + /// Set the title of the window. + fn setTitle(self: *Self, title: [:0]const u8) void { + const window_title = self.private().window_title; + window_title.setTitle(title); + } + + /// Set the subtitle of the window. + fn setSubtitle(self: *Self, subtitle: [:0]const u8) void { + const window_title = self.private().window_title; + window_title.setSubtitle(subtitle); + } + //--------------------------------------------------------------- // Signal handlers @@ -77,6 +158,42 @@ pub const Window = extern struct { self.as(gtk.Window).close(); } + fn surfaceNotifyHasFocus(surface: *Surface, _: *gobject.ParamSpec, self: *Self) callconv(.c) void { + assert(surface == self.private().surface); + + self.setTitle(surface.getTitle().?); + + const subtitle: [:0]const u8 = switch (Application.default().getConfig().get().@"window-subtitle") { + .@"working-directory" => surface.getPwd() orelse "", + .false => "", + }; + self.setSubtitle(subtitle); + } + + fn surfaceNotifyTitle(surface: *Surface, _: *gobject.ParamSpec, self: *Self) callconv(.c) void { + assert(surface == self.private().surface); + + if (surface.as(gtk.Widget).grabFocus() == 0) { + return; + } + + self.setTitle(surface.getTitle().?); + } + + fn surfaceNotifyPwd(surface: *Surface, _: *gobject.ParamSpec, self: *Self) callconv(.c) void { + assert(surface == self.private().surface); + + if (surface.as(gtk.Widget).grabFocus() == 0) { + return; + } + + if (Application.default().getConfig().get().@"window-subtitle" != .@"working-directory") { + return; + } + + self.setSubtitle(surface.getPwd() orelse ""); + } + const C = Common(Self, Private); pub const as = C.as; pub const ref = C.ref; @@ -100,8 +217,14 @@ pub const Window = extern struct { ); // Bindings + class.bindTemplateChildPrivate("window_title", .{}); class.bindTemplateChildPrivate("surface", .{}); + // Properties + gobject.ext.registerProperties(class, &.{ + properties.config.impl, + }); + // Virtual methods gobject.Object.virtual_methods.dispose.implement(class, &dispose); } |
