mirror of
https://github.com/ghostty-org/ghostty.git
synced 2026-04-19 14:00:29 +00:00
Allow for default or inherited CWD in new window, tab and split surfaces (redone for GTK-NG) (#9158)
This commit is contained in:
@@ -456,6 +456,9 @@ pub const Surface = struct {
|
||||
|
||||
/// Wait after the command exits
|
||||
wait_after_command: bool = false,
|
||||
|
||||
/// Context for the new surface
|
||||
context: apprt.surface.NewSurfaceContext = .window,
|
||||
};
|
||||
|
||||
pub fn init(self: *Surface, app: *App, opts: Options) !void {
|
||||
@@ -477,7 +480,7 @@ pub const Surface = struct {
|
||||
errdefer app.core_app.deleteSurface(self);
|
||||
|
||||
// Shallow copy the config so that we can modify it.
|
||||
var config = try apprt.surface.newConfig(app.core_app, &app.config);
|
||||
var config = try apprt.surface.newConfig(app.core_app, &app.config, opts.context);
|
||||
defer config.deinit();
|
||||
|
||||
// If we have a working directory from the options then we set it.
|
||||
@@ -894,14 +897,23 @@ pub const Surface = struct {
|
||||
};
|
||||
}
|
||||
|
||||
pub fn newSurfaceOptions(self: *const Surface) apprt.Surface.Options {
|
||||
pub fn newSurfaceOptions(self: *const Surface, context: apprt.surface.NewSurfaceContext) apprt.Surface.Options {
|
||||
const font_size: f32 = font_size: {
|
||||
if (!self.app.config.@"window-inherit-font-size") break :font_size 0;
|
||||
break :font_size self.core_surface.font_size.points;
|
||||
};
|
||||
|
||||
const working_directory: ?[*:0]const u8 = wd: {
|
||||
if (!apprt.surface.shouldInheritWorkingDirectory(context, &self.app.config)) break :wd null;
|
||||
const cwd = self.core_surface.pwd(self.app.core_app.alloc) catch null orelse break :wd null;
|
||||
defer self.app.core_app.alloc.free(cwd);
|
||||
break :wd self.app.core_app.alloc.dupeZ(u8, cwd) catch null;
|
||||
};
|
||||
|
||||
return .{
|
||||
.font_size = font_size,
|
||||
.working_directory = working_directory,
|
||||
.context = context,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1523,8 +1535,11 @@ pub const CAPI = struct {
|
||||
}
|
||||
|
||||
/// Returns the config to use for surfaces that inherit from this one.
|
||||
export fn ghostty_surface_inherited_config(surface: *Surface) Surface.Options {
|
||||
return surface.newSurfaceOptions();
|
||||
export fn ghostty_surface_inherited_config(
|
||||
surface: *Surface,
|
||||
source: apprt.surface.NewSurfaceContext,
|
||||
) Surface.Options {
|
||||
return surface.newSurfaceOptions(source);
|
||||
}
|
||||
|
||||
/// Update the configuration to the provided config for only this surface.
|
||||
|
||||
@@ -2238,8 +2238,8 @@ const Action = struct {
|
||||
.{},
|
||||
);
|
||||
|
||||
// Create a new tab
|
||||
win.newTab(parent);
|
||||
// Create a new tab with window context (first tab in new window)
|
||||
win.newTabForWindow(parent);
|
||||
|
||||
// Show the window
|
||||
gtk.Window.present(win.as(gtk.Window));
|
||||
|
||||
@@ -219,7 +219,7 @@ pub const SplitTree = extern struct {
|
||||
// Inherit properly if we were asked to.
|
||||
if (parent_) |p| {
|
||||
if (p.core()) |core| {
|
||||
surface.setParent(core);
|
||||
surface.setParent(core, .split);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -671,6 +671,9 @@ pub const Surface = extern struct {
|
||||
error_page: *adw.StatusPage,
|
||||
terminal_page: *gtk.Overlay,
|
||||
|
||||
/// The context for this surface (window, tab, or split)
|
||||
context: apprt.surface.NewSurfaceContext = .window,
|
||||
|
||||
pub var offset: c_int = 0;
|
||||
};
|
||||
|
||||
@@ -696,6 +699,7 @@ pub const Surface = extern struct {
|
||||
pub fn setParent(
|
||||
self: *Self,
|
||||
parent: *CoreSurface,
|
||||
context: apprt.surface.NewSurfaceContext,
|
||||
) void {
|
||||
const priv = self.private();
|
||||
|
||||
@@ -706,6 +710,9 @@ pub const Surface = extern struct {
|
||||
return;
|
||||
}
|
||||
|
||||
// Store the context so initSurface can use it
|
||||
priv.context = context;
|
||||
|
||||
// Setup our font size
|
||||
const font_size_ptr = glib.ext.create(font.face.DesiredSize);
|
||||
errdefer glib.ext.destroy(font_size_ptr);
|
||||
@@ -716,10 +723,8 @@ pub const Surface = extern struct {
|
||||
// Remainder needs a config. If there is no config we just assume
|
||||
// we aren't inheriting any of these values.
|
||||
if (priv.config) |config_obj| {
|
||||
const config = config_obj.get();
|
||||
|
||||
// Setup our pwd if configured to inherit
|
||||
if (config.@"window-inherit-working-directory") {
|
||||
// Setup our cwd if configured to inherit
|
||||
if (apprt.surface.shouldInheritWorkingDirectory(context, config_obj.get())) {
|
||||
if (parent.rt_surface.surface.getPwd()) |pwd| {
|
||||
priv.pwd = glib.ext.dupeZ(u8, pwd);
|
||||
self.as(gobject.Object).notifyByPspec(properties.pwd.impl.param_spec);
|
||||
@@ -3206,6 +3211,7 @@ pub const Surface = extern struct {
|
||||
var config = try apprt.surface.newConfig(
|
||||
app.core(),
|
||||
priv.config.?.get(),
|
||||
priv.context,
|
||||
);
|
||||
defer config.deinit();
|
||||
|
||||
|
||||
@@ -161,8 +161,12 @@ pub const Tab = extern struct {
|
||||
/// ever created for a tab. If a surface was already created this does
|
||||
/// nothing.
|
||||
pub fn setParent(self: *Self, parent: *CoreSurface) void {
|
||||
self.setParentWithContext(parent, .tab);
|
||||
}
|
||||
|
||||
pub fn setParentWithContext(self: *Self, parent: *CoreSurface, context: apprt.surface.NewSurfaceContext) void {
|
||||
if (self.getActiveSurface()) |surface| {
|
||||
surface.setParent(parent);
|
||||
surface.setParent(parent, context);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -361,10 +361,14 @@ pub const Window = extern struct {
|
||||
/// at the position dictated by the `window-new-tab-position` config.
|
||||
/// The new tab will be selected.
|
||||
pub fn newTab(self: *Self, parent_: ?*CoreSurface) void {
|
||||
_ = self.newTabPage(parent_);
|
||||
_ = self.newTabPage(parent_, .tab);
|
||||
}
|
||||
|
||||
fn newTabPage(self: *Self, parent_: ?*CoreSurface) *adw.TabPage {
|
||||
pub fn newTabForWindow(self: *Self, parent_: ?*CoreSurface) void {
|
||||
_ = self.newTabPage(parent_, .window);
|
||||
}
|
||||
|
||||
fn newTabPage(self: *Self, parent_: ?*CoreSurface, context: apprt.surface.NewSurfaceContext) *adw.TabPage {
|
||||
const priv = self.private();
|
||||
const tab_view = priv.tab_view;
|
||||
|
||||
@@ -372,7 +376,9 @@ pub const Window = extern struct {
|
||||
const tab = gobject.ext.newInstance(Tab, .{
|
||||
.config = priv.config,
|
||||
});
|
||||
if (parent_) |p| tab.setParent(p);
|
||||
if (parent_) |p| {
|
||||
tab.setParentWithContext(p, context);
|
||||
}
|
||||
|
||||
// Get the position that we should insert the new tab at.
|
||||
const config = if (priv.config) |v| v.get() else {
|
||||
@@ -1231,7 +1237,7 @@ pub const Window = extern struct {
|
||||
_: *adw.TabOverview,
|
||||
self: *Self,
|
||||
) callconv(.c) *adw.TabPage {
|
||||
return self.newTabPage(if (self.getActiveSurface()) |v| v.core() else null);
|
||||
return self.newTabPage(if (self.getActiveSurface()) |v| v.core() else null, .tab);
|
||||
}
|
||||
|
||||
fn tabOverviewOpen(
|
||||
|
||||
@@ -159,12 +159,28 @@ pub const Mailbox = struct {
|
||||
}
|
||||
};
|
||||
|
||||
/// Context for new surface creation to determine inheritance behavior
|
||||
pub const NewSurfaceContext = enum(c_int) {
|
||||
window = 0,
|
||||
tab = 1,
|
||||
split = 2,
|
||||
};
|
||||
|
||||
pub fn shouldInheritWorkingDirectory(context: NewSurfaceContext, config: *const Config) bool {
|
||||
return switch (context) {
|
||||
.window => config.@"window-inherit-working-directory",
|
||||
.tab => config.@"tab-inherit-working-directory",
|
||||
.split => config.@"split-inherit-working-directory",
|
||||
};
|
||||
}
|
||||
|
||||
/// Returns a new config for a surface for the given app that should be
|
||||
/// used for any new surfaces. The resulting config should be deinitialized
|
||||
/// after the surface is initialized.
|
||||
pub fn newConfig(
|
||||
app: *const App,
|
||||
config: *const Config,
|
||||
context: NewSurfaceContext,
|
||||
) Allocator.Error!Config {
|
||||
// Create a shallow clone
|
||||
var copy = config.shallowClone(app.alloc);
|
||||
@@ -175,7 +191,7 @@ pub fn newConfig(
|
||||
// Get our previously focused surface for some inherited values.
|
||||
const prev = app.focusedSurface();
|
||||
if (prev) |p| {
|
||||
if (config.@"window-inherit-working-directory") {
|
||||
if (shouldInheritWorkingDirectory(context, config)) {
|
||||
if (try p.pwd(alloc)) |pwd| {
|
||||
copy.@"working-directory" = pwd;
|
||||
}
|
||||
|
||||
@@ -1845,11 +1845,21 @@ keybind: Keybinds = .{},
|
||||
/// This setting is only supported currently on macOS.
|
||||
@"window-vsync": bool = true,
|
||||
|
||||
/// If true, new windows and tabs will inherit the working directory of the
|
||||
/// If true, new windows will inherit the working directory of the
|
||||
/// previously focused window. If no window was previously focused, the default
|
||||
/// working directory will be used (the `working-directory` option).
|
||||
@"window-inherit-working-directory": bool = true,
|
||||
|
||||
/// If true, new tabs will inherit the working directory of the
|
||||
/// previously focused tab. If no tab was previously focused, the default
|
||||
/// working directory will be used (the `working-directory` option).
|
||||
@"tab-inherit-working-directory": bool = true,
|
||||
|
||||
/// If true, new split panes will inherit the working directory of the
|
||||
/// previously focused split. If no split was previously focused, the default
|
||||
/// working directory will be used (the `working-directory` option).
|
||||
@"split-inherit-working-directory": bool = true,
|
||||
|
||||
/// If true, new windows and tabs will inherit the font size of the previously
|
||||
/// focused window. If no window was previously focused, the default font size
|
||||
/// will be used. If this is false, the default font size specified in the
|
||||
|
||||
Reference in New Issue
Block a user