diff --git a/build.zig b/build.zig index a17e09831..4318997cb 100644 --- a/build.zig +++ b/build.zig @@ -288,7 +288,7 @@ pub fn build(b: *std.Build) !void { const install = b.addInstallDirectory(.{ .source_dir = .{ .path = "src/shell-integration" }, .install_dir = .{ .custom = "share" }, - .install_subdir = "shell-integration", + .install_subdir = b.pathJoin(&.{ "ghostty", "shell-integration" }), .exclude_extensions = &.{".md"}, }); b.getInstallStep().dependOn(&install.step); @@ -311,7 +311,7 @@ pub fn build(b: *std.Build) !void { const install = b.addInstallDirectory(.{ .source_dir = upstream.path("ghostty"), .install_dir = .{ .custom = "share" }, - .install_subdir = "themes", + .install_subdir = b.pathJoin(&.{ "ghostty", "themes" }), .exclude_extensions = &.{".md"}, }); b.getInstallStep().dependOn(&install.step); diff --git a/macos/Ghostty.xcodeproj/project.pbxproj b/macos/Ghostty.xcodeproj/project.pbxproj index b635e16f0..8ea8bfca5 100644 --- a/macos/Ghostty.xcodeproj/project.pbxproj +++ b/macos/Ghostty.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + 55154BE02B33911F001622DC /* ghostty in Resources */ = {isa = PBXBuildFile; fileRef = 55154BDF2B33911F001622DC /* ghostty */; }; 8503D7C72A549C66006CFF3D /* FullScreenHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8503D7C62A549C66006CFF3D /* FullScreenHandler.swift */; }; 857F63812A5E64F200CA4815 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 857F63802A5E64F200CA4815 /* MainMenu.xib */; }; A51B78472AF4B58B00F3EDB9 /* TerminalWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = A51B78462AF4B58B00F3EDB9 /* TerminalWindow.swift */; }; @@ -18,7 +19,6 @@ A5278A9B2AA05B2600CD3039 /* Ghostty.Input.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5278A9A2AA05B2600CD3039 /* Ghostty.Input.swift */; }; A53426352A7DA53D00EBB7A2 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = A53426342A7DA53D00EBB7A2 /* AppDelegate.swift */; }; A535B9DA299C569B0017E2E4 /* ErrorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A535B9D9299C569B0017E2E4 /* ErrorView.swift */; }; - A545D1A22A5772CE006E0AE4 /* shell-integration in Resources */ = {isa = PBXBuildFile; fileRef = A545D1A12A5772CE006E0AE4 /* shell-integration */; }; A55685E029A03A9F004303CE /* AppError.swift in Sources */ = {isa = PBXBuildFile; fileRef = A55685DF29A03A9F004303CE /* AppError.swift */; }; A55B7BB629B6F47F0055DE60 /* AppState.swift in Sources */ = {isa = PBXBuildFile; fileRef = A55B7BB529B6F47F0055DE60 /* AppState.swift */; }; A55B7BB829B6F53A0055DE60 /* Package.swift in Sources */ = {isa = PBXBuildFile; fileRef = A55B7BB729B6F53A0055DE60 /* Package.swift */; }; @@ -39,7 +39,6 @@ A59FB5D12AE0DEA7009128F3 /* MetalView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A59FB5D02AE0DEA7009128F3 /* MetalView.swift */; }; A5A1F8852A489D6800D1E8BC /* terminfo in Resources */ = {isa = PBXBuildFile; fileRef = A5A1F8842A489D6800D1E8BC /* terminfo */; }; A5B30539299BEAAB0047F10C /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A5B30538299BEAAB0047F10C /* Assets.xcassets */; }; - A5CB04382B0F1C1C009ED217 /* themes in Resources */ = {isa = PBXBuildFile; fileRef = A5CB04372B0F1C1C009ED217 /* themes */; }; A5CDF1912AAF9A5800513312 /* ConfigurationErrors.xib in Resources */ = {isa = PBXBuildFile; fileRef = A5CDF1902AAF9A5800513312 /* ConfigurationErrors.xib */; }; A5CDF1932AAF9E0800513312 /* ConfigurationErrorsController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5CDF1922AAF9E0800513312 /* ConfigurationErrorsController.swift */; }; A5CDF1952AAFA19600513312 /* ConfigurationErrorsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5CDF1942AAFA19600513312 /* ConfigurationErrorsView.swift */; }; @@ -54,6 +53,7 @@ /* Begin PBXFileReference section */ 3B39CAA42B33949B00DABEB8 /* GhosttyReleaseLocal.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = GhosttyReleaseLocal.entitlements; sourceTree = ""; }; + 55154BDF2B33911F001622DC /* ghostty */ = {isa = PBXFileReference; lastKnownFileType = folder; name = ghostty; path = "../zig-out/share/ghostty"; sourceTree = ""; }; 8503D7C62A549C66006CFF3D /* FullScreenHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FullScreenHandler.swift; sourceTree = ""; }; 857F63802A5E64F200CA4815 /* MainMenu.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MainMenu.xib; sourceTree = ""; }; A51B78462AF4B58B00F3EDB9 /* TerminalWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TerminalWindow.swift; sourceTree = ""; }; @@ -65,7 +65,6 @@ A5278A9A2AA05B2600CD3039 /* Ghostty.Input.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Ghostty.Input.swift; sourceTree = ""; }; A53426342A7DA53D00EBB7A2 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; A535B9D9299C569B0017E2E4 /* ErrorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ErrorView.swift; sourceTree = ""; }; - A545D1A12A5772CE006E0AE4 /* shell-integration */ = {isa = PBXFileReference; lastKnownFileType = folder; name = "shell-integration"; path = "../zig-out/share/shell-integration"; sourceTree = ""; }; A55685DF29A03A9F004303CE /* AppError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppError.swift; sourceTree = ""; }; A55B7BB529B6F47F0055DE60 /* AppState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppState.swift; sourceTree = ""; }; A55B7BB729B6F53A0055DE60 /* Package.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Package.swift; sourceTree = ""; }; @@ -88,7 +87,6 @@ A5B30531299BEAAA0047F10C /* Ghostty.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Ghostty.app; sourceTree = BUILT_PRODUCTS_DIR; }; A5B30538299BEAAB0047F10C /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; A5B3053D299BEAAB0047F10C /* Ghostty.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Ghostty.entitlements; sourceTree = ""; }; - A5CB04372B0F1C1C009ED217 /* themes */ = {isa = PBXFileReference; lastKnownFileType = folder; name = themes; path = "../zig-out/share/themes"; sourceTree = ""; }; A5CDF1902AAF9A5800513312 /* ConfigurationErrors.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ConfigurationErrors.xib; sourceTree = ""; }; A5CDF1922AAF9E0800513312 /* ConfigurationErrorsController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConfigurationErrorsController.swift; sourceTree = ""; }; A5CDF1942AAFA19600513312 /* ConfigurationErrorsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConfigurationErrorsView.swift; sourceTree = ""; }; @@ -223,7 +221,7 @@ A5A1F8862A489D7400D1E8BC /* Resources */ = { isa = PBXGroup; children = ( - A545D1A12A5772CE006E0AE4 /* shell-integration */, + 55154BDF2B33911F001622DC /* ghostty */, A5A1F8842A489D6800D1E8BC /* terminfo */, ); name = Resources; @@ -232,7 +230,6 @@ A5B30528299BEAAA0047F10C = { isa = PBXGroup; children = ( - A5CB04372B0F1C1C009ED217 /* themes */, A571AB1C2A206FC600248498 /* Ghostty-Info.plist */, A5B30538299BEAAB0047F10C /* Assets.xcassets */, A5B3053D299BEAAB0047F10C /* Ghostty.entitlements */, @@ -345,15 +342,14 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - A51BFC1E2B2FB5CE00E92F16 /* About.xib in Resources */, - A5CB04382B0F1C1C009ED217 /* themes in Resources */, - A545D1A22A5772CE006E0AE4 /* shell-integration in Resources */, - A596309A2AEE1C6400D64628 /* Terminal.xib in Resources */, - A5A1F8852A489D6800D1E8BC /* terminfo in Resources */, - A5CDF1912AAF9A5800513312 /* ConfigurationErrors.xib in Resources */, - A5E112932AF73E6E00C6E0C2 /* ClipboardConfirmation.xib in Resources */, A5B30539299BEAAB0047F10C /* Assets.xcassets in Resources */, + A51BFC1E2B2FB5CE00E92F16 /* About.xib in Resources */, + A5E112932AF73E6E00C6E0C2 /* ClipboardConfirmation.xib in Resources */, + A5CDF1912AAF9A5800513312 /* ConfigurationErrors.xib in Resources */, 857F63812A5E64F200CA4815 /* MainMenu.xib in Resources */, + A596309A2AEE1C6400D64628 /* Terminal.xib in Resources */, + 55154BE02B33911F001622DC /* ghostty in Resources */, + A5A1F8852A489D6800D1E8BC /* terminfo in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/src/cli/list_themes.zig b/src/cli/list_themes.zig index 37e515a42..be3a41c14 100644 --- a/src/cli/list_themes.zig +++ b/src/cli/list_themes.zig @@ -17,8 +17,8 @@ pub const Options = struct { /// /// Themes require that Ghostty have access to the resources directory. /// On macOS this is embedded in the app bundle. On Linux, this is usually -/// in `/usr/share`. If you're compiling from source, this is the -/// `zig-out/share` directory. You can also set the `GHOSTTY_RESOURCES_DIR` +/// in `/usr/share/ghostty`. If you're compiling from source, this is the +/// `zig-out/share/ghostty` directory. You can also set the `GHOSTTY_RESOURCES_DIR` /// environment variable to point to the resources directory. Themes /// live in the `themes` subdirectory of the resources directory. pub fn run(alloc: Allocator) !u8 { diff --git a/src/os/resourcesdir.zig b/src/os/resourcesdir.zig index 9726b6cdf..067c029d2 100644 --- a/src/os/resourcesdir.zig +++ b/src/os/resourcesdir.zig @@ -36,7 +36,7 @@ pub fn resourcesDir(alloc: std.mem.Allocator) !?[]const u8 { // On MacOS, we look for the app bundle path. if (comptime builtin.target.isDarwin()) { if (try maybeDir(&dir_buf, dir, "Contents/Resources", sentinel)) |v| { - return try alloc.dupe(u8, v); + return try std.fs.path.join(alloc, &.{ v, "ghostty" }); } } @@ -44,7 +44,7 @@ pub fn resourcesDir(alloc: std.mem.Allocator) !?[]const u8 { // is valid even on Mac since there is nothing that requires // Ghostty to be in an app bundle. if (try maybeDir(&dir_buf, dir, "share", sentinel)) |v| { - return try alloc.dupe(u8, v); + return try std.fs.path.join(alloc, &.{ v, "ghostty" }); } } diff --git a/src/termio/Exec.zig b/src/termio/Exec.zig index 863a4a86f..690cce752 100644 --- a/src/termio/Exec.zig +++ b/src/termio/Exec.zig @@ -759,10 +759,15 @@ const Subprocess = struct { // For now, we just look up a bundled dir but in the future we should // also load the terminfo database and look for it. if (opts.resources_dir) |base| { - var buf: [std.fs.MAX_PATH_BYTES]u8 = undefined; - const dir = try std.fmt.bufPrint(&buf, "{s}/terminfo", .{base}); try env.put("TERM", opts.config.term); try env.put("COLORTERM", "truecolor"); + + // Assume that the resources directory is adjacent to the terminfo + // database + var buf: [std.fs.MAX_PATH_BYTES]u8 = undefined; + const dir = try std.fmt.bufPrint(&buf, "{s}/terminfo", .{ + std.fs.path.dirname(base) orelse unreachable, + }); try env.put("TERMINFO", dir); } else { if (comptime builtin.target.isDarwin()) {