@@ -2,13 +2,41 @@ const std = @import("std");
2
2
const builtin = @import ("builtin" );
3
3
const Allocator = std .mem .Allocator ;
4
4
5
+ pub const ResourcesDir = struct {
6
+ app_path : ? []const u8 = null ,
7
+ host_path : ? []const u8 = null ,
8
+
9
+ /// Free resources held. Requires the same allocator as when resourcesDir()
10
+ /// is called.
11
+ pub fn deinit (self : * ResourcesDir , alloc : std.mem.Allocator ) void {
12
+ if (self .app_path ) | p | alloc .free (p );
13
+ if (self .host_path ) | p | alloc .free (p );
14
+ }
15
+
16
+ /// Get the directory to the bundled resources directory accessible
17
+ /// by the application.
18
+ pub fn app (self : * ResourcesDir ) ? []const u8 {
19
+ return self .app_path ;
20
+ }
21
+
22
+ /// Get the directory to the bundled resources directory accessible
23
+ /// by the host environment (i.e. for sandboxed applications). The
24
+ /// returned directory might not be accessible from the application
25
+ /// itself.
26
+ ///
27
+ /// In non-sandboxed environment, this should be the same as app().
28
+ pub fn host (self : * ResourcesDir ) ? []const u8 {
29
+ return self .host_path orelse self .app_path ;
30
+ }
31
+ };
32
+
5
33
/// Gets the directory to the bundled resources directory, if it
6
34
/// exists (not all platforms or packages have it). The output is
7
35
/// owned by the caller.
8
36
///
9
37
/// This is highly Ghostty-specific and can likely be generalized at
10
38
/// some point but we can cross that bridge if we ever need to.
11
- pub fn resourcesDir (alloc : std.mem.Allocator ) ! ? [] const u8 {
39
+ pub fn resourcesDir (alloc : std.mem.Allocator ) ! ResourcesDir {
12
40
// Use the GHOSTTY_RESOURCES_DIR environment variable in release builds.
13
41
//
14
42
// In debug builds we try using terminfo detection first instead, since
@@ -20,7 +48,7 @@ pub fn resourcesDir(alloc: std.mem.Allocator) !?[]const u8 {
20
48
// freed, do not try to use internal_os.getenv or posix getenv.
21
49
if (comptime builtin .mode != .Debug ) {
22
50
if (std .process .getEnvVarOwned (alloc , "GHOSTTY_RESOURCES_DIR" )) | dir | {
23
- if (dir .len > 0 ) return dir ;
51
+ if (dir .len > 0 ) return .{ . app_path = dir } ;
24
52
} else | err | switch (err ) {
25
53
error .EnvironmentVariableNotFound = > {},
26
54
else = > return err ,
@@ -37,7 +65,7 @@ pub fn resourcesDir(alloc: std.mem.Allocator) !?[]const u8 {
37
65
38
66
// Get the path to our running binary
39
67
var exe_buf : [std .fs .max_path_bytes ]u8 = undefined ;
40
- var exe : []const u8 = std .fs .selfExePath (& exe_buf ) catch return null ;
68
+ var exe : []const u8 = std .fs .selfExePath (& exe_buf ) catch return .{} ;
41
69
42
70
// We have an exe path! Climb the tree looking for the terminfo
43
71
// bundle as we expect it.
@@ -49,7 +77,7 @@ pub fn resourcesDir(alloc: std.mem.Allocator) !?[]const u8 {
49
77
if (comptime builtin .target .os .tag .isDarwin ()) {
50
78
inline for (sentinels ) | sentinel | {
51
79
if (try maybeDir (& dir_buf , dir , "Contents/Resources" , sentinel )) | v | {
52
- return try std .fs .path .join (alloc , &.{ v , "ghostty" });
80
+ return .{ . app_path = try std .fs .path .join (alloc , &.{ v , "ghostty" }) } ;
53
81
}
54
82
}
55
83
}
@@ -59,7 +87,7 @@ pub fn resourcesDir(alloc: std.mem.Allocator) !?[]const u8 {
59
87
// Ghostty to be in an app bundle.
60
88
inline for (sentinels ) | sentinel | {
61
89
if (try maybeDir (& dir_buf , dir , "share" , sentinel )) | v | {
62
- return try std .fs .path .join (alloc , &.{ v , "ghostty" });
90
+ return .{ . app_path = try std .fs .path .join (alloc , &.{ v , "ghostty" }) } ;
63
91
}
64
92
}
65
93
}
@@ -68,14 +96,14 @@ pub fn resourcesDir(alloc: std.mem.Allocator) !?[]const u8 {
68
96
// fallback and use the provided resources dir.
69
97
if (comptime builtin .mode == .Debug ) {
70
98
if (std .process .getEnvVarOwned (alloc , "GHOSTTY_RESOURCES_DIR" )) | dir | {
71
- if (dir .len > 0 ) return dir ;
99
+ if (dir .len > 0 ) return .{ . app_path = dir } ;
72
100
} else | err | switch (err ) {
73
101
error .EnvironmentVariableNotFound = > {},
74
102
else = > return err ,
75
103
}
76
104
}
77
105
78
- return null ;
106
+ return .{} ;
79
107
}
80
108
81
109
/// Little helper to check if the "base/sub/suffix" directory exists and
0 commit comments