Merge branch 'ghostty-org:main' into ms_MY

This commit is contained in:
яυzαιηι
2025-05-08 01:49:32 +08:00
committed by GitHub
133 changed files with 4021 additions and 2147 deletions

View File

@ -1,4 +1,4 @@
labels: ["needs confirmation"]
labels: ["needs-confirmation"]
body:
- type: markdown
attributes:
@ -14,22 +14,37 @@ body:
description: |
Provide a detailed description of the issue. Include relevant information, such as:
- The feature or configuration option you encounter the issue with.
- The expected behavior.
- The actual behavior (and how it deviates from the expected behavior, if it is not immediately obvious).
- Relevant Ghostty logs or other stacktraces.
- Relevant screenshots, screen recordings, or other supporting media (as needed).
- Screenshots, screen recordings, or other supporting media (as needed).
- If this is a regression of an existing issue that was closed or resolved, please include the previous item reference (Discussion, Issue, PR, commit) in your description.
>[!TIP]
> [!TIP]
> **Not sure what information to include?**
> Here are some recommendations:
> - **Input issues:** include your keyboard layout, a screenshot of the terminal inspector's logged keystrokes (Linux: <kbd>ctrl</kbd>+<kbd>shift</kbd>+<kbd>i</kbd>; MacOS: <kbd>cmd</kbd>+<kbd>alt</kbd>+<kbd>i</kbd>), input method, Linux input method engine (IBus, Fcitx 5, or none) and its version.
> - **Input issues:** include your keyboard layout, a screenshot of logged keystrokes from the terminal inspector's "Keyboard" tab (Linux: <kbd>ctrl</kbd>+<kbd>shift</kbd>+<kbd>i</kbd>; MacOS: <kbd>cmd</kbd>+<kbd>alt</kbd>+<kbd>i</kbd>), input method, Linux input method engine (IBus, Fcitx 5, or none) and its version.
> - **Font issues:** include the problematic character(s), the output of `ghostty +show-face` for these character(s), and if they work in other applications.
> - **VT issues (including image rendering issues):** attach an [asciinema](https://docs.asciinema.org/getting-started/) cast file, shell script, or text file for reproduction.
> - **Terminal emulation issues (including image rendering issues):** attach an [asciinema](https://docs.asciinema.org/getting-started/) cast file, shell script, or text file for reproduction.
> - **Renderer issues:** (Linux) include your OpenGL version, graphics card, driver version.
> - **Crashes:** (macOS) include the [Sentry UUID](https://github.com/ghostty-org/ghostty?tab=readme-ov-file#crash-reports); (Linux) try to reproduce using a debug build and provide the stack trace.
placeholder: |
Example: When using SSH to connect to my remote Linux machine from my local macOS device in Ghostty, I try to run `clear`, and the screen does not clear. Instead, I see the following error message printed to the terminal: `Error opening terminal: xterm-ghostty.`
When using SSH to connect to my remote Linux machine from my local macOS device in Ghostty, I try to run `clear`, and the screen does not clear. Instead, I see the following error message printed to the terminal: `Error opening terminal: xterm-ghostty.`
validations:
required: true
- type: textarea
attributes:
label: Expected Behavior
description: |
Describe how you expect Ghostty to behave in this situation. Include any relevant documentation links.
placeholder: |
The screen is cleared and the prompt is redrawn at the top of the window.
validations:
required: true
- type: textarea
attributes:
label: Actual Behavior
description: |
Describe how Ghostty actually behaves in this situation. If it is not immediately obvious how the actual behavior differs from the expected behavior described above, please be sure to mention the deviation specifically.
placeholder: |
The screen is not cleared, and an error is printed: `Error opening terminal: xterm-ghostty`.
validations:
required: true
- type: textarea
@ -44,6 +59,12 @@ body:
4. Observe `xterm-ghostty` error message above.
validations:
required: true
- type: textarea
attributes:
label: Ghostty Logs
description: |
Provide any captured Ghostty logs or stacktraces during your issue reproduction in this field. On Linux, logs can be found by running `ghostty` from the command-line; on macOS, logs can be viewed with `sudo log stream --level debug --predicate 'subsystem=="com.mitchellh.ghostty"'` from another terminal emulator.
render: text
- type: textarea
attributes:
label: Ghostty Version
@ -93,9 +114,9 @@ body:
required: false
- type: textarea
attributes:
label: Ghostty Configuration
label: Minimal Ghostty Configuration
description: |
Please provide the minimum configuration needed to reproduce this issue. If you cannot determine this, paste the output of `ghostty +show-config` here.
Please provide the **minimum** configuration needed to reproduce this issue. If you can still reproduce the issue with one of the lines removed, do not include that line. If and **only** if you are not able to determine this, paste the contents of your Ghostty configuration file here.
placeholder: |
font-family = CommitMono Nerd Font
font-family-bold = CommitMono Nerd Font
@ -112,15 +133,15 @@ body:
attributes:
label: Additional Relevant Configuration
description: |
If your issue involves other programs, tools, or applications in addition to Ghostty (e.g. Neovim, tmux, Zellij, etc.), please provide the minimum configuration needed for all relevant programs to reproduce the issue here. If you use custom CSS or shaders for Ghostty, also include them here, if applicable to your issue.
If your issue involves other programs, tools, or applications in addition to Ghostty (e.g. Neovim, tmux, Zellij, etc.), please provide the minimum configuration and versions needed for all relevant programs to reproduce the issue here. If you use custom CSS or shaders for Ghostty, also include them here, if applicable to your issue.
placeholder: |
`tmux.conf`
---
#### `tmux.conf` (tmux 3.5a)
```
set -g default-terminal "tmux-256color"
set-option -sa terminal-overrides ",xterm*:Tc"
set -g base-index 1
setw -g pane-base-index 1
render: text
```
validations:
required: false
- type: markdown
@ -137,3 +158,5 @@ body:
required: true
- label: I have searched the Ghostty repository (both open and closed Discussions and Issues) and confirm this is not a duplicate of an existing issue or discussion.
required: true
- label: I have checked the "Preview" tab on all text fields to ensure that everything looks right, and have wrapped all configuration and code in code blocks with a group of three backticks (` ``` `) on separate lines.
required: true

14
.github/scripts/check-translations.sh vendored Executable file
View File

@ -0,0 +1,14 @@
#!/bin/sh
old_pot=$(mktemp)
cp po/com.mitchellh.ghostty.pot "$old_pot"
zig build update-translations
# Compare previous POT to current POT
msgcmp "$old_pot" po/com.mitchellh.ghostty.pot --use-untranslated
# Compare all other POs to current POT
for f in po/*.po; do
# Ignore untranslated entries
msgcmp --use-untranslated "$f" po/com.mitchellh.ghostty.pot;
done

View File

@ -1,189 +0,0 @@
# /// script
# requires-python = ">=3.9"
# dependencies = [
# "githubkit",
# "loguru",
# ]
# ///
from __future__ import annotations
import asyncio
import os
import re
import sys
from collections.abc import Iterator
from contextlib import contextmanager
from itertools import chain
from githubkit import GitHub
from githubkit.exception import RequestFailed
from loguru import logger
ORG_NAME = "ghostty-org"
REPO_NAME = "ghostty"
ALLOWED_PARENT_TEAM = "localization"
LOCALIZATION_TEAM_NAME_PATTERN = re.compile(r"[a-z]{2}_[A-Z]{2}")
LEVEL_MAP = {"DEBUG": "DBG", "WARNING": "WRN", "ERROR": "ERR"}
logger.remove()
logger.add(
sys.stderr,
format=lambda record: (
"<green>{time:YYYY-MM-DD HH:mm:ss.SSS}</green> | "
f"<level>{LEVEL_MAP[record['level'].name]}</level> | "
"<cyan>{function}</cyan>:<cyan>{line}</cyan> - "
"<level>{message}</level>\n"
),
backtrace=True,
diagnose=True,
)
@contextmanager
def log_fail(message: str, *, die: bool = True) -> Iterator[None]:
try:
yield
except RequestFailed as exc:
logger.error(message)
logger.error(exc)
logger.error(exc.response.raw_response.json())
if die:
sys.exit(1)
gh = GitHub(os.environ["GITHUB_TOKEN"])
with log_fail("Invalid token"):
# Do the simplest request as a test
gh.rest.rate_limit.get()
async def fetch_and_parse_codeowners() -> dict[str, str]:
logger.debug("Fetching CODEOWNERS file...")
with log_fail("Failed to fetch CODEOWNERS file"):
content = (
await gh.rest.repos.async_get_content(
ORG_NAME,
REPO_NAME,
"CODEOWNERS",
headers={"Accept": "application/vnd.github.raw+json"},
)
).text
logger.debug("Parsing CODEOWNERS file...")
codeowners: dict[str, str] = {}
for line in content.splitlines():
if not line or line.lstrip().startswith("#"):
continue
# This assumes that all entries only list one owner
# and that this owner is a team (ghostty-org/foobar)
path, owner = line.split()
path = path.lstrip("/")
owner = owner.removeprefix(f"@{ORG_NAME}/")
if not is_localization_team(owner):
logger.debug(f"Skipping non-l11n codeowner {owner!r} for {path}")
continue
codeowners[path] = owner
logger.debug(f"Found codeowner {owner!r} for {path}")
return codeowners
async def get_team_members(team_name: str) -> list[str]:
logger.debug(f"Fetching team {team_name!r}...")
with log_fail(f"Failed to fetch team {team_name!r}"):
team = (await gh.rest.teams.async_get_by_name(ORG_NAME, team_name)).parsed_data
if team.parent and team.parent.slug == ALLOWED_PARENT_TEAM:
logger.debug(f"Fetching team {team_name!r} members...")
with log_fail(f"Failed to fetch team {team_name!r} members"):
resp = await gh.rest.teams.async_list_members_in_org(ORG_NAME, team_name)
members = [m.login for m in resp.parsed_data]
logger.debug(f"Team {team_name!r} members: {', '.join(members)}")
return members
logger.warning(f"Team {team_name} does not have a {ALLOWED_PARENT_TEAM!r} parent")
return []
async def get_changed_files(pr_number: int) -> list[str]:
logger.debug("Gathering changed files...")
with log_fail("Failed to gather changed files"):
diff_entries = (
await gh.rest.pulls.async_list_files(
ORG_NAME,
REPO_NAME,
pr_number,
per_page=3000,
headers={"Accept": "application/vnd.github+json"},
)
).parsed_data
return [d.filename for d in diff_entries]
async def request_review(pr_number: int, user: str, pr_author: str) -> None:
if user == pr_author:
logger.debug(f"Skipping review request for {user!r} (is PR author)")
logger.debug(f"Requesting review from {user!r}...")
with log_fail(f"Failed to request review from {user}", die=False):
await gh.rest.pulls.async_request_reviewers(
ORG_NAME,
REPO_NAME,
pr_number,
headers={"Accept": "application/vnd.github+json"},
data={"reviewers": [user]},
)
def is_localization_team(team_name: str) -> bool:
return LOCALIZATION_TEAM_NAME_PATTERN.fullmatch(team_name) is not None
async def get_pr_author(pr_number: int) -> str:
logger.debug("Fetching PR author...")
with log_fail("Failed to fetch PR author"):
resp = await gh.rest.pulls.async_get(ORG_NAME, REPO_NAME, pr_number)
pr_author = resp.parsed_data.user.login
logger.debug(f"Found author: {pr_author!r}")
return pr_author
async def main() -> None:
logger.debug("Reading PR number...")
pr_number = int(os.environ["PR_NUMBER"])
logger.debug(f"Starting review request process for PR #{pr_number}...")
changed_files = await get_changed_files(pr_number)
logger.debug(f"Changed files: {', '.join(map(repr, changed_files))}")
pr_author = await get_pr_author(pr_number)
codeowners = await fetch_and_parse_codeowners()
found_owners = set[str]()
for file in changed_files:
logger.debug(f"Finding owner for {file!r}...")
for path, owner in codeowners.items():
if file.startswith(path):
logger.debug(f"Found owner: {owner!r}")
break
else:
logger.debug("No owner found")
continue
found_owners.add(owner)
member_lists = await asyncio.gather(
*(get_team_members(owner) for owner in found_owners)
)
await asyncio.gather(
*(
request_review(pr_number, user, pr_author)
for user in chain.from_iterable(member_lists)
)
)
if __name__ == "__main__":
asyncio.run(main())

View File

@ -1,37 +0,0 @@
name: Request Review
on:
pull_request:
types:
- opened
- synchronize
env:
PY_COLORS: 1
jobs:
review:
runs-on: namespace-profile-ghostty-xsm
steps:
- uses: actions/checkout@v4
- name: Setup Cache
uses: namespacelabs/nscloud-cache-action@v1.2.0
with:
path: |
/nix
/zig
- uses: cachix/install-nix-action@v30
with:
nix_path: nixpkgs=channel:nixos-unstable
- uses: cachix/cachix-action@v15
with:
name: ghostty
authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
- name: Request Localization Review
env:
GITHUB_TOKEN: ${{ secrets.GH_REVIEW_TOKEN }}
PR_NUMBER: ${{ github.event.pull_request.number }}
run: nix develop -c uv run .github/scripts/request_review.py

View File

@ -21,6 +21,8 @@ jobs:
- build-macos-matrix
- build-windows
- build-windows-cross
- flatpak-check-zig-cache
- flatpak
- test
- test-gtk
- test-sentry-linux
@ -351,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:
@ -368,7 +374,14 @@ jobs:
/zig
- run: sudo apt install -y udev
- run: sudo systemctl start systemd-udevd
# Workaround until this is fixed: https://github.com/canonical/lxd-pkg-snap/pull/789
- run: |
_LXD_SNAP_DEVCGROUP_CONFIG="/var/lib/snapd/cgroup/snap.lxd.device"
sudo mkdir -p /var/lib/snapd/cgroup
echo 'self-managed=true' | sudo tee "${_LXD_SNAP_DEVCGROUP_CONFIG}"
- uses: snapcore/action-build@v1
with:
path: dist
build-windows:
runs-on: windows-2022
@ -734,7 +747,7 @@ jobs:
translations:
if: github.repository == 'ghostty-org/ghostty'
runs-on: namespace-profile-ghostty-sm
runs-on: namespace-profile-ghostty-xsm
timeout-minutes: 60
env:
ZIG_LOCAL_CACHE_DIR: /zig/local-cache
@ -757,23 +770,11 @@ jobs:
skipPush: true
useDaemon: false # sometimes fails on short jobs
- name: check translations
run: |
old_pot=$(mktemp)
cp po/com.mitchellh.ghostty.pot "$old_pot"
nix develop -c zig build update-translations
# Compare previous POT to current POT
msgcmp "$old_pot" po/com.mitchellh.ghostty.pot --use-untranslated
# Compare all other POs to current POT
for f in po/*.po; do
# Ignore untranslated entries
msgcmp --use-untranslated "$f" po/com.mitchellh.ghostty.pot;
done
run: nix develop -c .github/scripts/check-translations.sh
blueprint-compiler:
if: github.repository == 'ghostty-org/ghostty'
runs-on: namespace-profile-ghostty-sm
runs-on: namespace-profile-ghostty-xsm
timeout-minutes: 60
env:
ZIG_LOCAL_CACHE_DIR: /zig/local-cache
@ -863,3 +864,56 @@ jobs:
file: dist/src/build/docker/debian/Dockerfile
build-args: |
DISTRO_VERSION=12
flatpak-check-zig-cache:
if: github.repository == 'ghostty-org/ghostty'
runs-on: namespace-profile-ghostty-xsm
env:
ZIG_LOCAL_CACHE_DIR: /zig/local-cache
ZIG_GLOBAL_CACHE_DIR: /zig/global-cache
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Cache
uses: namespacelabs/nscloud-cache-action@v1.2.0
with:
path: |
/nix
/zig
- name: Setup Nix
uses: cachix/install-nix-action@v30
with:
nix_path: nixpkgs=channel:nixos-unstable
- uses: cachix/cachix-action@v15
with:
name: ghostty
authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
useDaemon: false # sometimes fails on short jobs
- name: Check Flatpak Zig Dependencies
run: nix develop -c ./flatpak/build-support/check-zig-cache.sh
flatpak:
if: github.repository == 'ghostty-org/ghostty'
name: "Flatpak"
container:
image: ghcr.io/flathub-infra/flatpak-github-actions:gnome-47
options: --privileged
strategy:
fail-fast: false
matrix:
variant:
- arch: x86_64
runner: namespace-profile-ghostty-md
- arch: aarch64
runner: namespace-profile-ghostty-md-arm64
runs-on: ${{ matrix.variant.runner }}
needs: [flatpak-check-zig-cache, test]
steps:
- uses: actions/checkout@v4
- uses: flatpak/flatpak-github-actions/flatpak-builder@v6
with:
bundle: com.mitchellh.ghostty
manifest-path: flatpak/com.mitchellh.ghostty.yml
cache-key: flatpak-builder-${{ github.sha }}
arch: ${{ matrix.variant.arch }}
verbose: true

View File

@ -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
@ -69,6 +71,7 @@ jobs:
build.zig.zon.nix
build.zig.zon.txt
build.zig.zon.json
flatpak/zig-packages.json
body: |
Upstream revision: https://github.com/mbadolato/iTerm2-Color-Schemes/tree/${{ steps.zig_fetch.outputs.upstream_rev }}
labels: dependencies

2
.gitignore vendored
View File

@ -14,6 +14,8 @@ zig-out/
example/*.wasm
test/ghostty
test/cases/**/*.actual.png
flatpak/builddir/
flatpak/repo/
glad.zip
/Box_test.ppm

View File

@ -144,7 +144,7 @@
# Shell
/src/shell-integration/ @ghostty-org/shell
/src/termio/shell-integration.zig @ghostty-org/shell
/src/termio/shell_integration.zig @ghostty-org/shell
# Terminal
/src/simd/ @ghostty-org/terminal

View File

@ -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/4c57d8c11d352a4aeda6928b65d78794c28883a5.tar.gz",
.hash = "N-V-__8AAEH8MwQaEsARbyV42-bSZGcu1am8xtg2h67wTFC3",
.url = "https://github.com/mbadolato/iTerm2-Color-Schemes/archive/1e4957e65005908993250f8f07be3f70e805195e.tar.gz",
.hash = "N-V-__8AAHOASAQuLADcCSHLHEJiKFVLZiCD9Aq2rh5GT01A",
.lazy = true,
},
},

12
build.zig.zon.json generated
View File

@ -54,10 +54,10 @@
"url": "https://deps.files.ghostty.org/imgui-1220bc6b9daceaf7c8c60f3c3998058045ba0c5c5f48ae255ff97776d9cd8bfc6402.tar.gz",
"hash": "sha256-oF/QHgTPEat4Hig4fGIdLkIPHmBEyOJ6JeYD6pnveGA="
},
"N-V-__8AAEH8MwQaEsARbyV42-bSZGcu1am8xtg2h67wTFC3": {
"N-V-__8AAHOASAQuLADcCSHLHEJiKFVLZiCD9Aq2rh5GT01A": {
"name": "iterm2_themes",
"url": "https://github.com/mbadolato/iTerm2-Color-Schemes/archive/4c57d8c11d352a4aeda6928b65d78794c28883a5.tar.gz",
"hash": "sha256-c+twvkEPiz1DaULYlnGXLxis19Q2h+TgBJxoARMasjU="
"url": "https://github.com/mbadolato/iTerm2-Color-Schemes/archive/1e4957e65005908993250f8f07be3f70e805195e.tar.gz",
"hash": "sha256-xpDitXpZrdU/EcgLyG4G0cEiT4r42viy+DJALmy2sQE="
},
"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
View File

@ -170,11 +170,11 @@ in
};
}
{
name = "N-V-__8AAEH8MwQaEsARbyV42-bSZGcu1am8xtg2h67wTFC3";
name = "N-V-__8AAHOASAQuLADcCSHLHEJiKFVLZiCD9Aq2rh5GT01A";
path = fetchZigArtifact {
name = "iterm2_themes";
url = "https://github.com/mbadolato/iTerm2-Color-Schemes/archive/4c57d8c11d352a4aeda6928b65d78794c28883a5.tar.gz";
hash = "sha256-c+twvkEPiz1DaULYlnGXLxis19Q2h+TgBJxoARMasjU=";
url = "https://github.com/mbadolato/iTerm2-Color-Schemes/archive/1e4957e65005908993250f8f07be3f70e805195e.tar.gz";
hash = "sha256-xpDitXpZrdU/EcgLyG4G0cEiT4r42viy+DJALmy2sQE=";
};
}
{
@ -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
View File

@ -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/4c57d8c11d352a4aeda6928b65d78794c28883a5.tar.gz
https://github.com/mbadolato/iTerm2-Color-Schemes/archive/1e4957e65005908993250f8f07be3f70e805195e.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

View File

@ -1,59 +0,0 @@
# Note: the flatpak build is likely broken right now and is not actively
# maintained. We may completely remove this file in the future. For now,
# we want to keep _trying_ but its something with known issues.
app-id: com.mitchellh.ghostty
runtime: org.gnome.Platform
runtime-version: "43"
sdk: org.gnome.Sdk
default-branch: tip
command: ghostty
build-options:
append-path: /app/tmp/zig
strip: false
no-debuginfo: true
# Note: we have to use cleanup-commands because flatpak-builder doesn't
# run "cleanup" on its own: https://github.com/flatpak/flatpak-builder/issues/14
cleanup-commands:
- "rm -rf /app/tmp"
finish-args:
# 3D rendering
- --device=dri
# Windowing
- --share=ipc
- --socket=x11
- --socket=wayland
# Files (we are a terminal so we need all of them)
- --filesystem=host
# So we can escape the sandbox
- --talk-name=org.freedesktop.Flatpak
modules:
# Note: this should be kept in sync with our flake.nix. Over time this
# should stabilize to being a release version and not a nightly.
- name: zig
buildsystem: simple
build-commands:
- mkdir -p /app/tmp/zig
- cp -r ./* /app/tmp/zig
sources:
- type: archive
url: https://ziglang.org/builds/zig-linux-x86_64-0.12.0-dev.141+ddf5859c2.tar.xz
sha256: eaf519b1ec3cb0f3c9bcbc47ead5f50610f9c106279a35b9feb09bed8afc628b
only-arches:
- x86_64
- type: archive
url: https://ziglang.org/builds/zig-linux-aarch64-0.12.0-dev.141+ddf5859c2.tar.xz
sha256: 4f918ae185a5dc281b5d30be92cd4c36ebd77b8665729c5e2c47a8eeccd243e8
only-arches:
- aarch64
- name: ghostty
buildsystem: simple
build-commands:
- MACH_SDK_PATH="$(pwd)/vendor/mach-sdk" zig build -Doptimize=ReleaseSafe -Dcpu=baseline -Dflatpak=true -Dapp-runtime=gtk --prefix /app
sources:
- type: dir
path: .
skip:
- .flatpak-builder
- zig-cache
- zig-out

View File

@ -0,0 +1,59 @@
<?xml version="1.0" encoding="UTF-8"?>
<component type="desktop-application">
<id>com.mitchellh.ghostty</id>
<launchable type="desktop-id">com.mitchellh.ghostty.desktop</launchable>
<name>Ghostty</name>
<url type="homepage">https://ghostty.org</url>
<url type="help">https://ghostty.org/docs</url>
<url type="bugtracker">https://github.com/ghostty-org/ghostty/discussions</url>
<url type="contact">https://ghostty.org/docs/help</url>
<url type="contribute">https://github.com/ghostty-org/ghostty/blob/main/CONTRIBUTING.md</url>
<url type="translate">https://github.com/ghostty-org/ghostty/blob/main/po/README_TRANSLATORS.md</url>
<url type="vcs-browser">https://github.com/ghostty-org/ghostty</url>
<summary>Ghostty is a fast, feature-rich, and cross-platform terminal emulator</summary>
<metadata_license>MIT</metadata_license>
<project_license>MIT</project_license>
<content_rating type="oars-1.1" />
<developer id="com.mitchellh">
<name>Mitchell Hashimoto</name>
</developer>
<update_contact>m@mitchellh.com</update_contact>
<description>
<p>
Ghostty is a terminal emulator that differentiates itself by being fast,
feature-rich, and native. While there are many excellent terminal
emulators available, they all force you to choose between speed,
features, or native UIs. Ghostty provides all three.
</p>
</description>
<recommends>
<control>keyboard</control>
<control>pointing</control>
</recommends>
<requires>
<!--
Mobile/tablet AND desktop supported
Ref: https://docs.flathub.org/docs/for-app-authors/metainfo-guidelines#display-size
-->
<display_length compare="ge">360</display_length>
</requires>
<translation type="gettext">com.mitchellh.ghostty</translation>
<!--
TODO: Generate manifest location data.
Ref: https://docs.flathub.org/docs/for-app-authors/metainfo-guidelines#manifest-location
<custom>
<value key="flathub::manifest">https://github.com/ghostty-org/ghostty/blob/<hash>/flatpak/com.mitchellh.ghostty.yml</value>
</custom>
-->
<releases>
<!-- TODO: Generate this automatically -->
<release version="1.0.1" date="2024-12-31">
<url type="details">https://ghostty.org/docs/install/release-notes/1-0-1</url>
</release>
</releases>
</component>

View File

@ -0,0 +1,108 @@
#!/usr/bin/env bash
#
# This script checks if the flatpak/zig-packages.json file is up-to-date.
# If the `--update` flag is passed, it will update all necessary
# files to be up to date.
#
# The files owned by this are:
#
# - flatpak/zig-packages.json
#
# All of these are auto-generated and should not be edited manually.
# Nothing in this script should fail.
set -eu
set -o pipefail
WORK_DIR=$(mktemp -d)
if [[ ! "$WORK_DIR" || ! -d "$WORK_DIR" ]]; then
echo "could not create temp dir"
exit 1
fi
function cleanup {
rm -rf "$WORK_DIR"
}
trap cleanup EXIT
help() {
echo ""
echo "To fix, please (manually) re-run the script from the repository root,"
echo "commit, and submit a PR with the update:"
echo ""
echo " ./flatpak/build-support/check-zig-cache.sh --update"
echo " git add flatpak/zig-packages.json"
echo " git commit -m \"flatpak: update zig-packages.json\""
echo ""
}
# Turn Nix's base64 hashes into regular hexadecimal form
decode_hash() {
input=$1
input=${input#sha256-}
echo "$input" | base64 -d | od -vAn -t x1 | tr -d ' \n'
}
ROOT="$(realpath "$(dirname "$0")/../../")"
ZIG_PACKAGES_JSON="$ROOT/flatpak/zig-packages.json"
BUILD_ZIG_ZON_JSON="$ROOT/build.zig.zon.json"
if [ ! -f "${BUILD_ZIG_ZON_JSON}" ]; then
echo -e "\nERROR: build.zig.zon2json-lock missing."
help
exit 1
fi
if [ -f "${ZIG_PACKAGES_JSON}" ]; then
OLD_HASH=$(sha512sum "${ZIG_PACKAGES_JSON}" | awk '{print $1}')
fi
while read -r url sha256 dest; do
src_type=archive
sha256=$(decode_hash "$sha256")
git_commit=
if [[ "$url" =~ ^git\+* ]]; then
src_type=git
sha256=
url=${url#git+}
git_commit=${url##*#}
url=${url%%/\?ref*}
url=${url%%#*}
fi
jq \
-nec \
--arg type "$src_type" \
--arg url "$url" \
--arg git_commit "$git_commit" \
--arg dest "$dest" \
--arg sha256 "$sha256" \
'{
type: $type,
url: $url,
commit: $git_commit,
dest: $dest,
sha256: $sha256,
} | with_entries(select(.value != ""))'
done < <(jq -rc 'to_entries[] | [.value.url, .value.hash, "vendor/p/\(.key)"] | @tsv' "$BUILD_ZIG_ZON_JSON") |
jq -s '.' >"$WORK_DIR/zig-packages.json"
NEW_HASH=$(sha512sum "$WORK_DIR/zig-packages.json" | awk '{print $1}')
if [ "${OLD_HASH}" == "${NEW_HASH}" ]; then
echo -e "\nOK: flatpak/zig-packages.json unchanged."
exit 0
elif [ "${1:-}" != "--update" ]; then
echo -e "\nERROR: flatpak/zig-packages.json needs to be updated."
echo ""
echo " * Old hash: ${OLD_HASH}"
echo " * New hash: ${NEW_HASH}"
help
exit 1
else
mv "$WORK_DIR/zig-packages.json" "$ZIG_PACKAGES_JSON"
echo -e "\nOK: flatpak/zig-packages.json updated."
exit 0
fi

View File

@ -0,0 +1,63 @@
app-id: com.mitchellh.ghostty.Devel
runtime: org.gnome.Platform
runtime-version: "48"
sdk: org.gnome.Sdk
sdk-extensions:
- org.freedesktop.Sdk.Extension.ziglang
default-branch: tip
command: ghostty
# Integrate the rename into zig build, maybe?
rename-desktop-file: com.mitchellh.ghostty.desktop
rename-appdata-file: com.mitchellh.ghostty.metainfo.xml
rename-icon: com.mitchellh.ghostty
desktop-file-name-suffix: " (Devel)"
finish-args:
# 3D rendering
- --device=dri
# Windowing
- --share=ipc
- --socket=fallback-x11
- --socket=wayland
# Allow user to specify additional config files in home by default
- --filesystem=home:ro
# So we can escape the sandbox
- --talk-name=org.freedesktop.Flatpak
cleanup:
- /include
- /lib/girepository-1.0
- /lib/pkgconfig
- /share/gir-1.0
- /share/pkgconfig
- /share/vala
- "*.la"
- "*.a"
- "*.so"
modules:
- dependencies.yml
- name: ghostty
buildsystem: simple
build-options:
append-path: /usr/lib/sdk/ziglang
build-commands:
- zig build
-Doptimize=Debug
-Dcpu=baseline
-Dflatpak=true
-Dstrip=false
-fno-sys=oniguruma
--prefix /app
--search-prefix /app
--system $PWD/vendor/p
sources:
- type: dir
path: ..
skip:
- flatpak/.flatpak-builder
- flatpak/builddir
- flatpak/repo
- zig-cache
- zig-out
- zig-packages.json

View File

@ -0,0 +1,58 @@
app-id: com.mitchellh.ghostty
runtime: org.gnome.Platform
runtime-version: "48"
sdk: org.gnome.Sdk
sdk-extensions:
- org.freedesktop.Sdk.Extension.ziglang
default-branch: tip
command: ghostty
finish-args:
# 3D rendering
- --device=dri
# Windowing
- --share=ipc
- --socket=fallback-x11
- --socket=wayland
# Allow user to specify additional config files in home by default
- --filesystem=home:ro
# So we can escape the sandbox
- --talk-name=org.freedesktop.Flatpak
cleanup:
- /include
- /lib/girepository-1.0
- /lib/pkgconfig
- /share/gir-1.0
- /share/pkgconfig
- /share/vala
- "*.la"
- "*.a"
- "*.so"
modules:
- dependencies.yml
- name: ghostty
buildsystem: simple
build-options:
append-path: /usr/lib/sdk/ziglang
build-commands:
- zig build
-Doptimize=ReleaseFast
-Dcpu=baseline
-Dflatpak=true
-Dstrip=false
-fno-sys=oniguruma
--prefix /app
--search-prefix /app
--system $PWD/vendor/p
sources:
- type: dir
path: ..
skip:
- flatpak/.flatpak-builder
- flatpak/builddir
- flatpak/repo
- zig-cache
- zig-out
- zig-packages.json

66
flatpak/dependencies.yml Normal file
View File

@ -0,0 +1,66 @@
name: dependencies-meta
buildsystem: simple
build-commands:
- true
modules:
- name: bzip2-redirect
buildsystem: simple
build-commands:
- install -Dm644 libbzip2.so /app/lib/libbzip2.so
sources:
- type: inline
contents: INPUT(libbz2.so)
dest-filename: libbzip2.so
- name: blueprint-compiler
buildsystem: meson
cleanup:
- "*"
sources:
- type: git
url: https://gitlab.gnome.org/jwestman/blueprint-compiler.git
tag: v0.16.0
commit: 04ef0944db56ab01307a29aaa7303df6067cb3c0
x-checker-data:
type: git
tag-pattern: ^v([\d.]+)$
- name: gtk4-layer-shell
buildsystem: meson
sources:
# no x-checker-data since this should be synchronized with Nix
#
# TODO: Automate this with check-zig-cache.sh
- type: archive
url: https://github.com/wmww/gtk4-layer-shell/archive/refs/tags/v1.1.0.tar.gz
sha256: 98284281260a5eef5b4f63a55f16c4bf6a788a1020a6db037ecb0f71fa336988
- name: pandoc
buildsystem: simple
cleanup:
- "*"
build-commands:
- install -Dm755 bin/pandoc /app/bin/pandoc
sources:
- type: archive
sha256: d04c95c138202f87d6b00ac19aa3dd874c681f60a9feb3b55c74f764d6d1a17d
url: https://github.com/jgm/pandoc/releases/download/3.6.3/pandoc-3.6.3-linux-amd64.tar.gz
only-arches: [x86_64]
x-checker-data:
type: json
url: https://api.github.com/repos/jgm/pandoc/releases/latest
url-query:
.assets[] | select(.name=="pandoc-" + $version + "-linux-amd64.tar.gz")
| .browser_download_url
version-query: .tag_name
- type: archive
sha256: 4e774cb1bdb6e56bc55b8eb79200bd9aa6a39905a04ecda7267f5149116f0881
url: https://github.com/jgm/pandoc/releases/download/3.6.3/pandoc-3.6.3-linux-arm64.tar.gz
only-arches: [aarch64]
x-checker-data:
type: json
url: https://api.github.com/repos/jgm/pandoc/releases/latest
url-query:
.assets[] | select(.name=="pandoc-" + $version + "-linux-arm64.tar.gz")
| .browser_download_url
version-query: .tag_name

3
flatpak/exceptions.json Normal file
View File

@ -0,0 +1,3 @@
{
"com.mitchellh.ghostty": ["finish-args-flatpak-spawn-access"]
}

206
flatpak/zig-packages.json Normal file
View File

@ -0,0 +1,206 @@
[
{
"type": "archive",
"url": "https://deps.files.ghostty.org/breakpad-b99f444ba5f6b98cac261cbb391d8766b34a5918.tar.gz",
"dest": "vendor/p/N-V-__8AALw2uwF_03u4JRkZwRLc3Y9hakkYV7NKRR9-RIZJ",
"sha256": "6cca98943d1a990766cef61077c09aff5938063fe17a1efe1228e5412b6d6ad9"
},
{
"type": "archive",
"url": "https://deps.files.ghostty.org/fontconfig-2.14.2.tar.gz",
"dest": "vendor/p/N-V-__8AAIrfdwARSa-zMmxWwFuwpXf1T3asIN7s5jqi9c1v",
"sha256": "3ba2dd92158718acec5caaf1a716043b5aa055c27b081d914af3ccb40dce8a55"
},
{
"type": "archive",
"url": "https://deps.files.ghostty.org/freetype-1220b81f6ecfb3fd222f76cf9106fecfa6554ab07ec7fdc4124b9bb063ae2adf969d.tar.gz",
"dest": "vendor/p/N-V-__8AAKLKpwC4H27Ps_0iL3bPkQb-z6ZVSrB-x_3EEkub",
"sha256": "427201f5d5151670d05c1f5b45bef5dda1f2e7dd971ef54f0feaaa7ffd2ab90c"
},
{
"type": "archive",
"url": "https://deps.files.ghostty.org/gettext-0.24.tar.gz",
"dest": "vendor/p/N-V-__8AADcZkgn4cMhTUpIz6mShCKyqqB-NBtf_S2bHaTC-",
"sha256": "c918503d593d70daf4844d175a13d816afacb667c06fba1ec9dcd5002c1518b7"
},
{
"type": "archive",
"url": "https://github.com/glfw/glfw/archive/e7ea71be039836da3a98cea55ae5569cb5eb885c.tar.gz",
"dest": "vendor/p/N-V-__8AAMrJSwAUGb9-vTzkNR-5LXS81MR__ZRVfF3tWgG6",
"sha256": "3373755d402531e6c1a395f53f2fbd6318ca5e067a79a72a59109b526c0b290a"
},
{
"type": "archive",
"url": "https://deps.files.ghostty.org/glslang-12201278a1a05c0ce0b6eb6026c65cd3e9247aa041b1c260324bf29cee559dd23ba1.tar.gz",
"dest": "vendor/p/N-V-__8AABzkUgISeKGgXAzgtutgJsZc0-kkeqBBscJgMkvy",
"sha256": "14a2edbb509cb3e51a9a53e3f5e435dbf5971604b4b833e63e6076e8c0a997b5"
},
{
"type": "archive",
"url": "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",
"dest": "vendor/p/gobject-0.2.0-Skun7IWDlQAOKu4BV7LapIxL9Imbq1JRmzvcIkazvAxR",
"sha256": "85672997459ddd7c9d4fe458efe548a315cf842cde95ed48a7be984a1f8a98b2"
},
{
"type": "archive",
"url": "https://deps.files.ghostty.org/gtk4-layer-shell-1.1.0.tar.gz",
"dest": "vendor/p/N-V-__8AALiNBAA-_0gprYr92CjrMj1I5bqNu0TSJOnjFNSr",
"sha256": "98284281260a5eef5b4f63a55f16c4bf6a788a1020a6db037ecb0f71fa336988"
},
{
"type": "archive",
"url": "https://deps.files.ghostty.org/harfbuzz-11.0.0.tar.xz",
"dest": "vendor/p/N-V-__8AAG02ugUcWec-Ndp-i7JTsJ0dgF8nnJRUInkGLG7G",
"sha256": "f16351bafe214725fe2c1d5b59f0d93e49905a4b247899fb90d70cff953a2b9b"
},
{
"type": "archive",
"url": "https://deps.files.ghostty.org/highway-66486a10623fa0d72fe91260f96c892e41aceb06.tar.gz",
"dest": "vendor/p/N-V-__8AAGmZhABbsPJLfbqrh6JTHsXhY6qCaLAQyx25e0XE",
"sha256": "87d4f8893ef4e08f224973608ffebf94268a81380ba79c12e8841968c80aa212"
},
{
"type": "archive",
"url": "https://deps.files.ghostty.org/imgui-1220bc6b9daceaf7c8c60f3c3998058045ba0c5c5f48ae255ff97776d9cd8bfc6402.tar.gz",
"dest": "vendor/p/N-V-__8AAH0GaQC8a52s6vfIxg88OZgFgEW6DFxfSK4lX_l3",
"sha256": "a05fd01e04cf11ab781e28387c621d2e420f1e6044c8e27a25e603ea99ef7860"
},
{
"type": "archive",
"url": "https://github.com/mbadolato/iTerm2-Color-Schemes/archive/1e4957e65005908993250f8f07be3f70e805195e.tar.gz",
"dest": "vendor/p/N-V-__8AAHOASAQuLADcCSHLHEJiKFVLZiCD9Aq2rh5GT01A",
"sha256": "c690e2b57a59add53f11c80bc86e06d1c1224f8af8daf8b2f832402e6cb6b101"
},
{
"type": "archive",
"url": "https://deps.files.ghostty.org/libpng-1220aa013f0c83da3fb64ea6d327f9173fa008d10e28bc9349eac3463457723b1c66.tar.gz",
"dest": "vendor/p/N-V-__8AAJrvXQCqAT8Mg9o_tk6m0yf5Fz-gCNEOKLyTSerD",
"sha256": "fecc95b46cf05e8e3fc8a414750e0ba5aad00d89e9fdf175e94ff041caf1a03a"
},
{
"type": "archive",
"url": "https://github.com/mitchellh/libxev/archive/3df9337a9e84450a58a2c4af434ec1a036f7b494.tar.gz",
"dest": "vendor/p/libxev-0.0.0-86vtc-ziEgDbLP0vihUn1MhsxNKY4GJEga6BEr7oyHpz",
"sha256": "a0a66a03d77bf631e7a7f1eca89590137dc57e7e447b91b85679507a942e638a"
},
{
"type": "archive",
"url": "https://deps.files.ghostty.org/libxml2-2.11.5.tar.gz",
"dest": "vendor/p/N-V-__8AAG3RoQEyRC2Vw7Qoro5SYBf62IHn3HjqtNVY6aWK",
"sha256": "6c28059e2e3eeb42b5b4b16489e3916a6346c1095a74fee3bc65cdc5d89a6215"
},
{
"type": "archive",
"url": "https://deps.files.ghostty.org/oniguruma-1220c15e72eadd0d9085a8af134904d9a0f5dfcbed5f606ad60edc60ebeccd9706bb.tar.gz",
"dest": "vendor/p/N-V-__8AAHjwMQDBXnLq3Q2QhaivE0kE2aD138vtX2Bq1g7c",
"sha256": "001aa1202e78448f4c0bf1a48c76e556876b36f16d92ce3207eccfd61d99f2a0"
},
{
"type": "archive",
"url": "https://deps.files.ghostty.org/pixels-12207ff340169c7d40c570b4b6a97db614fe47e0d83b5801a932dcd44917424c8806.tar.gz",
"dest": "vendor/p/N-V-__8AADYiAAB_80AWnH1AxXC0tql9thT-R-DYO1gBqTLc",
"sha256": "55e83b16d091082502bf149bf457f31f42092c5982650e3ffbae7b48871bf11a"
},
{
"type": "archive",
"url": "https://deps.files.ghostty.org/plasma_wayland_protocols-12207e0851c12acdeee0991e893e0132fc87bb763969a585dc16ecca33e88334c566.tar.gz",
"dest": "vendor/p/N-V-__8AAKYZBAB-CFHBKs3u4JkeiT4BMvyHu3Y5aaWF3Bbs",
"sha256": "5c58ba214acd8e6bca3426dc08b022c46a8dd997b29a1b3e28badf71c20df441"
},
{
"type": "archive",
"url": "https://deps.files.ghostty.org/sentry-1220446be831adcca918167647c06c7b825849fa3fba5f22da394667974537a9c77e.tar.gz",
"dest": "vendor/p/N-V-__8AAPlZGwBEa-gxrcypGBZ2R8Bse4JYSfo_ul8i2jlG",
"sha256": "2ac6497cc8d61a8d31093e47addb8c9b2c45b16b0705bb334a835b6423c318df"
},
{
"type": "archive",
"url": "https://deps.files.ghostty.org/spirv_cross-1220fb3b5586e8be67bc3feb34cbe749cf42a60d628d2953632c2f8141302748c8da.tar.gz",
"dest": "vendor/p/N-V-__8AANb6pwD7O1WG6L5nvD_rNMvnSc9Cpg1ijSlTYywv",
"sha256": "b52b6fcfc45e7fa69b1f06a1362c155473444e2cc09995556b156c53ba6657e3"
},
{
"type": "archive",
"url": "https://deps.files.ghostty.org/utfcpp-1220d4d18426ca72fc2b7e56ce47273149815501d0d2395c2a98c726b31ba931e641.tar.gz",
"dest": "vendor/p/N-V-__8AAHffAgDU0YQmynL8K35WzkcnMUmBVQHQ0jlcKpjH",
"sha256": "ffc668a310e77607d393f3c18b32715f223da1eac4c4d6e0579a11df8e6b59cf"
},
{
"type": "git",
"url": "https://github.com/rockorager/libvaxis",
"commit": "1f41c121e8fc153d9ce8c6eb64b2bbab68ad7d23",
"dest": "vendor/p/vaxis-0.1.0-BWNV_FUICQAFZnTCL11TUvnUr1Y0_ZdqtXHhd51d76Rn"
},
{
"type": "archive",
"url": "https://deps.files.ghostty.org/wayland-9cb3d7aa9dc995ffafdbdef7ab86a949d0fb0e7d.tar.gz",
"dest": "vendor/p/N-V-__8AAKrHGAAs2shYq8UkE6bGcR1QJtLTyOE_lcosMn6t",
"sha256": "ea4191d68e437677e51f3aacde27829810144e931d397a327dc6035e2c39c50d"
},
{
"type": "archive",
"url": "https://deps.files.ghostty.org/wayland-protocols-258d8f88f2c8c25a830c6316f87d23ce1a0f12d9.tar.gz",
"dest": "vendor/p/N-V-__8AAKw-DAAaV8bOAAGqA0-oD7o-HNIlPFYKRXSPT03S",
"sha256": "5cedcadde81b75e60f23e5e83b5dd2b8eb4efb9f8f79bd7a347d148aeb0530f8"
},
{
"type": "archive",
"url": "https://deps.files.ghostty.org/wuffs-122037b39d577ec2db3fd7b2130e7b69ef6cc1807d68607a7c232c958315d381b5cd.tar.gz",
"dest": "vendor/p/N-V-__8AAAzZywE3s51XfsLbP9eyEw57ae9swYB9aGB6fCMs",
"sha256": "9e4cd20abe96e6c4c6ede9c3057108860126e7be2e2c3e35515476c250be1c13"
},
{
"type": "archive",
"url": "https://github.com/vancluever/z2d/archive/1bf4bc81819385f4b24596445c9a7cf3b3592b08.tar.gz",
"dest": "vendor/p/z2d-0.6.1-j5P_HlerCgBokMgrkl9QhJUKXuZWBGdPnH7cSXwv_ScW",
"sha256": "c2226cebf2d48b2f80a42e6ced53f2a5b06e92306be2f8f1deffe5f4ead3ef45"
},
{
"type": "archive",
"url": "https://github.com/natecraddock/zf/archive/7aacbe6d155d64d15937ca95ca6c014905eb531f.tar.gz",
"dest": "vendor/p/zf-0.10.3-OIRy8aiIAACLrBllz0zjxaH0aOe5oNm3KtEMyCntST-9",
"sha256": "de7ba535077fe2b678a5a7972585f002588d37244db08397feadf3d4907c0bb2"
},
{
"type": "git",
"url": "https://codeberg.org/atman/zg",
"commit": "4a002763419a34d61dcbb1f415821b83b9bf8ddc",
"dest": "vendor/p/zg-0.13.4-AAAAAGiZ7QLz4pvECFa_wG4O4TP4FLABHHbemH2KakWM"
},
{
"type": "archive",
"url": "https://deps.files.ghostty.org/zig_js-12205a66d423259567764fa0fc60c82be35365c21aeb76c5a7dc99698401f4f6fefc.tar.gz",
"dest": "vendor/p/N-V-__8AAB9YCQBaZtQjJZVndk-g_GDIK-NTZcIa63bFp9yZ",
"sha256": "7f235e0956c2f5401a28963a261019953d00e3bf4cfc029830f2161196c3583d"
},
{
"type": "archive",
"url": "https://github.com/mitchellh/zig-objc/archive/3ab0d37c7d6b933d6ded1b3a35b6b60f05590a98.tar.gz",
"dest": "vendor/p/zig_objc-0.0.0-Ir_Sp3TyAADEVRTxXlScq3t_uKAM91MYNerZkHfbD0yt",
"sha256": "ce7d6d47ac614a60e56b8509dedf869e2e0d8b747c75e48aded11eec31b3357c"
},
{
"type": "archive",
"url": "https://codeberg.org/ifreund/zig-wayland/archive/f3c5d503e540ada8cbcb056420de240af0c094f7.tar.gz",
"dest": "vendor/p/wayland-0.4.0-dev-lQa1kjfIAQCmhhQu3xF0KH-94-TzeMXOqfnP0-Dg6Wyy",
"sha256": "13bec6675e403d86db3b55b39ae262f1e1bdfe24056dcd82824341c6308b5219"
},
{
"type": "git",
"url": "https://github.com/TUSF/zigimg",
"commit": "31268548fe3276c0e95f318a6c0d2ab10565b58d",
"dest": "vendor/p/zigimg-0.1.0-lly-O6N2EABOxke8dqyzCwhtUCAafqP35zC7wsZ4Ddxj"
},
{
"type": "archive",
"url": "https://deps.files.ghostty.org/ziglyph-b89d43d1e3fb01b6074bc1f7fc980324b04d26a5.tar.gz",
"dest": "vendor/p/ziglyph-0.11.2-AAAAAHPtHwB4Mbzn1KvOV7Wpjo82NYEc_v0WC8oCLrkf",
"sha256": "72c7bdf3e16df105235fe3fcf32c987dac49389190f4ced89b0ee31710f3f3d9"
},
{
"type": "archive",
"url": "https://deps.files.ghostty.org/zlib-1220fed0c74e1019b3ee29edae2051788b080cd96e90d56836eea857b0b966742efb.tar.gz",
"dest": "vendor/p/N-V-__8AAB0eQwD-0MdOEBmz7intriBReIsIDNlukNVoNu6o",
"sha256": "17e88863f3600672ab49182f217281b6fc4d3c762bde361935e436a95214d05c"
}
]

View File

@ -279,6 +279,13 @@ typedef struct {
ghostty_input_mods_e mods;
} ghostty_input_trigger_s;
typedef struct {
const char* action_key;
const char* action;
const char* title;
const char* description;
} ghostty_command_s;
typedef enum {
GHOSTTY_BUILD_MODE_DEBUG,
GHOSTTY_BUILD_MODE_RELEASE_SAFE,
@ -350,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,
@ -417,6 +429,13 @@ typedef enum {
GHOSTTY_FULLSCREEN_NON_NATIVE_PADDED_NOTCH,
} ghostty_action_fullscreen_e;
// apprt.action.FloatWindow
typedef enum {
GHOSTTY_FLOAT_WINDOW_ON,
GHOSTTY_FLOAT_WINDOW_OFF,
GHOSTTY_FLOAT_WINDOW_TOGGLE,
} ghostty_action_float_window_e;
// apprt.action.SecureInput
typedef enum {
GHOSTTY_SECURE_INPUT_ON,
@ -573,6 +592,7 @@ typedef enum {
GHOSTTY_ACTION_TOGGLE_TAB_OVERVIEW,
GHOSTTY_ACTION_TOGGLE_WINDOW_DECORATIONS,
GHOSTTY_ACTION_TOGGLE_QUICK_TERMINAL,
GHOSTTY_ACTION_TOGGLE_COMMAND_PALETTE,
GHOSTTY_ACTION_TOGGLE_VISIBILITY,
GHOSTTY_ACTION_MOVE_TAB,
GHOSTTY_ACTION_GOTO_TAB,
@ -597,6 +617,7 @@ typedef enum {
GHOSTTY_ACTION_RENDERER_HEALTH,
GHOSTTY_ACTION_OPEN_CONFIG,
GHOSTTY_ACTION_QUIT_TIMER,
GHOSTTY_ACTION_FLOAT_WINDOW,
GHOSTTY_ACTION_SECURE_INPUT,
GHOSTTY_ACTION_KEY_SEQUENCE,
GHOSTTY_ACTION_COLOR_CHANGE,
@ -625,6 +646,7 @@ typedef union {
ghostty_action_mouse_over_link_s mouse_over_link;
ghostty_action_renderer_health_e renderer_health;
ghostty_action_quit_timer_e quit_timer;
ghostty_action_float_window_e float_window;
ghostty_action_secure_input_e secure_input;
ghostty_action_key_sequence_s key_sequence;
ghostty_action_color_change_s color_change;
@ -724,6 +746,7 @@ void ghostty_surface_set_color_scheme(ghostty_surface_t,
ghostty_color_scheme_e);
ghostty_input_mods_e ghostty_surface_key_translation_mods(ghostty_surface_t,
ghostty_input_mods_e);
void ghostty_surface_commands(ghostty_surface_t, ghostty_command_s**, size_t*);
bool ghostty_surface_key(ghostty_surface_t, ghostty_input_key_s);
bool ghostty_surface_key_is_binding(ghostty_surface_t, ghostty_input_key_s);
void ghostty_surface_text(ghostty_surface_t, const char*, uintptr_t);

View File

@ -34,6 +34,10 @@
A5333E242B5A22D9008AEFF7 /* Ghostty.Shell.swift in Sources */ = {isa = PBXBuildFile; fileRef = A56D58852ACDDB4100508D2C /* Ghostty.Shell.swift */; };
A53426352A7DA53D00EBB7A2 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = A53426342A7DA53D00EBB7A2 /* AppDelegate.swift */; };
A535B9DA299C569B0017E2E4 /* ErrorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A535B9D9299C569B0017E2E4 /* ErrorView.swift */; };
A53A297B2DB2E49700B6E02C /* CommandPalette.swift in Sources */ = {isa = PBXBuildFile; fileRef = A53A297A2DB2E49400B6E02C /* CommandPalette.swift */; };
A53A297F2DB4480F00B6E02C /* EventModifiers+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = A53A297E2DB4480A00B6E02C /* EventModifiers+Extension.swift */; };
A53A29812DB44A6100B6E02C /* KeyboardShortcut+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = A53A29802DB44A5E00B6E02C /* KeyboardShortcut+Extension.swift */; };
A53A29882DB69D2F00B6E02C /* TerminalCommandPalette.swift in Sources */ = {isa = PBXBuildFile; fileRef = A53A29872DB69D2C00B6E02C /* TerminalCommandPalette.swift */; };
A53A6C032CCC1B7F00943E98 /* Ghostty.Action.swift in Sources */ = {isa = PBXBuildFile; fileRef = A53A6C022CCC1B7D00943E98 /* Ghostty.Action.swift */; };
A53D0C8E2B53B0EA00305CE6 /* GhosttyKit.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = A5D495A1299BEC7E00DD1313 /* GhosttyKit.xcframework */; };
A53D0C942B53B43700305CE6 /* iOSApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = A53D0C932B53B43700305CE6 /* iOSApp.swift */; };
@ -138,6 +142,10 @@
A5333E212B5A2128008AEFF7 /* SurfaceView_AppKit.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SurfaceView_AppKit.swift; sourceTree = "<group>"; };
A53426342A7DA53D00EBB7A2 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
A535B9D9299C569B0017E2E4 /* ErrorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ErrorView.swift; sourceTree = "<group>"; };
A53A297A2DB2E49400B6E02C /* CommandPalette.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CommandPalette.swift; sourceTree = "<group>"; };
A53A297E2DB4480A00B6E02C /* EventModifiers+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "EventModifiers+Extension.swift"; sourceTree = "<group>"; };
A53A29802DB44A5E00B6E02C /* KeyboardShortcut+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "KeyboardShortcut+Extension.swift"; sourceTree = "<group>"; };
A53A29872DB69D2C00B6E02C /* TerminalCommandPalette.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TerminalCommandPalette.swift; sourceTree = "<group>"; };
A53A6C022CCC1B7D00943E98 /* Ghostty.Action.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Ghostty.Action.swift; sourceTree = "<group>"; };
A53D0C932B53B43700305CE6 /* iOSApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = iOSApp.swift; sourceTree = "<group>"; };
A53D0C992B543F3B00305CE6 /* Ghostty.App.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Ghostty.App.swift; sourceTree = "<group>"; };
@ -267,6 +275,7 @@
A5CBD05A2CA0C5910017A1AE /* QuickTerminal */,
A5E112912AF73E4D00C6E0C2 /* ClipboardConfirmation */,
A57D79252C9C8782001D522E /* Secure Input */,
A53A29742DB2E04900B6E02C /* Command Palette */,
A534263E2A7DCC5800EBB7A2 /* Settings */,
A51BFC1C2B2FB5AB00E92F16 /* About */,
A54B0CE72D0CEC9800CBEFF8 /* Colorized Ghostty Icon */,
@ -288,8 +297,10 @@
A52FFF582CAA4FF1000C6A5B /* Fullscreen.swift */,
A59630962AEE163600D64628 /* HostingWindow.swift */,
A5CA378B2D2A4DE800931030 /* KeyboardLayout.swift */,
A53A29802DB44A5E00B6E02C /* KeyboardShortcut+Extension.swift */,
A59FB5D02AE0DEA7009128F3 /* MetalView.swift */,
A5CBD0552C9E65A50017A1AE /* DraggableWindowView.swift */,
A53A297E2DB4480A00B6E02C /* EventModifiers+Extension.swift */,
C159E81C2B66A06B00FDFE9C /* OSColor+Extension.swift */,
A599CDAF2CF103F20049FA26 /* NSAppearance+Extension.swift */,
A5A2A3CB2D444AB80033CF96 /* NSApplication+Extension.swift */,
@ -319,6 +330,15 @@
path = Settings;
sourceTree = "<group>";
};
A53A29742DB2E04900B6E02C /* Command Palette */ = {
isa = PBXGroup;
children = (
A53A297A2DB2E49400B6E02C /* CommandPalette.swift */,
A53A29872DB69D2C00B6E02C /* TerminalCommandPalette.swift */,
);
path = "Command Palette";
sourceTree = "<group>";
};
A53D0C912B53B41900305CE6 /* App */ = {
isa = PBXGroup;
children = (
@ -667,6 +687,7 @@
A5A2A3CA2D4445E30033CF96 /* Dock.swift in Sources */,
A51BFC222B2FB6B400E92F16 /* AboutView.swift in Sources */,
A5278A9B2AA05B2600CD3039 /* Ghostty.Input.swift in Sources */,
A53A29812DB44A6100B6E02C /* KeyboardShortcut+Extension.swift in Sources */,
A5CBD0562C9E65B80017A1AE /* DraggableWindowView.swift in Sources */,
C1F26EE92B76CBFC00404083 /* VibrantLayer.m in Sources */,
A59630972AEE163600D64628 /* HostingWindow.swift in Sources */,
@ -691,6 +712,8 @@
A5A2A3CC2D444ABB0033CF96 /* NSApplication+Extension.swift in Sources */,
A59630A22AF0415000D64628 /* Ghostty.TerminalSplit.swift in Sources */,
A5FEB3002ABB69450068369E /* main.swift in Sources */,
A53A297F2DB4480F00B6E02C /* EventModifiers+Extension.swift in Sources */,
A53A297B2DB2E49700B6E02C /* CommandPalette.swift in Sources */,
A55B7BB829B6F53A0055DE60 /* Package.swift in Sources */,
A51B78472AF4B58B00F3EDB9 /* TerminalWindow.swift in Sources */,
A57D79272C9C879B001D522E /* SecureInput.swift in Sources */,
@ -706,6 +729,7 @@
A52FFF572CA90484000C6A5B /* QuickTerminalScreen.swift in Sources */,
A5CC36132C9CD72D004D6760 /* SecureInputOverlay.swift in Sources */,
A535B9DA299C569B0017E2E4 /* ErrorView.swift in Sources */,
A53A29882DB69D2F00B6E02C /* TerminalCommandPalette.swift in Sources */,
A51BFC202B2FB64F00E92F16 /* AboutController.swift in Sources */,
A5CEAFFF29C2410700646FDA /* Backport.swift in Sources */,
A5E112952AF73E8A00C6E0C2 /* ClipboardConfirmationController.swift in Sources */,

View File

@ -52,6 +52,8 @@ class AppDelegate: NSObject,
@IBOutlet private var menuSelectSplitLeft: NSMenuItem?
@IBOutlet private var menuSelectSplitRight: NSMenuItem?
@IBOutlet private var menuReturnToDefaultSize: NSMenuItem?
@IBOutlet private var menuFloatOnTop: NSMenuItem?
@IBOutlet private var menuUseAsDefault: NSMenuItem?
@IBOutlet private var menuIncreaseFontSize: NSMenuItem?
@IBOutlet private var menuDecreaseFontSize: NSMenuItem?
@ -59,6 +61,7 @@ class AppDelegate: NSObject,
@IBOutlet private var menuChangeTitle: NSMenuItem?
@IBOutlet private var menuQuickTerminal: NSMenuItem?
@IBOutlet private var menuTerminalInspector: NSMenuItem?
@IBOutlet private var menuCommandPalette: NSMenuItem?
@IBOutlet private var menuEqualizeSplits: NSMenuItem?
@IBOutlet private var menuMoveSplitDividerUp: NSMenuItem?
@ -174,6 +177,12 @@ class AppDelegate: NSObject,
handler: localEventHandler)
// Notifications
NotificationCenter.default.addObserver(
self,
selector: #selector(windowDidBecomeKey),
name: NSWindow.didBecomeKeyNotification,
object: nil
)
NotificationCenter.default.addObserver(
self,
selector: #selector(quickTerminalDidChangeVisibility),
@ -199,6 +208,7 @@ class AppDelegate: NSObject,
]
let center = UNUserNotificationCenter.current()
center.setNotificationCategories([
UNNotificationCategory(
identifier: Ghostty.userNotificationCategory,
@ -231,6 +241,9 @@ class AppDelegate: NSObject,
// If we're back manually then clear the hidden state because macOS handles it.
self.hiddenState = nil
// Clear the dock badge when the app becomes active
self.setDockBadge(nil)
// First launch stuff
if (!applicationHasBecomeActive) {
applicationHasBecomeActive = true
@ -398,10 +411,12 @@ class AppDelegate: NSObject,
syncMenuShortcut(config, action: "increase_font_size:1", menuItem: self.menuIncreaseFontSize)
syncMenuShortcut(config, action: "decrease_font_size:1", menuItem: self.menuDecreaseFontSize)
syncMenuShortcut(config, action: "reset_font_size", menuItem: self.menuResetFontSize)
syncMenuShortcut(config, action: "change_title_prompt", menuItem: self.menuChangeTitle)
syncMenuShortcut(config, action: "prompt_surface_title", menuItem: self.menuChangeTitle)
syncMenuShortcut(config, action: "toggle_quick_terminal", menuItem: self.menuQuickTerminal)
syncMenuShortcut(config, action: "toggle_visibility", menuItem: self.menuToggleVisibility)
syncMenuShortcut(config, action: "toggle_window_float_on_top", menuItem: self.menuFloatOnTop)
syncMenuShortcut(config, action: "inspector:toggle", menuItem: self.menuTerminalInspector)
syncMenuShortcut(config, action: "toggle_command_palette", menuItem: self.menuCommandPalette)
syncMenuShortcut(config, action: "toggle_secure_input", menuItem: self.menuSecureInput)
@ -419,15 +434,15 @@ class AppDelegate: NSObject,
/// action string used for the Ghostty configuration.
private func syncMenuShortcut(_ config: Ghostty.Config, action: String, menuItem: NSMenuItem?) {
guard let menu = menuItem else { return }
guard let equiv = config.keyEquivalent(for: action) else {
guard let shortcut = config.keyboardShortcut(for: action) else {
// No shortcut, clear the menu item
menu.keyEquivalent = ""
menu.keyEquivalentModifierMask = []
return
}
menu.keyEquivalent = equiv.key
menu.keyEquivalentModifierMask = equiv.modifiers
menu.keyEquivalent = shortcut.key.character.description
menu.keyEquivalentModifierMask = .init(swiftUIFlags: shortcut.modifiers)
}
private func focusedSurface() -> ghostty_surface_t? {
@ -491,6 +506,10 @@ class AppDelegate: NSObject,
return event
}
@objc private func windowDidBecomeKey(_ notification: Notification) {
syncFloatOnTopMenu(notification.object as? NSWindow)
}
@objc private func quickTerminalDidChangeVisibility(_ notification: Notification) {
guard let quickController = notification.object as? QuickTerminalController else { return }
self.menuQuickTerminal?.state = if (quickController.visible) { .on } else { .off }
@ -511,6 +530,53 @@ class AppDelegate: NSObject,
@objc private func ghosttyBellDidRing(_ notification: Notification) {
// Bounce the dock icon if we're not focused.
NSApp.requestUserAttention(.informationalRequest)
// Handle setting the dock badge based on permissions
ghosttyUpdateBadgeForBell()
}
private func ghosttyUpdateBadgeForBell() {
let center = UNUserNotificationCenter.current()
center.getNotificationSettings { settings in
switch settings.authorizationStatus {
case .authorized:
// Already authorized, check badge setting and set if enabled
if settings.badgeSetting == .enabled {
DispatchQueue.main.async {
self.setDockBadge()
}
}
case .notDetermined:
// Not determined yet, request authorization for badge
center.requestAuthorization(options: [.badge]) { granted, error in
if let error = error {
Self.logger.warning("Error requesting badge authorization: \(error)")
return
}
if granted {
// Permission granted, set the badge
DispatchQueue.main.async {
self.setDockBadge()
}
}
}
case .denied, .provisional, .ephemeral:
// In these known non-authorized states, do not attempt to set the badge.
break
@unknown default:
// Handle future unknown states by doing nothing.
break
}
}
}
private func setDockBadge(_ label: String? = "") {
NSApp.dockTile.badgeLabel = label
NSApp.dockTile.display()
}
private func ghosttyConfigDidChange(config: Ghostty.Config) {
@ -846,3 +912,50 @@ class AppDelegate: NSObject,
}
}
}
// MARK: Floating Windows
extension AppDelegate {
func syncFloatOnTopMenu(_ window: NSWindow?) {
guard let window = (window ?? NSApp.keyWindow) as? TerminalWindow else {
// If some other window became key we always turn this off
self.menuFloatOnTop?.state = .off
return
}
self.menuFloatOnTop?.state = window.level == .floating ? .on : .off
}
@IBAction func floatOnTop(_ menuItem: NSMenuItem) {
menuItem.state = menuItem.state == .on ? .off : .on
guard let window = NSApp.keyWindow else { return }
window.level = menuItem.state == .on ? .floating : .normal
}
@IBAction func useAsDefault(_ sender: NSMenuItem) {
let ud = UserDefaults.standard
let key = TerminalWindow.defaultLevelKey
if (menuFloatOnTop?.state == .on) {
ud.set(NSWindow.Level.floating, forKey: key)
} else {
ud.removeObject(forKey: key)
}
}
}
// MARK: NSMenuItemValidation
extension AppDelegate: NSMenuItemValidation {
func validateMenuItem(_ item: NSMenuItem) -> Bool {
switch item.action {
case #selector(floatOnTop(_:)),
#selector(useAsDefault(_:)):
// Float on top items only active if the key window is a primary
// terminal window (not quick terminal).
return NSApp.keyWindow is TerminalWindow
default:
return true
}
}
}

View File

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="23504" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="23727" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="23504"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="23727"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="NSApplication">
@ -21,9 +21,11 @@
<outlet property="menuCloseAllWindows" destination="yKr-Vi-Yqw" id="Zet-Ir-zbm"/>
<outlet property="menuCloseTab" destination="Obb-Mk-j8J" id="Gda-L0-gdz"/>
<outlet property="menuCloseWindow" destination="W5w-UZ-crk" id="6ff-BT-ENV"/>
<outlet property="menuCommandPalette" destination="et6-de-Mh7" id="53t-cu-dm5"/>
<outlet property="menuCopy" destination="Jqf-pv-Zcu" id="bKd-1C-oy9"/>
<outlet property="menuDecreaseFontSize" destination="kzb-SZ-dOA" id="Y1B-Vh-6Z2"/>
<outlet property="menuEqualizeSplits" destination="3gH-VD-vL9" id="SiZ-ce-FOF"/>
<outlet property="menuFloatOnTop" destination="uRj-7z-1Nh" id="94n-o9-Jol"/>
<outlet property="menuIncreaseFontSize" destination="CIH-ey-Z6x" id="hkc-9C-80E"/>
<outlet property="menuMoveSplitDividerDown" destination="Zj7-2W-fdF" id="997-LL-nlN"/>
<outlet property="menuMoveSplitDividerLeft" destination="wSR-ny-j1a" id="HCZ-CI-2ob"/>
@ -55,6 +57,7 @@
<outlet property="menuTerminalInspector" destination="QwP-M5-fvh" id="wJi-Dh-S9f"/>
<outlet property="menuToggleFullScreen" destination="8kY-Pi-KaY" id="yQg-6V-OO6"/>
<outlet property="menuToggleVisibility" destination="DOX-wA-ilh" id="iBj-Bc-2bq"/>
<outlet property="menuUseAsDefault" destination="TrB-O8-g8H" id="af4-Jh-2HU"/>
<outlet property="menuZoomSplit" destination="oPd-mn-IEH" id="wTu-jK-egI"/>
</connections>
</customObject>
@ -249,6 +252,12 @@
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="L3L-I8-sqk"/>
<menuItem title="Command Palette" id="et6-de-Mh7">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleCommandPalette:" target="-1" id="FcT-XD-gM1"/>
</connections>
</menuItem>
<menuItem title="Change Title..." id="24I-xg-qIq">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
@ -395,6 +404,19 @@
<action selector="returnToDefaultSize:" target="-1" id="Bpt-GO-UU1"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="Cm3-gn-vtj"/>
<menuItem title="Float on Top" id="uRj-7z-1Nh">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="floatOnTop:" target="bbz-4X-AYv" id="N58-PO-7pj"/>
</connections>
</menuItem>
<menuItem title="Use as Default" id="TrB-O8-g8H">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="useAsDefault:" target="bbz-4X-AYv" id="RHA-Nl-L2U"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="CpM-rI-Sc1"/>
<menuItem title="Bring All to Front" id="LE2-aR-0XJ">
<modifierMask key="keyEquivalentModifierMask"/>

View File

@ -0,0 +1,276 @@
import SwiftUI
struct CommandOption: Identifiable, Hashable {
let id = UUID()
let title: String
let description: String?
let symbols: [String]?
let action: () -> Void
static func == (lhs: CommandOption, rhs: CommandOption) -> Bool {
lhs.id == rhs.id
}
func hash(into hasher: inout Hasher) {
hasher.combine(id)
}
}
struct CommandPaletteView: View {
@Binding var isPresented: Bool
var backgroundColor: Color = Color(nsColor: .windowBackgroundColor)
var options: [CommandOption]
@State private var query = ""
@State private var selectedIndex: UInt?
@State private var hoveredOptionID: UUID?
// The options that we should show, taking into account any filtering from
// the query.
var filteredOptions: [CommandOption] {
if query.isEmpty {
return options
} else {
return options.filter { $0.title.localizedCaseInsensitiveContains(query) }
}
}
var selectedOption: CommandOption? {
guard let selectedIndex else { return nil }
return if selectedIndex < filteredOptions.count {
filteredOptions[Int(selectedIndex)]
} else {
filteredOptions.last
}
}
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) {
case .exit:
isPresented = false
case .submit:
isPresented = false
selectedOption?.action()
case .move(.up):
if filteredOptions.isEmpty { break }
let current = selectedIndex ?? UInt(filteredOptions.count)
selectedIndex = (current == 0)
? UInt(filteredOptions.count - 1)
: current - 1
case .move(.down):
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()
CommandTable(
options: filteredOptions,
selectedIndex: $selectedIndex,
hoveredOptionID: $hoveredOptionID) { option in
isPresented = false
option.action()
}
}
.frame(maxWidth: 500)
.background(
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)
}
}
/// The text field for building the query for the command palette.
fileprivate struct CommandPaletteQuery: View {
@Binding var query: String
var onEvent: ((KeyboardEvent) -> Void)? = nil
@FocusState private var isTextFieldFocused: Bool
enum KeyboardEvent {
case exit
case submit
case move(MoveCommandDirection)
}
var body: some View {
ZStack {
Group {
Button { onEvent?(.move(.up)) } label: { Color.clear }
.buttonStyle(PlainButtonStyle())
.keyboardShortcut(.upArrow, modifiers: [])
Button { onEvent?(.move(.down)) } label: { Color.clear }
.buttonStyle(PlainButtonStyle())
.keyboardShortcut(.downArrow, modifiers: [])
Button { onEvent?(.move(.up)) } label: { Color.clear }
.buttonStyle(PlainButtonStyle())
.keyboardShortcut(.init("p"), modifiers: [.control])
Button { onEvent?(.move(.down)) } label: { Color.clear }
.buttonStyle(PlainButtonStyle())
.keyboardShortcut(.init("n"), modifiers: [.control])
}
.frame(width: 0, height: 0)
.accessibilityHidden(true)
TextField("Execute a command…", text: $query)
.padding()
.font(.system(size: 20, weight: .light))
.frame(height: 48)
.textFieldStyle(.plain)
.focused($isTextFieldFocused)
.onAppear {
isTextFieldFocused = true
}
.onChange(of: isTextFieldFocused) { focused in
if !focused {
onEvent?(.exit)
}
}
.onExitCommand { onEvent?(.exit) }
.onMoveCommand { onEvent?(.move($0)) }
.onSubmit { onEvent?(.submit) }
}
}
}
fileprivate struct CommandTable: View {
var options: [CommandOption]
@Binding var selectedIndex: UInt?
@Binding var hoveredOptionID: UUID?
var action: (CommandOption) -> Void
var body: some View {
if options.isEmpty {
Text("No matches")
.foregroundStyle(.secondary)
.padding()
} else {
ScrollViewReader { proxy in
ScrollView {
VStack(alignment: .leading, spacing: 0) {
ForEach(Array(options.enumerated()), id: \.1.id) { index, option in
CommandRow(
option: option,
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 let selectedIndex,
selectedIndex < options.count else { return }
proxy.scrollTo(
options[Int(selectedIndex)].id)
}
}
}
}
}
/// A single row in the command palette.
fileprivate struct CommandRow: View {
let option: CommandOption
var isSelected: Bool
@Binding var hoveredID: UUID?
var action: () -> Void
var body: some View {
Button(action: action) {
HStack {
Text(option.title)
Spacer()
if let symbols = option.symbols {
ShortcutSymbolsView(symbols: symbols)
.foregroundStyle(.secondary)
}
}
.padding(8)
.background(
isSelected
? Color.accentColor.opacity(0.2)
: (hoveredID == option.id
? Color.secondary.opacity(0.2)
: Color.clear)
)
.cornerRadius(5)
}
.help(option.description ?? "")
.buttonStyle(.plain)
.onHover { hovering in
hoveredID = hovering ? option.id : nil
}
}
}
/// 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)
}
}
}
}

View File

@ -0,0 +1,105 @@
import SwiftUI
import GhosttyKit
struct TerminalCommandPaletteView: View {
/// The surface that this command palette represents.
let surfaceView: Ghostty.SurfaceView
/// Set this to true to show the view, this will be set to false if any actions
/// result in the view disappearing.
@Binding var isPresented: Bool
/// The configuration so we can lookup keyboard shortcuts.
@ObservedObject var ghosttyConfig: Ghostty.Config
/// The callback when an action is submitted.
var onAction: ((String) -> Void)
// The commands available to the command palette.
private var commandOptions: [CommandOption] {
guard let surface = surfaceView.surface else { return [] }
var ptr: UnsafeMutablePointer<ghostty_command_s>? = nil
var count: Int = 0
ghostty_surface_commands(surface, &ptr, &count)
guard let ptr else { return [] }
let buffer = UnsafeBufferPointer(start: ptr, count: count)
return Array(buffer).filter { c in
let key = String(cString: c.action_key)
switch (key) {
case "toggle_tab_overview",
"toggle_window_decorations":
return false
default:
return true
}
}.map { c in
let action = String(cString: c.action)
return CommandOption(
title: String(cString: c.title),
description: String(cString: c.description),
symbols: ghosttyConfig.keyboardShortcut(for: action)?.keyList
) {
onAction(action)
}
}
}
var body: some View {
ZStack {
if isPresented {
GeometryReader { geometry in
VStack {
Spacer().frame(height: geometry.size.height * 0.05)
ResponderChainInjector(responder: surfaceView)
.frame(width: 0, height: 0)
CommandPaletteView(
isPresented: $isPresented,
backgroundColor: ghosttyConfig.backgroundColor,
options: commandOptions
)
.transition(
.move(edge: .top)
.combined(with: .opacity)
.animation(.spring(response: 0.4, dampingFraction: 0.8))
) // Spring animation
.zIndex(1) // Ensure it's on top
Spacer()
}
.frame(width: geometry.size.width, height: geometry.size.height, alignment: .top)
}
}
}
.onChange(of: isPresented) { newValue in
// When the command palette disappears we need to send focus back to the
// surface view we were overlaid on top of. There's probably a better way
// to handle the first responder state here but I don't know it.
if !newValue {
// Has to be on queue because onChange happens on a user-interactive
// thread and Xcode is mad about this call on that.
DispatchQueue.main.async {
surfaceView.window?.makeFirstResponder(surfaceView)
}
}
}
}
}
/// This is done to ensure that the given view is in the responder chain.
fileprivate struct ResponderChainInjector: NSViewRepresentable {
let responder: NSResponder
func makeNSView(context: Context) -> NSView {
let dummy = NSView()
DispatchQueue.main.async {
dummy.nextResponder = responder
}
return dummy
}
func updateNSView(_ nsView: NSView, context: Context) {}
}

View File

@ -1,5 +1,6 @@
import Cocoa
import SwiftUI
import Combine
import GhosttyKit
/// A base class for windows that can contain Ghostty windows. This base class implements
@ -45,6 +46,9 @@ class BaseTerminalController: NSWindowController,
didSet { surfaceTreeDidChange(from: oldValue, to: surfaceTree) }
}
/// This can be set to show/hide the command palette.
@Published var commandPaletteIsShowing: Bool = false
/// Whether the terminal surface should focus when the mouse is over it.
var focusFollowsMouse: Bool {
self.derivedConfig.focusFollowsMouse
@ -68,6 +72,9 @@ class BaseTerminalController: NSWindowController,
/// The configuration derived from the Ghostty config so we don't need to rely on references.
private var derivedConfig: DerivedConfig
/// The cancellables related to our focused surface.
private var focusedSurfaceCancellables: Set<AnyCancellable> = []
struct SavedFrame {
let window: NSRect
let screen: NSRect
@ -107,6 +114,16 @@ class BaseTerminalController: NSWindowController,
selector: #selector(ghosttyConfigDidChangeBase(_:)),
name: .ghosttyConfigDidChange,
object: nil)
center.addObserver(
self,
selector: #selector(ghosttyCommandPaletteDidToggle(_:)),
name: .ghosttyCommandPaletteDidToggle,
object: nil)
center.addObserver(
self,
selector: #selector(ghosttyMaximizeDidToggle(_:)),
name: .ghosttyMaximizeDidToggle,
object: nil)
// Listen for local events that we need to know of outside of
// single surface handlers.
@ -144,6 +161,7 @@ class BaseTerminalController: NSWindowController,
// Our focus state requires that this window is key and our currently
// focused surface is the surface in this leaf.
let focused: Bool = (window?.isKeyWindow ?? false) &&
!commandPaletteIsShowing &&
focusedSurface != nil &&
leaf.surface == focusedSurface!
leaf.surface.focusDidChange(focused)
@ -219,6 +237,19 @@ class BaseTerminalController: NSWindowController,
self.derivedConfig = DerivedConfig(config)
}
@objc private func ghosttyCommandPaletteDidToggle(_ notification: Notification) {
guard let surfaceView = notification.object as? Ghostty.SurfaceView else { return }
guard surfaceTree?.contains(view: surfaceView) ?? false else { return }
toggleCommandPalette(nil)
}
@objc private func ghosttyMaximizeDidToggle(_ notification: Notification) {
guard let window else { return }
guard let surfaceView = notification.object as? Ghostty.SurfaceView else { return }
guard surfaceTree?.contains(view: surfaceView) ?? false else { return }
window.zoom(nil)
}
// MARK: Local Events
private func localEventHandler(_ event: NSEvent) -> NSEvent? {
@ -259,7 +290,26 @@ class BaseTerminalController: NSWindowController,
func surfaceTreeDidChange() {}
func focusedSurfaceDidChange(to: Ghostty.SurfaceView?) {
let lastFocusedSurface = focusedSurface
focusedSurface = to
// Important to cancel any prior subscriptions
focusedSurfaceCancellables = []
// Setup our title listener. If we have a focused surface we always use that.
// Otherwise, we try to use our last focused surface. In either case, we only
// want to care if the surface is in the tree so we don't listen to titles of
// closed surfaces.
if let titleSurface = focusedSurface ?? lastFocusedSurface,
surfaceTree?.contains(view: titleSurface) ?? false {
// If we have a surface, we want to listen for title changes.
titleSurface.$title
.sink { [weak self] in self?.titleDidChange(to: $0) }
.store(in: &focusedSurfaceCancellables)
} else {
// There is no surface to listen to titles for.
titleDidChange(to: "👻")
}
}
func titleDidChange(to: String) {
@ -288,6 +338,15 @@ class BaseTerminalController: NSWindowController,
func zoomStateDidChange(to: Bool) {}
func performAction(_ action: String, on surfaceView: Ghostty.SurfaceView) {
guard let surface = surfaceView.surface else { return }
let len = action.utf8CString.count
if (len == 0) { return }
_ = action.withCString { cString in
ghostty_surface_binding_action(surface, cString, UInt(len - 1))
}
}
// MARK: Fullscreen
/// Toggle fullscreen for the given mode.
@ -337,14 +396,6 @@ class BaseTerminalController: NSWindowController,
}
}
func fullscreenDidChange() {
// For some reason focus can get lost when we change fullscreen. Regardless of
// mode above we just move it back.
if let focusedSurface {
Ghostty.moveFocus(to: focusedSurface)
}
}
// MARK: Clipboard Confirmation
@objc private func onConfirmClipboardRequest(notification: SwiftUI.Notification) {
@ -619,6 +670,10 @@ class BaseTerminalController: NSWindowController,
ghostty.changeFontSize(surface: surface, .reset)
}
@IBAction func toggleCommandPalette(_ sender: Any?) {
commandPaletteIsShowing.toggle()
}
@objc func resetTerminal(_ sender: Any) {
guard let surface = focusedSurface?.surface else { return }
ghostty.resetTerminal(surface: surface)

View File

@ -121,9 +121,7 @@ class TerminalController: BaseTerminalController {
}
override func fullscreenDidChange() {
super.fullscreenDidChange()
func fullscreenDidChange() {
// When our fullscreen state changes, we resync our appearance because some
// properties change when fullscreen or not.
guard let focusedSurface else { return }
@ -192,7 +190,7 @@ class TerminalController: BaseTerminalController {
}
let action = "goto_tab:\(tab)"
if let equiv = ghostty.config.keyEquivalent(for: action) {
if let equiv = ghostty.config.keyboardShortcut(for: action) {
window.keyEquivalent = "\(equiv)"
} else {
window.keyEquivalent = ""

View File

@ -8,9 +8,6 @@ protocol TerminalViewDelegate: AnyObject {
/// Called when the currently focused surface changed. This can be nil.
func focusedSurfaceDidChange(to: Ghostty.SurfaceView?)
/// The title of the terminal should change.
func titleDidChange(to: String)
/// The URL of the pwd should change.
func pwdDidChange(to: URL?)
@ -23,6 +20,9 @@ protocol TerminalViewDelegate: AnyObject {
/// This is called when a split is zoomed.
func zoomStateDidChange(to: Bool)
/// Perform an action. At the time of writing this is only triggered by the command palette.
func performAction(_ action: String, on: Ghostty.SurfaceView)
}
/// The view model is a required implementation for TerminalView callers. This contains
@ -32,6 +32,9 @@ protocol TerminalViewModel: ObservableObject {
/// The tree of terminal surfaces (splits) within the view. This is mutated by TerminalView
/// and children. This should be @Published.
var surfaceTree: Ghostty.SplitNode? { get set }
/// The command palette state.
var commandPaletteIsShowing: Bool { get set }
}
/// The main terminal view. This terminal view supports splits.
@ -44,24 +47,19 @@ struct TerminalView<ViewModel: TerminalViewModel>: View {
// An optional delegate to receive information about terminal changes.
weak var delegate: (any TerminalViewDelegate)? = nil
// The most recently focused surface, equal to focusedSurface when
// it is non-nil.
@State private var lastFocusedSurface: Weak<Ghostty.SurfaceView> = .init()
// This seems like a crutch after switching from SwiftUI to AppKit lifecycle.
@FocusState private var focused: Bool
// Various state values sent back up from the currently focused terminals.
@FocusedValue(\.ghosttySurfaceView) private var focusedSurface
@FocusedValue(\.ghosttySurfaceTitle) private var surfaceTitle
@FocusedValue(\.ghosttySurfacePwd) private var surfacePwd
@FocusedValue(\.ghosttySurfaceZoomed) private var zoomedSplit
@FocusedValue(\.ghosttySurfaceCellSize) private var cellSize
// The title for our window
private var title: String {
if let surfaceTitle, !surfaceTitle.isEmpty {
return surfaceTitle
}
return "👻"
}
// The pwd of the focused surface as a URL
private var pwdURL: URL? {
guard let surfacePwd, surfacePwd != "" else { return nil }
@ -75,42 +73,55 @@ struct TerminalView<ViewModel: TerminalViewModel>: View {
case .error:
ErrorView()
case .ready:
VStack(spacing: 0) {
// If we're running in debug mode we show a warning so that users
// know that performance will be degraded.
if (Ghostty.info.mode == GHOSTTY_BUILD_MODE_DEBUG || Ghostty.info.mode == GHOSTTY_BUILD_MODE_RELEASE_SAFE) {
DebugBuildWarningView()
}
ZStack {
VStack(spacing: 0) {
// If we're running in debug mode we show a warning so that users
// know that performance will be degraded.
if (Ghostty.info.mode == GHOSTTY_BUILD_MODE_DEBUG || Ghostty.info.mode == GHOSTTY_BUILD_MODE_RELEASE_SAFE) {
DebugBuildWarningView()
}
Ghostty.TerminalSplit(node: $viewModel.surfaceTree)
.environmentObject(ghostty)
.focused($focused)
.onAppear { self.focused = true }
.onChange(of: focusedSurface) { newValue in
self.delegate?.focusedSurfaceDidChange(to: newValue)
}
.onChange(of: title) { newValue in
self.delegate?.titleDidChange(to: newValue)
}
.onChange(of: pwdURL) { newValue in
self.delegate?.pwdDidChange(to: newValue)
}
.onChange(of: cellSize) { newValue in
guard let size = newValue else { return }
self.delegate?.cellSizeDidChange(to: size)
}
.onChange(of: viewModel.surfaceTree?.hashValue) { _ in
// This is funky, but its the best way I could think of to detect
// ANY CHANGE within the deeply nested surface tree -- detecting a change
// in the hash value.
self.delegate?.surfaceTreeDidChange()
}
.onChange(of: zoomedSplit) { newValue in
self.delegate?.zoomStateDidChange(to: newValue ?? false)
Ghostty.TerminalSplit(node: $viewModel.surfaceTree)
.environmentObject(ghostty)
.focused($focused)
.onAppear { self.focused = true }
.onChange(of: focusedSurface) { newValue in
// We want to keep track of our last focused surface so even if
// we lose focus we keep this set to the last non-nil value.
if newValue != nil {
lastFocusedSurface = .init(newValue)
self.delegate?.focusedSurfaceDidChange(to: newValue)
}
}
.onChange(of: pwdURL) { newValue in
self.delegate?.pwdDidChange(to: newValue)
}
.onChange(of: cellSize) { newValue in
guard let size = newValue else { return }
self.delegate?.cellSizeDidChange(to: size)
}
.onChange(of: viewModel.surfaceTree?.hashValue) { _ in
// This is funky, but its the best way I could think of to detect
// ANY CHANGE within the deeply nested surface tree -- detecting a change
// in the hash value.
self.delegate?.surfaceTreeDidChange()
}
.onChange(of: zoomedSplit) { newValue in
self.delegate?.zoomStateDidChange(to: newValue ?? false)
}
}
// Ignore safe area to extend up in to the titlebar region if we have the "hidden" titlebar style
.ignoresSafeArea(.container, edges: ghostty.config.macosTitlebarStyle == "hidden" ? .top : [])
if let surfaceView = lastFocusedSurface.value {
TerminalCommandPaletteView(
surfaceView: surfaceView,
isPresented: $viewModel.commandPaletteIsShowing,
ghosttyConfig: ghostty.config) { action in
self.delegate?.performAction(action, on: surfaceView)
}
}
}
// Ignore safe area to extend up in to the titlebar region if we have the "hidden" titlebar style
.ignoresSafeArea(.container, edges: ghostty.config.macosTitlebarStyle == "hidden" ? .top : [])
}
}
}

View File

@ -1,6 +1,9 @@
import Cocoa
class TerminalWindow: NSWindow {
/// This is the key in UserDefaults to use for the default `level` value.
static let defaultLevelKey: String = "TerminalDefaultLevel"
@objc dynamic var keyEquivalent: String = ""
/// This is used to determine if certain elements should be drawn light or dark and should
@ -63,6 +66,8 @@ class TerminalWindow: NSWindow {
if titlebarTabs {
generateToolbar()
}
level = UserDefaults.standard.value(forKey: Self.defaultLevelKey) as? NSWindow.Level ?? .normal
}
deinit {

View File

@ -496,6 +496,9 @@ extension Ghostty {
case GHOSTTY_ACTION_OPEN_CONFIG:
ghostty_config_open()
case GHOSTTY_ACTION_FLOAT_WINDOW:
toggleFloatWindow(app, target: target, mode: action.action.float_window)
case GHOSTTY_ACTION_SECURE_INPUT:
toggleSecureInput(app, target: target, mode: action.action.secure_input)
@ -520,6 +523,12 @@ extension Ghostty {
case GHOSTTY_ACTION_RENDERER_HEALTH:
rendererHealth(app, target: target, v: action.action.renderer_health)
case GHOSTTY_ACTION_TOGGLE_COMMAND_PALETTE:
toggleCommandPalette(app, target: target)
case GHOSTTY_ACTION_TOGGLE_MAXIMIZE:
toggleMaximize(app, target: target)
case GHOSTTY_ACTION_TOGGLE_QUICK_TERMINAL:
toggleQuickTerminal(app, target: target)
@ -742,6 +751,51 @@ extension Ghostty {
}
}
private static func toggleCommandPalette(
_ app: ghostty_app_t,
target: ghostty_target_s) {
switch (target.tag) {
case GHOSTTY_TARGET_APP:
Ghostty.logger.warning("toggle command palette does nothing with an app target")
return
case GHOSTTY_TARGET_SURFACE:
guard let surface = target.target.surface else { return }
guard let surfaceView = self.surfaceView(from: surface) else { return }
NotificationCenter.default.post(
name: .ghosttyCommandPaletteDidToggle,
object: surfaceView
)
default:
assertionFailure()
}
}
private static func toggleMaximize(
_ app: ghostty_app_t,
target: ghostty_target_s
) {
switch (target.tag) {
case GHOSTTY_TARGET_APP:
Ghostty.logger.warning("toggle maximize does nothing with an app target")
return
case GHOSTTY_TARGET_SURFACE:
guard let surface = target.target.surface else { return }
guard let surfaceView = self.surfaceView(from: surface) else { return }
NotificationCenter.default.post(
name: .ghosttyMaximizeDidToggle,
object: surfaceView
)
default:
assertionFailure()
}
}
private static func toggleVisibility(
_ app: ghostty_app_t,
target: ghostty_target_s
@ -1001,6 +1055,43 @@ extension Ghostty {
}
}
private static func toggleFloatWindow(
_ app: ghostty_app_t,
target: ghostty_target_s,
mode mode_raw: ghostty_action_float_window_e
) {
guard let mode = SetFloatWIndow.from(mode_raw) else { return }
switch (target.tag) {
case GHOSTTY_TARGET_APP:
Ghostty.logger.warning("toggle float window does nothing with an app target")
return
case GHOSTTY_TARGET_SURFACE:
guard let surface = target.target.surface else { return }
guard let surfaceView = self.surfaceView(from: surface) else { return }
guard let window = surfaceView.window as? TerminalWindow else { return }
switch (mode) {
case .on:
window.level = .floating
case .off:
window.level = .normal
case .toggle:
window.level = window.level == .floating ? .normal : .floating
}
if let appDelegate = NSApplication.shared.delegate as? AppDelegate {
appDelegate.syncFloatOnTopMenu(window)
}
default:
assertionFailure()
}
}
private static func toggleSecureInput(
_ app: ghostty_app_t,
target: ghostty_target_s,
@ -1306,7 +1397,7 @@ extension Ghostty {
name: Notification.didContinueKeySequence,
object: surfaceView,
userInfo: [
Notification.KeySequenceKey: keyEquivalent(for: v.trigger) as Any
Notification.KeySequenceKey: keyboardShortcut(for: v.trigger) as Any
]
)
} else {

View File

@ -102,11 +102,11 @@ extension Ghostty {
/// configuration would be "quit" action.
///
/// Returns nil if there is no key equivalent for the given action.
func keyEquivalent(for action: String) -> KeyEquivalent? {
func keyboardShortcut(for action: String) -> KeyboardShortcut? {
guard let cfg = self.config else { return nil }
let trigger = ghostty_config_trigger(cfg, action, UInt(action.count))
return Ghostty.keyEquivalent(for: trigger)
return Ghostty.keyboardShortcut(for: trigger)
}
#endif

View File

@ -1,66 +1,52 @@
import Cocoa
import SwiftUI
import GhosttyKit
extension Ghostty {
// MARK: Key Equivalents
// MARK: Keyboard Shortcuts
/// Returns the "keyEquivalent" string for a given input key. This doesn't always have a corresponding key.
static func keyEquivalent(key: ghostty_input_key_e) -> String? {
/// Returns the SwiftUI KeyEquivalent for a given key. Note that not all keys known by
/// Ghostty have a macOS equivalent since macOS doesn't allow all keys as equivalents.
static func keyEquivalent(key: ghostty_input_key_e) -> KeyEquivalent? {
return Self.keyToEquivalent[key]
}
/// A convenience struct that has the key + modifiers for some keybinding.
struct KeyEquivalent: CustomStringConvertible {
let key: String
let modifiers: NSEvent.ModifierFlags
var description: String {
var key = self.key
// Note: the order below matters; it matches the ordering modifiers
// shown for macOS menu shortcut labels.
if modifiers.contains(.command) { key = "\(key)" }
if modifiers.contains(.shift) { key = "\(key)" }
if modifiers.contains(.option) { key = "\(key)" }
if modifiers.contains(.control) { key = "\(key)" }
return key
}
}
/// Return the key equivalent for the given trigger.
///
/// Returns nil if the trigger can't be processed. This should only happen for unknown trigger types
/// or keys.
static func keyEquivalent(for trigger: ghostty_input_trigger_s) -> KeyEquivalent? {
let equiv: String
/// Returns nil if the trigger doesn't have an equivalent KeyboardShortcut. This is possible
/// because Ghostty input triggers are a superset of what can be represented by a macOS
/// KeyboardShortcut. For example, macOS doesn't have any way to represent function keys
/// (F1, F2, ...) with a KeyboardShortcut. This doesn't represent a practical issue because input
/// handling for Ghostty is handled at a lower level (usually). This function should generally only
/// be used for things like NSMenu that only support keyboard shortcuts anyways.
static func keyboardShortcut(for trigger: ghostty_input_trigger_s) -> KeyboardShortcut? {
let key: KeyEquivalent
switch (trigger.tag) {
case GHOSTTY_TRIGGER_TRANSLATED:
if let v = Ghostty.keyEquivalent(key: trigger.key.translated) {
equiv = v
key = v
} else {
return nil
}
case GHOSTTY_TRIGGER_PHYSICAL:
if let v = Ghostty.keyEquivalent(key: trigger.key.physical) {
equiv = v
key = v
} else {
return nil
}
case GHOSTTY_TRIGGER_UNICODE:
guard let scalar = UnicodeScalar(trigger.key.unicode) else { return nil }
equiv = String(scalar)
key = KeyEquivalent(Character(scalar))
default:
return nil
}
return KeyEquivalent(
key: equiv,
modifiers: Ghostty.eventModifierFlags(mods: trigger.mods)
)
return KeyboardShortcut(
key,
modifiers: EventModifiers(nsFlags: Ghostty.eventModifierFlags(mods: trigger.mods)))
}
// MARK: Mods
@ -96,8 +82,10 @@ extension Ghostty {
return ghostty_input_mods_e(mods)
}
/// A map from the Ghostty key enum to the keyEquivalent string for shortcuts.
static let keyToEquivalent: [ghostty_input_key_e : String] = [
/// A map from the Ghostty key enum to the keyEquivalent string for shortcuts. Note that
/// not all ghostty key enum values are represented here because not all of them can be
/// mapped to a KeyEquivalent.
static let keyToEquivalent: [ghostty_input_key_e : KeyEquivalent] = [
// 0-9
GHOSTTY_KEY_ZERO: "0",
GHOSTTY_KEY_ONE: "1",
@ -152,48 +140,19 @@ extension Ghostty {
GHOSTTY_KEY_SLASH: "/",
// Function keys
GHOSTTY_KEY_UP: "\u{F700}",
GHOSTTY_KEY_DOWN: "\u{F701}",
GHOSTTY_KEY_LEFT: "\u{F702}",
GHOSTTY_KEY_RIGHT: "\u{F703}",
GHOSTTY_KEY_HOME: "\u{F729}",
GHOSTTY_KEY_END: "\u{F72B}",
GHOSTTY_KEY_INSERT: "\u{F727}",
GHOSTTY_KEY_DELETE: "\u{F728}",
GHOSTTY_KEY_PAGE_UP: "\u{F72C}",
GHOSTTY_KEY_PAGE_DOWN: "\u{F72D}",
GHOSTTY_KEY_ESCAPE: "\u{1B}",
GHOSTTY_KEY_ENTER: "\r",
GHOSTTY_KEY_TAB: "\t",
GHOSTTY_KEY_BACKSPACE: "\u{7F}",
GHOSTTY_KEY_PRINT_SCREEN: "\u{F72E}",
GHOSTTY_KEY_PAUSE: "\u{F72F}",
GHOSTTY_KEY_F1: "\u{F704}",
GHOSTTY_KEY_F2: "\u{F705}",
GHOSTTY_KEY_F3: "\u{F706}",
GHOSTTY_KEY_F4: "\u{F707}",
GHOSTTY_KEY_F5: "\u{F708}",
GHOSTTY_KEY_F6: "\u{F709}",
GHOSTTY_KEY_F7: "\u{F70A}",
GHOSTTY_KEY_F8: "\u{F70B}",
GHOSTTY_KEY_F9: "\u{F70C}",
GHOSTTY_KEY_F10: "\u{F70D}",
GHOSTTY_KEY_F11: "\u{F70E}",
GHOSTTY_KEY_F12: "\u{F70F}",
GHOSTTY_KEY_F13: "\u{F710}",
GHOSTTY_KEY_F14: "\u{F711}",
GHOSTTY_KEY_F15: "\u{F712}",
GHOSTTY_KEY_F16: "\u{F713}",
GHOSTTY_KEY_F17: "\u{F714}",
GHOSTTY_KEY_F18: "\u{F715}",
GHOSTTY_KEY_F19: "\u{F716}",
GHOSTTY_KEY_F20: "\u{F717}",
GHOSTTY_KEY_F21: "\u{F718}",
GHOSTTY_KEY_F22: "\u{F719}",
GHOSTTY_KEY_F23: "\u{F71A}",
GHOSTTY_KEY_F24: "\u{F71B}",
GHOSTTY_KEY_F25: "\u{F71C}",
GHOSTTY_KEY_UP: .upArrow,
GHOSTTY_KEY_DOWN: .downArrow,
GHOSTTY_KEY_LEFT: .leftArrow,
GHOSTTY_KEY_RIGHT: .rightArrow,
GHOSTTY_KEY_HOME: .home,
GHOSTTY_KEY_END: .end,
GHOSTTY_KEY_DELETE: .delete,
GHOSTTY_KEY_PAGE_UP: .pageUp,
GHOSTTY_KEY_PAGE_DOWN: .pageDown,
GHOSTTY_KEY_ESCAPE: .escape,
GHOSTTY_KEY_ENTER: .return,
GHOSTTY_KEY_TAB: .tab,
GHOSTTY_KEY_BACKSPACE: .delete,
]
static let asciiToKey: [UInt8 : ghostty_input_key_e] = [

View File

@ -45,8 +45,6 @@ extension Ghostty {
/// this one.
@Binding var zoomedSurface: SurfaceView?
@FocusedValue(\.ghosttySurfaceTitle) private var surfaceTitle: String?
var body: some View {
let center = NotificationCenter.default
let pubZoom = center.publisher(for: Notification.didToggleSplitZoom)
@ -77,7 +75,6 @@ extension Ghostty {
.onReceive(pubZoom) { onZoom(notification: $0) }
}
}
.navigationTitle(surfaceTitle ?? "Ghostty")
.id(node) // Needed for change detection on node
} else {
// On these events we want to reset the split state and call it.

View File

@ -31,7 +31,6 @@ extension Ghostty {
}, right: {
InspectorViewRepresentable(surfaceView: surfaceView)
.focused($inspectorFocus)
.focusedValue(\.ghosttySurfaceTitle, surfaceView.title)
.focusedValue(\.ghosttySurfaceView, surfaceView)
})
}

View File

@ -33,11 +33,13 @@ extension NSEvent {
.subtracting([.control, .command]))
// Our unshifted codepoint is the codepoint with no modifiers. We
// ignore multi-codepoint values.
// ignore multi-codepoint values. We have to use `byApplyingModifiers`
// instead of `charactersIgnoringModifiers` because the latter changes
// behavior with ctrl pressed and we don't want any of that.
key_ev.unshifted_codepoint = 0
if type == .keyDown || type == .keyUp {
if let charactersIgnoringModifiers,
let codepoint = charactersIgnoringModifiers.unicodeScalars.first
if let chars = characters(byApplyingModifiers: []),
let codepoint = chars.unicodeScalars.first
{
key_ev.unshifted_codepoint = codepoint.value
}

View File

@ -42,6 +42,28 @@ extension Ghostty {
// MARK: Swift Types for C Types
extension Ghostty {
enum SetFloatWIndow {
case on
case off
case toggle
static func from(_ c: ghostty_action_float_window_e) -> Self? {
switch (c) {
case GHOSTTY_FLOAT_WINDOW_ON:
return .on
case GHOSTTY_FLOAT_WINDOW_OFF:
return .off
case GHOSTTY_FLOAT_WINDOW_TOGGLE:
return .toggle
default:
return nil
}
}
}
enum SetSecureInput {
case on
case off
@ -256,6 +278,10 @@ extension Notification.Name {
/// Ring the bell
static let ghosttyBellDidRing = Notification.Name("com.mitchellh.ghostty.ghosttyBellDidRing")
static let ghosttyCommandPaletteDidToggle = Notification.Name("com.mitchellh.ghostty.commandPaletteDidToggle")
/// Toggle maximize of current window
static let ghosttyMaximizeDidToggle = Notification.Name("com.mitchellh.ghostty.maximizeDidToggle")
}
// NOTE: I am moving all of these to Notification.Name extensions over time. This

View File

@ -6,14 +6,12 @@ extension Ghostty {
/// Render a terminal for the active app in the environment.
struct Terminal: View {
@EnvironmentObject private var ghostty: Ghostty.App
@FocusedValue(\.ghosttySurfaceTitle) private var surfaceTitle: String?
var body: some View {
if let app = self.ghostty.app {
SurfaceForApp(app) { surfaceView in
SurfaceWrapper(surfaceView: surfaceView)
}
.navigationTitle(surfaceTitle ?? "Ghostty")
}
}
}
@ -83,7 +81,6 @@ extension Ghostty {
Surface(view: surfaceView, size: geo.size)
.focused($surfaceFocus)
.focusedValue(\.ghosttySurfaceTitle, title)
.focusedValue(\.ghosttySurfacePwd, surfaceView.pwd)
.focusedValue(\.ghosttySurfaceView, surfaceView)
.focusedValue(\.ghosttySurfaceCellSize, surfaceView.cellSize)
@ -329,7 +326,7 @@ extension Ghostty {
Spacer()
}
Text(verbatim: "\(size.columns)c \(size.rows)r")
Text(verbatim: "\(size.columns) \(size.rows)")
.padding(.init(top: padding, leading: padding, bottom: padding, trailing: padding))
.background(
RoundedRectangle(cornerRadius: 4)
@ -496,15 +493,6 @@ extension FocusedValues {
typealias Value = Ghostty.SurfaceView
}
var ghosttySurfaceTitle: String? {
get { self[FocusedGhosttySurfaceTitle.self] }
set { self[FocusedGhosttySurfaceTitle.self] = newValue }
}
struct FocusedGhosttySurfaceTitle: FocusedValueKey {
typealias Value = String
}
var ghosttySurfacePwd: String? {
get { self[FocusedGhosttySurfacePwd.self] }
set { self[FocusedGhosttySurfacePwd.self] = newValue }

View File

@ -43,7 +43,7 @@ extension Ghostty {
@Published var hoverUrl: String? = nil
// The currently active key sequence. The sequence is not active if this is empty.
@Published var keySequence: [Ghostty.KeyEquivalent] = []
@Published var keySequence: [KeyboardShortcut] = []
// The time this surface last became focused. This is a ContinuousClock.Instant
// on supported platforms.
@ -526,7 +526,7 @@ extension Ghostty {
@objc private func ghosttyDidContinueKeySequence(notification: SwiftUI.Notification) {
guard let keyAny = notification.userInfo?[Ghostty.Notification.KeySequenceKey] else { return }
guard let key = keyAny as? Ghostty.KeyEquivalent else { return }
guard let key = keyAny as? KeyboardShortcut else { return }
DispatchQueue.main.async { [weak self] in
self?.keySequence.append(key)
}
@ -975,7 +975,14 @@ extension Ghostty {
event: event,
translationEvent: translationEvent,
text: translationEvent.ghosttyCharacters,
composing: markedText.length > 0
// We're composing if we have preedit (the obvious case). But we're also
// composing if we don't have preedit and we had marked text before,
// because this input probably just reset the preedit state. It shouldn't
// be encoded. Example: Japanese begin composing, the press backspace.
// This should only cancel the composing state but not actually delete
// the prior input characters (prior to the composing).
composing: markedText.length > 0 || markedTextBefore
)
}
}
@ -1169,7 +1176,12 @@ extension Ghostty {
var key_ev = event.ghosttyKeyEvent(action, translationMods: translationEvent?.modifierFlags)
key_ev.composing = composing
if let text {
// For text, we only encode UTF8 if we don't have a single control
// character. Control characters are encoded by Ghostty itself.
// Without this, `ctrl+enter` does the wrong thing.
if let text, text.count > 0,
let codepoint = text.utf8.first, codepoint >= 0x20 {
return text.withCString { ptr in
key_ev.text = ptr
return ghostty_surface_key(surface, key_ev)

View File

@ -0,0 +1,27 @@
import SwiftUI
// MARK: EventModifiers to NSEvent and Back
extension EventModifiers {
init(nsFlags: NSEvent.ModifierFlags) {
var result: SwiftUI.EventModifiers = []
if nsFlags.contains(.shift) { result.insert(.shift) }
if nsFlags.contains(.control) { result.insert(.control) }
if nsFlags.contains(.option) { result.insert(.option) }
if nsFlags.contains(.command) { result.insert(.command) }
if nsFlags.contains(.capsLock) { result.insert(.capsLock) }
self = result
}
}
extension NSEvent.ModifierFlags {
init(swiftUIFlags: SwiftUI.EventModifiers) {
var result: NSEvent.ModifierFlags = []
if swiftUIFlags.contains(.shift) { result.insert(.shift) }
if swiftUIFlags.contains(.control) { result.insert(.control) }
if swiftUIFlags.contains(.option) { result.insert(.option) }
if swiftUIFlags.contains(.command) { result.insert(.command) }
if swiftUIFlags.contains(.capsLock) { result.insert(.capsLock) }
self = result
}
}

View File

@ -171,6 +171,13 @@ class NonNativeFullscreen: FullscreenBase, FullscreenStyle {
guard let savedState = SavedState(window) else { return }
self.savedState = savedState
// Get our current first responder on this window. For non-native fullscreen
// we have to restore this because for some reason the operations below
// lose it (see: https://github.com/ghostty-org/ghostty/issues/6999).
// I don't know the root cause here so if we can figure that out there may
// be a nicer way than this.
let firstResponder = window.firstResponder
// We hide the dock if the window is on a screen with the dock.
// We must hide the dock FIRST then hide the menu:
// If you specify autoHideMenuBar, it must be accompanied by either hideDock or autoHideDock.
@ -207,6 +214,10 @@ class NonNativeFullscreen: FullscreenBase, FullscreenStyle {
// https://github.com/ghostty-org/ghostty/issues/1996
DispatchQueue.main.async {
self.window.setFrame(self.fullscreenFrame(screen), display: true)
if let firstResponder {
self.window.makeFirstResponder(firstResponder)
}
self.delegate?.fullscreenDidChange()
}
}
@ -220,6 +231,9 @@ class NonNativeFullscreen: FullscreenBase, FullscreenStyle {
let center = NotificationCenter.default
center.removeObserver(self, name: NSWindow.didChangeScreenNotification, object: window)
// See enter where we do the same thing to understand why.
let firstResponder = window.firstResponder
// Unhide our elements
if savedState.dock {
unhideDock()
@ -258,6 +272,10 @@ class NonNativeFullscreen: FullscreenBase, FullscreenStyle {
}
}
if let firstResponder {
window.makeFirstResponder(firstResponder)
}
// Unset our saved state, we're restored!
self.savedState = nil
@ -355,16 +373,23 @@ class NonNativeFullscreen: FullscreenBase, FullscreenStyle {
self.styleMask = window.styleMask
self.dock = window.screen?.hasDock ?? false
// We hide the menu only if this window is not on any fullscreen
// spaces. We do this because fullscreen spaces already hide the
// menu and if we insert/remove this presentation option we get
// issues (see #7075)
let activeSpace = CGSSpace.active()
let spaces = CGSSpace.list(for: window.cgWindowId)
if spaces.contains(activeSpace) {
self.menu = activeSpace.type != .fullscreen
if let cgWindowId = window.cgWindowId {
// We hide the menu only if this window is not on any fullscreen
// spaces. We do this because fullscreen spaces already hide the
// menu and if we insert/remove this presentation option we get
// issues (see #7075)
let activeSpace = CGSSpace.active()
let spaces = CGSSpace.list(for: cgWindowId)
if spaces.contains(activeSpace) {
self.menu = activeSpace.type != .fullscreen
} else {
self.menu = spaces.allSatisfy { $0.type != .fullscreen }
}
} else {
self.menu = spaces.allSatisfy { $0.type != .fullscreen }
// Window doesn't have a window device, its not visible or something.
// In this case, we assume we can hide the menu. We may want to do
// something more sophisticated but this works for now.
self.menu = true
}
}
}

View File

@ -0,0 +1,53 @@
import SwiftUI
extension KeyboardShortcut: @retroactive CustomStringConvertible {
public var keyList: [String] {
var result: [String] = []
if modifiers.contains(.control) {
result.append("")
}
if modifiers.contains(.option) {
result.append("")
}
if modifiers.contains(.shift) {
result.append("")
}
if modifiers.contains(.command) {
result.append("")
}
let keyString: String
switch key {
case .return: keyString = ""
case .escape: keyString = ""
case .delete: keyString = ""
case .space: keyString = ""
case .tab: 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())
}
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.
extension KeyEquivalent: @retroactive Equatable {
public static func == (lhs: KeyEquivalent, rhs: KeyEquivalent) -> Bool {
lhs.character == rhs.character
}
}

View File

@ -2,7 +2,11 @@ import AppKit
extension NSWindow {
/// Get the CGWindowID type for the window (used for low level CoreGraphics APIs).
var cgWindowId: CGWindowID {
CGWindowID(windowNumber)
var cgWindowId: CGWindowID? {
// "If the window doesnt have a window device, the value of this
// property is equal to or less than 0." - Docs. In practice I've
// found this is true if a window is not visible.
guard windowNumber > 0 else { return nil }
return CGWindowID(windowNumber)
}
}

View File

@ -3,7 +3,7 @@
class Weak<T: AnyObject> {
weak var value: T?
init(_ value: T) {
init(_ value: T? = nil) {
self.value = value
}
}

View File

@ -3,6 +3,8 @@
lib,
stdenv,
bashInteractive,
appstream,
flatpak-builder,
gdb,
#, glxinfo # unused
ncurses,
@ -128,6 +130,8 @@ in
# build only has the qemu-system files.
qemu
appstream
flatpak-builder
gdb
snapcraft
valgrind

View File

@ -1,20 +1,20 @@
pub const c = @import("c.zig").c;
// OpenGL
pub extern fn ImGui_ImplOpenGL3_Init(?[*:0]const u8) callconv(.C) bool;
pub extern fn ImGui_ImplOpenGL3_Shutdown() callconv(.C) void;
pub extern fn ImGui_ImplOpenGL3_NewFrame() callconv(.C) void;
pub extern fn ImGui_ImplOpenGL3_RenderDrawData(*c.ImDrawData) callconv(.C) void;
pub extern fn ImGui_ImplOpenGL3_Init(?[*:0]const u8) callconv(.c) bool;
pub extern fn ImGui_ImplOpenGL3_Shutdown() callconv(.c) void;
pub extern fn ImGui_ImplOpenGL3_NewFrame() callconv(.c) void;
pub extern fn ImGui_ImplOpenGL3_RenderDrawData(*c.ImDrawData) callconv(.c) void;
// Metal
pub extern fn ImGui_ImplMetal_Init(*anyopaque) callconv(.C) bool;
pub extern fn ImGui_ImplMetal_Shutdown() callconv(.C) void;
pub extern fn ImGui_ImplMetal_NewFrame(*anyopaque) callconv(.C) void;
pub extern fn ImGui_ImplMetal_RenderDrawData(*c.ImDrawData, *anyopaque, *anyopaque) callconv(.C) void;
pub extern fn ImGui_ImplMetal_Init(*anyopaque) callconv(.c) bool;
pub extern fn ImGui_ImplMetal_Shutdown() callconv(.c) void;
pub extern fn ImGui_ImplMetal_NewFrame(*anyopaque) callconv(.c) void;
pub extern fn ImGui_ImplMetal_RenderDrawData(*c.ImDrawData, *anyopaque, *anyopaque) callconv(.c) void;
// OSX
pub extern fn ImGui_ImplOSX_Init(*anyopaque) callconv(.C) bool;
pub extern fn ImGui_ImplOSX_Shutdown() callconv(.C) void;
pub extern fn ImGui_ImplOSX_NewFrame(*anyopaque) callconv(.C) void;
pub extern fn ImGui_ImplOSX_Init(*anyopaque) callconv(.c) bool;
pub extern fn ImGui_ImplOSX_Shutdown() callconv(.c) void;
pub extern fn ImGui_ImplOSX_NewFrame(*anyopaque) callconv(.c) void;
test {}

View File

@ -333,7 +333,7 @@ pub inline fn setCallback(comptime callback: ?fn (joystick: Joystick, event: Eve
if (callback) |user_callback| {
const CWrapper = struct {
pub fn joystickCallbackWrapper(jid: c_int, event: c_int) callconv(.C) void {
pub fn joystickCallbackWrapper(jid: c_int, event: c_int) callconv(.c) void {
@call(.always_inline, user_callback, .{
Joystick{ .jid = @as(Joystick.Id, @enumFromInt(jid)) },
@as(Event, @enumFromInt(event)),

View File

@ -389,7 +389,7 @@ pub inline fn setCallback(comptime callback: ?fn (monitor: Monitor, event: Event
if (callback) |user_callback| {
const CWrapper = struct {
pub fn monitorCallbackWrapper(monitor: ?*c.GLFWmonitor, event: c_int) callconv(.C) void {
pub fn monitorCallbackWrapper(monitor: ?*c.GLFWmonitor, event: c_int) callconv(.c) void {
@call(.always_inline, user_callback, .{
Monitor{ .handle = monitor.? },
@as(Event, @enumFromInt(event)),

View File

@ -1230,7 +1230,7 @@ pub inline fn setPosCallback(self: Window, comptime callback: ?fn (window: Windo
if (callback) |user_callback| {
const CWrapper = struct {
pub fn posCallbackWrapper(handle: ?*c.GLFWwindow, xpos: c_int, ypos: c_int) callconv(.C) void {
pub fn posCallbackWrapper(handle: ?*c.GLFWwindow, xpos: c_int, ypos: c_int) callconv(.c) void {
@call(.always_inline, user_callback, .{
from(handle.?),
@as(i32, @intCast(xpos)),
@ -1263,7 +1263,7 @@ pub inline fn setSizeCallback(self: Window, comptime callback: ?fn (window: Wind
if (callback) |user_callback| {
const CWrapper = struct {
pub fn sizeCallbackWrapper(handle: ?*c.GLFWwindow, width: c_int, height: c_int) callconv(.C) void {
pub fn sizeCallbackWrapper(handle: ?*c.GLFWwindow, width: c_int, height: c_int) callconv(.c) void {
@call(.always_inline, user_callback, .{
from(handle.?),
@as(i32, @intCast(width)),
@ -1304,7 +1304,7 @@ pub inline fn setCloseCallback(self: Window, comptime callback: ?fn (window: Win
if (callback) |user_callback| {
const CWrapper = struct {
pub fn closeCallbackWrapper(handle: ?*c.GLFWwindow) callconv(.C) void {
pub fn closeCallbackWrapper(handle: ?*c.GLFWwindow) callconv(.c) void {
@call(.always_inline, user_callback, .{
from(handle.?),
});
@ -1341,7 +1341,7 @@ pub inline fn setRefreshCallback(self: Window, comptime callback: ?fn (window: W
if (callback) |user_callback| {
const CWrapper = struct {
pub fn refreshCallbackWrapper(handle: ?*c.GLFWwindow) callconv(.C) void {
pub fn refreshCallbackWrapper(handle: ?*c.GLFWwindow) callconv(.c) void {
@call(.always_inline, user_callback, .{
from(handle.?),
});
@ -1379,7 +1379,7 @@ pub inline fn setFocusCallback(self: Window, comptime callback: ?fn (window: Win
if (callback) |user_callback| {
const CWrapper = struct {
pub fn focusCallbackWrapper(handle: ?*c.GLFWwindow, focused: c_int) callconv(.C) void {
pub fn focusCallbackWrapper(handle: ?*c.GLFWwindow, focused: c_int) callconv(.c) void {
@call(.always_inline, user_callback, .{
from(handle.?),
focused == c.GLFW_TRUE,
@ -1413,7 +1413,7 @@ pub inline fn setIconifyCallback(self: Window, comptime callback: ?fn (window: W
if (callback) |user_callback| {
const CWrapper = struct {
pub fn iconifyCallbackWrapper(handle: ?*c.GLFWwindow, iconified: c_int) callconv(.C) void {
pub fn iconifyCallbackWrapper(handle: ?*c.GLFWwindow, iconified: c_int) callconv(.c) void {
@call(.always_inline, user_callback, .{
from(handle.?),
iconified == c.GLFW_TRUE,
@ -1448,7 +1448,7 @@ pub inline fn setMaximizeCallback(self: Window, comptime callback: ?fn (window:
if (callback) |user_callback| {
const CWrapper = struct {
pub fn maximizeCallbackWrapper(handle: ?*c.GLFWwindow, maximized: c_int) callconv(.C) void {
pub fn maximizeCallbackWrapper(handle: ?*c.GLFWwindow, maximized: c_int) callconv(.c) void {
@call(.always_inline, user_callback, .{
from(handle.?),
maximized == c.GLFW_TRUE,
@ -1483,7 +1483,7 @@ pub inline fn setFramebufferSizeCallback(self: Window, comptime callback: ?fn (w
if (callback) |user_callback| {
const CWrapper = struct {
pub fn framebufferSizeCallbackWrapper(handle: ?*c.GLFWwindow, width: c_int, height: c_int) callconv(.C) void {
pub fn framebufferSizeCallbackWrapper(handle: ?*c.GLFWwindow, width: c_int, height: c_int) callconv(.c) void {
@call(.always_inline, user_callback, .{
from(handle.?),
@as(u32, @intCast(width)),
@ -1519,7 +1519,7 @@ pub inline fn setContentScaleCallback(self: Window, comptime callback: ?fn (wind
if (callback) |user_callback| {
const CWrapper = struct {
pub fn windowScaleCallbackWrapper(handle: ?*c.GLFWwindow, xscale: f32, yscale: f32) callconv(.C) void {
pub fn windowScaleCallbackWrapper(handle: ?*c.GLFWwindow, xscale: f32, yscale: f32) callconv(.c) void {
@call(.always_inline, user_callback, .{
from(handle.?),
xscale,
@ -1871,7 +1871,7 @@ pub inline fn setKeyCallback(self: Window, comptime callback: ?fn (window: Windo
if (callback) |user_callback| {
const CWrapper = struct {
pub fn keyCallbackWrapper(handle: ?*c.GLFWwindow, key: c_int, scancode: c_int, action: c_int, mods: c_int) callconv(.C) void {
pub fn keyCallbackWrapper(handle: ?*c.GLFWwindow, key: c_int, scancode: c_int, action: c_int, mods: c_int) callconv(.c) void {
@call(.always_inline, user_callback, .{
from(handle.?),
@as(Key, @enumFromInt(key)),
@ -1917,7 +1917,7 @@ pub inline fn setCharCallback(self: Window, comptime callback: ?fn (window: Wind
if (callback) |user_callback| {
const CWrapper = struct {
pub fn charCallbackWrapper(handle: ?*c.GLFWwindow, codepoint: c_uint) callconv(.C) void {
pub fn charCallbackWrapper(handle: ?*c.GLFWwindow, codepoint: c_uint) callconv(.c) void {
@call(.always_inline, user_callback, .{
from(handle.?),
@as(u21, @intCast(codepoint)),
@ -1958,7 +1958,7 @@ pub inline fn setMouseButtonCallback(self: Window, comptime callback: ?fn (windo
if (callback) |user_callback| {
const CWrapper = struct {
pub fn mouseButtonCallbackWrapper(handle: ?*c.GLFWwindow, button: c_int, action: c_int, mods: c_int) callconv(.C) void {
pub fn mouseButtonCallbackWrapper(handle: ?*c.GLFWwindow, button: c_int, action: c_int, mods: c_int) callconv(.c) void {
@call(.always_inline, user_callback, .{
from(handle.?),
@as(MouseButton, @enumFromInt(button)),
@ -1996,7 +1996,7 @@ pub inline fn setCursorPosCallback(self: Window, comptime callback: ?fn (window:
if (callback) |user_callback| {
const CWrapper = struct {
pub fn cursorPosCallbackWrapper(handle: ?*c.GLFWwindow, xpos: f64, ypos: f64) callconv(.C) void {
pub fn cursorPosCallbackWrapper(handle: ?*c.GLFWwindow, xpos: f64, ypos: f64) callconv(.c) void {
@call(.always_inline, user_callback, .{
from(handle.?),
xpos,
@ -2030,7 +2030,7 @@ pub inline fn setCursorEnterCallback(self: Window, comptime callback: ?fn (windo
if (callback) |user_callback| {
const CWrapper = struct {
pub fn cursorEnterCallbackWrapper(handle: ?*c.GLFWwindow, entered: c_int) callconv(.C) void {
pub fn cursorEnterCallbackWrapper(handle: ?*c.GLFWwindow, entered: c_int) callconv(.c) void {
@call(.always_inline, user_callback, .{
from(handle.?),
entered == c.GLFW_TRUE,
@ -2067,7 +2067,7 @@ pub inline fn setScrollCallback(self: Window, comptime callback: ?fn (window: Wi
if (callback) |user_callback| {
const CWrapper = struct {
pub fn scrollCallbackWrapper(handle: ?*c.GLFWwindow, xoffset: f64, yoffset: f64) callconv(.C) void {
pub fn scrollCallbackWrapper(handle: ?*c.GLFWwindow, xoffset: f64, yoffset: f64) callconv(.c) void {
@call(.always_inline, user_callback, .{
from(handle.?),
xoffset,
@ -2110,7 +2110,7 @@ pub inline fn setDropCallback(self: Window, comptime callback: ?fn (window: Wind
if (callback) |user_callback| {
const CWrapper = struct {
pub fn dropCallbackWrapper(handle: ?*c.GLFWwindow, path_count: c_int, paths: [*c][*c]const u8) callconv(.C) void {
pub fn dropCallbackWrapper(handle: ?*c.GLFWwindow, path_count: c_int, paths: [*c][*c]const u8) callconv(.c) void {
@call(.always_inline, user_callback, .{
from(handle.?),
@as([*][*:0]const u8, @ptrCast(paths))[0..@as(u32, @intCast(path_count))],

View File

@ -300,7 +300,7 @@ pub inline fn mustGetErrorString() [:0]const u8 {
pub fn setErrorCallback(comptime callback: ?fn (error_code: ErrorCode, description: [:0]const u8) void) void {
if (callback) |user_callback| {
const CWrapper = struct {
pub fn errorCallbackWrapper(err_int: c_int, c_description: [*c]const u8) callconv(.C) void {
pub fn errorCallbackWrapper(err_int: c_int, c_description: [*c]const u8) callconv(.c) void {
convertError(err_int) catch |error_code| {
user_callback(error_code, mem.sliceTo(c_description, 0));
};

View File

@ -161,7 +161,7 @@ pub const GLProc = *const fn () callconv(if (builtin.os.tag == .windows and buil
/// @thread_safety This function may be called from any thread.
///
/// see also: context_glext, glfwExtensionSupported
pub fn getProcAddress(proc_name: [*:0]const u8) callconv(.C) ?GLProc {
pub fn getProcAddress(proc_name: [*:0]const u8) callconv(.c) ?GLProc {
internal_debug.assertInitialized();
if (c.glfwGetProcAddress(proc_name)) |proc_address| return @ptrCast(proc_address);
return null;

View File

@ -33,7 +33,7 @@ pub fn initVulkanLoader(loader_function: ?VKGetInstanceProcAddr) void {
c.glfwInitVulkanLoader(loader_function orelse null);
}
pub const VKGetInstanceProcAddr = *const fn (vk_instance: c.VkInstance, name: [*c]const u8) callconv(.C) ?VKProc;
pub const VKGetInstanceProcAddr = *const fn (vk_instance: c.VkInstance, name: [*c]const u8) callconv(.c) ?VKProc;
/// Returns whether the Vulkan loader and an ICD have been found.
///
@ -127,7 +127,7 @@ pub const VKProc = *const fn () callconv(if (builtin.os.tag == .windows and buil
/// @pointer_lifetime The returned function pointer is valid until the library is terminated.
///
/// @thread_safety This function may be called from any thread.
pub fn getInstanceProcAddress(vk_instance: ?*anyopaque, proc_name: [*:0]const u8) callconv(.C) ?VKProc {
pub fn getInstanceProcAddress(vk_instance: ?*anyopaque, proc_name: [*:0]const u8) callconv(.c) ?VKProc {
internal_debug.assertInitialized();
if (c.glfwGetInstanceProcAddress(if (vk_instance) |v| @as(c.VkInstance, @ptrCast(v)) else null, proc_name)) |proc_address| return proc_address;
return null;

View File

@ -77,11 +77,11 @@ pub const Blob = struct {
comptime T: type,
key: ?*anyopaque,
ptr: ?*T,
comptime destroycb: ?*const fn (?*T) callconv(.C) void,
comptime destroycb: ?*const fn (?*T) callconv(.c) void,
replace: bool,
) bool {
const Callback = struct {
pub fn callback(data: ?*anyopaque) callconv(.C) void {
pub fn callback(data: ?*anyopaque) callconv(.c) void {
@call(.{ .modifier = .always_inline }, destroycb, .{
@as(?*T, @ptrCast(@alignCast(data))),
});

View File

@ -84,7 +84,7 @@ pub const MutableArray = opaque {
a: *const Elem,
b: *const Elem,
context: ?*Context,
) callconv(.C) ComparisonResult,
) callconv(.c) ComparisonResult,
) void {
CFArraySortValues(
self,
@ -155,7 +155,7 @@ test "array sorting" {
void,
null,
struct {
fn compare(a: *const u8, b: *const u8, _: ?*void) callconv(.C) ComparisonResult {
fn compare(a: *const u8, b: *const u8, _: ?*void) callconv(.c) ComparisonResult {
if (a.* > b.*) return .greater;
if (a.* == b.*) return .equal;
return .less;

View File

@ -66,7 +66,7 @@ pub const DisplayLink = opaque {
flagsIn: c.CVOptionFlags,
flagsOut: *c.CVOptionFlags,
inner_userinfo: ?*anyopaque,
) callconv(.C) c.CVReturn {
) callconv(.c) c.CVReturn {
_ = inNow;
_ = inOutputTime;
_ = flagsIn;

View File

@ -13,8 +13,8 @@ pub threadlocal var context: Context = undefined;
/// The getProcAddress param is an anytype so that we can accept multiple
/// forms of the function depending on what we're interfacing with.
pub fn load(getProcAddress: anytype) !c_int {
const GlProc = *const fn () callconv(.C) void;
const GlfwFn = *const fn ([*:0]const u8) callconv(.C) ?GlProc;
const GlProc = *const fn () callconv(.c) void;
const GlfwFn = *const fn ([*:0]const u8) callconv(.c) ?GlProc;
const res = switch (@TypeOf(getProcAddress)) {
// glfw

View File

@ -5,8 +5,8 @@ const Envelope = @import("envelope.zig").Envelope;
/// sentry_transport_t
pub const Transport = opaque {
pub const SendFunc = *const fn (envelope: *Envelope, state: ?*anyopaque) callconv(.C) void;
pub const FreeFunc = *const fn (state: ?*anyopaque) callconv(.C) void;
pub const SendFunc = *const fn (envelope: *Envelope, state: ?*anyopaque) callconv(.c) void;
pub const FreeFunc = *const fn (state: ?*anyopaque) callconv(.c) void;
pub fn init(f: SendFunc) *Transport {
return @ptrCast(c.sentry_transport_new(@ptrCast(f)).?);

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: com.mitchellh.ghostty\n"
"Report-Msgid-Bugs-To: m@mitchellh.com\n"
"POT-Creation-Date: 2025-03-19 08:28-0700\n"
"POT-Creation-Date: 2025-04-22 08:57-0700\n"
"PO-Revision-Date: 2025-03-20 08:07+0100\n"
"Last-Translator: Francesc Arpi <francesc.arpi@gmail.com>\n"
"Language-Team: \n"
@ -43,8 +43,8 @@ msgid ""
"One or more configuration errors were found. Please review the errors below, "
"and either reload your configuration or ignore these errors."
msgstr ""
"S'han trobat un o més errors de configuració. Si us plau, revisa els errors a "
"continuació i torna a carregar la configuració o ignora aquests errors."
"S'han trobat un o més errors de configuració. Si us plau, revisa els errors "
"a continuació i torna a carregar la configuració o ignora aquests errors."
#: src/apprt/gtk/ui/1.5/config-errors-dialog.blp:9
msgid "Ignore"
@ -56,6 +56,30 @@ msgstr "Ignora"
msgid "Reload Configuration"
msgstr "Carrega la configuració"
#: src/apprt/gtk/ui/1.0/menu-headerbar-split_menu.blp:6
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:38
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:50
msgid "Split Up"
msgstr "Divideix cap amunt"
#: src/apprt/gtk/ui/1.0/menu-headerbar-split_menu.blp:11
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:43
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:55
msgid "Split Down"
msgstr "Divideix cap avall"
#: src/apprt/gtk/ui/1.0/menu-headerbar-split_menu.blp:16
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:48
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:60
msgid "Split Left"
msgstr "Divideix a l'esquerra"
#: src/apprt/gtk/ui/1.0/menu-headerbar-split_menu.blp:21
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:53
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:65
msgid "Split Right"
msgstr "Divideix a la dreta"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:6
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:6
msgid "Copy"
@ -87,33 +111,13 @@ msgstr "Divideix"
msgid "Change Title…"
msgstr "Canvia el títol…"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:38
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:50
msgid "Split Up"
msgstr "Divideix cap amunt"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:43
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:55
msgid "Split Down"
msgstr "Divideix cap avall"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:48
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:60
msgid "Split Left"
msgstr "Divideix a l'esquerra"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:53
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:65
msgid "Split Right"
msgstr "Divideix a la dreta"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:59
msgid "Tab"
msgstr "Pestanya"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:62
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:30
#: src/apprt/gtk/Window.zig:246
#: src/apprt/gtk/Window.zig:248
msgid "New Tab"
msgstr "Nova pestanya"
@ -150,7 +154,7 @@ msgid "Terminal Inspector"
msgstr "Inspector de terminal"
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:102
#: src/apprt/gtk/Window.zig:960
#: src/apprt/gtk/Window.zig:1003
msgid "About Ghostty"
msgstr "Sobre Ghostty"
@ -201,13 +205,32 @@ msgstr ""
"Enganxar aquest text al terminal pot ser perillós, ja que sembla que es "
"podrien executar algunes ordres."
#: src/apprt/gtk/inspector.zig:144
msgid "Ghostty: Terminal Inspector"
msgstr "Ghostty: Inspector de terminal"
#: src/apprt/gtk/Window.zig:201
msgid "Main Menu"
msgstr "Menú principal"
#: src/apprt/gtk/Surface.zig:1243
msgid "Copied to clipboard"
msgstr "Copiat al porta-retalls"
#: src/apprt/gtk/Window.zig:222
msgid "View Open Tabs"
msgstr "Mostra les pestanyes obertes"
#: src/apprt/gtk/Window.zig:249
msgid "New Split"
msgstr ""
#: src/apprt/gtk/Window.zig:312
msgid ""
"⚠️ You're running a debug build of Ghostty! Performance will be degraded."
msgstr ""
"⚠️ Estàs executant una versió de depuració de Ghostty! El rendiment es veurà "
"afectat."
#: src/apprt/gtk/Window.zig:744
msgid "Reloaded the configuration"
msgstr "S'ha tornat a carregar la configuració"
#: src/apprt/gtk/Window.zig:984
msgid "Ghostty Developers"
msgstr "Desenvolupadors de Ghostty"
#: src/apprt/gtk/CloseDialog.zig:47
msgid "Close"
@ -245,25 +268,10 @@ msgstr "Totes les sessions del terminal en aquesta pestanya es tancaran."
msgid "The currently running process in this split will be terminated."
msgstr "El procés actualment en execució en aquesta divisió es tancarà."
#: src/apprt/gtk/Window.zig:200
msgid "Main Menu"
msgstr "Menú principal"
#: src/apprt/gtk/Surface.zig:1243
msgid "Copied to clipboard"
msgstr "Copiat al porta-retalls"
#: src/apprt/gtk/Window.zig:221
msgid "View Open Tabs"
msgstr "Mostra les pestanyes obertes"
#: src/apprt/gtk/Window.zig:295
msgid ""
"⚠️ You're running a debug build of Ghostty! Performance will be degraded."
msgstr ""
"⚠️ Estàs executant una versió de depuració de Ghostty! El rendiment es "
"veurà afectat."
#: src/apprt/gtk/Window.zig:725
msgid "Reloaded the configuration"
msgstr "S'ha tornat a carregar la configuració"
#: src/apprt/gtk/Window.zig:941
msgid "Ghostty Developers"
msgstr "Desenvolupadors de Ghostty"
#: src/apprt/gtk/inspector.zig:144
msgid "Ghostty: Terminal Inspector"
msgstr "Ghostty: Inspector de terminal"

View File

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: com.mitchellh.ghostty\n"
"Report-Msgid-Bugs-To: m@mitchellh.com\n"
"POT-Creation-Date: 2025-03-19 08:54-0700\n"
"POT-Creation-Date: 2025-04-22 08:57-0700\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -54,6 +54,30 @@ msgstr ""
msgid "Reload Configuration"
msgstr ""
#: src/apprt/gtk/ui/1.0/menu-headerbar-split_menu.blp:6
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:38
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:50
msgid "Split Up"
msgstr ""
#: src/apprt/gtk/ui/1.0/menu-headerbar-split_menu.blp:11
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:43
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:55
msgid "Split Down"
msgstr ""
#: src/apprt/gtk/ui/1.0/menu-headerbar-split_menu.blp:16
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:48
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:60
msgid "Split Left"
msgstr ""
#: src/apprt/gtk/ui/1.0/menu-headerbar-split_menu.blp:21
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:53
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:65
msgid "Split Right"
msgstr ""
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:6
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:6
msgid "Copy"
@ -85,33 +109,13 @@ msgstr ""
msgid "Change Title…"
msgstr ""
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:38
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:50
msgid "Split Up"
msgstr ""
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:43
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:55
msgid "Split Down"
msgstr ""
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:48
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:60
msgid "Split Left"
msgstr ""
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:53
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:65
msgid "Split Right"
msgstr ""
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:59
msgid "Tab"
msgstr ""
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:62
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:30
#: src/apprt/gtk/Window.zig:246
#: src/apprt/gtk/Window.zig:248
msgid "New Tab"
msgstr ""
@ -148,7 +152,7 @@ msgid "Terminal Inspector"
msgstr ""
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:102
#: src/apprt/gtk/Window.zig:960
#: src/apprt/gtk/Window.zig:1003
msgid "About Ghostty"
msgstr ""
@ -193,12 +197,29 @@ msgid ""
"commands may be executed."
msgstr ""
#: src/apprt/gtk/inspector.zig:144
msgid "Ghostty: Terminal Inspector"
#: src/apprt/gtk/Window.zig:201
msgid "Main Menu"
msgstr ""
#: src/apprt/gtk/Surface.zig:1243
msgid "Copied to clipboard"
#: src/apprt/gtk/Window.zig:222
msgid "View Open Tabs"
msgstr ""
#: src/apprt/gtk/Window.zig:249
msgid "New Split"
msgstr ""
#: src/apprt/gtk/Window.zig:312
msgid ""
"⚠️ You're running a debug build of Ghostty! Performance will be degraded."
msgstr ""
#: src/apprt/gtk/Window.zig:744
msgid "Reloaded the configuration"
msgstr ""
#: src/apprt/gtk/Window.zig:984
msgid "Ghostty Developers"
msgstr ""
#: src/apprt/gtk/CloseDialog.zig:47
@ -237,23 +258,10 @@ msgstr ""
msgid "The currently running process in this split will be terminated."
msgstr ""
#: src/apprt/gtk/Window.zig:200
msgid "Main Menu"
#: src/apprt/gtk/Surface.zig:1243
msgid "Copied to clipboard"
msgstr ""
#: src/apprt/gtk/Window.zig:221
msgid "View Open Tabs"
msgstr ""
#: src/apprt/gtk/Window.zig:295
msgid ""
"⚠️ You're running a debug build of Ghostty! Performance will be degraded."
msgstr ""
#: src/apprt/gtk/Window.zig:725
msgid "Reloaded the configuration"
msgstr ""
#: src/apprt/gtk/Window.zig:941
msgid "Ghostty Developers"
#: src/apprt/gtk/inspector.zig:144
msgid "Ghostty: Terminal Inspector"
msgstr ""

View File

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: com.mitchellh.ghostty\n"
"Report-Msgid-Bugs-To: m@mitchellh.com\n"
"POT-Creation-Date: 2025-03-19 08:54-0700\n"
"POT-Creation-Date: 2025-04-22 08:57-0700\n"
"PO-Revision-Date: 2025-03-06 14:57+0100\n"
"Last-Translator: Robin <r@rpfaeffle.com>\n"
"Language-Team: German <translation-team-de@lists.sourceforge.net>\n"
@ -55,6 +55,30 @@ msgstr ""
msgid "Reload Configuration"
msgstr "Konfiguration neu laden"
#: src/apprt/gtk/ui/1.0/menu-headerbar-split_menu.blp:6
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:38
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:50
msgid "Split Up"
msgstr "Fenster nach oben teilen"
#: src/apprt/gtk/ui/1.0/menu-headerbar-split_menu.blp:11
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:43
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:55
msgid "Split Down"
msgstr "Fenster nach unten teilen"
#: src/apprt/gtk/ui/1.0/menu-headerbar-split_menu.blp:16
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:48
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:60
msgid "Split Left"
msgstr "Fenter nach links teilen"
#: src/apprt/gtk/ui/1.0/menu-headerbar-split_menu.blp:21
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:53
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:65
msgid "Split Right"
msgstr "Fenster nach rechts teilen"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:6
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:6
msgid "Copy"
@ -86,33 +110,13 @@ msgstr "Fenster teilen"
msgid "Change Title…"
msgstr "Titel bearbeiten…"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:38
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:50
msgid "Split Up"
msgstr "Fenster nach oben teilen"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:43
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:55
msgid "Split Down"
msgstr "Fenster nach unten teilen"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:48
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:60
msgid "Split Left"
msgstr "Fenter nach links teilen"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:53
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:65
msgid "Split Right"
msgstr "Fenster nach rechts teilen"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:59
msgid "Tab"
msgstr "Tab"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:62
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:30
#: src/apprt/gtk/Window.zig:246
#: src/apprt/gtk/Window.zig:248
msgid "New Tab"
msgstr "Neuer Tab"
@ -149,7 +153,7 @@ msgid "Terminal Inspector"
msgstr "Terminalinspektor"
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:102
#: src/apprt/gtk/Window.zig:960
#: src/apprt/gtk/Window.zig:1003
msgid "About Ghostty"
msgstr "Über Ghostty"
@ -200,13 +204,32 @@ msgstr ""
"Diesen Text in das Terminal einzufügen könnte möglicherweise gefährlich "
"sein. Es scheint, dass Anweisungen ausgeführt werden könnten."
#: src/apprt/gtk/inspector.zig:144
msgid "Ghostty: Terminal Inspector"
#: src/apprt/gtk/Window.zig:201
msgid "Main Menu"
msgstr "Hauptmenü"
#: src/apprt/gtk/Window.zig:222
msgid "View Open Tabs"
msgstr "Offene Tabs einblenden"
#: src/apprt/gtk/Window.zig:249
msgid "New Split"
msgstr ""
#: src/apprt/gtk/Surface.zig:1243
msgid "Copied to clipboard"
msgstr "In die Zwischenablage kopiert"
#: src/apprt/gtk/Window.zig:312
msgid ""
"⚠️ You're running a debug build of Ghostty! Performance will be degraded."
msgstr ""
"⚠️ Du verwendest einen Debug Build von Ghostty! Die Leistung wird reduziert "
"sein."
#: src/apprt/gtk/Window.zig:744
msgid "Reloaded the configuration"
msgstr "Konfiguration wurde neu geladen"
#: src/apprt/gtk/Window.zig:984
msgid "Ghostty Developers"
msgstr "Ghostty-Entwickler"
#: src/apprt/gtk/CloseDialog.zig:47
msgid "Close"
@ -244,25 +267,10 @@ msgstr "Alle Terminalsitzungen in diesem Tab werden beendet."
msgid "The currently running process in this split will be terminated."
msgstr "Der aktuell laufende Prozess in diesem geteilten Fenster wird beendet."
#: src/apprt/gtk/Window.zig:200
msgid "Main Menu"
msgstr "Hauptmenü"
#: src/apprt/gtk/Surface.zig:1243
msgid "Copied to clipboard"
msgstr "In die Zwischenablage kopiert"
#: src/apprt/gtk/Window.zig:221
msgid "View Open Tabs"
msgstr "Offene Tabs einblenden"
#: src/apprt/gtk/Window.zig:295
msgid ""
"⚠️ You're running a debug build of Ghostty! Performance will be degraded."
#: src/apprt/gtk/inspector.zig:144
msgid "Ghostty: Terminal Inspector"
msgstr ""
"⚠️ Du verwendest einen Debug Build von Ghostty! Die Leistung wird reduziert "
"sein."
#: src/apprt/gtk/Window.zig:725
msgid "Reloaded the configuration"
msgstr "Konfiguration wurde neu geladen"
#: src/apprt/gtk/Window.zig:941
msgid "Ghostty Developers"
msgstr "Ghostty-Entwickler"

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: com.mitchellh.ghostty\n"
"Report-Msgid-Bugs-To: m@mitchellh.com\n"
"POT-Creation-Date: 2025-03-19 08:54-0700\n"
"POT-Creation-Date: 2025-04-22 08:57-0700\n"
"PO-Revision-Date: 2025-03-28 17:46+0200\n"
"Last-Translator: Miguel Peredo <miguelp@quientienemail.com>\n"
"Language-Team: Spanish <es@tp.org.es>\n"
@ -43,8 +43,8 @@ msgid ""
"One or more configuration errors were found. Please review the errors below, "
"and either reload your configuration or ignore these errors."
msgstr ""
"Se encontraron uno o más errores de configuración. Por favor revise los errores a continuación, "
"y recargue su configuración o ignore estos errores."
"Se encontraron uno o más errores de configuración. Por favor revise los "
"errores a continuación, y recargue su configuración o ignore estos errores."
#: src/apprt/gtk/ui/1.5/config-errors-dialog.blp:9
msgid "Ignore"
@ -56,6 +56,30 @@ msgstr "Ignorar"
msgid "Reload Configuration"
msgstr "Recargar configuración"
#: src/apprt/gtk/ui/1.0/menu-headerbar-split_menu.blp:6
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:38
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:50
msgid "Split Up"
msgstr "Dividir arriba"
#: src/apprt/gtk/ui/1.0/menu-headerbar-split_menu.blp:11
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:43
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:55
msgid "Split Down"
msgstr "Dividir abajo"
#: src/apprt/gtk/ui/1.0/menu-headerbar-split_menu.blp:16
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:48
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:60
msgid "Split Left"
msgstr "Dividir a la izquierda"
#: src/apprt/gtk/ui/1.0/menu-headerbar-split_menu.blp:21
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:53
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:65
msgid "Split Right"
msgstr "Dividir a la derecha"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:6
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:6
msgid "Copy"
@ -87,33 +111,13 @@ msgstr "Dividir"
msgid "Change Title…"
msgstr "Cambiar título…"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:38
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:50
msgid "Split Up"
msgstr "Dividir arriba"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:43
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:55
msgid "Split Down"
msgstr "Dividir abajo"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:48
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:60
msgid "Split Left"
msgstr "Dividir a la izquierda"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:53
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:65
msgid "Split Right"
msgstr "Dividir a la derecha"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:59
msgid "Tab"
msgstr "Pestaña"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:62
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:30
#: src/apprt/gtk/Window.zig:246
#: src/apprt/gtk/Window.zig:248
msgid "New Tab"
msgstr "Nueva pestaña"
@ -150,7 +154,7 @@ msgid "Terminal Inspector"
msgstr "Inspector de la terminal"
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:102
#: src/apprt/gtk/Window.zig:960
#: src/apprt/gtk/Window.zig:1003
msgid "About Ghostty"
msgstr "Acerca de Ghostty"
@ -201,13 +205,32 @@ msgstr ""
"Pegar este texto en la terminal puede ser peligroso ya que parece que "
"algunos comandos podrían ejecutarse."
#: src/apprt/gtk/inspector.zig:144
msgid "Ghostty: Terminal Inspector"
msgstr "Ghostty: Inspector de la terminal"
#: src/apprt/gtk/Window.zig:201
msgid "Main Menu"
msgstr "Menú principal"
#: src/apprt/gtk/Surface.zig:1243
msgid "Copied to clipboard"
msgstr "Copiado al portapapeles"
#: src/apprt/gtk/Window.zig:222
msgid "View Open Tabs"
msgstr "Ver pestañas abiertas"
#: src/apprt/gtk/Window.zig:249
msgid "New Split"
msgstr ""
#: src/apprt/gtk/Window.zig:312
msgid ""
"⚠️ You're running a debug build of Ghostty! Performance will be degraded."
msgstr ""
"⚠️ Está ejecutando una versión de depuración de Ghostty. El rendimiento no "
"será óptimo."
#: src/apprt/gtk/Window.zig:744
msgid "Reloaded the configuration"
msgstr "Configuración recargada"
#: src/apprt/gtk/Window.zig:984
msgid "Ghostty Developers"
msgstr "Desarrolladores de Ghostty"
#: src/apprt/gtk/CloseDialog.zig:47
msgid "Close"
@ -245,23 +268,10 @@ msgstr "Todas las sesiones de terminal en esta pestaña serán terminadas."
msgid "The currently running process in this split will be terminated."
msgstr "El proceso actualmente en ejecución en esta división será terminado."
#: src/apprt/gtk/Window.zig:200
msgid "Main Menu"
msgstr "Menú principal"
#: src/apprt/gtk/Surface.zig:1243
msgid "Copied to clipboard"
msgstr "Copiado al portapapeles"
#: src/apprt/gtk/Window.zig:221
msgid "View Open Tabs"
msgstr "Ver pestañas abiertas"
#: src/apprt/gtk/Window.zig:295
msgid ""
"⚠️ You're running a debug build of Ghostty! Performance will be degraded."
msgstr "⚠️ Está ejecutando una versión de depuración de Ghostty. El rendimiento no será óptimo."
#: src/apprt/gtk/Window.zig:725
msgid "Reloaded the configuration"
msgstr "Configuración recargada"
#: src/apprt/gtk/Window.zig:941
msgid "Ghostty Developers"
msgstr "Desarrolladores de Ghostty"
#: src/apprt/gtk/inspector.zig:144
msgid "Ghostty: Terminal Inspector"
msgstr "Ghostty: Inspector de la terminal"

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: com.mitchellh.ghostty\n"
"Report-Msgid-Bugs-To: m@mitchellh.com\n"
"POT-Creation-Date: 2025-03-19 08:28-0700\n"
"POT-Creation-Date: 2025-04-22 08:57-0700\n"
"PO-Revision-Date: 2025-03-22 09:31+0100\n"
"Last-Translator: Kirwiisp <swiip__@hotmail.com>\n"
"Language-Team: French <traduc@traduc.org>\n"
@ -43,8 +43,9 @@ msgid ""
"One or more configuration errors were found. Please review the errors below, "
"and either reload your configuration or ignore these errors."
msgstr ""
"Une ou plusieurs erreurs de configuration ont été trouvées. Veuillez lire les erreurs ci-dessous,"
"et recharger votre configuration ou bien ignorer ces erreurs."
"Une ou plusieurs erreurs de configuration ont été trouvées. Veuillez lire "
"les erreurs ci-dessous,et recharger votre configuration ou bien ignorer ces "
"erreurs."
#: src/apprt/gtk/ui/1.5/config-errors-dialog.blp:9
msgid "Ignore"
@ -56,6 +57,30 @@ msgstr "Ignorer"
msgid "Reload Configuration"
msgstr "Recharger la configuration"
#: src/apprt/gtk/ui/1.0/menu-headerbar-split_menu.blp:6
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:38
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:50
msgid "Split Up"
msgstr "Panneau en haut"
#: src/apprt/gtk/ui/1.0/menu-headerbar-split_menu.blp:11
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:43
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:55
msgid "Split Down"
msgstr "Panneau en bas"
#: src/apprt/gtk/ui/1.0/menu-headerbar-split_menu.blp:16
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:48
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:60
msgid "Split Left"
msgstr "Panneau à gauche"
#: src/apprt/gtk/ui/1.0/menu-headerbar-split_menu.blp:21
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:53
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:65
msgid "Split Right"
msgstr "Panneau à droite"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:6
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:6
msgid "Copy"
@ -87,33 +112,13 @@ msgstr "Créer panneau"
msgid "Change Title…"
msgstr "Changer le titre…"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:38
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:50
msgid "Split Up"
msgstr "Panneau en haut"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:43
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:55
msgid "Split Down"
msgstr "Panneau en bas"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:48
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:60
msgid "Split Left"
msgstr "Panneau à gauche"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:53
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:65
msgid "Split Right"
msgstr "Panneau à droite"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:59
msgid "Tab"
msgstr "Onglet"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:62
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:30
#: src/apprt/gtk/Window.zig:246
#: src/apprt/gtk/Window.zig:248
msgid "New Tab"
msgstr "Nouvel onglet"
@ -150,7 +155,7 @@ msgid "Terminal Inspector"
msgstr "Inspecteur de terminal"
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:102
#: src/apprt/gtk/Window.zig:960
#: src/apprt/gtk/Window.zig:1003
msgid "About Ghostty"
msgstr "À propos de Ghostty"
@ -168,8 +173,8 @@ msgid ""
"An application is attempting to read from the clipboard. The current "
"clipboard contents are shown below."
msgstr ""
"Une application essaie de lire depuis le presse-papiers."
"Le contenu actuel du presse-papiers est affiché ci-dessous."
"Une application essaie de lire depuis le presse-papiers.Le contenu actuel du "
"presse-papiers est affiché ci-dessous."
#: src/apprt/gtk/ui/1.5/ccw-osc-52-read.blp:10
#: src/apprt/gtk/ui/1.5/ccw-osc-52-write.blp:10
@ -186,8 +191,8 @@ msgid ""
"An application is attempting to write to the clipboard. The current "
"clipboard contents are shown below."
msgstr ""
"Une application essaie d'écrire dans le presse-papiers."
"Le contenu actuel du presse-papiers est affiché ci-dessous."
"Une application essaie d'écrire dans le presse-papiers.Le contenu actuel du "
"presse-papiers est affiché ci-dessous."
#: src/apprt/gtk/ui/1.5/ccw-paste.blp:6
msgid "Warning: Potentially Unsafe Paste"
@ -198,16 +203,35 @@ msgid ""
"Pasting this text into the terminal may be dangerous as it looks like some "
"commands may be executed."
msgstr ""
"Coller ce texte dans le terminal pourrait être dangereux, "
"il semblerait que certaines commandes pourraient être exécutées."
"Coller ce texte dans le terminal pourrait être dangereux, il semblerait que "
"certaines commandes pourraient être exécutées."
#: src/apprt/gtk/inspector.zig:144
msgid "Ghostty: Terminal Inspector"
msgstr "Ghostty: Inspecteur"
#: src/apprt/gtk/Window.zig:201
msgid "Main Menu"
msgstr "Menu principal"
#: src/apprt/gtk/Surface.zig:1243
msgid "Copied to clipboard"
msgstr "Copié dans le presse-papiers"
#: src/apprt/gtk/Window.zig:222
msgid "View Open Tabs"
msgstr "Voir les onglets ouverts"
#: src/apprt/gtk/Window.zig:249
msgid "New Split"
msgstr ""
#: src/apprt/gtk/Window.zig:312
msgid ""
"⚠️ You're running a debug build of Ghostty! Performance will be degraded."
msgstr ""
"⚠️ Vous utilisez une version de débogage de Ghostty ! Les performances seront "
"dégradées."
#: src/apprt/gtk/Window.zig:744
msgid "Reloaded the configuration"
msgstr "Recharger la configuration"
#: src/apprt/gtk/Window.zig:984
msgid "Ghostty Developers"
msgstr "Les développeurs de Ghostty"
#: src/apprt/gtk/CloseDialog.zig:47
msgid "Close"
@ -245,24 +269,10 @@ msgstr "Toutes les sessions de cet onglet vont être arrêtées."
msgid "The currently running process in this split will be terminated."
msgstr "Le processus en cours dans ce panneau va être arrêté."
#: src/apprt/gtk/Window.zig:200
msgid "Main Menu"
msgstr "Menu principal"
#: src/apprt/gtk/Surface.zig:1243
msgid "Copied to clipboard"
msgstr "Copié dans le presse-papiers"
#: src/apprt/gtk/Window.zig:221
msgid "View Open Tabs"
msgstr "Voir les onglets ouverts"
#: src/apprt/gtk/Window.zig:295
msgid ""
"⚠️ You're running a debug build of Ghostty! Performance will be degraded."
msgstr ""
"⚠️ Vous utilisez une version de débogage de Ghostty ! Les performances seront dégradées."
#: src/apprt/gtk/Window.zig:725
msgid "Reloaded the configuration"
msgstr "Recharger la configuration"
#: src/apprt/gtk/Window.zig:941
msgid "Ghostty Developers"
msgstr "Les développeurs de Ghostty"
#: src/apprt/gtk/inspector.zig:144
msgid "Ghostty: Terminal Inspector"
msgstr "Ghostty: Inspecteur"

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: com.mitchellh.ghostty\n"
"Report-Msgid-Bugs-To: m@mitchellh.com\n"
"POT-Creation-Date: 2025-03-19 08:28-0700\n"
"POT-Creation-Date: 2025-04-22 08:57-0700\n"
"PO-Revision-Date: 2025-03-20 15:19+0700\n"
"Last-Translator: Satrio Bayu Aji <halosatrio@gmail.com>\n"
"Language-Team: Indonesian <translation-team-id@lists.sourceforge.net>\n"
@ -42,8 +42,8 @@ msgid ""
"One or more configuration errors were found. Please review the errors below, "
"and either reload your configuration or ignore these errors."
msgstr ""
"Ditemukan satu atau lebih kesalahan konfigurasi. Silakan tinjau kesalahan di bawah ini, "
"dan muat ulang konfigurasi anda atau abaikan kesalahan ini."
"Ditemukan satu atau lebih kesalahan konfigurasi. Silakan tinjau kesalahan di "
"bawah ini, dan muat ulang konfigurasi anda atau abaikan kesalahan ini."
#: src/apprt/gtk/ui/1.5/config-errors-dialog.blp:9
msgid "Ignore"
@ -55,6 +55,30 @@ msgstr "Abaikan"
msgid "Reload Configuration"
msgstr "Muat ulang konfigurasi"
#: src/apprt/gtk/ui/1.0/menu-headerbar-split_menu.blp:6
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:38
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:50
msgid "Split Up"
msgstr "Belah atas"
#: src/apprt/gtk/ui/1.0/menu-headerbar-split_menu.blp:11
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:43
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:55
msgid "Split Down"
msgstr "Belah bawah"
#: src/apprt/gtk/ui/1.0/menu-headerbar-split_menu.blp:16
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:48
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:60
msgid "Split Left"
msgstr "Belah kiri"
#: src/apprt/gtk/ui/1.0/menu-headerbar-split_menu.blp:21
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:53
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:65
msgid "Split Right"
msgstr "Belah kanan"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:6
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:6
msgid "Copy"
@ -86,33 +110,13 @@ msgstr "Belah"
msgid "Change Title…"
msgstr "Ubah judul…"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:38
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:50
msgid "Split Up"
msgstr "Belah atas"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:43
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:55
msgid "Split Down"
msgstr "Belah bawah"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:48
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:60
msgid "Split Left"
msgstr "Belah kiri"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:53
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:65
msgid "Split Right"
msgstr "Belah kanan"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:59
msgid "Tab"
msgstr "Tab"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:62
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:30
#: src/apprt/gtk/Window.zig:246
#: src/apprt/gtk/Window.zig:248
msgid "New Tab"
msgstr "Tab baru"
@ -149,7 +153,7 @@ msgid "Terminal Inspector"
msgstr "Inspektur terminal"
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:102
#: src/apprt/gtk/Window.zig:960
#: src/apprt/gtk/Window.zig:1003
msgid "About Ghostty"
msgstr "Tentang Ghostty"
@ -167,8 +171,8 @@ msgid ""
"An application is attempting to read from the clipboard. The current "
"clipboard contents are shown below."
msgstr ""
"Aplikasi sedang mencoba membaca dari papan klip. Isi papan klip "
"saat ini ditampilkan di bawah ini."
"Aplikasi sedang mencoba membaca dari papan klip. Isi papan klip saat ini "
"ditampilkan di bawah ini."
#: src/apprt/gtk/ui/1.5/ccw-osc-52-read.blp:10
#: src/apprt/gtk/ui/1.5/ccw-osc-52-write.blp:10
@ -185,8 +189,8 @@ msgid ""
"An application is attempting to write to the clipboard. The current "
"clipboard contents are shown below."
msgstr ""
"Aplikasi sedang mencoba menulis ke papan klip. Isi papan klip "
"saat ini ditampilkan di bawah ini."
"Aplikasi sedang mencoba menulis ke papan klip. Isi papan klip saat ini "
"ditampilkan di bawah ini."
#: src/apprt/gtk/ui/1.5/ccw-paste.blp:6
msgid "Warning: Potentially Unsafe Paste"
@ -200,13 +204,31 @@ msgstr ""
"Menempelkan teks ini ke terminal mungkin berbahaya karena sepertinya "
"beberapa perintah mungkin dijalankan."
#: src/apprt/gtk/inspector.zig:144
msgid "Ghostty: Terminal Inspector"
msgstr "Ghostty: Inspektur terminal"
#: src/apprt/gtk/Window.zig:201
msgid "Main Menu"
msgstr "Menu utama"
#: src/apprt/gtk/Surface.zig:1243
msgid "Copied to clipboard"
msgstr "Disalin ke papan klip"
#: src/apprt/gtk/Window.zig:222
msgid "View Open Tabs"
msgstr "Lihat tab terbuka"
#: src/apprt/gtk/Window.zig:249
msgid "New Split"
msgstr ""
#: src/apprt/gtk/Window.zig:312
msgid ""
"⚠️ You're running a debug build of Ghostty! Performance will be degraded."
msgstr ""
"⚠️ Anda sedang menjalankan versi debug dari Ghostty! Performa akan menurun."
#: src/apprt/gtk/Window.zig:744
msgid "Reloaded the configuration"
msgstr "Memuat ulang konfigurasi"
#: src/apprt/gtk/Window.zig:984
msgid "Ghostty Developers"
msgstr "Pengembang Ghostty"
#: src/apprt/gtk/CloseDialog.zig:47
msgid "Close"
@ -244,23 +266,10 @@ msgstr "Semua sesi terminal di tab ini akan diakhiri."
msgid "The currently running process in this split will be terminated."
msgstr "Proses yang sedang berjalan dalam belahan ini akan diakhiri."
#: src/apprt/gtk/Window.zig:200
msgid "Main Menu"
msgstr "Menu utama"
#: src/apprt/gtk/Surface.zig:1243
msgid "Copied to clipboard"
msgstr "Disalin ke papan klip"
#: src/apprt/gtk/Window.zig:221
msgid "View Open Tabs"
msgstr "Lihat tab terbuka"
#: src/apprt/gtk/Window.zig:295
msgid ""
"⚠️ You're running a debug build of Ghostty! Performance will be degraded."
msgstr "⚠️ Anda sedang menjalankan versi debug dari Ghostty! Performa akan menurun."
#: src/apprt/gtk/Window.zig:725
msgid "Reloaded the configuration"
msgstr "Memuat ulang konfigurasi"
#: src/apprt/gtk/Window.zig:941
msgid "Ghostty Developers"
msgstr "Pengembang Ghostty"
#: src/apprt/gtk/inspector.zig:144
msgid "Ghostty: Terminal Inspector"
msgstr "Ghostty: Inspektur terminal"

View File

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: com.mitchellh.ghostty\n"
"Report-Msgid-Bugs-To: m@mitchellh.com\n"
"POT-Creation-Date: 2025-03-19 08:28-0700\n"
"POT-Creation-Date: 2025-04-22 08:57-0700\n"
"PO-Revision-Date: 2025-03-21 00:08+0900\n"
"Last-Translator: Lon Sagisawa <lon@sagisawa.me>\n"
"Language-Team: Japanese\n"
@ -44,8 +44,8 @@ msgid ""
"One or more configuration errors were found. Please review the errors below, "
"and either reload your configuration or ignore these errors."
msgstr ""
"設定ファイルにエラーがあります。以下のエラーを確認し、"
"設定ファイルの再読み込みをするか、無視してください。"
"設定ファイルにエラーがあります。以下のエラーを確認し、設定ファイルの再読み込"
"みをするか、無視してください。"
#: src/apprt/gtk/ui/1.5/config-errors-dialog.blp:9
msgid "Ignore"
@ -57,6 +57,30 @@ msgstr "無視"
msgid "Reload Configuration"
msgstr "設定ファイルの再読み込み"
#: src/apprt/gtk/ui/1.0/menu-headerbar-split_menu.blp:6
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:38
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:50
msgid "Split Up"
msgstr "上に分割"
#: src/apprt/gtk/ui/1.0/menu-headerbar-split_menu.blp:11
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:43
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:55
msgid "Split Down"
msgstr "下に分割"
#: src/apprt/gtk/ui/1.0/menu-headerbar-split_menu.blp:16
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:48
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:60
msgid "Split Left"
msgstr "左に分割"
#: src/apprt/gtk/ui/1.0/menu-headerbar-split_menu.blp:21
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:53
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:65
msgid "Split Right"
msgstr "右に分割"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:6
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:6
msgid "Copy"
@ -88,33 +112,13 @@ msgstr "分割"
msgid "Change Title…"
msgstr "タイトルを変更…"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:38
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:50
msgid "Split Up"
msgstr "上に分割"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:43
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:55
msgid "Split Down"
msgstr "下に分割"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:48
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:60
msgid "Split Left"
msgstr "左に分割"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:53
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:65
msgid "Split Right"
msgstr "右に分割"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:59
msgid "Tab"
msgstr "タブ"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:62
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:30
#: src/apprt/gtk/Window.zig:246
#: src/apprt/gtk/Window.zig:248
msgid "New Tab"
msgstr "新しいタブ"
@ -151,7 +155,7 @@ msgid "Terminal Inspector"
msgstr "端末インスペクター"
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:102
#: src/apprt/gtk/Window.zig:960
#: src/apprt/gtk/Window.zig:1003
msgid "About Ghostty"
msgstr "Ghostty について"
@ -169,8 +173,8 @@ msgid ""
"An application is attempting to read from the clipboard. The current "
"clipboard contents are shown below."
msgstr ""
"アプリケーションがクリップボードを読み取ろうとしています。"
"現在のクリップボードの内容は以下の通りです。"
"アプリケーションがクリップボードを読み取ろうとしています。現在のクリップボー"
"ドの内容は以下の通りです。"
#: src/apprt/gtk/ui/1.5/ccw-osc-52-read.blp:10
#: src/apprt/gtk/ui/1.5/ccw-osc-52-write.blp:10
@ -187,8 +191,8 @@ msgid ""
"An application is attempting to write to the clipboard. The current "
"clipboard contents are shown below."
msgstr ""
"アプリケーションがクリップボードに書き込もうとしています。"
"現在のクリップボードの内容は以下の通りです。"
"アプリケーションがクリップボードに書き込もうとしています。現在のクリップボー"
"ドの内容は以下の通りです。"
#: src/apprt/gtk/ui/1.5/ccw-paste.blp:6
msgid "Warning: Potentially Unsafe Paste"
@ -199,16 +203,34 @@ msgid ""
"Pasting this text into the terminal may be dangerous as it looks like some "
"commands may be executed."
msgstr ""
"このテキストには実行可能なコマンドが含まれており、"
"ターミナルに貼り付けるのは危険な可能性があります。"
"このテキストには実行可能なコマンドが含まれており、ターミナルに貼り付けるのは"
"危険な可能性があります。"
#: src/apprt/gtk/inspector.zig:144
msgid "Ghostty: Terminal Inspector"
msgstr "Ghostty: 端末インスペクター"
#: src/apprt/gtk/Window.zig:201
msgid "Main Menu"
msgstr "メインメニュー"
#: src/apprt/gtk/Surface.zig:1243
msgid "Copied to clipboard"
msgstr "クリップボードにコピーしました"
#: src/apprt/gtk/Window.zig:222
msgid "View Open Tabs"
msgstr "開いているすべてのタブを表示"
#: src/apprt/gtk/Window.zig:249
msgid "New Split"
msgstr ""
#: src/apprt/gtk/Window.zig:312
msgid ""
"⚠️ You're running a debug build of Ghostty! Performance will be degraded."
msgstr ""
"⚠️ Ghostty のデバッグビルドを実行しています! パフォーマンスが低下しています。"
#: src/apprt/gtk/Window.zig:744
msgid "Reloaded the configuration"
msgstr "設定を再読み込みしました"
#: src/apprt/gtk/Window.zig:984
msgid "Ghostty Developers"
msgstr "Ghostty 開発者"
#: src/apprt/gtk/CloseDialog.zig:47
msgid "Close"
@ -246,23 +268,10 @@ msgstr "タブ内のすべてのターミナルセッションが終了します
msgid "The currently running process in this split will be terminated."
msgstr "分割ウィンドウ内のすべてのプロセスが終了します。"
#: src/apprt/gtk/Window.zig:200
msgid "Main Menu"
msgstr "メインメニュー"
#: src/apprt/gtk/Surface.zig:1243
msgid "Copied to clipboard"
msgstr "クリップボードにコピーしました"
#: src/apprt/gtk/Window.zig:221
msgid "View Open Tabs"
msgstr "開いているすべてのタブを表示"
#: src/apprt/gtk/Window.zig:295
msgid ""
"⚠️ You're running a debug build of Ghostty! Performance will be degraded."
msgstr "⚠️ Ghostty のデバッグビルドを実行しています! パフォーマンスが低下しています。"
#: src/apprt/gtk/Window.zig:725
msgid "Reloaded the configuration"
msgstr "設定を再読み込みしました"
#: src/apprt/gtk/Window.zig:941
msgid "Ghostty Developers"
msgstr "Ghostty 開発者"
#: src/apprt/gtk/inspector.zig:144
msgid "Ghostty: Terminal Inspector"
msgstr "Ghostty: 端末インスペクター"

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: com.mitchellh.ghostty\n"
"Report-Msgid-Bugs-To: m@mitchellh.com\n"
"POT-Creation-Date: 2025-03-19 08:28-0700\n"
"POT-Creation-Date: 2025-04-22 08:57-0700\n"
"PO-Revision-Date: 2025-03-23 14:17+0100\n"
"Last-Translator: Andrej Daskalov <andrej.daskalov@gmail.com>\n"
"Language-Team: Macedonian\n"
@ -41,7 +41,10 @@ msgstr "Грешки во конфигурацијата"
msgid ""
"One or more configuration errors were found. Please review the errors below, "
"and either reload your configuration or ignore these errors."
msgstr "Пронајдени се една или повеќе грешки во конфигурацијата. Прегледајте ги грешките подолу и повторно вчитајте ја конфигурацијата или игнорирајте ги овие грешки."
msgstr ""
"Пронајдени се една или повеќе грешки во конфигурацијата. Прегледајте ги "
"грешките подолу и повторно вчитајте ја конфигурацијата или игнорирајте ги "
"овие грешки."
#: src/apprt/gtk/ui/1.5/config-errors-dialog.blp:9
msgid "Ignore"
@ -53,6 +56,30 @@ msgstr "Игнорирај"
msgid "Reload Configuration"
msgstr "Одново вчитај конфигурација"
#: src/apprt/gtk/ui/1.0/menu-headerbar-split_menu.blp:6
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:38
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:50
msgid "Split Up"
msgstr "Подели нагоре"
#: src/apprt/gtk/ui/1.0/menu-headerbar-split_menu.blp:11
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:43
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:55
msgid "Split Down"
msgstr "Подели надолу"
#: src/apprt/gtk/ui/1.0/menu-headerbar-split_menu.blp:16
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:48
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:60
msgid "Split Left"
msgstr "Подели налево"
#: src/apprt/gtk/ui/1.0/menu-headerbar-split_menu.blp:21
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:53
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:65
msgid "Split Right"
msgstr "Подели надесно"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:6
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:6
msgid "Copy"
@ -84,33 +111,13 @@ msgstr "Подели"
msgid "Change Title…"
msgstr "Промени наслов…"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:38
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:50
msgid "Split Up"
msgstr "Подели нагоре"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:43
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:55
msgid "Split Down"
msgstr "Подели надолу"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:48
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:60
msgid "Split Left"
msgstr "Подели налево"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:53
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:65
msgid "Split Right"
msgstr "Подели надесно"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:59
msgid "Tab"
msgstr "Јазиче"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:62
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:30
#: src/apprt/gtk/Window.zig:246
#: src/apprt/gtk/Window.zig:248
msgid "New Tab"
msgstr "Ново јазиче"
@ -147,7 +154,7 @@ msgid "Terminal Inspector"
msgstr "Инспектор на терминал"
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:102
#: src/apprt/gtk/Window.zig:960
#: src/apprt/gtk/Window.zig:1003
msgid "About Ghostty"
msgstr "За Ghostty"
@ -164,7 +171,9 @@ msgstr "Авторизирај пристап до привремена мемо
msgid ""
"An application is attempting to read from the clipboard. The current "
"clipboard contents are shown below."
msgstr "Апликација се обидува да чита од привремената меморија. Содржината е прикажана подолу."
msgstr ""
"Апликација се обидува да чита од привремената меморија. Содржината е "
"прикажана подолу."
#: src/apprt/gtk/ui/1.5/ccw-osc-52-read.blp:10
#: src/apprt/gtk/ui/1.5/ccw-osc-52-write.blp:10
@ -180,7 +189,9 @@ msgstr "Дозволи"
msgid ""
"An application is attempting to write to the clipboard. The current "
"clipboard contents are shown below."
msgstr "Апликација се обидува да запише во привремената меморија. Содржината е прикажана подолу."
msgstr ""
"Апликација се обидува да запише во привремената меморија. Содржината е "
"прикажана подолу."
#: src/apprt/gtk/ui/1.5/ccw-paste.blp:6
msgid "Warning: Potentially Unsafe Paste"
@ -190,15 +201,35 @@ msgstr "Предупредување: Потенцијално небезбед
msgid ""
"Pasting this text into the terminal may be dangerous as it looks like some "
"commands may be executed."
msgstr "Вметнувањето на овој текст во терминалот може да биде опасно, бидејќи изгледа како да ќе се извршат одредени команди."
msgstr ""
"Вметнувањето на овој текст во терминалот може да биде опасно, бидејќи "
"изгледа како да ќе се извршат одредени команди."
#: src/apprt/gtk/inspector.zig:144
msgid "Ghostty: Terminal Inspector"
msgstr "Ghostty: Инспектор на терминал"
#: src/apprt/gtk/Window.zig:201
msgid "Main Menu"
msgstr "Главно мени"
#: src/apprt/gtk/Surface.zig:1243
msgid "Copied to clipboard"
msgstr "Копирано во привремена меморија"
#: src/apprt/gtk/Window.zig:222
msgid "View Open Tabs"
msgstr "Прегледај отворени јазичиња"
#: src/apprt/gtk/Window.zig:249
msgid "New Split"
msgstr ""
#: src/apprt/gtk/Window.zig:312
msgid ""
"⚠️ You're running a debug build of Ghostty! Performance will be degraded."
msgstr ""
"⚠️ Извршувате дебаг верзија на Ghostty! Перформансите ќе бидат намалени."
#: src/apprt/gtk/Window.zig:744
msgid "Reloaded the configuration"
msgstr "Конфигурацијата е одново вчитана"
#: src/apprt/gtk/Window.zig:984
msgid "Ghostty Developers"
msgstr "Развивачи на Ghostty"
#: src/apprt/gtk/CloseDialog.zig:47
msgid "Close"
@ -236,23 +267,10 @@ msgstr "Сите сесии во ова јазиче ќе бидат преки
msgid "The currently running process in this split will be terminated."
msgstr "Процесот кој моментално се извршува во оваа поделба ќе биде прекинат."
#: src/apprt/gtk/Window.zig:200
msgid "Main Menu"
msgstr "Главно мени"
#: src/apprt/gtk/Surface.zig:1243
msgid "Copied to clipboard"
msgstr "Копирано во привремена меморија"
#: src/apprt/gtk/Window.zig:221
msgid "View Open Tabs"
msgstr "Прегледај отворени јазичиња"
#: src/apprt/gtk/Window.zig:295
msgid ""
"⚠️ You're running a debug build of Ghostty! Performance will be degraded."
msgstr "⚠️ Извршувате дебаг верзија на Ghostty! Перформансите ќе бидат намалени."
#: src/apprt/gtk/Window.zig:725
msgid "Reloaded the configuration"
msgstr "Конфигурацијата е одново вчитана"
#: src/apprt/gtk/Window.zig:941
msgid "Ghostty Developers"
msgstr "Развивачи на Ghostty"
#: src/apprt/gtk/inspector.zig:144
msgid "Ghostty: Terminal Inspector"
msgstr "Ghostty: Инспектор на терминал"

View File

@ -10,6 +10,7 @@ msgid ""
msgstr ""
"Project-Id-Version: com.mitchellh.ghostty\n"
"Report-Msgid-Bugs-To: m@mitchellh.com\n"
"POT-Creation-Date: 2025-04-22 08:57-0700\n"
"PO-Revision-Date: 2025-04-14 16:25+0200\n"
"Last-Translator: cryptocode <cryptocode@zolo.io>\n"
"Language-Team: Norwegian Bokmal <l10n-no@lister.huftis.org>\n"
@ -45,8 +46,8 @@ msgid ""
"One or more configuration errors were found. Please review the errors below, "
"and either reload your configuration or ignore these errors."
msgstr ""
"Én eller flere konfigurasjonsfeil ble funnet. Vennligst gjennomgå feilene under, "
"og enten last konfigurasjonen din på nytt eller ignorer disse feilene."
"Én eller flere konfigurasjonsfeil ble funnet. Vennligst gjennomgå feilene "
"under, og enten last konfigurasjonen din på nytt eller ignorer disse feilene."
#: src/apprt/gtk/ui/1.5/config-errors-dialog.blp:9
msgid "Ignore"
@ -58,6 +59,30 @@ msgstr "Ignorer"
msgid "Reload Configuration"
msgstr "Last konfigurasjon på nytt"
#: src/apprt/gtk/ui/1.0/menu-headerbar-split_menu.blp:6
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:38
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:50
msgid "Split Up"
msgstr "Splitt opp"
#: src/apprt/gtk/ui/1.0/menu-headerbar-split_menu.blp:11
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:43
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:55
msgid "Split Down"
msgstr "Splitt ned"
#: src/apprt/gtk/ui/1.0/menu-headerbar-split_menu.blp:16
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:48
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:60
msgid "Split Left"
msgstr "Splitt venstre"
#: src/apprt/gtk/ui/1.0/menu-headerbar-split_menu.blp:21
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:53
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:65
msgid "Split Right"
msgstr "Splitt høyre"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:6
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:6
msgid "Copy"
@ -89,33 +114,13 @@ msgstr "Splitt"
msgid "Change Title…"
msgstr "Endre tittel…"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:38
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:50
msgid "Split Up"
msgstr "Splitt opp"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:43
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:55
msgid "Split Down"
msgstr "Splitt ned"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:48
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:60
msgid "Split Left"
msgstr "Splitt venstre"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:53
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:65
msgid "Split Right"
msgstr "Splitt høyre"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:59
msgid "Tab"
msgstr "Fane"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:62
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:30
#: src/apprt/gtk/Window.zig:246
#: src/apprt/gtk/Window.zig:248
msgid "New Tab"
msgstr "Ny fane"
@ -152,7 +157,7 @@ msgid "Terminal Inspector"
msgstr "Terminalinspektør"
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:102
#: src/apprt/gtk/Window.zig:960
#: src/apprt/gtk/Window.zig:1003
msgid "About Ghostty"
msgstr "Om Ghostty"
@ -203,13 +208,30 @@ msgstr ""
"Det ser ut som at kommandoer vil bli kjørt hvis du limer inn dette, vurder "
"om du mener det er trygt."
#: src/apprt/gtk/inspector.zig:144
msgid "Ghostty: Terminal Inspector"
msgstr "Ghostty: Terminalinspektør"
#: src/apprt/gtk/Window.zig:201
msgid "Main Menu"
msgstr "Hovedmeny"
#: src/apprt/gtk/Surface.zig:1243
msgid "Copied to clipboard"
msgstr "Kopiert til utklippstavlen"
#: src/apprt/gtk/Window.zig:222
msgid "View Open Tabs"
msgstr "Se åpne faner"
#: src/apprt/gtk/Window.zig:249
msgid "New Split"
msgstr ""
#: src/apprt/gtk/Window.zig:312
msgid ""
"⚠️ You're running a debug build of Ghostty! Performance will be degraded."
msgstr "⚠️ Du kjører et debug-bygg av Ghostty. Debug-bygg har redusert ytelse."
#: src/apprt/gtk/Window.zig:744
msgid "Reloaded the configuration"
msgstr "Konfigurasjonen ble lastet på nytt"
#: src/apprt/gtk/Window.zig:984
msgid "Ghostty Developers"
msgstr "Ghostty-utviklere"
#: src/apprt/gtk/CloseDialog.zig:47
msgid "Close"
@ -247,23 +269,10 @@ msgstr "Alle terminaløkter i denne fanen vil bli avsluttet."
msgid "The currently running process in this split will be terminated."
msgstr "Den kjørende prosessen for denne splitten vil bli avsluttet."
#: src/apprt/gtk/Window.zig:200
msgid "Main Menu"
msgstr "Hovedmeny"
#: src/apprt/gtk/Surface.zig:1243
msgid "Copied to clipboard"
msgstr "Kopiert til utklippstavlen"
#: src/apprt/gtk/Window.zig:221
msgid "View Open Tabs"
msgstr "Se åpne faner"
#: src/apprt/gtk/Window.zig:295
msgid ""
"⚠️ You're running a debug build of Ghostty! Performance will be degraded."
msgstr "⚠️ Du kjører et debug-bygg av Ghostty. Debug-bygg har redusert ytelse."
#: src/apprt/gtk/Window.zig:725
msgid "Reloaded the configuration"
msgstr "Konfigurasjonen ble lastet på nytt"
#: src/apprt/gtk/Window.zig:941
msgid "Ghostty Developers"
msgstr "Ghostty-utviklere"
#: src/apprt/gtk/inspector.zig:144
msgid "Ghostty: Terminal Inspector"
msgstr "Ghostty: Terminalinspektør"

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: com.mitchellh.ghostty\n"
"Report-Msgid-Bugs-To: m@mitchellh.com\n"
"POT-Creation-Date: 2025-03-19 08:28-0700\n"
"POT-Creation-Date: 2025-04-22 08:57-0700\n"
"PO-Revision-Date: 2025-03-24 15:00+0100\n"
"Last-Translator: Nico Geesink <geesinknico@gmail.com>\n"
"Language-Team: Dutch <vertaling@vrijschrift.org>\n"
@ -43,8 +43,8 @@ msgid ""
"One or more configuration errors were found. Please review the errors below, "
"and either reload your configuration or ignore these errors."
msgstr ""
"Er zijn één of meer configuratiefouten gevonden. Bekijk de onderstaande fouten "
"en herlaad je configuratie of negeer deze fouten."
"Er zijn één of meer configuratiefouten gevonden. Bekijk de onderstaande "
"fouten en herlaad je configuratie of negeer deze fouten."
#: src/apprt/gtk/ui/1.5/config-errors-dialog.blp:9
msgid "Ignore"
@ -56,6 +56,30 @@ msgstr "Negeer"
msgid "Reload Configuration"
msgstr "Herlaad configuratie"
#: src/apprt/gtk/ui/1.0/menu-headerbar-split_menu.blp:6
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:38
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:50
msgid "Split Up"
msgstr "Splits naar boven"
#: src/apprt/gtk/ui/1.0/menu-headerbar-split_menu.blp:11
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:43
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:55
msgid "Split Down"
msgstr "Splits naar beneden"
#: src/apprt/gtk/ui/1.0/menu-headerbar-split_menu.blp:16
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:48
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:60
msgid "Split Left"
msgstr "Splits naar links"
#: src/apprt/gtk/ui/1.0/menu-headerbar-split_menu.blp:21
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:53
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:65
msgid "Split Right"
msgstr "Splits naar rechts"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:6
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:6
msgid "Copy"
@ -87,33 +111,13 @@ msgstr "Splitsen"
msgid "Change Title…"
msgstr "Wijzig titel…"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:38
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:50
msgid "Split Up"
msgstr "Splits naar boven"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:43
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:55
msgid "Split Down"
msgstr "Splits naar beneden"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:48
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:60
msgid "Split Left"
msgstr "Splits naar links"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:53
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:65
msgid "Split Right"
msgstr "Splits naar rechts"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:59
msgid "Tab"
msgstr "Tabblad"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:62
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:30
#: src/apprt/gtk/Window.zig:246
#: src/apprt/gtk/Window.zig:248
msgid "New Tab"
msgstr "Nieuw tabblad"
@ -150,7 +154,7 @@ msgid "Terminal Inspector"
msgstr "Terminal inspecteur"
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:102
#: src/apprt/gtk/Window.zig:960
#: src/apprt/gtk/Window.zig:1003
msgid "About Ghostty"
msgstr "Over Ghostty"
@ -198,16 +202,35 @@ msgid ""
"Pasting this text into the terminal may be dangerous as it looks like some "
"commands may be executed."
msgstr ""
"Het plakken van deze tekst in de terminal is mogelijk gevaarlijk, omdat "
"het lijkt op een commando dat uitgevoerd kan worden."
"Het plakken van deze tekst in de terminal is mogelijk gevaarlijk, omdat het "
"lijkt op een commando dat uitgevoerd kan worden."
#: src/apprt/gtk/inspector.zig:144
msgid "Ghostty: Terminal Inspector"
msgstr "Ghostty: terminal inspecteur"
#: src/apprt/gtk/Window.zig:201
msgid "Main Menu"
msgstr "Hoofdmenu"
#: src/apprt/gtk/Surface.zig:1243
msgid "Copied to clipboard"
msgstr "Gekopieerd naar klembord"
#: src/apprt/gtk/Window.zig:222
msgid "View Open Tabs"
msgstr "Open tabbladen bekijken"
#: src/apprt/gtk/Window.zig:249
msgid "New Split"
msgstr ""
#: src/apprt/gtk/Window.zig:312
msgid ""
"⚠️ You're running a debug build of Ghostty! Performance will be degraded."
msgstr ""
"⚠️ Je draait een debug versie van Ghostty! Prestaties zullen minder zijn dan "
"normaal."
#: src/apprt/gtk/Window.zig:744
msgid "Reloaded the configuration"
msgstr "De configuratie is herladen"
#: src/apprt/gtk/Window.zig:984
msgid "Ghostty Developers"
msgstr "Ghostty ontwikkelaars"
#: src/apprt/gtk/CloseDialog.zig:47
msgid "Close"
@ -243,26 +266,13 @@ msgstr "Alle terminalsessies binnen dit tabblad zullen worden beëindigd."
#: src/apprt/gtk/CloseDialog.zig:99
msgid "The currently running process in this split will be terminated."
msgstr "Alle processen die nu draaien in deze splitsing zullen worden beëindigd."
#: src/apprt/gtk/Window.zig:200
msgid "Main Menu"
msgstr "Hoofdmenu"
#: src/apprt/gtk/Window.zig:221
msgid "View Open Tabs"
msgstr "Open tabbladen bekijken"
#: src/apprt/gtk/Window.zig:295
msgid ""
"⚠️ You're running a debug build of Ghostty! Performance will be degraded."
msgstr ""
"⚠️ Je draait een debug versie van Ghostty! Prestaties zullen minder zijn dan normaal."
"Alle processen die nu draaien in deze splitsing zullen worden beëindigd."
#: src/apprt/gtk/Window.zig:725
msgid "Reloaded the configuration"
msgstr "De configuratie is herladen"
#: src/apprt/gtk/Surface.zig:1243
msgid "Copied to clipboard"
msgstr "Gekopieerd naar klembord"
#: src/apprt/gtk/Window.zig:941
msgid "Ghostty Developers"
msgstr "Ghostty ontwikkelaars"
#: src/apprt/gtk/inspector.zig:144
msgid "Ghostty: Terminal Inspector"
msgstr "Ghostty: terminal inspecteur"

View File

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: com.mitchellh.ghostty\n"
"Report-Msgid-Bugs-To: m@mitchellh.com\n"
"POT-Creation-Date: 2025-03-18 11:48+0100\n"
"POT-Creation-Date: 2025-04-22 08:57-0700\n"
"PO-Revision-Date: 2025-03-17 12:15+0100\n"
"Last-Translator: Bartosz Sokorski <b.sokorski@gmail.com>\n"
"Language-Team: Polish <translation-team-pl@lists.sourceforge.net>\n"
@ -45,8 +45,8 @@ msgid ""
"One or more configuration errors were found. Please review the errors below, "
"and either reload your configuration or ignore these errors."
msgstr ""
"Znaleziono jeden lub więcej błędów konfiguracji. Sprawdź błędy wylistowane poniżej "
"i przeładuj konfigurację lub zignoruj je."
"Znaleziono jeden lub więcej błędów konfiguracji. Sprawdź błędy wylistowane "
"poniżej i przeładuj konfigurację lub zignoruj je."
#: src/apprt/gtk/ui/1.5/config-errors-dialog.blp:9
msgid "Ignore"
@ -58,6 +58,30 @@ msgstr "Zignoruj"
msgid "Reload Configuration"
msgstr "Przeładuj konfigurację"
#: src/apprt/gtk/ui/1.0/menu-headerbar-split_menu.blp:6
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:38
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:50
msgid "Split Up"
msgstr "Podziel w górę"
#: src/apprt/gtk/ui/1.0/menu-headerbar-split_menu.blp:11
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:43
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:55
msgid "Split Down"
msgstr "Podziel w dół"
#: src/apprt/gtk/ui/1.0/menu-headerbar-split_menu.blp:16
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:48
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:60
msgid "Split Left"
msgstr "Podziel w lewo"
#: src/apprt/gtk/ui/1.0/menu-headerbar-split_menu.blp:21
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:53
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:65
msgid "Split Right"
msgstr "Podziel w prawo"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:6
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:6
msgid "Copy"
@ -89,33 +113,13 @@ msgstr "Podział"
msgid "Change Title…"
msgstr "Zmień tytuł…"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:38
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:50
msgid "Split Up"
msgstr "Podziel w górę"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:43
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:55
msgid "Split Down"
msgstr "Podziel w dół"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:48
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:60
msgid "Split Left"
msgstr "Podziel w lewo"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:53
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:65
msgid "Split Right"
msgstr "Podziel w prawo"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:59
msgid "Tab"
msgstr "Karta"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:62
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:30
#: src/apprt/gtk/Window.zig:246
#: src/apprt/gtk/Window.zig:248
msgid "New Tab"
msgstr "Nowa karta"
@ -152,7 +156,7 @@ msgid "Terminal Inspector"
msgstr "Inspektor terminala"
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:102
#: src/apprt/gtk/Window.zig:958
#: src/apprt/gtk/Window.zig:1003
msgid "About Ghostty"
msgstr "O Ghostty"
@ -203,31 +207,31 @@ msgstr ""
"Wklejenie tego tekstu do terminala może być niebezpieczne, ponieważ może "
"spowodować wykonanie komend."
#: src/apprt/gtk/Window.zig:200
#: src/apprt/gtk/Window.zig:201
msgid "Main Menu"
msgstr "Menu główne"
#: src/apprt/gtk/Window.zig:221
#: src/apprt/gtk/Window.zig:222
msgid "View Open Tabs"
msgstr "Zobacz otwarte karty"
#: src/apprt/gtk/Window.zig:295
#: src/apprt/gtk/Window.zig:249
msgid "New Split"
msgstr ""
#: src/apprt/gtk/Window.zig:312
msgid ""
"⚠️ You're running a debug build of Ghostty! Performance will be degraded."
msgstr "⚠️ Używasz wersji Ghostty do debugowania! Wydajność będzie obniżona."
#: src/apprt/gtk/Window.zig:725
#: src/apprt/gtk/Window.zig:744
msgid "Reloaded the configuration"
msgstr "Przeładowano konfigurację"
#: src/apprt/gtk/Window.zig:939
#: src/apprt/gtk/Window.zig:984
msgid "Ghostty Developers"
msgstr "Twórcy Ghostty"
#: src/apprt/gtk/inspector.zig:144
msgid "Ghostty: Terminal Inspector"
msgstr "Inspektor terminala Ghostty"
#: src/apprt/gtk/CloseDialog.zig:47
msgid "Close"
msgstr "Zamknij"
@ -264,6 +268,10 @@ msgstr "Wszystkie sesje terminala w obecnej karcie zostaną zakończone."
msgid "The currently running process in this split will be terminated."
msgstr "Wszyskie trwające procesy w obecnym podziale zostaną zakończone."
#: src/apprt/gtk/Surface.zig:1242
#: src/apprt/gtk/Surface.zig:1243
msgid "Copied to clipboard"
msgstr "Skopiowano do schowka"
#: src/apprt/gtk/inspector.zig:144
msgid "Ghostty: Terminal Inspector"
msgstr "Inspektor terminala Ghostty"

View File

@ -8,11 +8,11 @@ msgid ""
msgstr ""
"Project-Id-Version: com.mitchellh.ghostty\n"
"Report-Msgid-Bugs-To: m@mitchellh.com\n"
"POT-Creation-Date: 2025-03-19 08:54-0700\n"
"POT-Creation-Date: 2025-04-22 08:57-0700\n"
"PO-Revision-Date: 2025-03-28 11:04-0300\n"
"Last-Translator: Gustavo Peres <gsodevel@gmail.com>\n"
"Language-Team: Brazilian Portuguese <ldpbr-"
"translation@lists.sourceforge.net>\n"
"Language-Team: Brazilian Portuguese <ldpbr-translation@lists.sourceforge."
"net>\n"
"Language: pt_BR\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@ -45,8 +45,8 @@ msgid ""
"One or more configuration errors were found. Please review the errors below, "
"and either reload your configuration or ignore these errors."
msgstr ""
"Um ou mais erros de configuração encontrados. Por favor revise os erros abaixo, "
"e ou recarregue sua configuração, ou ignore esses erros."
"Um ou mais erros de configuração encontrados. Por favor revise os erros "
"abaixo, e ou recarregue sua configuração, ou ignore esses erros."
#: src/apprt/gtk/ui/1.5/config-errors-dialog.blp:9
msgid "Ignore"
@ -58,6 +58,30 @@ msgstr "Ignorar"
msgid "Reload Configuration"
msgstr "Recarregar configuração"
#: src/apprt/gtk/ui/1.0/menu-headerbar-split_menu.blp:6
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:38
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:50
msgid "Split Up"
msgstr "Dividir para cima"
#: src/apprt/gtk/ui/1.0/menu-headerbar-split_menu.blp:11
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:43
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:55
msgid "Split Down"
msgstr "Dividir para baixo"
#: src/apprt/gtk/ui/1.0/menu-headerbar-split_menu.blp:16
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:48
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:60
msgid "Split Left"
msgstr "Dividir à esquerda"
#: src/apprt/gtk/ui/1.0/menu-headerbar-split_menu.blp:21
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:53
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:65
msgid "Split Right"
msgstr "Dividir à direita"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:6
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:6
msgid "Copy"
@ -89,33 +113,13 @@ msgstr "Dividir"
msgid "Change Title…"
msgstr "Mudar título…"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:38
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:50
msgid "Split Up"
msgstr "Dividir para cima"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:43
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:55
msgid "Split Down"
msgstr "Dividir para baixo"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:48
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:60
msgid "Split Left"
msgstr "Dividir à esquerda"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:53
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:65
msgid "Split Right"
msgstr "Dividir à direita"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:59
msgid "Tab"
msgstr "Aba"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:62
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:30
#: src/apprt/gtk/Window.zig:246
#: src/apprt/gtk/Window.zig:248
msgid "New Tab"
msgstr "Nova aba"
@ -152,7 +156,7 @@ msgid "Terminal Inspector"
msgstr "Inspetor de terminal"
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:102
#: src/apprt/gtk/Window.zig:960
#: src/apprt/gtk/Window.zig:1003
msgid "About Ghostty"
msgstr "Sobre o Ghostty"
@ -170,8 +174,8 @@ msgid ""
"An application is attempting to read from the clipboard. The current "
"clipboard contents are shown below."
msgstr ""
"Uma aplicação está tentando ler da área de transferência. O conteúdo "
"atual da área de transferência está sendo exibido abaixo."
"Uma aplicação está tentando ler da área de transferência. O conteúdo atual "
"da área de transferência está sendo exibido abaixo."
#: src/apprt/gtk/ui/1.5/ccw-osc-52-read.blp:10
#: src/apprt/gtk/ui/1.5/ccw-osc-52-write.blp:10
@ -203,13 +207,31 @@ msgstr ""
"Colar esse texto em um terminal pode ser perigoso, pois parece que alguns "
"comandos podem ser executados."
#: src/apprt/gtk/inspector.zig:144
msgid "Ghostty: Terminal Inspector"
msgstr "Ghostty: Inspetor de terminal"
#: src/apprt/gtk/Window.zig:201
msgid "Main Menu"
msgstr "Menu Principal"
#: src/apprt/gtk/Surface.zig:1243
msgid "Copied to clipboard"
msgstr "Copiado para a área de transferência"
#: src/apprt/gtk/Window.zig:222
msgid "View Open Tabs"
msgstr "Visualizar abas abertas"
#: src/apprt/gtk/Window.zig:249
msgid "New Split"
msgstr ""
#: src/apprt/gtk/Window.zig:312
msgid ""
"⚠️ You're running a debug build of Ghostty! Performance will be degraded."
msgstr ""
"⚠️ Você está rodando uma build de debug do Ghostty! O desempenho será afetado."
#: src/apprt/gtk/Window.zig:744
msgid "Reloaded the configuration"
msgstr "Configuração recarregada"
#: src/apprt/gtk/Window.zig:984
msgid "Ghostty Developers"
msgstr "Desenvolvedores Ghostty"
#: src/apprt/gtk/CloseDialog.zig:47
msgid "Close"
@ -247,23 +269,10 @@ msgstr "Todas as sessões de terminal nessa aba serão finalizadas."
msgid "The currently running process in this split will be terminated."
msgstr "O processo atual rodando nessa divisão será finalizado."
#: src/apprt/gtk/Window.zig:200
msgid "Main Menu"
msgstr "Menu Principal"
#: src/apprt/gtk/Surface.zig:1243
msgid "Copied to clipboard"
msgstr "Copiado para a área de transferência"
#: src/apprt/gtk/Window.zig:221
msgid "View Open Tabs"
msgstr "Visualizar abas abertas"
#: src/apprt/gtk/Window.zig:295
msgid ""
"⚠️ You're running a debug build of Ghostty! Performance will be degraded."
msgstr "⚠️ Você está rodando uma build de debug do Ghostty! O desempenho será afetado."
#: src/apprt/gtk/Window.zig:725
msgid "Reloaded the configuration"
msgstr "Configuração recarregada"
#: src/apprt/gtk/Window.zig:941
msgid "Ghostty Developers"
msgstr "Desenvolvedores Ghostty"
#: src/apprt/gtk/inspector.zig:144
msgid "Ghostty: Terminal Inspector"
msgstr "Ghostty: Inspetor de terminal"

View File

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: com.mitchellh.ghostty\n"
"Report-Msgid-Bugs-To: m@mitchellh.com\n"
"POT-Creation-Date: 2025-03-19 08:28-0700\n"
"POT-Creation-Date: 2025-04-22 08:57-0700\n"
"PO-Revision-Date: 2025-03-24 00:01+0500\n"
"Last-Translator: blackzeshi <sergey_zhuzhgov@mail.ru>\n"
"Language-Team: Russian <gnu@d07.ru>\n"
@ -45,8 +45,8 @@ msgid ""
"One or more configuration errors were found. Please review the errors below, "
"and either reload your configuration or ignore these errors."
msgstr ""
"Конфигурация содержит ошибки. Проверьте их ниже, а затем"
"либо перезагрузите конфигурацию, либо проигнорируйте ошибки."
"Конфигурация содержит ошибки. Проверьте их ниже, а затем либо перезагрузите "
"конфигурацию, либо проигнорируйте ошибки."
#: src/apprt/gtk/ui/1.5/config-errors-dialog.blp:9
msgid "Ignore"
@ -58,6 +58,30 @@ msgstr "Игнорировать"
msgid "Reload Configuration"
msgstr "Обновить конфигурацию"
#: src/apprt/gtk/ui/1.0/menu-headerbar-split_menu.blp:6
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:38
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:50
msgid "Split Up"
msgstr "Сплит вверх"
#: src/apprt/gtk/ui/1.0/menu-headerbar-split_menu.blp:11
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:43
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:55
msgid "Split Down"
msgstr "Сплит вниз"
#: src/apprt/gtk/ui/1.0/menu-headerbar-split_menu.blp:16
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:48
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:60
msgid "Split Left"
msgstr "Сплит влево"
#: src/apprt/gtk/ui/1.0/menu-headerbar-split_menu.blp:21
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:53
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:65
msgid "Split Right"
msgstr "Сплит вправо"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:6
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:6
msgid "Copy"
@ -89,33 +113,13 @@ msgstr "Сплит"
msgid "Change Title…"
msgstr "Изменить заголовок…"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:38
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:50
msgid "Split Up"
msgstr "Сплит вверх"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:43
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:55
msgid "Split Down"
msgstr "Сплит вниз"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:48
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:60
msgid "Split Left"
msgstr "Сплит влево"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:53
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:65
msgid "Split Right"
msgstr "Сплит вправо"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:59
msgid "Tab"
msgstr "Вкладка"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:62
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:30
#: src/apprt/gtk/Window.zig:246
#: src/apprt/gtk/Window.zig:248
msgid "New Tab"
msgstr "Новая вкладка"
@ -152,7 +156,7 @@ msgid "Terminal Inspector"
msgstr "Инспектор терминала"
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:102
#: src/apprt/gtk/Window.zig:960
#: src/apprt/gtk/Window.zig:1003
msgid "About Ghostty"
msgstr "О Ghostty"
@ -170,8 +174,8 @@ msgid ""
"An application is attempting to read from the clipboard. The current "
"clipboard contents are shown below."
msgstr ""
"Приложение пытается прочитать данные из буфера обмена. Эти данные "
"отображены ниже."
"Приложение пытается прочитать данные из буфера обмена. Эти данные отображены "
"ниже."
#: src/apprt/gtk/ui/1.5/ccw-osc-52-read.blp:10
#: src/apprt/gtk/ui/1.5/ccw-osc-52-write.blp:10
@ -188,8 +192,7 @@ msgid ""
"An application is attempting to write to the clipboard. The current "
"clipboard contents are shown below."
msgstr ""
"Приложение пытается записать данные в буфер обмена. Эти данные "
"показаны ниже."
"Приложение пытается записать данные в буфер обмена. Эти данные показаны ниже."
#: src/apprt/gtk/ui/1.5/ccw-paste.blp:6
msgid "Warning: Potentially Unsafe Paste"
@ -200,16 +203,35 @@ msgid ""
"Pasting this text into the terminal may be dangerous as it looks like some "
"commands may be executed."
msgstr ""
"Вставка этого текста в терминал может быть опасной. Это выглядит "
ак команды, которые могут быть исполнены."
"Вставка этого текста в терминал может быть опасной. Это выглядит как "
"команды, которые могут быть исполнены."
#: src/apprt/gtk/inspector.zig:144
msgid "Ghostty: Terminal Inspector"
msgstr "Ghostty: инспектор терминала"
#: src/apprt/gtk/Window.zig:201
msgid "Main Menu"
msgstr "Главное меню"
#: src/apprt/gtk/Surface.zig:1243
msgid "Copied to clipboard"
msgstr "Скопировано в буфер обмена"
#: src/apprt/gtk/Window.zig:222
msgid "View Open Tabs"
msgstr "Просмотреть открытые вкладки"
#: src/apprt/gtk/Window.zig:249
msgid "New Split"
msgstr ""
#: src/apprt/gtk/Window.zig:312
msgid ""
"⚠️ You're running a debug build of Ghostty! Performance will be degraded."
msgstr ""
"⚠️ Вы запустили отладочную сборку Ghostty! Это может влиять на "
"производительность."
#: src/apprt/gtk/Window.zig:744
msgid "Reloaded the configuration"
msgstr "Конфигурация была обновлена"
#: src/apprt/gtk/Window.zig:984
msgid "Ghostty Developers"
msgstr "Разработчики Ghostty"
#: src/apprt/gtk/CloseDialog.zig:47
msgid "Close"
@ -247,24 +269,10 @@ msgstr "Все сессии терминала в этой вкладке буд
msgid "The currently running process in this split will be terminated."
msgstr "Процесс, работающий в этой сплит-области, будет остановлен."
#: src/apprt/gtk/Window.zig:200
msgid "Main Menu"
msgstr "Главное меню"
#: src/apprt/gtk/Surface.zig:1243
msgid "Copied to clipboard"
msgstr "Скопировано в буфер обмена"
#: src/apprt/gtk/Window.zig:221
msgid "View Open Tabs"
msgstr "Просмотреть открытые вкладки"
#: src/apprt/gtk/Window.zig:295
msgid ""
"⚠️ You're running a debug build of Ghostty! Performance will be degraded."
msgstr ""
"⚠️ Вы запустили отладочную сборку Ghostty! Это может влиять на производительность."
#: src/apprt/gtk/Window.zig:725
msgid "Reloaded the configuration"
msgstr "Конфигурация была обновлена"
#: src/apprt/gtk/Window.zig:941
msgid "Ghostty Developers"
msgstr "Разработчики Ghostty"
#: src/apprt/gtk/inspector.zig:144
msgid "Ghostty: Terminal Inspector"
msgstr "Ghostty: инспектор терминала"

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: com.mitchellh.ghostty\n"
"Report-Msgid-Bugs-To: m@mitchellh.com\n"
"POT-Creation-Date: 2025-03-19 08:54-0700\n"
"POT-Creation-Date: 2025-04-22 08:57-0700\n"
"PO-Revision-Date: 2025-03-24 22:01+0300\n"
"Last-Translator: Emir SARI <emir_sari@icloud.com>\n"
"Language-Team: Turkish\n"
@ -57,6 +57,30 @@ msgstr "Yok Say"
msgid "Reload Configuration"
msgstr "Yapılandırmayı Yeniden Yükle"
#: src/apprt/gtk/ui/1.0/menu-headerbar-split_menu.blp:6
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:38
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:50
msgid "Split Up"
msgstr "Yukarı Doğru Böl"
#: src/apprt/gtk/ui/1.0/menu-headerbar-split_menu.blp:11
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:43
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:55
msgid "Split Down"
msgstr "Aşağı Doğru Böl"
#: src/apprt/gtk/ui/1.0/menu-headerbar-split_menu.blp:16
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:48
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:60
msgid "Split Left"
msgstr "Sola Doğru Böl"
#: src/apprt/gtk/ui/1.0/menu-headerbar-split_menu.blp:21
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:53
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:65
msgid "Split Right"
msgstr "Sağa Doğru Böl"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:6
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:6
msgid "Copy"
@ -88,33 +112,13 @@ msgstr "Böl"
msgid "Change Title…"
msgstr "Başlığı Değiştir…"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:38
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:50
msgid "Split Up"
msgstr "Yukarı Doğru Böl"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:43
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:55
msgid "Split Down"
msgstr "Aşağı Doğru Böl"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:48
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:60
msgid "Split Left"
msgstr "Sola Doğru Böl"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:53
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:65
msgid "Split Right"
msgstr "Sağa Doğru Böl"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:59
msgid "Tab"
msgstr "Sekme"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:62
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:30
#: src/apprt/gtk/Window.zig:246
#: src/apprt/gtk/Window.zig:248
msgid "New Tab"
msgstr "Yeni Sekme"
@ -151,7 +155,7 @@ msgid "Terminal Inspector"
msgstr "Uçbirim Denetçisi"
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:102
#: src/apprt/gtk/Window.zig:960
#: src/apprt/gtk/Window.zig:1003
msgid "About Ghostty"
msgstr "Ghostty Hakkında"
@ -202,13 +206,32 @@ msgstr ""
"Bu metni uçbirime yapıştırmak tehlikeli olabilir; çünkü bir komut "
"yürütülebilecekmiş gibi duruyor."
#: src/apprt/gtk/inspector.zig:144
msgid "Ghostty: Terminal Inspector"
msgstr "Ghostty: Uçbirim Denetçisi"
#: src/apprt/gtk/Window.zig:201
msgid "Main Menu"
msgstr "Ana Menü"
#: src/apprt/gtk/Surface.zig:1243
msgid "Copied to clipboard"
msgstr "Panoya kopyalandı"
#: src/apprt/gtk/Window.zig:222
msgid "View Open Tabs"
msgstr "Açık Sekmeleri Görüntüle"
#: src/apprt/gtk/Window.zig:249
msgid "New Split"
msgstr ""
#: src/apprt/gtk/Window.zig:312
msgid ""
"⚠️ You're running a debug build of Ghostty! Performance will be degraded."
msgstr ""
"⚠️ Ghosttynin hata ayıklama amaçlı yapılmış bir sürümünü kullanıyorsunuz! "
"Başarım normale göre daha düşük olacaktır."
#: src/apprt/gtk/Window.zig:744
msgid "Reloaded the configuration"
msgstr "Yapılandırma yeniden yüklendi"
#: src/apprt/gtk/Window.zig:984
msgid "Ghostty Developers"
msgstr "Ghostty Geliştiricileri"
#: src/apprt/gtk/CloseDialog.zig:47
msgid "Close"
@ -246,25 +269,10 @@ msgstr "Bu sekmedeki tüm uçbirim oturumları sonlandırılacaktır."
msgid "The currently running process in this split will be terminated."
msgstr "Bu bölmedeki şu anda çalışan süreç sonlandırılacaktır."
#: src/apprt/gtk/Window.zig:200
msgid "Main Menu"
msgstr "Ana Menü"
#: src/apprt/gtk/Surface.zig:1243
msgid "Copied to clipboard"
msgstr "Panoya kopyalandı"
#: src/apprt/gtk/Window.zig:221
msgid "View Open Tabs"
msgstr "Açık Sekmeleri Görüntüle"
#: src/apprt/gtk/Window.zig:295
msgid ""
"⚠️ You're running a debug build of Ghostty! Performance will be degraded."
msgstr ""
"⚠️ Ghosttynin hata ayıklama amaçlı yapılmış bir sürümünü kullanıyorsunuz! "
"Başarım normale göre daha düşük olacaktır."
#: src/apprt/gtk/Window.zig:725
msgid "Reloaded the configuration"
msgstr "Yapılandırma yeniden yüklendi"
#: src/apprt/gtk/Window.zig:941
msgid "Ghostty Developers"
msgstr "Ghostty Geliştiricileri"
#: src/apprt/gtk/inspector.zig:144
msgid "Ghostty: Terminal Inspector"
msgstr "Ghostty: Uçbirim Denetçisi"

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: com.mitchellh.ghostty\n"
"Report-Msgid-Bugs-To: m@mitchellh.com\n"
"POT-Creation-Date: 2025-03-19 08:54-0700\n"
"POT-Creation-Date: 2025-04-22 08:57-0700\n"
"PO-Revision-Date: 2025-03-16 20:16+0200\n"
"Last-Translator: Danylo Zalizchuk <danilmail0110@gmail.com>\n"
"Language-Team: Ukrainian <trans-uk@lists.fedoraproject.org>\n"
@ -44,8 +44,9 @@ msgid ""
"One or more configuration errors were found. Please review the errors below, "
"and either reload your configuration or ignore these errors."
msgstr ""
"Виявлено одну або декілька помилок у конфігурації. Будь ласка, перегляньте наведені "
"нижче помилки і або перезавантажте конфігурацію, або проігноруйте ці помилки."
"Виявлено одну або декілька помилок у конфігурації. Будь ласка, перегляньте "
"наведені нижче помилки і або перезавантажте конфігурацію, або проігноруйте "
"ці помилки."
#: src/apprt/gtk/ui/1.5/config-errors-dialog.blp:9
msgid "Ignore"
@ -57,6 +58,30 @@ msgstr "Ігнорувати"
msgid "Reload Configuration"
msgstr "Перезавантажити конфігурацію"
#: src/apprt/gtk/ui/1.0/menu-headerbar-split_menu.blp:6
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:38
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:50
msgid "Split Up"
msgstr "Розділити панель вгору"
#: src/apprt/gtk/ui/1.0/menu-headerbar-split_menu.blp:11
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:43
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:55
msgid "Split Down"
msgstr "Розділити панель вниз"
#: src/apprt/gtk/ui/1.0/menu-headerbar-split_menu.blp:16
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:48
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:60
msgid "Split Left"
msgstr "Розділити панель ліворуч"
#: src/apprt/gtk/ui/1.0/menu-headerbar-split_menu.blp:21
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:53
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:65
msgid "Split Right"
msgstr "Розділити панель праворуч"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:6
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:6
msgid "Copy"
@ -88,33 +113,13 @@ msgstr "Розділена панель"
msgid "Change Title…"
msgstr "Змінити заголовок…"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:38
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:50
msgid "Split Up"
msgstr "Розділити панель вгору"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:43
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:55
msgid "Split Down"
msgstr "Розділити панель вниз"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:48
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:60
msgid "Split Left"
msgstr "Розділити панель ліворуч"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:53
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:65
msgid "Split Right"
msgstr "Розділити панель праворуч"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:59
msgid "Tab"
msgstr "Вкладка"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:62
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:30
#: src/apprt/gtk/Window.zig:246
#: src/apprt/gtk/Window.zig:248
msgid "New Tab"
msgstr "Нова вкладка"
@ -151,7 +156,7 @@ msgid "Terminal Inspector"
msgstr "Інспектор терміналу"
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:102
#: src/apprt/gtk/Window.zig:960
#: src/apprt/gtk/Window.zig:1003
msgid "About Ghostty"
msgstr "Про Ghostty"
@ -202,13 +207,31 @@ msgstr ""
"Вставка цього тексту в термінал може бути небезпечною, оскільки виглядає "
"так, ніби деякі команди можуть бути виконані."
#: src/apprt/gtk/inspector.zig:144
msgid "Ghostty: Terminal Inspector"
msgstr "Ghostty: Інспектор терміналу"
#: src/apprt/gtk/Window.zig:201
msgid "Main Menu"
msgstr "Головне меню"
#: src/apprt/gtk/Surface.zig:1243
msgid "Copied to clipboard"
msgstr "Скопійовано в буфер обміну"
#: src/apprt/gtk/Window.zig:222
msgid "View Open Tabs"
msgstr "Переглянути відкриті вкладки"
#: src/apprt/gtk/Window.zig:249
msgid "New Split"
msgstr ""
#: src/apprt/gtk/Window.zig:312
msgid ""
"⚠️ You're running a debug build of Ghostty! Performance will be degraded."
msgstr ""
"⚠️ Ви використовуєте відладочну збірку Ghostty! Продуктивність буде погіршено."
#: src/apprt/gtk/Window.zig:744
msgid "Reloaded the configuration"
msgstr "Конфігурацію перезавантажено"
#: src/apprt/gtk/Window.zig:984
msgid "Ghostty Developers"
msgstr "Розробники Ghostty"
#: src/apprt/gtk/CloseDialog.zig:47
msgid "Close"
@ -247,24 +270,10 @@ msgid "The currently running process in this split will be terminated."
msgstr ""
"Поточний процес, що виконується в цій розділеній панелі, буде завершено."
#: src/apprt/gtk/Window.zig:200
msgid "Main Menu"
msgstr "Головне меню"
#: src/apprt/gtk/Surface.zig:1243
msgid "Copied to clipboard"
msgstr "Скопійовано в буфер обміну"
#: src/apprt/gtk/Window.zig:221
msgid "View Open Tabs"
msgstr "Переглянути відкриті вкладки"
#: src/apprt/gtk/Window.zig:295
msgid ""
"⚠️ You're running a debug build of Ghostty! Performance will be degraded."
msgstr ""
"⚠️ Ви використовуєте відладочну збірку Ghostty! Продуктивність буде погіршено."
#: src/apprt/gtk/Window.zig:725
msgid "Reloaded the configuration"
msgstr "Конфігурацію перезавантажено"
#: src/apprt/gtk/Window.zig:941
msgid "Ghostty Developers"
msgstr "Розробники Ghostty"
#: src/apprt/gtk/inspector.zig:144
msgid "Ghostty: Terminal Inspector"
msgstr "Ghostty: Інспектор терміналу"

View File

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: com.mitchellh.ghostty\n"
"Report-Msgid-Bugs-To: m@mitchellh.com\n"
"POT-Creation-Date: 2025-03-19 08:54-0700\n"
"POT-Creation-Date: 2025-04-22 08:57-0700\n"
"PO-Revision-Date: 2025-02-27 09:16+0100\n"
"Last-Translator: Leah <hi@pluie.me>\n"
"Language-Team: Chinese (simplified) <i18n-zh@googlegroups.com>\n"
@ -55,6 +55,30 @@ msgstr "忽略"
msgid "Reload Configuration"
msgstr "重新加载配置"
#: src/apprt/gtk/ui/1.0/menu-headerbar-split_menu.blp:6
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:38
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:50
msgid "Split Up"
msgstr "向上分屏"
#: src/apprt/gtk/ui/1.0/menu-headerbar-split_menu.blp:11
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:43
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:55
msgid "Split Down"
msgstr "向下分屏"
#: src/apprt/gtk/ui/1.0/menu-headerbar-split_menu.blp:16
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:48
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:60
msgid "Split Left"
msgstr "向左分屏"
#: src/apprt/gtk/ui/1.0/menu-headerbar-split_menu.blp:21
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:53
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:65
msgid "Split Right"
msgstr "向右分屏"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:6
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:6
msgid "Copy"
@ -86,33 +110,13 @@ msgstr "分屏"
msgid "Change Title…"
msgstr "更改标题……"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:38
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:50
msgid "Split Up"
msgstr "向上分屏"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:43
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:55
msgid "Split Down"
msgstr "向下分屏"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:48
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:60
msgid "Split Left"
msgstr "向左分屏"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:53
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:65
msgid "Split Right"
msgstr "向右分屏"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:59
msgid "Tab"
msgstr "标签页"
#: src/apprt/gtk/ui/1.0/menu-surface-context_menu.blp:62
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:30
#: src/apprt/gtk/Window.zig:246
#: src/apprt/gtk/Window.zig:248
msgid "New Tab"
msgstr "新建标签页"
@ -149,7 +153,7 @@ msgid "Terminal Inspector"
msgstr "终端调试器"
#: src/apprt/gtk/ui/1.0/menu-window-titlebar_menu.blp:102
#: src/apprt/gtk/Window.zig:960
#: src/apprt/gtk/Window.zig:1003
msgid "About Ghostty"
msgstr "关于 Ghostty"
@ -194,13 +198,30 @@ msgid ""
"commands may be executed."
msgstr "将以下内容粘贴至终端内将可能执行有害命令。"
#: src/apprt/gtk/inspector.zig:144
msgid "Ghostty: Terminal Inspector"
msgstr "Ghostty 终端调试器"
#: src/apprt/gtk/Window.zig:201
msgid "Main Menu"
msgstr "主菜单"
#: src/apprt/gtk/Surface.zig:1243
msgid "Copied to clipboard"
msgstr "已复制至剪贴板"
#: src/apprt/gtk/Window.zig:222
msgid "View Open Tabs"
msgstr "浏览标签页"
#: src/apprt/gtk/Window.zig:249
msgid "New Split"
msgstr ""
#: src/apprt/gtk/Window.zig:312
msgid ""
"⚠️ You're running a debug build of Ghostty! Performance will be degraded."
msgstr "⚠️ Ghostty 正在以调试模式运行!性能将大打折扣。"
#: src/apprt/gtk/Window.zig:744
msgid "Reloaded the configuration"
msgstr "已重新加载配置"
#: src/apprt/gtk/Window.zig:984
msgid "Ghostty Developers"
msgstr "Ghostty 开发团队"
#: src/apprt/gtk/CloseDialog.zig:47
msgid "Close"
@ -238,23 +259,10 @@ msgstr "标签页内所有运行中的进程将被终止。"
msgid "The currently running process in this split will be terminated."
msgstr "分屏内正在运行中的进程将被终止。"
#: src/apprt/gtk/Window.zig:200
msgid "Main Menu"
msgstr "主菜单"
#: src/apprt/gtk/Surface.zig:1243
msgid "Copied to clipboard"
msgstr "已复制至剪贴板"
#: src/apprt/gtk/Window.zig:221
msgid "View Open Tabs"
msgstr "浏览标签页"
#: src/apprt/gtk/Window.zig:295
msgid ""
"⚠️ You're running a debug build of Ghostty! Performance will be degraded."
msgstr "⚠️ Ghostty 正在以调试模式运行!性能将大打折扣。"
#: src/apprt/gtk/Window.zig:725
msgid "Reloaded the configuration"
msgstr "已重新加载配置"
#: src/apprt/gtk/Window.zig:941
msgid "Ghostty Developers"
msgstr "Ghostty 开发团队"
#: src/apprt/gtk/inspector.zig:144
msgid "Ghostty: Terminal Inspector"
msgstr "Ghostty 终端调试器"

View File

@ -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

View File

@ -4119,6 +4119,14 @@ pub fn performBindingAction(self: *Surface, action: input.Binding.Action) !bool
}, .unlocked);
},
.scroll_to_selection => {
self.renderer_state.mutex.lock();
defer self.renderer_state.mutex.unlock();
const sel = self.io.terminal.screen.selection orelse return false;
const tl = sel.topLeft(&self.io.terminal.screen);
self.io.terminal.screen.scroll(.{ .pin = tl });
},
.scroll_page_up => {
const rows: isize = @intCast(self.size.grid().rows);
self.io.queueMessage(.{
@ -4289,12 +4297,24 @@ pub fn performBindingAction(self: *Surface, action: input.Binding.Action) !bool
{},
),
.toggle_window_float_on_top => return try self.rt_app.performAction(
.{ .surface = self },
.float_window,
.toggle,
),
.toggle_secure_input => return try self.rt_app.performAction(
.{ .surface = self },
.secure_input,
.toggle,
),
.toggle_command_palette => return try self.rt_app.performAction(
.{ .surface = self },
.toggle_command_palette,
{},
),
.select_all => {
const sel = self.io.terminal.screen.selectAll();
if (sel) |s| {

View File

@ -107,6 +107,9 @@ pub const Action = union(Key) {
/// Toggle the quick terminal in or out.
toggle_quick_terminal,
/// Toggle the command palette. This currently only works on macOS.
toggle_command_palette,
/// Toggle the visibility of all Ghostty terminal windows.
toggle_visibility,
@ -202,6 +205,10 @@ pub const Action = union(Key) {
/// happen and can be ignored or cause a restart it isn't that important.
quit_timer: QuitTimer,
/// Set the window floating state. A floating window is one that is
/// always on top of other windows even when not focused.
float_window: FloatWindow,
/// Set the secure input functionality on or off. "Secure input" means
/// that the user is currently at some sort of prompt where they may be
/// entering a password or other sensitive information. This can be used
@ -244,6 +251,8 @@ pub const Action = union(Key) {
/// Closes the currently focused window.
close_window,
/// Called when the bell character is seen. The apprt should do whatever
/// it needs to ring the bell. This is usually a sound or visual effect.
ring_bell,
/// Sync with: ghostty_action_tag_e
@ -259,6 +268,7 @@ pub const Action = union(Key) {
toggle_tab_overview,
toggle_window_decorations,
toggle_quick_terminal,
toggle_command_palette,
toggle_visibility,
move_tab,
goto_tab,
@ -283,6 +293,7 @@ pub const Action = union(Key) {
renderer_health,
open_config,
quit_timer,
float_window,
secure_input,
key_sequence,
color_change,
@ -419,6 +430,12 @@ pub const Fullscreen = enum(c_int) {
macos_non_native_padded_notch,
};
pub const FloatWindow = enum(c_int) {
on,
off,
toggle,
};
pub const SecureInput = enum(c_int) {
on,
off,

View File

@ -43,15 +43,15 @@ pub const App = struct {
/// Callback called to wakeup the event loop. This should trigger
/// a full tick of the app loop.
wakeup: *const fn (AppUD) callconv(.C) void,
wakeup: *const fn (AppUD) callconv(.c) void,
/// Callback called to handle an action.
action: *const fn (*App, apprt.Target.C, apprt.Action.C) callconv(.C) bool,
action: *const fn (*App, apprt.Target.C, apprt.Action.C) callconv(.c) bool,
/// Read the clipboard value. The return value must be preserved
/// by the host until the next call. If there is no valid clipboard
/// value then this should return null.
read_clipboard: *const fn (SurfaceUD, c_int, *apprt.ClipboardRequest) callconv(.C) void,
read_clipboard: *const fn (SurfaceUD, c_int, *apprt.ClipboardRequest) callconv(.c) void,
/// This may be called after a read clipboard call to request
/// confirmation that the clipboard value is safe to read. The embedder
@ -61,13 +61,13 @@ pub const App = struct {
[*:0]const u8,
*apprt.ClipboardRequest,
apprt.ClipboardRequestType,
) callconv(.C) void,
) callconv(.c) void,
/// Write the clipboard value.
write_clipboard: *const fn (SurfaceUD, [*:0]const u8, c_int, bool) callconv(.C) void,
write_clipboard: *const fn (SurfaceUD, [*:0]const u8, c_int, bool) callconv(.c) void,
/// Close the current surface given by this function.
close_surface: ?*const fn (SurfaceUD, bool) callconv(.C) void = null,
close_surface: ?*const fn (SurfaceUD, bool) callconv(.c) void = null,
};
/// This is the key event sent for ghostty_surface_key and
@ -1487,6 +1487,23 @@ pub const CAPI = struct {
return @intCast(@as(input.Mods.Backing, @bitCast(result)));
}
/// Returns the current possible commands for a surface
/// in the output parameter. The memory is owned by libghostty
/// and doesn't need to be freed.
export fn ghostty_surface_commands(
surface: *Surface,
out: *[*]const input.Command.C,
len: *usize,
) void {
// In the future we may use this information to filter
// some commands.
_ = surface;
const commands = input.command.defaultsC;
out.* = commands.ptr;
len.* = commands.len;
}
/// Send this for raw keypresses (i.e. the keyDown event on macOS).
/// This will handle the keymap translation and send the appropriate
/// key and char events.

View File

@ -228,12 +228,14 @@ pub const App = struct {
.toggle_tab_overview,
.toggle_window_decorations,
.toggle_quick_terminal,
.toggle_command_palette,
.toggle_visibility,
.goto_tab,
.move_tab,
.inspector,
.render_inspector,
.quit_timer,
.float_window,
.secure_input,
.key_sequence,
.desktop_notification,

View File

@ -159,6 +159,7 @@ pub fn init(core_app: *CoreApp, opts: Options) !App {
opengl: bool = false,
/// disable GLES, Ghostty can't use GLES
@"gl-disable-gles": bool = false,
// GTK's new renderer can cause blurry font when using fractional scaling.
@"gl-no-fractional": bool = false,
/// Disabling Vulkan can improve startup times by hundreds of
/// milliseconds on some systems. We don't use Vulkan so we can just
@ -190,7 +191,6 @@ pub fn init(core_app: *CoreApp, opts: Options) !App {
// For the remainder of "why" see the 4.14 comment below.
gdk_disable.@"gles-api" = true;
gdk_disable.vulkan = true;
gdk_debug.@"gl-no-fractional" = true;
break :environment;
}
if (gtk_version.runtimeAtLeast(4, 14, 0)) {
@ -201,8 +201,12 @@ pub fn init(core_app: *CoreApp, opts: Options) !App {
//
// Upstream issue: https://gitlab.gnome.org/GNOME/gtk/-/issues/6589
gdk_debug.@"gl-disable-gles" = true;
gdk_debug.@"gl-no-fractional" = true;
gdk_debug.@"vulkan-disable" = true;
if (gtk_version.runtimeUntil(4, 17, 5)) {
// Removed at GTK v4.17.5
gdk_debug.@"gl-no-fractional" = true;
}
break :environment;
}
// Versions prior to 4.14 are a bit of an unknown for Ghostty. It
@ -488,6 +492,8 @@ pub fn performAction(
// Unimplemented
.close_all_windows,
.float_window,
.toggle_command_palette,
.toggle_visibility,
.cell_size,
.key_sequence,
@ -1290,6 +1296,13 @@ pub fn run(self: *App) !void {
// Setup our actions
self.initActions();
// On startup, we want to check for configuration errors right away
// so we can show our error window. We also need to setup other initial
// state.
self.syncConfigChanges(null) catch |err| {
log.warn("error handling configuration changes err={}", .{err});
};
while (self.running) {
_ = glib.MainContext.iteration(self.ctx, 1);
@ -1514,7 +1527,7 @@ fn adwNotifyDark(
style_manager: *adw.StyleManager,
_: *gobject.ParamSpec,
self: *App,
) callconv(.C) void {
) callconv(.c) void {
const color_scheme: apprt.ColorScheme = if (style_manager.getDark() == 0)
.light
else

View File

@ -18,88 +18,37 @@ pub fn init(
/// The minor version of the minimum Adwaita version that is required to use
/// this resource.
comptime minor: u16,
/// `blp` signifies that the resource is a Blueprint that has been compiled
/// to GTK Builder XML at compile time. `ui` signifies that the resource is
/// a GTK Builder XML file that is included in the Ghostty source (perhaps
/// because the Blueprint compiler on some target platforms cannot compile a
/// Blueprint that generates the necessary resources).
comptime kind: enum { blp, ui },
) Builder {
const resource_path = comptime resource_path: {
const gresource = @import("gresource.zig");
switch (kind) {
.blp => {
// Check to make sure that our file is listed as a
// `blueprint_file` in `gresource.zig`. If it isn't Ghostty
// could crash at runtime when we try and load a nonexistent
// GResource.
for (gresource.blueprint_files) |file| {
if (major != file.major or minor != file.minor or !std.mem.eql(u8, file.name, name)) continue;
// Use @embedFile to make sure that the `.blp` file exists
// at compile time. Zig _should_ discard the data so that
// it doesn't end up in the final executable. At runtime we
// will load the data from a GResource.
const blp_filename = std.fmt.comptimePrint(
"ui/{d}.{d}/{s}.blp",
.{
file.major,
file.minor,
file.name,
},
);
_ = @embedFile(blp_filename);
break :resource_path std.fmt.comptimePrint(
"/com/mitchellh/ghostty/ui/{d}.{d}/{s}.ui",
.{
file.major,
file.minor,
file.name,
},
);
} else @compileError("missing blueprint file '" ++ name ++ "' in gresource.zig");
},
.ui => {
// Check to make sure that our file is listed as a `ui_file` in
// `gresource.zig`. If it isn't Ghostty could crash at runtime
// when we try and load a nonexistent GResource.
for (gresource.ui_files) |file| {
if (major != file.major or minor != file.minor or !std.mem.eql(u8, file.name, name)) continue;
// Use @embedFile to make sure that the `.ui` file exists
// at compile time. Zig _should_ discard the data so that
// it doesn't end up in the final executable. At runtime we
// will load the data from a GResource.
const ui_filename = std.fmt.comptimePrint(
"ui/{d}.{d}/{s}.ui",
.{
file.major,
file.minor,
file.name,
},
);
_ = @embedFile(ui_filename);
// Also use @embedFile to make sure that a matching `.blp`
// file exists at compile time. Zig _should_ discard the
// data so that it doesn't end up in the final executable.
const blp_filename = std.fmt.comptimePrint(
"ui/{d}.{d}/{s}.blp",
.{
file.major,
file.minor,
file.name,
},
);
_ = @embedFile(blp_filename);
break :resource_path std.fmt.comptimePrint(
"/com/mitchellh/ghostty/ui/{d}.{d}/{s}.ui",
.{
file.major,
file.minor,
file.name,
},
);
} else @compileError("missing ui file '" ++ name ++ "' in gresource.zig");
},
}
// Check to make sure that our file is listed as a
// `blueprint_file` in `gresource.zig`. If it isn't Ghostty
// could crash at runtime when we try and load a nonexistent
// GResource.
for (gresource.blueprint_files) |file| {
if (major != file.major or minor != file.minor or !std.mem.eql(u8, file.name, name)) continue;
// Use @embedFile to make sure that the `.blp` file exists
// at compile time. Zig _should_ discard the data so that
// it doesn't end up in the final executable. At runtime we
// will load the data from a GResource.
const blp_filename = std.fmt.comptimePrint(
"ui/{d}.{d}/{s}.blp",
.{
file.major,
file.minor,
file.name,
},
);
_ = @embedFile(blp_filename);
break :resource_path std.fmt.comptimePrint(
"/com/mitchellh/ghostty/ui/{d}.{d}/{s}.ui",
.{
file.major,
file.minor,
file.name,
},
);
} else @compileError("missing blueprint file '" ++ name ++ "' in gresource.zig");
};
return .{

View File

@ -71,14 +71,14 @@ fn init(
) !void {
var builder = switch (DialogType) {
adw.AlertDialog => switch (request) {
.osc_52_read => Builder.init("ccw-osc-52-read", 1, 5, .blp),
.osc_52_write => Builder.init("ccw-osc-52-write", 1, 5, .blp),
.paste => Builder.init("ccw-paste", 1, 5, .blp),
.osc_52_read => Builder.init("ccw-osc-52-read", 1, 5),
.osc_52_write => Builder.init("ccw-osc-52-write", 1, 5),
.paste => Builder.init("ccw-paste", 1, 5),
},
adw.MessageDialog => switch (request) {
.osc_52_read => Builder.init("ccw-osc-52-read", 1, 2, .ui),
.osc_52_write => Builder.init("ccw-osc-52-write", 1, 2, .ui),
.paste => Builder.init("ccw-paste", 1, 2, .ui),
.osc_52_read => Builder.init("ccw-osc-52-read", 1, 2),
.osc_52_write => Builder.init("ccw-osc-52-write", 1, 2),
.paste => Builder.init("ccw-paste", 1, 2),
},
else => unreachable,
};
@ -152,7 +152,7 @@ fn init(
}
}
fn gtkResponse(_: *DialogType, response: [*:0]u8, self: *ClipboardConfirmation) callconv(.C) void {
fn gtkResponse(_: *DialogType, response: [*:0]u8, self: *ClipboardConfirmation) callconv(.c) void {
if (std.mem.orderZ(u8, response, "ok") == .eq) {
self.core_surface.completeClipboardRequest(
self.pending_req,
@ -165,7 +165,7 @@ fn gtkResponse(_: *DialogType, response: [*:0]u8, self: *ClipboardConfirmation)
self.destroy();
}
fn gtkRevealButtonClicked(_: *gtk.Button, self: *ClipboardConfirmation) callconv(.C) void {
fn gtkRevealButtonClicked(_: *gtk.Button, self: *ClipboardConfirmation) callconv(.c) void {
self.text_view_scroll.as(gtk.Widget).setSensitive(@intFromBool(true));
self.text_view.as(gtk.Widget).removeCssClass("blurred");
@ -173,7 +173,7 @@ fn gtkRevealButtonClicked(_: *gtk.Button, self: *ClipboardConfirmation) callconv
self.reveal_button.as(gtk.Widget).setVisible(@intFromBool(false));
}
fn gtkHideButtonClicked(_: *gtk.Button, self: *ClipboardConfirmation) callconv(.C) void {
fn gtkHideButtonClicked(_: *gtk.Button, self: *ClipboardConfirmation) callconv(.c) void {
self.text_view_scroll.as(gtk.Widget).setSensitive(@intFromBool(false));
self.text_view.as(gtk.Widget).addCssClass("blurred");

View File

@ -64,7 +64,7 @@ fn responseCallback(
_: *DialogType,
response: [*:0]const u8,
target: *Target,
) callconv(.C) void {
) callconv(.c) void {
const alloc = target.allocator();
defer alloc.destroy(target);
@ -141,7 +141,7 @@ pub const Target = union(enum) {
}
};
fn findActiveWindow(data: ?*const anyopaque, _: ?*const anyopaque) callconv(.C) c_int {
fn findActiveWindow(data: ?*const anyopaque, _: ?*const anyopaque) callconv(.c) c_int {
const window: *gtk.Window = @ptrCast(@alignCast(@constCast(data orelse return -1)));
// Confusingly, `isActive` returns 1 when active,

View File

@ -30,8 +30,8 @@ pub fn maybePresent(app: *App, window: ?*Window) void {
if (app.config._diagnostics.empty()) return;
var builder = switch (DialogType) {
adw.AlertDialog => Builder.init("config-errors-dialog", 1, 5, .blp),
adw.MessageDialog => Builder.init("config-errors-dialog", 1, 2, .ui),
adw.AlertDialog => Builder.init("config-errors-dialog", 1, 5),
adw.MessageDialog => Builder.init("config-errors-dialog", 1, 2),
else => unreachable,
};
defer builder.deinit();
@ -67,7 +67,7 @@ pub fn maybePresent(app: *App, window: ?*Window) void {
}
}
fn onResponse(_: *DialogType, response: [*:0]const u8, app: *App) callconv(.C) void {
fn onResponse(_: *DialogType, response: [*:0]const u8, app: *App) callconv(.c) void {
if (std.mem.orderZ(u8, response, "reload") == .eq) {
app.reloadConfig(.app, .{}) catch |err| {
log.warn("error reloading config error={}", .{err});

View File

@ -221,12 +221,12 @@ fn translateMouseButton(button: c_uint) ?c_int {
};
}
fn gtkDestroy(_: *gtk.GLArea, self: *ImguiWidget) callconv(.C) void {
fn gtkDestroy(_: *gtk.GLArea, self: *ImguiWidget) callconv(.c) void {
log.debug("imgui widget destroy", .{});
self.deinit();
}
fn gtkRealize(area: *gtk.GLArea, self: *ImguiWidget) callconv(.C) void {
fn gtkRealize(area: *gtk.GLArea, self: *ImguiWidget) callconv(.c) void {
log.debug("gl surface realized", .{});
// We need to make the context current so we can call GL functions.
@ -242,7 +242,7 @@ fn gtkRealize(area: *gtk.GLArea, self: *ImguiWidget) callconv(.C) void {
_ = cimgui.ImGui_ImplOpenGL3_Init(null);
}
fn gtkUnrealize(area: *gtk.GLArea, self: *ImguiWidget) callconv(.C) void {
fn gtkUnrealize(area: *gtk.GLArea, self: *ImguiWidget) callconv(.c) void {
_ = area;
log.debug("gl surface unrealized", .{});
@ -250,7 +250,7 @@ fn gtkUnrealize(area: *gtk.GLArea, self: *ImguiWidget) callconv(.C) void {
cimgui.ImGui_ImplOpenGL3_Shutdown();
}
fn gtkResize(area: *gtk.GLArea, width: c_int, height: c_int, self: *ImguiWidget) callconv(.C) void {
fn gtkResize(area: *gtk.GLArea, width: c_int, height: c_int, self: *ImguiWidget) callconv(.c) void {
cimgui.c.igSetCurrentContext(self.ig_ctx);
const io: *cimgui.c.ImGuiIO = cimgui.c.igGetIO();
const scale_factor = area.as(gtk.Widget).getScaleFactor();
@ -273,7 +273,7 @@ fn gtkResize(area: *gtk.GLArea, width: c_int, height: c_int, self: *ImguiWidget)
active_style.* = style.*;
}
fn gtkRender(_: *gtk.GLArea, _: *gdk.GLContext, self: *ImguiWidget) callconv(.C) c_int {
fn gtkRender(_: *gtk.GLArea, _: *gdk.GLContext, self: *ImguiWidget) callconv(.c) c_int {
cimgui.c.igSetCurrentContext(self.ig_ctx);
// Setup our frame. We render twice because some ImGui behaviors
@ -307,7 +307,7 @@ fn gtkMouseMotion(
x: f64,
y: f64,
self: *ImguiWidget,
) callconv(.C) void {
) callconv(.c) void {
cimgui.c.igSetCurrentContext(self.ig_ctx);
const io: *cimgui.c.ImGuiIO = cimgui.c.igGetIO();
const scale_factor: f64 = @floatFromInt(self.gl_area.as(gtk.Widget).getScaleFactor());
@ -325,7 +325,7 @@ fn gtkMouseDown(
_: f64,
_: f64,
self: *ImguiWidget,
) callconv(.C) void {
) callconv(.c) void {
self.queueRender();
cimgui.c.igSetCurrentContext(self.ig_ctx);
@ -343,7 +343,7 @@ fn gtkMouseUp(
_: f64,
_: f64,
self: *ImguiWidget,
) callconv(.C) void {
) callconv(.c) void {
self.queueRender();
cimgui.c.igSetCurrentContext(self.ig_ctx);
@ -359,7 +359,7 @@ fn gtkMouseScroll(
x: f64,
y: f64,
self: *ImguiWidget,
) callconv(.C) c_int {
) callconv(.c) c_int {
self.queueRender();
cimgui.c.igSetCurrentContext(self.ig_ctx);
@ -373,7 +373,7 @@ fn gtkMouseScroll(
return @intFromBool(true);
}
fn gtkFocusEnter(_: *gtk.EventControllerFocus, self: *ImguiWidget) callconv(.C) void {
fn gtkFocusEnter(_: *gtk.EventControllerFocus, self: *ImguiWidget) callconv(.c) void {
self.queueRender();
cimgui.c.igSetCurrentContext(self.ig_ctx);
@ -381,7 +381,7 @@ fn gtkFocusEnter(_: *gtk.EventControllerFocus, self: *ImguiWidget) callconv(.C)
cimgui.c.ImGuiIO_AddFocusEvent(io, true);
}
fn gtkFocusLeave(_: *gtk.EventControllerFocus, self: *ImguiWidget) callconv(.C) void {
fn gtkFocusLeave(_: *gtk.EventControllerFocus, self: *ImguiWidget) callconv(.c) void {
self.queueRender();
cimgui.c.igSetCurrentContext(self.ig_ctx);
@ -393,7 +393,7 @@ fn gtkInputCommit(
_: *gtk.IMMulticontext,
bytes: [*:0]u8,
self: *ImguiWidget,
) callconv(.C) void {
) callconv(.c) void {
self.queueRender();
cimgui.c.igSetCurrentContext(self.ig_ctx);
@ -407,7 +407,7 @@ fn gtkKeyPressed(
keycode: c_uint,
gtk_mods: gdk.ModifierType,
self: *ImguiWidget,
) callconv(.C) c_int {
) callconv(.c) c_int {
return @intFromBool(self.keyEvent(
.press,
ec_key,
@ -423,7 +423,7 @@ fn gtkKeyReleased(
keycode: c_uint,
gtk_mods: gdk.ModifierType,
self: *ImguiWidget,
) callconv(.C) void {
) callconv(.c) void {
_ = self.keyEvent(
.release,
ec_key,

View File

@ -104,7 +104,7 @@ pub fn maybeShow(self: *ResizeOverlay) void {
/// Actually update the overlay widget. This should only be called from a GTK
/// idle handler.
fn gtkUpdate(ud: ?*anyopaque) callconv(.C) c_int {
fn gtkUpdate(ud: ?*anyopaque) callconv(.c) c_int {
const self: *ResizeOverlay = @ptrCast(@alignCast(ud orelse return 0));
// No matter what our idler is complete with this callback
@ -198,7 +198,7 @@ fn setPosition(label: *gtk.Label, config: *DerivedConfig) void {
/// If this fires, it means that the delay period has expired and the resize
/// overlay widget should be hidden.
fn gtkTimerExpired(ud: ?*anyopaque) callconv(.C) c_int {
fn gtkTimerExpired(ud: ?*anyopaque) callconv(.c) c_int {
const self: *ResizeOverlay = @ptrCast(@alignCast(ud orelse return 0));
self.timer = null;
if (self.label) |label| hide(label);

View File

@ -1025,7 +1025,7 @@ pub fn setTitle(self: *Surface, slice: [:0]const u8, source: SetTitleSource) !vo
self.update_title_timer = glib.timeoutAdd(75, updateTitleTimerExpired, self);
}
fn updateTitleTimerExpired(ud: ?*anyopaque) callconv(.C) c_int {
fn updateTitleTimerExpired(ud: ?*anyopaque) callconv(.c) c_int {
const self: *Surface = @ptrCast(@alignCast(ud.?));
self.updateTitleLabels();
@ -1061,7 +1061,7 @@ pub fn promptTitle(self: *Surface) !void {
if (!adw_version.atLeast(1, 5, 0)) return;
const window = self.container.window() orelse return;
var builder = Builder.init("prompt-title-dialog", 1, 5, .blp);
var builder = Builder.init("prompt-title-dialog", 1, 5);
defer builder.deinit();
const entry = builder.getObject(gtk.Entry, "title_entry").?;
@ -1265,7 +1265,7 @@ fn gtkClipboardRead(
source: ?*gobject.Object,
res: *gio.AsyncResult,
ud: ?*anyopaque,
) callconv(.C) void {
) callconv(.c) void {
const clipboard = gobject.ext.cast(gdk.Clipboard, source orelse return) orelse return;
const req: *ClipboardRequest = @ptrCast(@alignCast(ud orelse return));
const self = req.self;
@ -1349,7 +1349,7 @@ pub fn showDesktopNotification(
app.sendNotification(body.ptr, notification);
}
fn gtkRealize(gl_area: *gtk.GLArea, self: *Surface) callconv(.C) void {
fn gtkRealize(gl_area: *gtk.GLArea, self: *Surface) callconv(.c) void {
log.debug("gl surface realized", .{});
// We need to make the context current so we can call GL functions.
@ -1377,7 +1377,7 @@ fn gtkRealize(gl_area: *gtk.GLArea, self: *Surface) callconv(.C) void {
/// This is called when the underlying OpenGL resources must be released.
/// This is usually due to the OpenGL area changing GDK surfaces.
fn gtkUnrealize(gl_area: *gtk.GLArea, self: *Surface) callconv(.C) void {
fn gtkUnrealize(gl_area: *gtk.GLArea, self: *Surface) callconv(.c) void {
log.debug("gl surface unrealized", .{});
// See gtkRealize for why we do this here.
@ -1405,7 +1405,7 @@ fn gtkUnrealize(gl_area: *gtk.GLArea, self: *Surface) callconv(.C) void {
}
/// render signal
fn gtkRender(_: *gtk.GLArea, _: *gdk.GLContext, self: *Surface) callconv(.C) c_int {
fn gtkRender(_: *gtk.GLArea, _: *gdk.GLContext, self: *Surface) callconv(.c) c_int {
self.render() catch |err| {
log.err("surface failed to render: {}", .{err});
return 0;
@ -1415,7 +1415,7 @@ fn gtkRender(_: *gtk.GLArea, _: *gdk.GLContext, self: *Surface) callconv(.C) c_i
}
/// resize signal
fn gtkResize(gl_area: *gtk.GLArea, width: c_int, height: c_int, self: *Surface) callconv(.C) void {
fn gtkResize(gl_area: *gtk.GLArea, width: c_int, height: c_int, self: *Surface) callconv(.c) void {
// Some debug output to help understand what GTK is telling us.
{
const scale_factor = scale: {
@ -1471,7 +1471,7 @@ fn gtkResize(gl_area: *gtk.GLArea, width: c_int, height: c_int, self: *Surface)
}
/// "destroy" signal for surface
fn gtkDestroy(_: *gtk.GLArea, self: *Surface) callconv(.C) void {
fn gtkDestroy(_: *gtk.GLArea, self: *Surface) callconv(.c) void {
log.debug("gl destroy", .{});
const alloc = self.app.core_app.alloc;
@ -1505,7 +1505,7 @@ fn gtkMouseDown(
x: f64,
y: f64,
self: *Surface,
) callconv(.C) void {
) callconv(.c) void {
const event = gesture.as(gtk.EventController).getCurrentEvent() orelse return;
const gtk_mods = event.getModifierState();
@ -1538,7 +1538,7 @@ fn gtkMouseUp(
_: f64,
_: f64,
self: *Surface,
) callconv(.C) void {
) callconv(.c) void {
const event = gesture.as(gtk.EventController).getCurrentEvent() orelse return;
const gtk_mods = event.getModifierState();
@ -1557,7 +1557,7 @@ fn gtkMouseMotion(
x: f64,
y: f64,
self: *Surface,
) callconv(.C) void {
) callconv(.c) void {
const event = ec.as(gtk.EventController).getCurrentEvent() orelse return;
const scaled = self.scaledCoordinates(x, y);
@ -1603,7 +1603,7 @@ fn gtkMouseMotion(
fn gtkMouseLeave(
ec_motion: *gtk.EventControllerMotion,
self: *Surface,
) callconv(.C) void {
) callconv(.c) void {
const event = ec_motion.as(gtk.EventController).getCurrentEvent() orelse return;
// Get our modifiers
@ -1618,14 +1618,14 @@ fn gtkMouseLeave(
fn gtkMouseScrollPrecisionBegin(
_: *gtk.EventControllerScroll,
self: *Surface,
) callconv(.C) void {
) callconv(.c) void {
self.precision_scroll = true;
}
fn gtkMouseScrollPrecisionEnd(
_: *gtk.EventControllerScroll,
self: *Surface,
) callconv(.C) void {
) callconv(.c) void {
self.precision_scroll = false;
}
@ -1634,7 +1634,7 @@ fn gtkMouseScroll(
x: f64,
y: f64,
self: *Surface,
) callconv(.C) c_int {
) callconv(.c) c_int {
const scaled = self.scaledCoordinates(x, y);
// GTK doesn't support any of the scroll mods.
@ -1664,7 +1664,7 @@ fn gtkKeyPressed(
keycode: c_uint,
gtk_mods: gdk.ModifierType,
self: *Surface,
) callconv(.C) c_int {
) callconv(.c) c_int {
return @intFromBool(self.keyEvent(
.press,
ec_key,
@ -1680,7 +1680,7 @@ fn gtkKeyReleased(
keycode: c_uint,
state: gdk.ModifierType,
self: *Surface,
) callconv(.C) void {
) callconv(.c) void {
_ = self.keyEvent(
.release,
ec_key,
@ -1971,7 +1971,7 @@ pub fn keyEvent(
fn gtkInputPreeditStart(
_: *gtk.IMMulticontext,
self: *Surface,
) callconv(.C) void {
) callconv(.c) void {
// log.warn("GTKIM: preedit start", .{});
// Start our composing state for the input method and reset our
@ -1983,7 +1983,7 @@ fn gtkInputPreeditStart(
fn gtkInputPreeditChanged(
ctx: *gtk.IMMulticontext,
self: *Surface,
) callconv(.C) void {
) callconv(.c) void {
// Any preedit change should mark that we're composing. Its possible this
// is false using fcitx5-hangul and typing "dkssud<space>" ("안녕"). The
// second "s" results in a "commit" for "" which sets composing to false,
@ -2009,7 +2009,7 @@ fn gtkInputPreeditChanged(
fn gtkInputPreeditEnd(
_: *gtk.IMMulticontext,
self: *Surface,
) callconv(.C) void {
) callconv(.c) void {
// log.warn("GTKIM: preedit end", .{});
// End our composing state for GTK, allowing us to commit the text.
@ -2025,7 +2025,7 @@ fn gtkInputCommit(
_: *gtk.IMMulticontext,
bytes: [*:0]u8,
self: *Surface,
) callconv(.C) void {
) callconv(.c) void {
const str = std.mem.sliceTo(bytes, 0);
// log.debug("GTKIM: input commit composing={} keyevent={} str={s}", .{
@ -2100,7 +2100,7 @@ fn gtkInputCommit(
};
}
fn gtkFocusEnter(_: *gtk.EventControllerFocus, self: *Surface) callconv(.C) void {
fn gtkFocusEnter(_: *gtk.EventControllerFocus, self: *Surface) callconv(.c) void {
if (!self.realized) return;
// Notify our IM context
@ -2125,7 +2125,7 @@ fn gtkFocusEnter(_: *gtk.EventControllerFocus, self: *Surface) callconv(.C) void
};
}
fn gtkFocusLeave(_: *gtk.EventControllerFocus, self: *Surface) callconv(.C) void {
fn gtkFocusLeave(_: *gtk.EventControllerFocus, self: *Surface) callconv(.c) void {
if (!self.realized) return;
// Notify our IM context
@ -2243,7 +2243,7 @@ fn gtkDrop(
_: f64,
_: f64,
self: *Surface,
) callconv(.C) c_int {
) callconv(.c) c_int {
const alloc = self.app.core_app.alloc;
if (g_value_holds(value, gdk.FileList.getGObjectType())) {
@ -2395,7 +2395,7 @@ fn g_value_holds(value_: ?*gobject.Value, g_type: gobject.Type) bool {
return false;
}
fn gtkPromptTitleResponse(source_object: ?*gobject.Object, result: *gio.AsyncResult, ud: ?*anyopaque) callconv(.C) void {
fn gtkPromptTitleResponse(source_object: ?*gobject.Object, result: *gio.AsyncResult, ud: ?*anyopaque) callconv(.c) void {
if (!adw_version.supportsDialogs()) return;
const dialog = gobject.ext.cast(adw.AlertDialog, source_object.?).?;
const self: *Surface = @ptrCast(@alignCast(ud));

View File

@ -161,7 +161,7 @@ pub fn closeWithConfirmation(tab: *Tab) void {
}
}
fn gtkDestroy(_: *gtk.Box, self: *Tab) callconv(.C) void {
fn gtkDestroy(_: *gtk.Box, self: *Tab) callconv(.c) void {
log.debug("tab box destroy", .{});
const alloc = self.window.app.core_app.alloc;

View File

@ -227,7 +227,7 @@ pub fn createWindow(window: *Window) !*Window {
return new_window;
}
fn adwPageAttached(_: *adw.TabView, page: *adw.TabPage, _: c_int, self: *TabView) callconv(.C) void {
fn adwPageAttached(_: *adw.TabView, page: *adw.TabPage, _: c_int, self: *TabView) callconv(.c) void {
const child = page.getChild().as(gobject.Object);
const tab: *Tab = @ptrCast(@alignCast(child.getData(Tab.GHOSTTY_TAB) orelse return));
tab.window = self.window;
@ -239,7 +239,7 @@ fn adwClosePage(
_: *adw.TabView,
page: *adw.TabPage,
self: *TabView,
) callconv(.C) c_int {
) callconv(.c) c_int {
const child = page.getChild().as(gobject.Object);
const tab: *Tab = @ptrCast(@alignCast(child.getData(Tab.GHOSTTY_TAB) orelse return 0));
self.tab_view.closePageFinish(page, @intFromBool(self.forcing_close));
@ -251,7 +251,7 @@ fn adwClosePage(
fn adwTabViewCreateWindow(
_: *adw.TabView,
self: *TabView,
) callconv(.C) ?*adw.TabView {
) callconv(.c) ?*adw.TabView {
const window = createWindow(self.window) catch |err| {
log.warn("error creating new window error={}", .{err});
return null;
@ -259,7 +259,7 @@ fn adwTabViewCreateWindow(
return window.notebook.tab_view;
}
fn adwSelectPage(_: *adw.TabView, _: *gobject.ParamSpec, self: *TabView) callconv(.C) void {
fn adwSelectPage(_: *adw.TabView, _: *gobject.ParamSpec, self: *TabView) callconv(.c) void {
const page = self.tab_view.getSelectedPage() orelse return;
// If the tab was previously marked as needing attention

View File

@ -101,7 +101,7 @@ fn gtkLeftEnter(
_: f64,
_: f64,
right: *gtk.Label,
) callconv(.C) void {
) callconv(.c) void {
right.as(gtk.Widget).removeCssClass("hidden");
}
@ -110,6 +110,6 @@ fn gtkLeftEnter(
fn gtkLeftLeave(
_: *gtk.EventControllerMotion,
right: *gtk.Label,
) callconv(.C) void {
) callconv(.c) void {
right.as(gtk.Widget).addCssClass("hidden");
}

View File

@ -25,6 +25,7 @@ const input = @import("../../input.zig");
const CoreSurface = @import("../../Surface.zig");
const App = @import("App.zig");
const Builder = @import("Builder.zig");
const Color = configpkg.Config.Color;
const Surface = @import("Surface.zig");
const Menu = @import("menu.zig").Menu;
@ -242,12 +243,19 @@ pub fn init(self: *Window, app: *App) !void {
}
{
const btn = gtk.Button.newFromIconName("tab-new-symbolic");
const btn = adw.SplitButton.new();
btn.setIconName("tab-new-symbolic");
btn.as(gtk.Widget).setTooltipText(i18n._("New Tab"));
_ = gtk.Button.signals.clicked.connect(
btn.setDropdownTooltip(i18n._("New Split"));
var builder = Builder.init("menu-headerbar-split_menu", 1, 0);
defer builder.deinit();
btn.setMenuModel(builder.getObject(gio.MenuModel, "menu"));
_ = adw.SplitButton.signals.clicked.connect(
btn,
*Window,
gtkTabNewClick,
adwNewTabClick,
self,
.{},
);
@ -784,7 +792,7 @@ fn gtkWindowNotifyIsActive(
_: *adw.ApplicationWindow,
_: *gobject.ParamSpec,
self: *Window,
) callconv(.C) void {
) callconv(.c) void {
if (!self.isQuickTerminal()) return;
// Hide when we're unfocused
@ -824,6 +832,11 @@ fn gtkTabNewClick(_: *gtk.Button, self: *Window) callconv(.c) void {
self.performBindingAction(.{ .new_tab = {} });
}
/// Create a new surface (tab or split).
fn adwNewTabClick(_: *adw.SplitButton, self: *Window) callconv(.c) void {
self.performBindingAction(.{ .new_tab = {} });
}
/// Create a new tab from the AdwTabOverview. We can't copy gtkTabNewClick
/// because we need to return an AdwTabPage from this function.
fn gtkNewTabFromOverview(_: *adw.TabOverview, self: *Window) callconv(.c) *adw.TabPage {
@ -870,7 +883,7 @@ fn adwTabOverviewOpen(
fn adwTabOverviewFocusTimer(
ud: ?*anyopaque,
) callconv(.C) c_int {
) callconv(.c) c_int {
if (!adw_version.supportsTabOverview()) unreachable;
const self: *Window = @ptrCast(@alignCast(ud orelse return 0));
self.adw_tab_overview_focus_timer = null;
@ -957,7 +970,7 @@ fn gtkActionAbout(
_: *gio.SimpleAction,
_: ?*glib.Variant,
self: *Window,
) callconv(.C) void {
) callconv(.c) void {
const name = "Ghostty";
const icon = "com.mitchellh.ghostty";
const website = "https://ghostty.org";
@ -1001,7 +1014,7 @@ fn gtkActionClose(
_: *gio.SimpleAction,
_: ?*glib.Variant,
self: *Window,
) callconv(.C) void {
) callconv(.c) void {
self.closeWithConfirmation();
}
@ -1009,7 +1022,7 @@ fn gtkActionNewWindow(
_: *gio.SimpleAction,
_: ?*glib.Variant,
self: *Window,
) callconv(.C) void {
) callconv(.c) void {
self.performBindingAction(.{ .new_window = {} });
}
@ -1017,7 +1030,7 @@ fn gtkActionNewTab(
_: *gio.SimpleAction,
_: ?*glib.Variant,
self: *Window,
) callconv(.C) void {
) callconv(.c) void {
self.performBindingAction(.{ .new_tab = {} });
}
@ -1025,7 +1038,7 @@ fn gtkActionCloseTab(
_: *gio.SimpleAction,
_: ?*glib.Variant,
self: *Window,
) callconv(.C) void {
) callconv(.c) void {
self.performBindingAction(.{ .close_tab = {} });
}
@ -1033,7 +1046,7 @@ fn gtkActionSplitRight(
_: *gio.SimpleAction,
_: ?*glib.Variant,
self: *Window,
) callconv(.C) void {
) callconv(.c) void {
self.performBindingAction(.{ .new_split = .right });
}
@ -1041,7 +1054,7 @@ fn gtkActionSplitDown(
_: *gio.SimpleAction,
_: ?*glib.Variant,
self: *Window,
) callconv(.C) void {
) callconv(.c) void {
self.performBindingAction(.{ .new_split = .down });
}
@ -1049,7 +1062,7 @@ fn gtkActionSplitLeft(
_: *gio.SimpleAction,
_: ?*glib.Variant,
self: *Window,
) callconv(.C) void {
) callconv(.c) void {
self.performBindingAction(.{ .new_split = .left });
}
@ -1057,15 +1070,15 @@ fn gtkActionSplitUp(
_: *gio.SimpleAction,
_: ?*glib.Variant,
self: *Window,
) callconv(.C) void {
self.performBindingAction(.{ .new_split = .right });
) callconv(.c) void {
self.performBindingAction(.{ .new_split = .up });
}
fn gtkActionToggleInspector(
_: *gio.SimpleAction,
_: ?*glib.Variant,
self: *Window,
) callconv(.C) void {
) callconv(.c) void {
self.performBindingAction(.{ .inspector = .toggle });
}
@ -1073,7 +1086,7 @@ fn gtkActionCopy(
_: *gio.SimpleAction,
_: ?*glib.Variant,
self: *Window,
) callconv(.C) void {
) callconv(.c) void {
self.performBindingAction(.{ .copy_to_clipboard = {} });
}
@ -1081,7 +1094,7 @@ fn gtkActionPaste(
_: *gio.SimpleAction,
_: ?*glib.Variant,
self: *Window,
) callconv(.C) void {
) callconv(.c) void {
self.performBindingAction(.{ .paste_from_clipboard = {} });
}
@ -1089,7 +1102,7 @@ fn gtkActionReset(
_: *gio.SimpleAction,
_: ?*glib.Variant,
self: *Window,
) callconv(.C) void {
) callconv(.c) void {
self.performBindingAction(.{ .reset = {} });
}
@ -1097,7 +1110,7 @@ fn gtkActionClear(
_: *gio.SimpleAction,
_: ?*glib.Variant,
self: *Window,
) callconv(.C) void {
) callconv(.c) void {
self.performBindingAction(.{ .clear_screen = {} });
}
@ -1105,7 +1118,7 @@ fn gtkActionPromptTitle(
_: *gio.SimpleAction,
_: ?*glib.Variant,
self: *Window,
) callconv(.C) void {
) callconv(.c) void {
self.performBindingAction(.{ .prompt_surface_title = {} });
}
@ -1120,7 +1133,7 @@ fn gtkTitlebarMenuActivate(
btn: *gtk.MenuButton,
_: *gobject.ParamSpec,
self: *Window,
) callconv(.C) void {
) callconv(.c) void {
// debian 12 is stuck on GTK 4.8
if (!gtk_version.atLeast(4, 10, 0)) return;
const active = btn.getActive() != 0;

View File

@ -4,62 +4,157 @@ pub const c = @cImport({
@cInclude("adwaita.h");
});
const adwaita_version = std.SemanticVersion{
.major = c.ADW_MAJOR_VERSION,
.minor = c.ADW_MINOR_VERSION,
.patch = c.ADW_MICRO_VERSION,
};
const required_blueprint_version = std.SemanticVersion{
.major = 0,
.minor = 16,
.patch = 0,
};
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
const alloc = gpa.allocator();
var debug_allocator: std.heap.DebugAllocator(.{}) = .init;
defer _ = debug_allocator.deinit();
const alloc = debug_allocator.allocator();
var it = try std.process.argsWithAllocator(alloc);
defer it.deinit();
_ = it.next();
const major = try std.fmt.parseUnsigned(u8, it.next() orelse return error.NoMajorVersion, 10);
const minor = try std.fmt.parseUnsigned(u8, it.next() orelse return error.NoMinorVersion, 10);
const required_adwaita_version = std.SemanticVersion{
.major = try std.fmt.parseUnsigned(u8, it.next() orelse return error.NoMajorVersion, 10),
.minor = try std.fmt.parseUnsigned(u8, it.next() orelse return error.NoMinorVersion, 10),
.patch = 0,
};
const output = it.next() orelse return error.NoOutput;
const input = it.next() orelse return error.NoInput;
if (c.ADW_MAJOR_VERSION < major or (c.ADW_MAJOR_VERSION == major and c.ADW_MINOR_VERSION < minor)) {
// If the Adwaita version is too old, generate an "empty" file.
const file = try std.fs.createFileAbsolute(output, .{
.truncate = true,
});
try file.writeAll(
\\<?xml version="1.0" encoding="UTF-8"?>
\\<interface domain="com.mitchellh.ghostty"/>
);
defer file.close();
return;
if (adwaita_version.order(required_adwaita_version) == .lt) {
std.debug.print(
\\`libadwaita` is too old.
\\
\\Ghostty requires a version {} or newer of `libadwaita` to
\\compile this blueprint. Please install it, ensure that it is
\\available on your PATH, and then retry building Ghostty.
, .{required_adwaita_version});
std.posix.exit(1);
}
var compiler = std.process.Child.init(
&.{
"blueprint-compiler",
"compile",
"--output",
output,
input,
},
alloc,
);
{
var stdout: std.ArrayListUnmanaged(u8) = .empty;
defer stdout.deinit(alloc);
var stderr: std.ArrayListUnmanaged(u8) = .empty;
defer stderr.deinit(alloc);
const term = compiler.spawnAndWait() catch |err| switch (err) {
error.FileNotFound => {
std.log.err(
\\`blueprint-compiler` not found.
var blueprint_compiler = std.process.Child.init(
&.{
"blueprint-compiler",
"--version",
},
alloc,
);
blueprint_compiler.stdout_behavior = .Pipe;
blueprint_compiler.stderr_behavior = .Pipe;
try blueprint_compiler.spawn();
try blueprint_compiler.collectOutput(
alloc,
&stdout,
&stderr,
std.math.maxInt(u16),
);
const term = blueprint_compiler.wait() catch |err| switch (err) {
error.FileNotFound => {
std.debug.print(
\\`blueprint-compiler` not found.
\\
\\Ghostty requires version {} or newer of
\\`blueprint-compiler` as a build-time dependency starting
\\from version 1.2. Please install it, ensure that it is
\\available on your PATH, and then retry building Ghostty.
\\
, .{required_blueprint_version});
std.posix.exit(1);
},
else => return err,
};
switch (term) {
.Exited => |rc| {
if (rc != 0) std.process.exit(1);
},
else => std.process.exit(1),
}
const version = try std.SemanticVersion.parse(std.mem.trim(u8, stdout.items, &std.ascii.whitespace));
if (version.order(required_blueprint_version) == .lt) {
std.debug.print(
\\`blueprint-compiler` is the wrong version.
\\
\\Ghostty requires `blueprint-compiler` as a build-time dependency starting from version 1.2.
\\Please install it, ensure that it is available on your PATH, and then retry building Ghostty.
, .{});
\\Ghostty requires version {} or newer of
\\`blueprint-compiler` as a build-time dependency starting
\\from version 1.2. Please install it, ensure that it is
\\available on your PATH, and then retry building Ghostty.
\\
, .{required_blueprint_version});
std.posix.exit(1);
},
else => return err,
};
}
}
switch (term) {
.Exited => |rc| {
if (rc != 0) std.process.exit(1);
},
else => std.process.exit(1),
{
var stdout: std.ArrayListUnmanaged(u8) = .empty;
defer stdout.deinit(alloc);
var stderr: std.ArrayListUnmanaged(u8) = .empty;
defer stderr.deinit(alloc);
var blueprint_compiler = std.process.Child.init(
&.{
"blueprint-compiler",
"compile",
"--output",
output,
input,
},
alloc,
);
blueprint_compiler.stdout_behavior = .Pipe;
blueprint_compiler.stderr_behavior = .Pipe;
try blueprint_compiler.spawn();
try blueprint_compiler.collectOutput(
alloc,
&stdout,
&stderr,
std.math.maxInt(u16),
);
const term = blueprint_compiler.wait() catch |err| switch (err) {
error.FileNotFound => {
std.debug.print(
\\`blueprint-compiler` not found.
\\
\\Ghostty requires version {} or newer of
\\`blueprint-compiler` as a build-time dependency starting
\\from version 1.2. Please install it, ensure that it is
\\available on your PATH, and then retry building Ghostty.
\\
, .{required_blueprint_version});
std.posix.exit(1);
},
else => return err,
};
switch (term) {
.Exited => |rc| {
if (rc != 0) {
std.debug.print("{s}", .{stderr.items});
std.process.exit(1);
}
},
else => {
std.debug.print("{s}", .{stderr.items});
std.process.exit(1);
},
}
}
}

View File

@ -1,32 +0,0 @@
const std = @import("std");
const build_options = @import("build_options");
const gtk = @import("gtk");
const adw = @import("adw");
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
const alloc = gpa.allocator();
const filename = filename: {
var it = try std.process.argsWithAllocator(alloc);
defer it.deinit();
_ = it.next() orelse return error.NoFilename;
break :filename try alloc.dupeZ(u8, it.next() orelse return error.NoFilename);
};
defer alloc.free(filename);
const data = try std.fs.cwd().readFileAllocOptions(alloc, filename, std.math.maxInt(u16), null, 1, 0);
defer alloc.free(data);
if (gtk.initCheck() == 0) {
std.debug.print("{s}: skipping builder check because we can't connect to display!\n", .{filename});
return;
}
adw.init();
const builder = gtk.Builder.newFromString(data.ptr, @intCast(data.len));
defer builder.unref();
}

View File

@ -53,19 +53,6 @@ const icons = [_]struct {
},
};
pub const VersionedBuilderXML = struct {
major: u16,
minor: u16,
name: []const u8,
};
pub const ui_files = [_]VersionedBuilderXML{
.{ .major = 1, .minor = 2, .name = "config-errors-dialog" },
.{ .major = 1, .minor = 2, .name = "ccw-osc-52-read" },
.{ .major = 1, .minor = 2, .name = "ccw-osc-52-write" },
.{ .major = 1, .minor = 2, .name = "ccw-paste" },
};
pub const VersionedBlueprint = struct {
major: u16,
minor: u16,
@ -75,21 +62,27 @@ pub const VersionedBlueprint = struct {
pub const blueprint_files = [_]VersionedBlueprint{
.{ .major = 1, .minor = 5, .name = "prompt-title-dialog" },
.{ .major = 1, .minor = 5, .name = "config-errors-dialog" },
.{ .major = 1, .minor = 0, .name = "menu-headerbar-split_menu" },
.{ .major = 1, .minor = 0, .name = "menu-surface-context_menu" },
.{ .major = 1, .minor = 0, .name = "menu-window-titlebar_menu" },
.{ .major = 1, .minor = 5, .name = "ccw-osc-52-read" },
.{ .major = 1, .minor = 5, .name = "ccw-osc-52-write" },
.{ .major = 1, .minor = 5, .name = "ccw-paste" },
.{ .major = 1, .minor = 2, .name = "config-errors-dialog" },
.{ .major = 1, .minor = 2, .name = "ccw-osc-52-read" },
.{ .major = 1, .minor = 2, .name = "ccw-osc-52-write" },
.{ .major = 1, .minor = 2, .name = "ccw-paste" },
};
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
const alloc = gpa.allocator();
var debug_allocator: std.heap.DebugAllocator(.{}) = .init;
defer _ = debug_allocator.deinit();
const alloc = debug_allocator.allocator();
var extra_ui_files = std.ArrayList([]const u8).init(alloc);
var extra_ui_files: std.ArrayListUnmanaged([]const u8) = .empty;
defer {
for (extra_ui_files.items) |item| alloc.free(item);
extra_ui_files.deinit();
extra_ui_files.deinit(alloc);
}
var it = try std.process.argsWithAllocator(alloc);
@ -97,7 +90,7 @@ pub fn main() !void {
while (it.next()) |argument| {
if (std.mem.eql(u8, std.fs.path.extension(argument), ".ui")) {
try extra_ui_files.append(try alloc.dupe(u8, argument));
try extra_ui_files.append(alloc, try alloc.dupe(u8, argument));
}
}
@ -131,16 +124,11 @@ pub fn main() !void {
\\ <gresource prefix="/com/mitchellh/ghostty/ui">
\\
);
for (ui_files) |ui_file| {
try writer.print(
" <file compressed=\"true\" preprocess=\"xml-stripblanks\" alias=\"{0d}.{1d}/{2s}.ui\">src/apprt/gtk/ui/{0d}.{1d}/{2s}.ui</file>\n",
.{ ui_file.major, ui_file.minor, ui_file.name },
);
}
for (extra_ui_files.items) |ui_file| {
const stem = std.fs.path.stem(ui_file);
for (blueprint_files) |file| {
if (!std.mem.eql(u8, file.name, stem)) continue;
const expected = try std.fmt.allocPrint(alloc, "/{d}.{d}/{s}.ui", .{ file.major, file.minor, file.name });
defer alloc.free(expected);
if (!std.mem.endsWith(u8, ui_file, expected)) continue;
try writer.print(
" <file compressed=\"true\" preprocess=\"xml-stripblanks\" alias=\"{d}.{d}/{s}.ui\">{s}</file>\n",
.{ file.major, file.minor, file.name, ui_file },
@ -156,7 +144,7 @@ pub fn main() !void {
}
pub const dependencies = deps: {
const total = css_files.len + icons.len + ui_files.len + blueprint_files.len;
const total = css_files.len + icons.len + blueprint_files.len;
var deps: [total][]const u8 = undefined;
var index: usize = 0;
for (css_files) |css_file| {
@ -167,14 +155,6 @@ pub const dependencies = deps: {
deps[index] = std.fmt.comptimePrint("images/icons/icon_{s}.png", .{icon.source});
index += 1;
}
for (ui_files) |ui_file| {
deps[index] = std.fmt.comptimePrint("src/apprt/gtk/ui/{d}.{d}/{s}.ui", .{
ui_file.major,
ui_file.minor,
ui_file.name,
});
index += 1;
}
for (blueprint_files) |blueprint_file| {
deps[index] = std.fmt.comptimePrint("src/apprt/gtk/ui/{d}.{d}/{s}.blp", .{
blueprint_file.major,

View File

@ -87,10 +87,23 @@ pub inline fn runtimeAtLeast(
}) != .lt;
}
pub inline fn runtimeUntil(
comptime major: u16,
comptime minor: u16,
comptime micro: u16,
) bool {
const runtime_version = getRuntimeVersion();
return runtime_version.order(.{
.major = major,
.minor = minor,
.patch = micro,
}) == .lt;
}
test "atLeast" {
const testing = std.testing;
const funs = &.{ atLeast, runtimeAtLeast };
const funs = &.{ atLeast, runtimeAtLeast, runtimeUntil };
inline for (funs) |fun| {
try testing.expect(fun(c.GTK_MAJOR_VERSION, c.GTK_MINOR_VERSION, c.GTK_MICRO_VERSION));

View File

@ -177,7 +177,7 @@ const Window = struct {
}
/// "destroy" signal for the window
fn gtkDestroy(_: *gtk.ApplicationWindow, self: *Window) callconv(.C) void {
fn gtkDestroy(_: *gtk.ApplicationWindow, self: *Window) callconv(.c) void {
log.debug("window destroy", .{});
self.deinit();
}

View File

@ -41,7 +41,7 @@ pub fn Menu(
else => unreachable,
};
var builder = Builder.init("menu-" ++ object_type ++ "-" ++ menu_name, 1, 0, .blp);
var builder = Builder.init("menu-" ++ object_type ++ "-" ++ menu_name, 1, 0);
defer builder.deinit();
const menu_model = builder.getObject(gio.MenuModel, "menu").?;
@ -130,7 +130,7 @@ pub fn Menu(
}
/// Refocus tab that lost focus because of the popover menu
fn gtkRefocusTerm(_: *gtk.PopoverMenu, self: *Self) callconv(.C) void {
fn gtkRefocusTerm(_: *gtk.PopoverMenu, self: *Self) callconv(.c) void {
const window: *Window = switch (T) {
Window => self.parent,
Surface => self.parent.container.window() orelse return,

View File

@ -0,0 +1,25 @@
using Gtk 4.0;
menu menu {
section {
item {
label: _("Split Up");
action: "win.split-up";
}
item {
label: _("Split Down");
action: "win.split-down";
}
item {
label: _("Split Left");
action: "win.split-left";
}
item {
label: _("Split Right");
action: "win.split-right";
}
}
}

View File

@ -1,77 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
DO NOT EDIT!
This file was @generated by blueprint-compiler. Instead, edit the
corresponding .blp file and regenerate this file with blueprint-compiler.
-->
<interface domain="com.mitchellh.ghostty">
<requires lib="gtk" version="4.0"/>
<object class="AdwMessageDialog" id="clipboard_confirmation_window">
<property name="heading" translatable="true">Authorize Clipboard Access</property>
<property name="body" translatable="true">An application is attempting to read from the clipboard. The current clipboard contents are shown below.</property>
<responses>
<response id="cancel" translatable="true" appearance="suggested">Deny</response>
<response id="ok" translatable="true" appearance="destructive">Allow</response>
</responses>
<property name="default-response">cancel</property>
<property name="close-response">cancel</property>
<property name="extra-child">
<object class="GtkOverlay">
<style>
<class name="osd"/>
</style>
<child>
<object class="GtkScrolledWindow" id="text_view_scroll">
<property name="width-request">500</property>
<property name="height-request">250</property>
<child>
<object class="GtkTextView" id="text_view">
<property name="cursor-visible">false</property>
<property name="editable">false</property>
<property name="monospace">true</property>
<property name="top-margin">8</property>
<property name="left-margin">8</property>
<property name="bottom-margin">8</property>
<property name="right-margin">8</property>
<style>
<class name="clipboard-content-view"/>
</style>
</object>
</child>
</object>
</child>
<child type="overlay">
<object class="GtkButton" id="reveal_button">
<property name="visible">false</property>
<property name="halign">2</property>
<property name="valign">1</property>
<property name="margin-end">12</property>
<property name="margin-top">12</property>
<child>
<object class="GtkImage">
<property name="icon-name">view-reveal-symbolic</property>
</object>
</child>
</object>
</child>
<child type="overlay">
<object class="GtkButton" id="hide_button">
<property name="visible">false</property>
<property name="halign">2</property>
<property name="valign">1</property>
<property name="margin-end">12</property>
<property name="margin-top">12</property>
<style>
<class name="opaque"/>
</style>
<child>
<object class="GtkImage">
<property name="icon-name">view-conceal-symbolic</property>
</object>
</child>
</object>
</child>
</object>
</property>
</object>
</interface>

View File

@ -1,77 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
DO NOT EDIT!
This file was @generated by blueprint-compiler. Instead, edit the
corresponding .blp file and regenerate this file with blueprint-compiler.
-->
<interface domain="com.mitchellh.ghostty">
<requires lib="gtk" version="4.0"/>
<object class="AdwMessageDialog" id="clipboard_confirmation_window">
<property name="heading" translatable="true">Authorize Clipboard Access</property>
<property name="body" translatable="true">An application is attempting to write to the clipboard. The current clipboard contents are shown below.</property>
<responses>
<response id="cancel" translatable="true" appearance="suggested">Deny</response>
<response id="ok" translatable="true" appearance="destructive">Allow</response>
</responses>
<property name="default-response">cancel</property>
<property name="close-response">cancel</property>
<property name="extra-child">
<object class="GtkOverlay">
<style>
<class name="osd"/>
</style>
<child>
<object class="GtkScrolledWindow" id="text_view_scroll">
<property name="width-request">500</property>
<property name="height-request">250</property>
<child>
<object class="GtkTextView" id="text_view">
<property name="cursor-visible">false</property>
<property name="editable">false</property>
<property name="monospace">true</property>
<property name="top-margin">8</property>
<property name="left-margin">8</property>
<property name="bottom-margin">8</property>
<property name="right-margin">8</property>
<style>
<class name="clipboard-content-view"/>
</style>
</object>
</child>
</object>
</child>
<child type="overlay">
<object class="GtkButton" id="reveal_button">
<property name="visible">false</property>
<property name="halign">2</property>
<property name="valign">1</property>
<property name="margin-end">12</property>
<property name="margin-top">12</property>
<child>
<object class="GtkImage">
<property name="icon-name">view-reveal-symbolic</property>
</object>
</child>
</object>
</child>
<child type="overlay">
<object class="GtkButton" id="hide_button">
<property name="visible">false</property>
<property name="halign">2</property>
<property name="valign">1</property>
<property name="margin-end">12</property>
<property name="margin-top">12</property>
<style>
<class name="opaque"/>
</style>
<child>
<object class="GtkImage">
<property name="icon-name">view-conceal-symbolic</property>
</object>
</child>
</object>
</child>
</object>
</property>
</object>
</interface>

View File

@ -1,77 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
DO NOT EDIT!
This file was @generated by blueprint-compiler. Instead, edit the
corresponding .blp file and regenerate this file with blueprint-compiler.
-->
<interface domain="com.mitchellh.ghostty">
<requires lib="gtk" version="4.0"/>
<object class="AdwMessageDialog" id="clipboard_confirmation_window">
<property name="heading" translatable="true">Warning: Potentially Unsafe Paste</property>
<property name="body" translatable="true">Pasting this text into the terminal may be dangerous as it looks like some commands may be executed.</property>
<responses>
<response id="cancel" translatable="true" appearance="suggested">Cancel</response>
<response id="ok" translatable="true" appearance="destructive">Paste</response>
</responses>
<property name="default-response">cancel</property>
<property name="close-response">cancel</property>
<property name="extra-child">
<object class="GtkOverlay">
<style>
<class name="osd"/>
</style>
<child>
<object class="GtkScrolledWindow" id="text_view_scroll">
<property name="width-request">500</property>
<property name="height-request">250</property>
<child>
<object class="GtkTextView" id="text_view">
<property name="cursor-visible">false</property>
<property name="editable">false</property>
<property name="monospace">true</property>
<property name="top-margin">8</property>
<property name="left-margin">8</property>
<property name="bottom-margin">8</property>
<property name="right-margin">8</property>
<style>
<class name="clipboard-content-view"/>
</style>
</object>
</child>
</object>
</child>
<child type="overlay">
<object class="GtkButton" id="reveal_button">
<property name="visible">false</property>
<property name="halign">2</property>
<property name="valign">1</property>
<property name="margin-end">12</property>
<property name="margin-top">12</property>
<child>
<object class="GtkImage">
<property name="icon-name">view-reveal-symbolic</property>
</object>
</child>
</object>
</child>
<child type="overlay">
<object class="GtkButton" id="hide_button">
<property name="visible">false</property>
<property name="halign">2</property>
<property name="valign">1</property>
<property name="margin-end">12</property>
<property name="margin-top">12</property>
<style>
<class name="opaque"/>
</style>
<child>
<object class="GtkImage">
<property name="icon-name">view-conceal-symbolic</property>
</object>
</child>
</object>
</child>
</object>
</property>
</object>
</interface>

Some files were not shown because too many files have changed in this diff Show More