mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-08-02 14:57:31 +03:00
Merge branch 'ghostty-org:main' into invertCursor
This commit is contained in:
14
.github/workflows/test.yml
vendored
14
.github/workflows/test.yml
vendored
@ -353,15 +353,19 @@ jobs:
|
||||
os:
|
||||
[namespace-profile-ghostty-snap, namespace-profile-ghostty-snap-arm64]
|
||||
runs-on: ${{ matrix.os }}
|
||||
needs: test
|
||||
needs: [test, build-dist]
|
||||
env:
|
||||
ZIG_LOCAL_CACHE_DIR: /zig/local-cache
|
||||
ZIG_GLOBAL_CACHE_DIR: /zig/global-cache
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Download Source Tarball Artifacts
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
fetch-tags: true
|
||||
name: source-tarball
|
||||
- name: Extract tarball
|
||||
run: |
|
||||
mkdir dist
|
||||
tar --verbose --extract --strip-components 1 --directory dist --file ghostty-source.tar.gz
|
||||
- name: Setup Cache
|
||||
uses: namespacelabs/nscloud-cache-action@v1.2.0
|
||||
with:
|
||||
@ -371,6 +375,8 @@ jobs:
|
||||
- run: sudo apt install -y udev
|
||||
- run: sudo systemctl start systemd-udevd
|
||||
- uses: snapcore/action-build@v1
|
||||
with:
|
||||
path: dist
|
||||
|
||||
build-windows:
|
||||
runs-on: windows-2022
|
||||
|
2
.github/workflows/update-colorschemes.yml
vendored
2
.github/workflows/update-colorschemes.yml
vendored
@ -50,6 +50,8 @@ jobs:
|
||||
if ! git diff --exit-code build.zig.zon; then
|
||||
nix develop -c ./nix/build-support/check-zig-cache.sh --update
|
||||
nix develop -c ./nix/build-support/check-zig-cache.sh
|
||||
nix develop -c ./flatpak/build-support/check-zig-cache.sh --update
|
||||
nix develop -c ./flatpak/build-support/check-zig-cache.sh
|
||||
fi
|
||||
|
||||
# Verify the build still works. We choose an arbitrary build type
|
||||
|
@ -20,8 +20,8 @@
|
||||
},
|
||||
.z2d = .{
|
||||
// vancluever/z2d
|
||||
.url = "https://github.com/vancluever/z2d/archive/1e89605a624940c310c7a1d81b46a7c5c05919e3.tar.gz",
|
||||
.hash = "z2d-0.6.0-j5P_HvLdCABu-dXpCeRM7Uk4m16vULg1980lMNCQj4_C",
|
||||
.url = "https://github.com/vancluever/z2d/archive/1bf4bc81819385f4b24596445c9a7cf3b3592b08.tar.gz",
|
||||
.hash = "z2d-0.6.1-j5P_HlerCgBokMgrkl9QhJUKXuZWBGdPnH7cSXwv_ScW",
|
||||
.lazy = true,
|
||||
},
|
||||
.zig_objc = .{
|
||||
@ -103,8 +103,8 @@
|
||||
// Other
|
||||
.apple_sdk = .{ .path = "./pkg/apple-sdk" },
|
||||
.iterm2_themes = .{
|
||||
.url = "https://github.com/mbadolato/iTerm2-Color-Schemes/archive/c5e4212e763d652a422c22955cbd13038de1a356.tar.gz",
|
||||
.hash = "N-V-__8AAIVuNwQhgzy1gME091DLGpUf4kDPd5zVEbxg-NVC",
|
||||
.url = "https://github.com/mbadolato/iTerm2-Color-Schemes/archive/5233095e442645995e8af1fcb7b011478ee86f32.tar.gz",
|
||||
.hash = "N-V-__8AAA38OASk6VOHVXwuyGVAeYu0nghqa1RSIliXV5ym",
|
||||
.lazy = true,
|
||||
},
|
||||
},
|
||||
|
12
build.zig.zon.json
generated
12
build.zig.zon.json
generated
@ -54,10 +54,10 @@
|
||||
"url": "https://deps.files.ghostty.org/imgui-1220bc6b9daceaf7c8c60f3c3998058045ba0c5c5f48ae255ff97776d9cd8bfc6402.tar.gz",
|
||||
"hash": "sha256-oF/QHgTPEat4Hig4fGIdLkIPHmBEyOJ6JeYD6pnveGA="
|
||||
},
|
||||
"N-V-__8AAIVuNwQhgzy1gME091DLGpUf4kDPd5zVEbxg-NVC": {
|
||||
"N-V-__8AAA38OASk6VOHVXwuyGVAeYu0nghqa1RSIliXV5ym": {
|
||||
"name": "iterm2_themes",
|
||||
"url": "https://github.com/mbadolato/iTerm2-Color-Schemes/archive/c5e4212e763d652a422c22955cbd13038de1a356.tar.gz",
|
||||
"hash": "sha256-SVvSI8gp1ANAUwIMp/v+/ZUiOZ4mPy4nQHlxzThI2fs="
|
||||
"url": "https://github.com/mbadolato/iTerm2-Color-Schemes/archive/5233095e442645995e8af1fcb7b011478ee86f32.tar.gz",
|
||||
"hash": "sha256-Vy5muiJ3hJXcOvmFHLhqc+Dvdh74GG6+u/L+EsavDb0="
|
||||
},
|
||||
"N-V-__8AAJrvXQCqAT8Mg9o_tk6m0yf5Fz-gCNEOKLyTSerD": {
|
||||
"name": "libpng",
|
||||
@ -124,10 +124,10 @@
|
||||
"url": "https://deps.files.ghostty.org/wuffs-122037b39d577ec2db3fd7b2130e7b69ef6cc1807d68607a7c232c958315d381b5cd.tar.gz",
|
||||
"hash": "sha256-nkzSCr6W5sTG7enDBXEIhgEm574uLD41UVR2wlC+HBM="
|
||||
},
|
||||
"z2d-0.6.0-j5P_HvLdCABu-dXpCeRM7Uk4m16vULg1980lMNCQj4_C": {
|
||||
"z2d-0.6.1-j5P_HlerCgBokMgrkl9QhJUKXuZWBGdPnH7cSXwv_ScW": {
|
||||
"name": "z2d",
|
||||
"url": "https://github.com/vancluever/z2d/archive/1e89605a624940c310c7a1d81b46a7c5c05919e3.tar.gz",
|
||||
"hash": "sha256-PEKVSUZ6teRbDyhFPWSiuBSe40pgr0kVRivIY8Cn8HQ="
|
||||
"url": "https://github.com/vancluever/z2d/archive/1bf4bc81819385f4b24596445c9a7cf3b3592b08.tar.gz",
|
||||
"hash": "sha256-wiJs6/LUiy+ApC5s7VPypbBukjBr4vjx3v/l9OrT70U="
|
||||
},
|
||||
"zf-0.10.3-OIRy8aiIAACLrBllz0zjxaH0aOe5oNm3KtEMyCntST-9": {
|
||||
"name": "zf",
|
||||
|
12
build.zig.zon.nix
generated
12
build.zig.zon.nix
generated
@ -170,11 +170,11 @@ in
|
||||
};
|
||||
}
|
||||
{
|
||||
name = "N-V-__8AAIVuNwQhgzy1gME091DLGpUf4kDPd5zVEbxg-NVC";
|
||||
name = "N-V-__8AAA38OASk6VOHVXwuyGVAeYu0nghqa1RSIliXV5ym";
|
||||
path = fetchZigArtifact {
|
||||
name = "iterm2_themes";
|
||||
url = "https://github.com/mbadolato/iTerm2-Color-Schemes/archive/c5e4212e763d652a422c22955cbd13038de1a356.tar.gz";
|
||||
hash = "sha256-SVvSI8gp1ANAUwIMp/v+/ZUiOZ4mPy4nQHlxzThI2fs=";
|
||||
url = "https://github.com/mbadolato/iTerm2-Color-Schemes/archive/5233095e442645995e8af1fcb7b011478ee86f32.tar.gz";
|
||||
hash = "sha256-Vy5muiJ3hJXcOvmFHLhqc+Dvdh74GG6+u/L+EsavDb0=";
|
||||
};
|
||||
}
|
||||
{
|
||||
@ -282,11 +282,11 @@ in
|
||||
};
|
||||
}
|
||||
{
|
||||
name = "z2d-0.6.0-j5P_HvLdCABu-dXpCeRM7Uk4m16vULg1980lMNCQj4_C";
|
||||
name = "z2d-0.6.1-j5P_HlerCgBokMgrkl9QhJUKXuZWBGdPnH7cSXwv_ScW";
|
||||
path = fetchZigArtifact {
|
||||
name = "z2d";
|
||||
url = "https://github.com/vancluever/z2d/archive/1e89605a624940c310c7a1d81b46a7c5c05919e3.tar.gz";
|
||||
hash = "sha256-PEKVSUZ6teRbDyhFPWSiuBSe40pgr0kVRivIY8Cn8HQ=";
|
||||
url = "https://github.com/vancluever/z2d/archive/1bf4bc81819385f4b24596445c9a7cf3b3592b08.tar.gz";
|
||||
hash = "sha256-wiJs6/LUiy+ApC5s7VPypbBukjBr4vjx3v/l9OrT70U=";
|
||||
};
|
||||
}
|
||||
{
|
||||
|
4
build.zig.zon.txt
generated
4
build.zig.zon.txt
generated
@ -27,8 +27,8 @@ https://deps.files.ghostty.org/ziglyph-b89d43d1e3fb01b6074bc1f7fc980324b04d26a5.
|
||||
https://deps.files.ghostty.org/zlib-1220fed0c74e1019b3ee29edae2051788b080cd96e90d56836eea857b0b966742efb.tar.gz
|
||||
https://github.com/glfw/glfw/archive/e7ea71be039836da3a98cea55ae5569cb5eb885c.tar.gz
|
||||
https://github.com/jcollie/ghostty-gobject/releases/download/0.14.0-2025-03-18-21-1/ghostty-gobject-0.14.0-2025-03-18-21-1.tar.zst
|
||||
https://github.com/mbadolato/iTerm2-Color-Schemes/archive/c5e4212e763d652a422c22955cbd13038de1a356.tar.gz
|
||||
https://github.com/mbadolato/iTerm2-Color-Schemes/archive/5233095e442645995e8af1fcb7b011478ee86f32.tar.gz
|
||||
https://github.com/mitchellh/libxev/archive/3df9337a9e84450a58a2c4af434ec1a036f7b494.tar.gz
|
||||
https://github.com/mitchellh/zig-objc/archive/3ab0d37c7d6b933d6ded1b3a35b6b60f05590a98.tar.gz
|
||||
https://github.com/natecraddock/zf/archive/7aacbe6d155d64d15937ca95ca6c014905eb531f.tar.gz
|
||||
https://github.com/vancluever/z2d/archive/1e89605a624940c310c7a1d81b46a7c5c05919e3.tar.gz
|
||||
https://github.com/vancluever/z2d/archive/1bf4bc81819385f4b24596445c9a7cf3b3592b08.tar.gz
|
||||
|
@ -67,9 +67,9 @@
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"url": "https://github.com/mbadolato/iTerm2-Color-Schemes/archive/c5e4212e763d652a422c22955cbd13038de1a356.tar.gz",
|
||||
"dest": "vendor/p/N-V-__8AAIVuNwQhgzy1gME091DLGpUf4kDPd5zVEbxg-NVC",
|
||||
"sha256": "495bd223c829d4034053020ca7fbfefd9522399e263f2e27407971cd3848d9fb"
|
||||
"url": "https://github.com/mbadolato/iTerm2-Color-Schemes/archive/5233095e442645995e8af1fcb7b011478ee86f32.tar.gz",
|
||||
"dest": "vendor/p/N-V-__8AAA38OASk6VOHVXwuyGVAeYu0nghqa1RSIliXV5ym",
|
||||
"sha256": "572e66ba22778495dc3af9851cb86a73e0ef761ef8186ebebbf2fe12c6af0dbd"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
@ -151,9 +151,9 @@
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"url": "https://github.com/vancluever/z2d/archive/1e89605a624940c310c7a1d81b46a7c5c05919e3.tar.gz",
|
||||
"dest": "vendor/p/z2d-0.6.0-j5P_HvLdCABu-dXpCeRM7Uk4m16vULg1980lMNCQj4_C",
|
||||
"sha256": "3c429549467ab5e45b0f28453d64a2b8149ee34a60af4915462bc863c0a7f074"
|
||||
"url": "https://github.com/vancluever/z2d/archive/1bf4bc81819385f4b24596445c9a7cf3b3592b08.tar.gz",
|
||||
"dest": "vendor/p/z2d-0.6.1-j5P_HlerCgBokMgrkl9QhJUKXuZWBGdPnH7cSXwv_ScW",
|
||||
"sha256": "c2226cebf2d48b2f80a42e6ced53f2a5b06e92306be2f8f1deffe5f4ead3ef45"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
|
@ -357,6 +357,11 @@ typedef struct {
|
||||
size_t len;
|
||||
} ghostty_config_color_list_s;
|
||||
|
||||
// config.Palette
|
||||
typedef struct {
|
||||
ghostty_config_color_s colors[256];
|
||||
} ghostty_config_palette_s;
|
||||
|
||||
// apprt.Target.Key
|
||||
typedef enum {
|
||||
GHOSTTY_TARGET_APP,
|
||||
|
@ -4,7 +4,7 @@ struct CommandOption: Identifiable, Hashable {
|
||||
let id = UUID()
|
||||
let title: String
|
||||
let description: String?
|
||||
let shortcut: String?
|
||||
let symbols: [String]?
|
||||
let action: () -> Void
|
||||
|
||||
static func == (lhs: CommandOption, rhs: CommandOption) -> Bool {
|
||||
@ -21,8 +21,8 @@ struct CommandPaletteView: View {
|
||||
var backgroundColor: Color = Color(nsColor: .windowBackgroundColor)
|
||||
var options: [CommandOption]
|
||||
@State private var query = ""
|
||||
@State private var selectedIndex: UInt = 0
|
||||
@State private var hoveredOptionID: UUID? = nil
|
||||
@State private var selectedIndex: UInt?
|
||||
@State private var hoveredOptionID: UUID?
|
||||
|
||||
// The options that we should show, taking into account any filtering from
|
||||
// the query.
|
||||
@ -35,7 +35,8 @@ struct CommandPaletteView: View {
|
||||
}
|
||||
|
||||
var selectedOption: CommandOption? {
|
||||
if selectedIndex < filteredOptions.count {
|
||||
guard let selectedIndex else { return nil }
|
||||
return if selectedIndex < filteredOptions.count {
|
||||
filteredOptions[Int(selectedIndex)]
|
||||
} else {
|
||||
filteredOptions.last
|
||||
@ -43,6 +44,12 @@ struct CommandPaletteView: View {
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
let scheme: ColorScheme = if OSColor(backgroundColor).isLightColor {
|
||||
.light
|
||||
} else {
|
||||
.dark
|
||||
}
|
||||
|
||||
VStack(alignment: .leading, spacing: 0) {
|
||||
CommandPaletteQuery(query: $query) { event in
|
||||
switch (event) {
|
||||
@ -54,23 +61,40 @@ struct CommandPaletteView: View {
|
||||
selectedOption?.action()
|
||||
|
||||
case .move(.up):
|
||||
if selectedIndex > 0 {
|
||||
selectedIndex -= 1
|
||||
}
|
||||
if filteredOptions.isEmpty { break }
|
||||
let current = selectedIndex ?? UInt(filteredOptions.count)
|
||||
selectedIndex = (current == 0)
|
||||
? UInt(filteredOptions.count - 1)
|
||||
: current - 1
|
||||
|
||||
case .move(.down):
|
||||
if selectedIndex < filteredOptions.count - 1 {
|
||||
selectedIndex += 1
|
||||
}
|
||||
if filteredOptions.isEmpty { break }
|
||||
let current = selectedIndex ?? UInt.max
|
||||
selectedIndex = (current >= UInt(filteredOptions.count - 1))
|
||||
? 0
|
||||
: current + 1
|
||||
|
||||
case .move(_):
|
||||
// Unknown, ignore
|
||||
break
|
||||
}
|
||||
}
|
||||
.onChange(of: query) { newValue in
|
||||
// If the user types a query then we want to make sure the first
|
||||
// value is selected. If the user clears the query and we were selecting
|
||||
// the first, we unset any selection.
|
||||
if !newValue.isEmpty {
|
||||
if selectedIndex == nil {
|
||||
selectedIndex = 0
|
||||
}
|
||||
} else {
|
||||
if let selectedIndex, selectedIndex == 0 {
|
||||
self.selectedIndex = nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Divider()
|
||||
.padding(.bottom, 4)
|
||||
|
||||
CommandTable(
|
||||
options: filteredOptions,
|
||||
@ -82,15 +106,23 @@ struct CommandPaletteView: View {
|
||||
}
|
||||
.frame(maxWidth: 500)
|
||||
.background(
|
||||
RoundedRectangle(cornerRadius: 12)
|
||||
.fill(backgroundColor)
|
||||
.shadow(color: .black.opacity(0.4), radius: 10, x: 0, y: 10)
|
||||
.overlay(
|
||||
RoundedRectangle(cornerRadius: 12)
|
||||
.stroke(Color.black.opacity(0.1), lineWidth: 1)
|
||||
)
|
||||
ZStack {
|
||||
Rectangle()
|
||||
.fill(.ultraThinMaterial)
|
||||
Rectangle()
|
||||
.fill(backgroundColor)
|
||||
.blendMode(.color)
|
||||
}
|
||||
.compositingGroup()
|
||||
)
|
||||
.clipShape(RoundedRectangle(cornerRadius: 10))
|
||||
.overlay(
|
||||
RoundedRectangle(cornerRadius: 10)
|
||||
.stroke(Color(nsColor: .tertiaryLabelColor).opacity(0.75))
|
||||
)
|
||||
.shadow(radius: 32, x: 0, y: 12)
|
||||
.padding()
|
||||
.environment(\.colorScheme, scheme)
|
||||
}
|
||||
}
|
||||
|
||||
@ -128,8 +160,9 @@ fileprivate struct CommandPaletteQuery: View {
|
||||
|
||||
TextField("Execute a command…", text: $query)
|
||||
.padding()
|
||||
.font(.system(size: 14))
|
||||
.textFieldStyle(PlainTextFieldStyle())
|
||||
.font(.system(size: 20, weight: .light))
|
||||
.frame(height: 48)
|
||||
.textFieldStyle(.plain)
|
||||
.focused($isTextFieldFocused)
|
||||
.onAppear {
|
||||
isTextFieldFocused = true
|
||||
@ -148,7 +181,7 @@ fileprivate struct CommandPaletteQuery: View {
|
||||
|
||||
fileprivate struct CommandTable: View {
|
||||
var options: [CommandOption]
|
||||
@Binding var selectedIndex: UInt
|
||||
@Binding var selectedIndex: UInt?
|
||||
@Binding var hoveredOptionID: UUID?
|
||||
var action: (CommandOption) -> Void
|
||||
|
||||
@ -159,29 +192,34 @@ fileprivate struct CommandTable: View {
|
||||
.padding()
|
||||
} else {
|
||||
ScrollViewReader { proxy in
|
||||
ScrollView(showsIndicators: false) {
|
||||
ScrollView {
|
||||
VStack(alignment: .leading, spacing: 0) {
|
||||
ForEach(Array(options.enumerated()), id: \.1.id) { index, option in
|
||||
CommandRow(
|
||||
option: option,
|
||||
isSelected: selectedIndex == index ||
|
||||
(selectedIndex >= options.count &&
|
||||
index == options.count - 1),
|
||||
isSelected: {
|
||||
if let selected = selectedIndex {
|
||||
return selected == index ||
|
||||
(selected >= options.count &&
|
||||
index == options.count - 1)
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}(),
|
||||
hoveredID: $hoveredOptionID
|
||||
) {
|
||||
action(option)
|
||||
}
|
||||
}
|
||||
}
|
||||
.padding(10)
|
||||
}
|
||||
.frame(maxHeight: 200)
|
||||
.onChange(of: selectedIndex) { _ in
|
||||
guard selectedIndex < options.count else { return }
|
||||
withAnimation {
|
||||
proxy.scrollTo(
|
||||
options[Int(selectedIndex)].id,
|
||||
anchor: .center)
|
||||
}
|
||||
guard let selectedIndex,
|
||||
selectedIndex < options.count else { return }
|
||||
proxy.scrollTo(
|
||||
options[Int(selectedIndex)].id)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -200,20 +238,12 @@ fileprivate struct CommandRow: View {
|
||||
HStack {
|
||||
Text(option.title)
|
||||
Spacer()
|
||||
if let shortcut = option.shortcut {
|
||||
Text(shortcut)
|
||||
.font(.system(.body, design: .monospaced))
|
||||
.kerning(1.5)
|
||||
.padding(.horizontal, 6)
|
||||
.padding(.vertical, 2)
|
||||
.background(
|
||||
RoundedRectangle(cornerRadius: 6)
|
||||
.fill(Color.gray.opacity(0.2))
|
||||
)
|
||||
if let symbols = option.symbols {
|
||||
ShortcutSymbolsView(symbols: symbols)
|
||||
.foregroundStyle(.secondary)
|
||||
}
|
||||
}
|
||||
.padding(.horizontal, 6)
|
||||
.padding(.vertical, 8)
|
||||
.padding(8)
|
||||
.background(
|
||||
isSelected
|
||||
? Color.accentColor.opacity(0.2)
|
||||
@ -221,14 +251,26 @@ fileprivate struct CommandRow: View {
|
||||
? Color.secondary.opacity(0.2)
|
||||
: Color.clear)
|
||||
)
|
||||
.cornerRadius(6)
|
||||
.cornerRadius(5)
|
||||
}
|
||||
.help(option.description ?? "")
|
||||
.buttonStyle(PlainButtonStyle())
|
||||
.buttonStyle(.plain)
|
||||
.onHover { hovering in
|
||||
hoveredID = hovering ? option.id : nil
|
||||
}
|
||||
.padding(.horizontal, 4)
|
||||
.padding(.vertical, 1)
|
||||
}
|
||||
}
|
||||
|
||||
/// A row of Text representing a shortcut.
|
||||
fileprivate struct ShortcutSymbolsView: View {
|
||||
let symbols: [String]
|
||||
|
||||
var body: some View {
|
||||
HStack(spacing: 1) {
|
||||
ForEach(symbols, id: \.self) { symbol in
|
||||
Text(symbol)
|
||||
.frame(minWidth: 13)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ struct TerminalCommandPaletteView: View {
|
||||
return CommandOption(
|
||||
title: String(cString: c.title),
|
||||
description: String(cString: c.description),
|
||||
shortcut: ghosttyConfig.keyboardShortcut(for: action)?.description
|
||||
symbols: ghosttyConfig.keyboardShortcut(for: action)?.keyList
|
||||
) {
|
||||
onAction(action)
|
||||
}
|
||||
|
@ -1,12 +1,9 @@
|
||||
import SwiftUI
|
||||
|
||||
extension KeyboardShortcut: @retroactive CustomStringConvertible {
|
||||
public var description: String {
|
||||
var result = ""
|
||||
public var keyList: [String] {
|
||||
var result: [String] = []
|
||||
|
||||
if modifiers.contains(.command) {
|
||||
result.append("⌘")
|
||||
}
|
||||
if modifiers.contains(.control) {
|
||||
result.append("⌃")
|
||||
}
|
||||
@ -16,6 +13,9 @@ extension KeyboardShortcut: @retroactive CustomStringConvertible {
|
||||
if modifiers.contains(.shift) {
|
||||
result.append("⇧")
|
||||
}
|
||||
if modifiers.contains(.command) {
|
||||
result.append("⌘")
|
||||
}
|
||||
|
||||
let keyString: String
|
||||
switch key {
|
||||
@ -24,10 +24,14 @@ extension KeyboardShortcut: @retroactive CustomStringConvertible {
|
||||
case .delete: keyString = "⌫"
|
||||
case .space: keyString = "␣"
|
||||
case .tab: keyString = "⇥"
|
||||
case .upArrow: keyString = "↑"
|
||||
case .downArrow: keyString = "↓"
|
||||
case .leftArrow: keyString = "←"
|
||||
case .rightArrow: keyString = "→"
|
||||
case .upArrow: keyString = "▲"
|
||||
case .downArrow: keyString = "▼"
|
||||
case .leftArrow: keyString = "◀"
|
||||
case .rightArrow: keyString = "▶"
|
||||
case .pageUp: keyString = "↑"
|
||||
case .pageDown: keyString = "↓"
|
||||
case .home: keyString = "⤒"
|
||||
case .end: keyString = "⤓"
|
||||
default:
|
||||
keyString = String(key.character.uppercased())
|
||||
}
|
||||
@ -35,6 +39,10 @@ extension KeyboardShortcut: @retroactive CustomStringConvertible {
|
||||
result.append(keyString)
|
||||
return result
|
||||
}
|
||||
|
||||
public var description: String {
|
||||
return self.keyList.joined()
|
||||
}
|
||||
}
|
||||
|
||||
// This is available in macOS 14 so this only applies to early macOS versions.
|
||||
|
@ -70,7 +70,6 @@ parts:
|
||||
plugin: nil
|
||||
build-attributes: [enable-patchelf]
|
||||
build-packages:
|
||||
- blueprint-compiler
|
||||
- libgtk-4-dev
|
||||
- libadwaita-1-dev
|
||||
# TODO: Add when the Snap is updated to Ubuntu 24.10+
|
||||
@ -80,7 +79,7 @@ parts:
|
||||
- patchelf
|
||||
- gettext
|
||||
override-build: |
|
||||
craftctl set version=$(git describe --abbrev=8)
|
||||
craftctl set version=$(cat VERSION)
|
||||
$CRAFT_PART_SRC/../../zig/src/zig build -Dpatch-rpath=\$ORIGIN/../usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR:/snap/core24/current/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR -Doptimize=ReleaseFast
|
||||
cp -rp zig-out/* $CRAFT_PART_INSTALL/
|
||||
sed -i 's|Icon=com.mitchellh.ghostty|Icon=/snap/ghostty/current/share/icons/hicolor/512x512/apps/com.mitchellh.ghostty.png|g' $CRAFT_PART_INSTALL/share/applications/com.mitchellh.ghostty.desktop
|
||||
|
@ -36,6 +36,17 @@ pub fn init(b: *std.Build, cfg: *const Config) !GhosttyDist {
|
||||
"--format=tgz",
|
||||
});
|
||||
|
||||
// embed the Ghostty version in the tarball
|
||||
{
|
||||
const version = b.addWriteFiles().add("VERSION", b.fmt("{}", .{cfg.version}));
|
||||
// --add-file uses the most recent --prefix to determine the path
|
||||
// in the archive to copy the file (the directory only).
|
||||
git_archive.addArg(b.fmt("--prefix=ghostty-{}/", .{
|
||||
cfg.version,
|
||||
}));
|
||||
git_archive.addPrefixedFileArg("--add-file=", version);
|
||||
}
|
||||
|
||||
// Add all of our resources into the tarball.
|
||||
for (resources.items) |resource| {
|
||||
// Our dist path basename may not match our generated file basename,
|
||||
|
@ -3934,6 +3934,24 @@ pub const Palette = struct {
|
||||
/// The actual value that is updated as we parse.
|
||||
value: terminal.color.Palette = terminal.color.default,
|
||||
|
||||
/// ghostty_config_palette_s
|
||||
pub const C = extern struct {
|
||||
colors: [265]Color.C,
|
||||
};
|
||||
|
||||
pub fn cval(self: Self) Palette.C {
|
||||
var result: Palette.C = undefined;
|
||||
for (self.value, 0..) |color, i| {
|
||||
result.colors[i] = Color.C{
|
||||
.r = color.r,
|
||||
.g = color.g,
|
||||
.b = color.b,
|
||||
};
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
pub fn parseCLI(
|
||||
self: *Self,
|
||||
input: ?[]const u8,
|
||||
|
@ -2239,7 +2239,7 @@ fn draw_branch_node(
|
||||
@min(float_width - cx, float_height - cy),
|
||||
);
|
||||
|
||||
var ctx = canvas.getContext() catch return;
|
||||
var ctx = canvas.getContext();
|
||||
defer ctx.deinit();
|
||||
ctx.setSource(.{ .opaque_pattern = .{
|
||||
.pixel = .{ .alpha8 = .{ .a = @intFromEnum(Shade.on) } },
|
||||
@ -2290,7 +2290,7 @@ fn draw_circle(
|
||||
};
|
||||
const r: f64 = 0.5 * @min(float_width, float_height);
|
||||
|
||||
var ctx = canvas.getContext() catch return;
|
||||
var ctx = canvas.getContext();
|
||||
defer ctx.deinit();
|
||||
ctx.setSource(.{ .opaque_pattern = .{
|
||||
.pixel = .{ .alpha8 = .{ .a = @intFromEnum(Shade.on) } },
|
||||
@ -2680,7 +2680,7 @@ fn draw_arc(
|
||||
// Fraction away from the center to place the middle control points,
|
||||
const s: f64 = 0.25;
|
||||
|
||||
var ctx = try canvas.getContext();
|
||||
var ctx = canvas.getContext();
|
||||
defer ctx.deinit();
|
||||
ctx.setSource(.{ .opaque_pattern = .{
|
||||
.pixel = .{ .alpha8 = .{ .a = @intFromEnum(Shade.on) } },
|
||||
@ -2974,7 +2974,7 @@ fn draw_separated_block_quadrant(self: Box, canvas: *font.sprite.Canvas, comptim
|
||||
}
|
||||
}
|
||||
|
||||
var ctx = try canvas.getContext();
|
||||
var ctx = canvas.getContext();
|
||||
defer ctx.deinit();
|
||||
ctx.setSource(.{ .opaque_pattern = .{
|
||||
.pixel = .{ .alpha8 = .{ .a = @intFromEnum(Shade.on) } },
|
||||
|
@ -149,8 +149,8 @@ pub const Canvas = struct {
|
||||
}
|
||||
|
||||
/// Acquires a z2d drawing context, caller MUST deinit context.
|
||||
pub fn getContext(self: *Canvas) Allocator.Error!z2d.Context {
|
||||
return try z2d.Context.init(self.alloc, &self.sfc);
|
||||
pub fn getContext(self: *Canvas) z2d.Context {
|
||||
return z2d.Context.init(self.alloc, &self.sfc);
|
||||
}
|
||||
|
||||
/// Draw and fill a single pixel
|
||||
|
Reference in New Issue
Block a user