mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-08-02 14:57:31 +03:00
gtk: autogenerate GTK resource file from blueprints
Fixes #6760 Remove all GTK resource definitions (`.ui` files) from the repo. Building from a git checkout requires `blueprint-compiler` version 0.16.0 at build time to compile the Blueprints (`.blp` files) into GTK resource definitions. A script (accessed by `nix run .#compile-blueprints`) is provided to compile all of the blueprints in the repository for inclusion in generated tarballs. A CI job is also added to ensure that the Blueprint files are valid and formatter properly. Workflows for tag and tip will generate source tarballs that contain generated GTK resource definitions for use on distributions that do not provide a new enough `blueprint-compiler` (I'm looking at you Debian 12). Building from generated tarballs can use the pre-generated GTK resource definitions by adding the `-fno-sys=blueprint-compiler` flag to the Zig build.
This commit is contained in:
7
.github/workflows/release-tag.yml
vendored
7
.github/workflows/release-tag.yml
vendored
@ -89,10 +89,13 @@ jobs:
|
|||||||
name: ghostty
|
name: ghostty
|
||||||
authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
|
authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
|
||||||
|
|
||||||
|
- name: compile blueprints
|
||||||
|
run: nix run .#compile-blueprints
|
||||||
|
|
||||||
- name: Create Tarball
|
- name: Create Tarball
|
||||||
run: |
|
run: |
|
||||||
git archive --format=tgz --prefix="ghostty-${GHOSTTY_VERSION}/" -o "ghostty-${GHOSTTY_VERSION}.tar.gz" HEAD
|
git archive --format=tgz $(find src -name \*.ui -print0 | xargs --null --replace=UI echo --add-virtual-file=ghostty-${GHOSTTY_VERSION}/UI:UI) --prefix="ghostty-${GHOSTTY_VERSION}/" -o "ghostty-${GHOSTTY_VERSION}.tar.gz" HEAD
|
||||||
git archive --format=tgz --prefix=ghostty-source/ -o ghostty-source.tar.gz HEAD
|
git archive --format=tgz $(find src -name \*.ui -print0 | xargs --null --replace=UI echo --add-virtual-file=ghostty-source/UI:UI --prefix=ghostty-source/) -o ghostty-source.tar.gz HEAD
|
||||||
|
|
||||||
- name: Sign Tarball
|
- name: Sign Tarball
|
||||||
run: |
|
run: |
|
||||||
|
4
.github/workflows/release-tip.yml
vendored
4
.github/workflows/release-tip.yml
vendored
@ -110,8 +110,10 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
name: ghostty
|
name: ghostty
|
||||||
authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
|
authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
|
||||||
|
- name: compile blueprints
|
||||||
|
run: nix run .#compile-blueprints
|
||||||
- name: Create Tarball
|
- name: Create Tarball
|
||||||
run: git archive --format=tgz --prefix=ghostty-source/ -o ghostty-source.tar.gz HEAD
|
run: git archive --format=tgz $(find src -name \*.ui -print0 | xargs --null --replace=UI echo --add-virtual-file=ghostty-source/UI:UI --prefix=ghostty-source/) -o ghostty-source.tar.gz HEAD
|
||||||
- name: Sign Tarball
|
- name: Sign Tarball
|
||||||
run: |
|
run: |
|
||||||
echo -n "${{ secrets.MINISIGN_KEY }}" > minisign.key
|
echo -n "${{ secrets.MINISIGN_KEY }}" > minisign.key
|
||||||
|
50
.github/workflows/test.yml
vendored
50
.github/workflows/test.yml
vendored
@ -27,6 +27,7 @@ jobs:
|
|||||||
- prettier
|
- prettier
|
||||||
- alejandra
|
- alejandra
|
||||||
- typos
|
- typos
|
||||||
|
- blueprint-compiler
|
||||||
- translations
|
- translations
|
||||||
- test-pkg-linux
|
- test-pkg-linux
|
||||||
- test-debian-12
|
- test-debian-12
|
||||||
@ -609,6 +610,35 @@ jobs:
|
|||||||
- name: prettier check
|
- name: prettier check
|
||||||
run: nix develop -c prettier --check .
|
run: nix develop -c prettier --check .
|
||||||
|
|
||||||
|
blueprint-compiler:
|
||||||
|
if: github.repository == 'ghostty-org/ghostty'
|
||||||
|
runs-on: namespace-profile-ghostty-sm
|
||||||
|
timeout-minutes: 60
|
||||||
|
env:
|
||||||
|
ZIG_LOCAL_CACHE_DIR: /zig/local-cache
|
||||||
|
ZIG_GLOBAL_CACHE_DIR: /zig/global-cache
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4 # Check out repo so we can lint it
|
||||||
|
- 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 }}"
|
||||||
|
skipPush: true
|
||||||
|
useDaemon: false # sometimes fails on short jobs
|
||||||
|
- name: compile blueprints
|
||||||
|
run: nix run .#compile-blueprints
|
||||||
|
- name: check unchanged
|
||||||
|
run: git diff --exit-code
|
||||||
|
|
||||||
alejandra:
|
alejandra:
|
||||||
if: github.repository == 'ghostty-org/ghostty'
|
if: github.repository == 'ghostty-org/ghostty'
|
||||||
runs-on: namespace-profile-ghostty-sm
|
runs-on: namespace-profile-ghostty-sm
|
||||||
@ -742,6 +772,26 @@ jobs:
|
|||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Setup Cache
|
||||||
|
uses: namespacelabs/nscloud-cache-action@v1.2.0
|
||||||
|
with:
|
||||||
|
path: |
|
||||||
|
/nix
|
||||||
|
/zig
|
||||||
|
|
||||||
|
# Install Nix and use that to run our tests so our environment matches exactly.
|
||||||
|
- 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 }}"
|
||||||
|
|
||||||
|
# use Nix to compile blueprints since Debian 12 doesn't have a new enough version
|
||||||
|
- name: compile blueprints
|
||||||
|
run: nix run .#compile-blueprints
|
||||||
|
|
||||||
- name: Install and configure Namespace CLI
|
- name: Install and configure Namespace CLI
|
||||||
uses: namespacelabs/nscloud-setup@v0
|
uses: namespacelabs/nscloud-setup@v0
|
||||||
|
|
||||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -14,6 +14,7 @@ zig-out/
|
|||||||
example/*.wasm
|
example/*.wasm
|
||||||
test/ghostty
|
test/ghostty
|
||||||
test/cases/**/*.actual.png
|
test/cases/**/*.actual.png
|
||||||
|
src/apprt/gtk/ui/**/*.ui
|
||||||
|
|
||||||
glad.zip
|
glad.zip
|
||||||
/Box_test.ppm
|
/Box_test.ppm
|
||||||
|
@ -52,6 +52,8 @@
|
|||||||
zig = zig.packages.${system}."0.14.0";
|
zig = zig.packages.${system}."0.14.0";
|
||||||
wraptest = pkgs-stable.callPackage ./nix/wraptest.nix {};
|
wraptest = pkgs-stable.callPackage ./nix/wraptest.nix {};
|
||||||
zon2nix = zon2nix;
|
zon2nix = zon2nix;
|
||||||
|
# revert once blueprint-compiler 0.16.0 is in nixpkgs-stable
|
||||||
|
blueprint-compiler = pkgs-unstable.blueprint-compiler;
|
||||||
};
|
};
|
||||||
|
|
||||||
packages.${system} = let
|
packages.${system} = let
|
||||||
@ -99,6 +101,10 @@
|
|||||||
x11-gnome = runVM ./nix/vm/x11-gnome.nix;
|
x11-gnome = runVM ./nix/vm/x11-gnome.nix;
|
||||||
x11-plasma6 = runVM ./nix/vm/x11-plasma6.nix;
|
x11-plasma6 = runVM ./nix/vm/x11-plasma6.nix;
|
||||||
x11-xfce = runVM ./nix/vm/x11-xfce.nix;
|
x11-xfce = runVM ./nix/vm/x11-xfce.nix;
|
||||||
|
compile-blueprints = import ./nix/build-support/compile-blueprints.nix {
|
||||||
|
# change once Zig 0.14 and blueprints-compiler 0.16 are in a stable release of nixpkgs
|
||||||
|
pkgs = pkgs-unstable;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
# Our supported systems are the same supported systems as the Zig binaries.
|
# Our supported systems are the same supported systems as the Zig binaries.
|
||||||
|
BIN
ghostty-source.tar.gz
Normal file
BIN
ghostty-source.tar.gz
Normal file
Binary file not shown.
23
nix/build-support/compile-blueprints.nix
Normal file
23
nix/build-support/compile-blueprints.nix
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
{pkgs}: let
|
||||||
|
# this needs to be kept in sync with deps from devShell.nix and package.nix
|
||||||
|
gi_typelib_path = pkgs.lib.makeSearchPath "lib/girepository-1.0" (map (pkg: pkgs.lib.getOutput "lib" pkg) [
|
||||||
|
pkgs.cairo
|
||||||
|
pkgs.gdk-pixbuf
|
||||||
|
pkgs.glib
|
||||||
|
pkgs.gobject-introspection
|
||||||
|
pkgs.graphene
|
||||||
|
pkgs.gtk4
|
||||||
|
pkgs.gtk4-layer-shell
|
||||||
|
pkgs.harfbuzz
|
||||||
|
pkgs.libadwaita
|
||||||
|
pkgs.pango
|
||||||
|
]);
|
||||||
|
program = pkgs.writeShellScript "compile-blueprints" ''
|
||||||
|
set -e
|
||||||
|
${pkgs.findutils}/bin/find . -name \*.blp -print0 | ${pkgs.findutils}/bin/xargs --null --replace=BLP -- ${pkgs.lib.getExe pkgs.blueprint-compiler} format --fix BLP
|
||||||
|
${pkgs.findutils}/bin/find . -name \*.blp -print0 | ${pkgs.findutils}/bin/xargs --null --replace=BLP -- sh -c "export B=BLP; ${pkgs.lib.getExe pkgs.blueprint-compiler} compile --typelib-path=${gi_typelib_path} --output \''${B%.*}.ui \$B"
|
||||||
|
'';
|
||||||
|
in {
|
||||||
|
type = "app";
|
||||||
|
program = "${program}";
|
||||||
|
}
|
@ -63,7 +63,23 @@
|
|||||||
wayland-protocols,
|
wayland-protocols,
|
||||||
zon2nix,
|
zon2nix,
|
||||||
system,
|
system,
|
||||||
|
cairo,
|
||||||
|
gdk-pixbuf,
|
||||||
|
graphene,
|
||||||
|
pango,
|
||||||
}: let
|
}: let
|
||||||
|
gi_typelib_path = [
|
||||||
|
cairo
|
||||||
|
gdk-pixbuf
|
||||||
|
glib
|
||||||
|
gobject-introspection
|
||||||
|
graphene
|
||||||
|
gtk4
|
||||||
|
gtk4-layer-shell
|
||||||
|
harfbuzz
|
||||||
|
libadwaita
|
||||||
|
pango
|
||||||
|
];
|
||||||
# See package.nix. Keep in sync.
|
# See package.nix. Keep in sync.
|
||||||
rpathLibs =
|
rpathLibs =
|
||||||
[
|
[
|
||||||
@ -187,6 +203,7 @@ in
|
|||||||
# This should be set onto the rpath of the ghostty binary if you want
|
# This should be set onto the rpath of the ghostty binary if you want
|
||||||
# it to be "portable" across the system.
|
# it to be "portable" across the system.
|
||||||
LD_LIBRARY_PATH = lib.makeLibraryPath rpathLibs;
|
LD_LIBRARY_PATH = lib.makeLibraryPath rpathLibs;
|
||||||
|
GI_TYPELIB_PATH = lib.makeSearchPath "lib/girepository-1.0" (map (pkg: lib.getOutput "lib" pkg) gi_typelib_path);
|
||||||
|
|
||||||
shellHook =
|
shellHook =
|
||||||
(lib.optionalString stdenv.hostPlatform.isLinux ''
|
(lib.optionalString stdenv.hostPlatform.isLinux ''
|
||||||
|
@ -18,88 +18,37 @@ pub fn init(
|
|||||||
/// The minor version of the minimum Adwaita version that is required to use
|
/// The minor version of the minimum Adwaita version that is required to use
|
||||||
/// this resource.
|
/// this resource.
|
||||||
comptime minor: u16,
|
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 {
|
) Builder {
|
||||||
const resource_path = comptime resource_path: {
|
const resource_path = comptime resource_path: {
|
||||||
const gresource = @import("gresource.zig");
|
const gresource = @import("gresource.zig");
|
||||||
switch (kind) {
|
// Check to make sure that our file is listed as a
|
||||||
.blp => {
|
// `blueprint_file` in `gresource.zig`. If it isn't Ghostty
|
||||||
// Check to make sure that our file is listed as a
|
// could crash at runtime when we try and load a nonexistent
|
||||||
// `blueprint_file` in `gresource.zig`. If it isn't Ghostty
|
// GResource.
|
||||||
// could crash at runtime when we try and load a nonexistent
|
for (gresource.blueprint_files) |file| {
|
||||||
// GResource.
|
if (major != file.major or minor != file.minor or !std.mem.eql(u8, file.name, name)) continue;
|
||||||
for (gresource.blueprint_files) |file| {
|
// Use @embedFile to make sure that the `.blp` file exists
|
||||||
if (major != file.major or minor != file.minor or !std.mem.eql(u8, file.name, name)) continue;
|
// at compile time. Zig _should_ discard the data so that
|
||||||
// Use @embedFile to make sure that the `.blp` file exists
|
// it doesn't end up in the final executable. At runtime we
|
||||||
// at compile time. Zig _should_ discard the data so that
|
// will load the data from a GResource.
|
||||||
// it doesn't end up in the final executable. At runtime we
|
const blp_filename = std.fmt.comptimePrint(
|
||||||
// will load the data from a GResource.
|
"ui/{d}.{d}/{s}.blp",
|
||||||
const blp_filename = std.fmt.comptimePrint(
|
.{
|
||||||
"ui/{d}.{d}/{s}.blp",
|
file.major,
|
||||||
.{
|
file.minor,
|
||||||
file.major,
|
file.name,
|
||||||
file.minor,
|
},
|
||||||
file.name,
|
);
|
||||||
},
|
_ = @embedFile(blp_filename);
|
||||||
);
|
break :resource_path std.fmt.comptimePrint(
|
||||||
_ = @embedFile(blp_filename);
|
"/com/mitchellh/ghostty/ui/{d}.{d}/{s}.ui",
|
||||||
break :resource_path std.fmt.comptimePrint(
|
.{
|
||||||
"/com/mitchellh/ghostty/ui/{d}.{d}/{s}.ui",
|
file.major,
|
||||||
.{
|
file.minor,
|
||||||
file.major,
|
file.name,
|
||||||
file.minor,
|
},
|
||||||
file.name,
|
);
|
||||||
},
|
} else @compileError("missing blueprint file '" ++ name ++ "' in gresource.zig");
|
||||||
);
|
|
||||||
} 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");
|
|
||||||
},
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return .{
|
return .{
|
||||||
|
@ -72,14 +72,14 @@ fn init(
|
|||||||
) !void {
|
) !void {
|
||||||
var builder = switch (DialogType) {
|
var builder = switch (DialogType) {
|
||||||
adw.AlertDialog => switch (request) {
|
adw.AlertDialog => switch (request) {
|
||||||
.osc_52_read => Builder.init("ccw-osc-52-read", 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, .blp),
|
.osc_52_write => Builder.init("ccw-osc-52-write", 1, 5),
|
||||||
.paste => Builder.init("ccw-paste", 1, 5, .blp),
|
.paste => Builder.init("ccw-paste", 1, 5),
|
||||||
},
|
},
|
||||||
adw.MessageDialog => switch (request) {
|
adw.MessageDialog => switch (request) {
|
||||||
.osc_52_read => Builder.init("ccw-osc-52-read", 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, .ui),
|
.osc_52_write => Builder.init("ccw-osc-52-write", 1, 2),
|
||||||
.paste => Builder.init("ccw-paste", 1, 2, .ui),
|
.paste => Builder.init("ccw-paste", 1, 2),
|
||||||
},
|
},
|
||||||
else => unreachable,
|
else => unreachable,
|
||||||
};
|
};
|
||||||
|
@ -1062,7 +1062,7 @@ pub fn promptTitle(self: *Surface) !void {
|
|||||||
if (!adwaita.versionAtLeast(1, 5, 0)) return;
|
if (!adwaita.versionAtLeast(1, 5, 0)) return;
|
||||||
const window = self.container.window() orelse 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();
|
defer builder.deinit();
|
||||||
|
|
||||||
const entry = builder.getObject(gtk.Entry, "title_entry").?;
|
const entry = builder.getObject(gtk.Entry, "title_entry").?;
|
||||||
|
@ -4,9 +4,12 @@ pub const c = @cImport({
|
|||||||
@cInclude("adwaita.h");
|
@cInclude("adwaita.h");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const required_version = "0.16.0";
|
||||||
|
|
||||||
pub fn main() !void {
|
pub fn main() !void {
|
||||||
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
var debug_allocator: std.heap.DebugAllocator(.{}) = .init;
|
||||||
const alloc = gpa.allocator();
|
defer _ = debug_allocator.deinit();
|
||||||
|
const alloc = debug_allocator.allocator();
|
||||||
|
|
||||||
var it = try std.process.argsWithAllocator(alloc);
|
var it = try std.process.argsWithAllocator(alloc);
|
||||||
defer it.deinit();
|
defer it.deinit();
|
||||||
@ -19,47 +22,125 @@ pub fn main() !void {
|
|||||||
const input = it.next() orelse return error.NoInput;
|
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 (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.
|
std.log.err(
|
||||||
const file = try std.fs.createFileAbsolute(output, .{
|
\\`libadwaita` is too old.
|
||||||
.truncate = true,
|
\\
|
||||||
});
|
\\Ghostty requires a version {d}.{d} or newer of `libadwaita` to
|
||||||
try file.writeAll(
|
\\compile this blueprint. Please install it, ensure that it is
|
||||||
\\<?xml version="1.0" encoding="UTF-8"?>
|
\\available on your PATH, and then retry building Ghostty.
|
||||||
\\<interface domain="com.mitchellh.ghostty"/>
|
, .{ major, minor });
|
||||||
);
|
std.posix.exit(1);
|
||||||
defer file.close();
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var compiler = std.process.Child.init(
|
{
|
||||||
&.{
|
var stdout: std.ArrayListUnmanaged(u8) = .empty;
|
||||||
"blueprint-compiler",
|
defer stdout.deinit(alloc);
|
||||||
"compile",
|
var stderr: std.ArrayListUnmanaged(u8) = .empty;
|
||||||
"--output",
|
defer stderr.deinit(alloc);
|
||||||
output,
|
|
||||||
input,
|
|
||||||
},
|
|
||||||
alloc,
|
|
||||||
);
|
|
||||||
|
|
||||||
const term = compiler.spawnAndWait() catch |err| switch (err) {
|
var blueprint_compiler = std.process.Child.init(
|
||||||
error.FileNotFound => {
|
&.{
|
||||||
|
"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.log.err(
|
||||||
|
\\`blueprint-compiler` not found.
|
||||||
|
\\
|
||||||
|
\\Ghostty requires `blueprint-compiler` version {s} 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_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 = std.mem.trim(u8, stdout.items, &std.ascii.whitespace);
|
||||||
|
if (!std.mem.eql(u8, version, "0.16.0")) {
|
||||||
std.log.err(
|
std.log.err(
|
||||||
\\`blueprint-compiler` not found.
|
\\`blueprint-compiler` is the wrong version.
|
||||||
\\
|
\\
|
||||||
\\Ghostty requires `blueprint-compiler` as a build-time dependency starting from version 1.2.
|
\\Ghostty requires `blueprint-compiler` version {s} as
|
||||||
\\Please install it, ensure that it is available on your PATH, and then retry building Ghostty.
|
\\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_version});
|
||||||
std.posix.exit(1);
|
std.posix.exit(1);
|
||||||
},
|
}
|
||||||
else => return err,
|
}
|
||||||
};
|
|
||||||
|
|
||||||
switch (term) {
|
{
|
||||||
.Exited => |rc| {
|
var stdout: std.ArrayListUnmanaged(u8) = .empty;
|
||||||
if (rc != 0) std.process.exit(1);
|
defer stdout.deinit(alloc);
|
||||||
},
|
var stderr: std.ArrayListUnmanaged(u8) = .empty;
|
||||||
else => std.process.exit(1),
|
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.log.err(
|
||||||
|
\\`blueprint-compiler` not found.
|
||||||
|
\\
|
||||||
|
\\Ghostty requires `blueprint-compiler` version {s} 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_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);
|
||||||
|
},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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();
|
|
||||||
}
|
|
@ -53,18 +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 = "ccw-osc-52-read" },
|
|
||||||
.{ .major = 1, .minor = 2, .name = "ccw-osc-52-write" },
|
|
||||||
.{ .major = 1, .minor = 2, .name = "ccw-paste" },
|
|
||||||
};
|
|
||||||
|
|
||||||
pub const VersionedBlueprint = struct {
|
pub const VersionedBlueprint = struct {
|
||||||
major: u16,
|
major: u16,
|
||||||
minor: u16,
|
minor: u16,
|
||||||
@ -75,27 +63,33 @@ pub const blueprint_files = [_]VersionedBlueprint{
|
|||||||
.{ .major = 1, .minor = 5, .name = "prompt-title-dialog" },
|
.{ .major = 1, .minor = 5, .name = "prompt-title-dialog" },
|
||||||
.{ .major = 1, .minor = 0, .name = "menu-surface-context_menu" },
|
.{ .major = 1, .minor = 0, .name = "menu-surface-context_menu" },
|
||||||
.{ .major = 1, .minor = 0, .name = "menu-window-titlebar_menu" },
|
.{ .major = 1, .minor = 0, .name = "menu-window-titlebar_menu" },
|
||||||
|
.{ .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" },
|
||||||
.{ .major = 1, .minor = 5, .name = "ccw-osc-52-read" },
|
.{ .major = 1, .minor = 5, .name = "ccw-osc-52-read" },
|
||||||
.{ .major = 1, .minor = 5, .name = "ccw-osc-52-write" },
|
.{ .major = 1, .minor = 5, .name = "ccw-osc-52-write" },
|
||||||
.{ .major = 1, .minor = 5, .name = "ccw-paste" },
|
.{ .major = 1, .minor = 5, .name = "ccw-paste" },
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn main() !void {
|
pub fn main() !void {
|
||||||
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
var debug_allocator: std.heap.DebugAllocator(.{}) = .init;
|
||||||
const alloc = gpa.allocator();
|
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 {
|
defer {
|
||||||
for (extra_ui_files.items) |item| alloc.free(item);
|
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);
|
var it = try std.process.argsWithAllocator(alloc);
|
||||||
defer it.deinit();
|
defer it.deinit();
|
||||||
|
|
||||||
|
_ = it.next();
|
||||||
|
|
||||||
while (it.next()) |argument| {
|
while (it.next()) |argument| {
|
||||||
if (std.mem.eql(u8, std.fs.path.extension(argument), ".ui")) {
|
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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -129,16 +123,11 @@ pub fn main() !void {
|
|||||||
\\ <gresource prefix="/com/mitchellh/ghostty/ui">
|
\\ <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| {
|
for (extra_ui_files.items) |ui_file| {
|
||||||
const stem = std.fs.path.stem(ui_file);
|
|
||||||
for (blueprint_files) |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(
|
try writer.print(
|
||||||
" <file compressed=\"true\" preprocess=\"xml-stripblanks\" alias=\"{d}.{d}/{s}.ui\">{s}</file>\n",
|
" <file compressed=\"true\" preprocess=\"xml-stripblanks\" alias=\"{d}.{d}/{s}.ui\">{s}</file>\n",
|
||||||
.{ file.major, file.minor, file.name, ui_file },
|
.{ file.major, file.minor, file.name, ui_file },
|
||||||
@ -154,7 +143,7 @@ pub fn main() !void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub const dependencies = deps: {
|
pub const dependencies = deps: {
|
||||||
const total = css_files.len + icons.len + ui_files.len + blueprint_files.len;
|
const total = css_files.len + icons.len;
|
||||||
var deps: [total][]const u8 = undefined;
|
var deps: [total][]const u8 = undefined;
|
||||||
var index: usize = 0;
|
var index: usize = 0;
|
||||||
for (css_files) |css_file| {
|
for (css_files) |css_file| {
|
||||||
@ -165,21 +154,5 @@ pub const dependencies = deps: {
|
|||||||
deps[index] = std.fmt.comptimePrint("images/icons/icon_{s}.png", .{icon.source});
|
deps[index] = std.fmt.comptimePrint("images/icons/icon_{s}.png", .{icon.source});
|
||||||
index += 1;
|
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,
|
|
||||||
blueprint_file.minor,
|
|
||||||
blueprint_file.name,
|
|
||||||
});
|
|
||||||
index += 1;
|
|
||||||
}
|
|
||||||
break :deps deps;
|
break :deps deps;
|
||||||
};
|
};
|
||||||
|
@ -41,7 +41,7 @@ pub fn Menu(
|
|||||||
else => unreachable,
|
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();
|
defer builder.deinit();
|
||||||
|
|
||||||
const menu_model = builder.getObject(gio.MenuModel, "menu").?;
|
const menu_model = builder.getObject(gio.MenuModel, "menu").?;
|
||||||
|
@ -8,7 +8,7 @@ Adw.MessageDialog clipboard_confirmation_window {
|
|||||||
|
|
||||||
responses [
|
responses [
|
||||||
cancel: _("Deny") suggested,
|
cancel: _("Deny") suggested,
|
||||||
ok: _("Allow") destructive
|
ok: _("Allow") destructive,
|
||||||
]
|
]
|
||||||
|
|
||||||
default-response: "cancel";
|
default-response: "cancel";
|
||||||
@ -16,7 +16,7 @@ Adw.MessageDialog clipboard_confirmation_window {
|
|||||||
|
|
||||||
extra-child: Overlay {
|
extra-child: Overlay {
|
||||||
styles [
|
styles [
|
||||||
"osd"
|
"osd",
|
||||||
]
|
]
|
||||||
|
|
||||||
ScrolledWindow text_view_scroll {
|
ScrolledWindow text_view_scroll {
|
||||||
@ -33,7 +33,7 @@ Adw.MessageDialog clipboard_confirmation_window {
|
|||||||
right-margin: 8;
|
right-margin: 8;
|
||||||
|
|
||||||
styles [
|
styles [
|
||||||
"clipboard-content-view"
|
"clipboard-content-view",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -60,7 +60,7 @@ Adw.MessageDialog clipboard_confirmation_window {
|
|||||||
margin-top: 12;
|
margin-top: 12;
|
||||||
|
|
||||||
styles [
|
styles [
|
||||||
"opaque"
|
"opaque",
|
||||||
]
|
]
|
||||||
|
|
||||||
Image {
|
Image {
|
||||||
|
@ -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>
|
|
@ -8,7 +8,7 @@ Adw.MessageDialog clipboard_confirmation_window {
|
|||||||
|
|
||||||
responses [
|
responses [
|
||||||
cancel: _("Deny") suggested,
|
cancel: _("Deny") suggested,
|
||||||
ok: _("Allow") destructive
|
ok: _("Allow") destructive,
|
||||||
]
|
]
|
||||||
|
|
||||||
default-response: "cancel";
|
default-response: "cancel";
|
||||||
@ -16,7 +16,7 @@ Adw.MessageDialog clipboard_confirmation_window {
|
|||||||
|
|
||||||
extra-child: Overlay {
|
extra-child: Overlay {
|
||||||
styles [
|
styles [
|
||||||
"osd"
|
"osd",
|
||||||
]
|
]
|
||||||
|
|
||||||
ScrolledWindow text_view_scroll {
|
ScrolledWindow text_view_scroll {
|
||||||
@ -33,7 +33,7 @@ Adw.MessageDialog clipboard_confirmation_window {
|
|||||||
right-margin: 8;
|
right-margin: 8;
|
||||||
|
|
||||||
styles [
|
styles [
|
||||||
"clipboard-content-view"
|
"clipboard-content-view",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -60,7 +60,7 @@ Adw.MessageDialog clipboard_confirmation_window {
|
|||||||
margin-top: 12;
|
margin-top: 12;
|
||||||
|
|
||||||
styles [
|
styles [
|
||||||
"opaque"
|
"opaque",
|
||||||
]
|
]
|
||||||
|
|
||||||
Image {
|
Image {
|
||||||
|
@ -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>
|
|
@ -8,7 +8,7 @@ Adw.MessageDialog clipboard_confirmation_window {
|
|||||||
|
|
||||||
responses [
|
responses [
|
||||||
cancel: _("Cancel") suggested,
|
cancel: _("Cancel") suggested,
|
||||||
ok: _("Paste") destructive
|
ok: _("Paste") destructive,
|
||||||
]
|
]
|
||||||
|
|
||||||
default-response: "cancel";
|
default-response: "cancel";
|
||||||
@ -16,7 +16,7 @@ Adw.MessageDialog clipboard_confirmation_window {
|
|||||||
|
|
||||||
extra-child: Overlay {
|
extra-child: Overlay {
|
||||||
styles [
|
styles [
|
||||||
"osd"
|
"osd",
|
||||||
]
|
]
|
||||||
|
|
||||||
ScrolledWindow text_view_scroll {
|
ScrolledWindow text_view_scroll {
|
||||||
@ -33,7 +33,7 @@ Adw.MessageDialog clipboard_confirmation_window {
|
|||||||
right-margin: 8;
|
right-margin: 8;
|
||||||
|
|
||||||
styles [
|
styles [
|
||||||
"clipboard-content-view"
|
"clipboard-content-view",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -60,7 +60,7 @@ Adw.MessageDialog clipboard_confirmation_window {
|
|||||||
margin-top: 12;
|
margin-top: 12;
|
||||||
|
|
||||||
styles [
|
styles [
|
||||||
"opaque"
|
"opaque",
|
||||||
]
|
]
|
||||||
|
|
||||||
Image {
|
Image {
|
||||||
|
@ -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>
|
|
@ -8,7 +8,7 @@ Adw.AlertDialog clipboard_confirmation_window {
|
|||||||
|
|
||||||
responses [
|
responses [
|
||||||
cancel: _("Deny") suggested,
|
cancel: _("Deny") suggested,
|
||||||
ok: _("Allow") destructive
|
ok: _("Allow") destructive,
|
||||||
]
|
]
|
||||||
|
|
||||||
default-response: "cancel";
|
default-response: "cancel";
|
||||||
@ -16,7 +16,7 @@ Adw.AlertDialog clipboard_confirmation_window {
|
|||||||
|
|
||||||
extra-child: Overlay {
|
extra-child: Overlay {
|
||||||
styles [
|
styles [
|
||||||
"osd"
|
"osd",
|
||||||
]
|
]
|
||||||
|
|
||||||
ScrolledWindow text_view_scroll {
|
ScrolledWindow text_view_scroll {
|
||||||
@ -33,7 +33,7 @@ Adw.AlertDialog clipboard_confirmation_window {
|
|||||||
right-margin: 8;
|
right-margin: 8;
|
||||||
|
|
||||||
styles [
|
styles [
|
||||||
"clipboard-content-view"
|
"clipboard-content-view",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -60,7 +60,7 @@ Adw.AlertDialog clipboard_confirmation_window {
|
|||||||
margin-top: 12;
|
margin-top: 12;
|
||||||
|
|
||||||
styles [
|
styles [
|
||||||
"opaque"
|
"opaque",
|
||||||
]
|
]
|
||||||
|
|
||||||
Image {
|
Image {
|
||||||
|
@ -8,7 +8,7 @@ Adw.AlertDialog clipboard_confirmation_window {
|
|||||||
|
|
||||||
responses [
|
responses [
|
||||||
cancel: _("Deny") suggested,
|
cancel: _("Deny") suggested,
|
||||||
ok: _("Allow") destructive
|
ok: _("Allow") destructive,
|
||||||
]
|
]
|
||||||
|
|
||||||
default-response: "cancel";
|
default-response: "cancel";
|
||||||
@ -16,7 +16,7 @@ Adw.AlertDialog clipboard_confirmation_window {
|
|||||||
|
|
||||||
extra-child: Overlay {
|
extra-child: Overlay {
|
||||||
styles [
|
styles [
|
||||||
"osd"
|
"osd",
|
||||||
]
|
]
|
||||||
|
|
||||||
ScrolledWindow text_view_scroll {
|
ScrolledWindow text_view_scroll {
|
||||||
@ -33,7 +33,7 @@ Adw.AlertDialog clipboard_confirmation_window {
|
|||||||
right-margin: 8;
|
right-margin: 8;
|
||||||
|
|
||||||
styles [
|
styles [
|
||||||
"clipboard-content-view"
|
"clipboard-content-view",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -60,7 +60,7 @@ Adw.AlertDialog clipboard_confirmation_window {
|
|||||||
margin-top: 12;
|
margin-top: 12;
|
||||||
|
|
||||||
styles [
|
styles [
|
||||||
"opaque"
|
"opaque",
|
||||||
]
|
]
|
||||||
|
|
||||||
Image {
|
Image {
|
||||||
|
@ -8,7 +8,7 @@ Adw.AlertDialog clipboard_confirmation_window {
|
|||||||
|
|
||||||
responses [
|
responses [
|
||||||
cancel: _("Cancel") suggested,
|
cancel: _("Cancel") suggested,
|
||||||
ok: _("Paste") destructive
|
ok: _("Paste") destructive,
|
||||||
]
|
]
|
||||||
|
|
||||||
default-response: "cancel";
|
default-response: "cancel";
|
||||||
@ -16,7 +16,7 @@ Adw.AlertDialog clipboard_confirmation_window {
|
|||||||
|
|
||||||
extra-child: Overlay {
|
extra-child: Overlay {
|
||||||
styles [
|
styles [
|
||||||
"osd"
|
"osd",
|
||||||
]
|
]
|
||||||
|
|
||||||
ScrolledWindow text_view_scroll {
|
ScrolledWindow text_view_scroll {
|
||||||
@ -33,7 +33,7 @@ Adw.AlertDialog clipboard_confirmation_window {
|
|||||||
right-margin: 8;
|
right-margin: 8;
|
||||||
|
|
||||||
styles [
|
styles [
|
||||||
"clipboard-content-view"
|
"clipboard-content-view",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -60,7 +60,7 @@ Adw.AlertDialog clipboard_confirmation_window {
|
|||||||
margin-top: 12;
|
margin-top: 12;
|
||||||
|
|
||||||
styles [
|
styles [
|
||||||
"opaque"
|
"opaque",
|
||||||
]
|
]
|
||||||
|
|
||||||
Image {
|
Image {
|
||||||
|
@ -7,7 +7,7 @@ Adw.AlertDialog prompt_title_dialog {
|
|||||||
|
|
||||||
responses [
|
responses [
|
||||||
cancel: _("Cancel") suggested,
|
cancel: _("Cancel") suggested,
|
||||||
ok: _("OK") destructive
|
ok: _("OK") destructive,
|
||||||
]
|
]
|
||||||
|
|
||||||
focus-widget: title_entry;
|
focus-widget: title_entry;
|
||||||
|
@ -1,21 +1,20 @@
|
|||||||
# GTK UI files
|
# GTK UI files
|
||||||
|
|
||||||
This directory is for storing GTK resource definitions. With one exception, the
|
This directory is for storing GTK resource definitions. All resource definitions
|
||||||
files should be be in the Blueprint markup language.
|
_must_ start as GTK blueprint `.blp` files. GTK resource definitions are then
|
||||||
|
generated by `blueprint-compiler` at compile time. A CI job ensures that `.blp`
|
||||||
|
files are valid and properly formatted.
|
||||||
|
|
||||||
Resource files should be stored in directories that represent the minimum
|
Blueprint files should be stored in directories that represent the minimum
|
||||||
Adwaita version needed to use that resource. Resource files should also be
|
Adwaita version needed to use that resource. Blueprint files should also be
|
||||||
formatted using `blueprint-compiler format` as well to ensure consistency.
|
formatted using `blueprint-compiler format` as well to ensure consistency
|
||||||
|
(formatting will be checked in CI as well).
|
||||||
|
|
||||||
The one exception to files being in Blueprint markup language is when Adwaita
|
Blueprints can be formatted and compiled into resource definitions by running
|
||||||
features are used that the `blueprint-compiler` on a supported platform does not
|
this command from the root of the source tree:
|
||||||
compile. For example, Debian 12 includes Adwaita 1.2 and `blueprint-compiler`
|
|
||||||
0.6.0. Adwaita 1.2 includes support for `MessageDialog` but `blueprint-compiler`
|
|
||||||
0.6.0 does not. In cases like that the Blueprint markup should be compiled on a
|
|
||||||
platform that provides a new enough `blueprint-compiler` and the resulting `.ui`
|
|
||||||
file should be committed to the Ghostty source code. Care should be taken that
|
|
||||||
the `.blp` file and the `.ui` file remain in sync.
|
|
||||||
|
|
||||||
In all other cases only the `.blp` should be committed to the Ghostty source
|
```
|
||||||
code. The build process will use `blueprint-compiler` to generate the `.ui`
|
nix run .#compile-blueprints
|
||||||
files necessary at runtime.
|
```
|
||||||
|
|
||||||
|
Currently `blueprint-compiler` 0.16.0 is required to compile Blueprint files.
|
||||||
|
@ -668,71 +668,46 @@ fn addGTK(
|
|||||||
});
|
});
|
||||||
|
|
||||||
const generate = b.addRunArtifact(generate_gresource_xml);
|
const generate = b.addRunArtifact(generate_gresource_xml);
|
||||||
|
const blueprint_compiler = b.addExecutable(.{
|
||||||
const gtk_blueprint_compiler = b.addExecutable(.{
|
|
||||||
.name = "gtk_blueprint_compiler",
|
.name = "gtk_blueprint_compiler",
|
||||||
.root_source_file = b.path("src/apprt/gtk/blueprint_compiler.zig"),
|
.root_source_file = b.path("src/apprt/gtk/blueprint_compiler.zig"),
|
||||||
.target = b.graph.host,
|
.target = b.graph.host,
|
||||||
});
|
});
|
||||||
gtk_blueprint_compiler.linkSystemLibrary2("gtk4", dynamic_link_opts);
|
blueprint_compiler.linkSystemLibrary2("gtk4", dynamic_link_opts);
|
||||||
gtk_blueprint_compiler.linkSystemLibrary2("libadwaita-1", dynamic_link_opts);
|
blueprint_compiler.linkSystemLibrary2("libadwaita-1", dynamic_link_opts);
|
||||||
gtk_blueprint_compiler.linkLibC();
|
blueprint_compiler.linkLibC();
|
||||||
|
|
||||||
for (gresource.blueprint_files) |blueprint_file| {
|
for (gresource.blueprint_files) |blueprint_file| {
|
||||||
const blueprint_compiler = b.addRunArtifact(gtk_blueprint_compiler);
|
if (b.systemIntegrationOption("blueprint-compiler", .{ .default = true })) {
|
||||||
blueprint_compiler.addArgs(&.{
|
const blueprint_compile = b.addRunArtifact(blueprint_compiler);
|
||||||
b.fmt("{d}", .{blueprint_file.major}),
|
blueprint_compile.addArgs(&.{
|
||||||
b.fmt("{d}", .{blueprint_file.minor}),
|
b.fmt("{d}", .{blueprint_file.major}),
|
||||||
});
|
b.fmt("{d}", .{blueprint_file.minor}),
|
||||||
const ui_file = blueprint_compiler.addOutputFileArg(b.fmt(
|
});
|
||||||
"{d}.{d}/{s}.ui",
|
const blueprint_output = blueprint_compile.addOutputFileArg(b.fmt(
|
||||||
.{
|
"{[major]d}.{[minor]d}/{[name]s}.ui",
|
||||||
blueprint_file.major,
|
blueprint_file,
|
||||||
blueprint_file.minor,
|
));
|
||||||
blueprint_file.name,
|
blueprint_compile.addFileArg(b.path(b.fmt(
|
||||||
},
|
"src/apprt/gtk/ui/{[major]d}.{[minor]d}/{[name]s}.blp",
|
||||||
));
|
blueprint_file,
|
||||||
blueprint_compiler.addFileArg(b.path(b.fmt(
|
)));
|
||||||
"src/apprt/gtk/ui/{d}.{d}/{s}.blp",
|
generate.addFileArg(blueprint_output);
|
||||||
.{
|
} else {
|
||||||
blueprint_file.major,
|
generate.addFileInput(b.path(b.fmt(
|
||||||
blueprint_file.minor,
|
"src/apprt/gtk/ui/{[major]d}.{[minor]d}/{[name]s}.ui",
|
||||||
blueprint_file.name,
|
blueprint_file,
|
||||||
},
|
)));
|
||||||
)));
|
}
|
||||||
generate.addFileArg(ui_file);
|
}
|
||||||
|
for (gresource.dependencies) |pathname| {
|
||||||
|
if (std.mem.eql(u8, std.fs.path.extension(pathname), ".blp")) continue;
|
||||||
|
generate.addFileInput(b.path(pathname));
|
||||||
}
|
}
|
||||||
|
|
||||||
break :gresource_xml generate.captureStdOut();
|
break :gresource_xml generate.captureStdOut();
|
||||||
};
|
};
|
||||||
|
|
||||||
{
|
|
||||||
const gtk_builder_check = b.addExecutable(.{
|
|
||||||
.name = "gtk_builder_check",
|
|
||||||
.root_source_file = b.path("src/apprt/gtk/builder_check.zig"),
|
|
||||||
.target = b.graph.host,
|
|
||||||
});
|
|
||||||
gtk_builder_check.root_module.addOptions("build_options", self.options);
|
|
||||||
if (gobject_) |gobject| {
|
|
||||||
gtk_builder_check.root_module.addImport(
|
|
||||||
"gtk",
|
|
||||||
gobject.module("gtk4"),
|
|
||||||
);
|
|
||||||
gtk_builder_check.root_module.addImport(
|
|
||||||
"adw",
|
|
||||||
gobject.module("adw1"),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (gresource.dependencies) |pathname| {
|
|
||||||
const extension = std.fs.path.extension(pathname);
|
|
||||||
if (!std.mem.eql(u8, extension, ".ui")) continue;
|
|
||||||
const check = b.addRunArtifact(gtk_builder_check);
|
|
||||||
check.addFileArg(b.path(pathname));
|
|
||||||
step.step.dependOn(&check.step);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const generate_resources_c = b.addSystemCommand(&.{
|
const generate_resources_c = b.addSystemCommand(&.{
|
||||||
"glib-compile-resources",
|
"glib-compile-resources",
|
||||||
"--c-name",
|
"--c-name",
|
||||||
|
@ -5,7 +5,6 @@ FROM docker.io/library/debian:${DISTRO_VERSION}
|
|||||||
RUN DEBIAN_FRONTEND="noninteractive" apt-get -qq update && \
|
RUN DEBIAN_FRONTEND="noninteractive" apt-get -qq update && \
|
||||||
apt-get -qq -y --no-install-recommends install \
|
apt-get -qq -y --no-install-recommends install \
|
||||||
# Build Tools
|
# Build Tools
|
||||||
blueprint-compiler \
|
|
||||||
build-essential \
|
build-essential \
|
||||||
libbz2-dev \
|
libbz2-dev \
|
||||||
libonig-dev \
|
libonig-dev \
|
||||||
@ -52,5 +51,5 @@ RUN ZIG_GLOBAL_CACHE_DIR=/zig/global-cache ./nix/build-support/fetch-zig-cache.s
|
|||||||
COPY ./src /src/src
|
COPY ./src /src/src
|
||||||
|
|
||||||
# Debian 12 doesn't have gtk4-layer-shell, so we have to manually compile it ourselves
|
# Debian 12 doesn't have gtk4-layer-shell, so we have to manually compile it ourselves
|
||||||
RUN zig build -Doptimize=Debug -Dcpu=baseline -Dapp-runtime=gtk -fno-sys=gtk4-layer-shell --system /zig/global-cache/p
|
RUN zig build -Doptimize=Debug -Dcpu=baseline -Dapp-runtime=gtk -fno-sys=gtk4-layer-shell -fno-sys=blueprint-compiler --system /zig/global-cache/p
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user