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
|
||||
authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
|
||||
|
||||
- name: compile blueprints
|
||||
run: nix run .#compile-blueprints
|
||||
|
||||
- name: Create Tarball
|
||||
run: |
|
||||
git archive --format=tgz --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-${GHOSTTY_VERSION}/UI:UI) --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-source/UI:UI --prefix=ghostty-source/) -o ghostty-source.tar.gz HEAD
|
||||
|
||||
- name: Sign Tarball
|
||||
run: |
|
||||
|
4
.github/workflows/release-tip.yml
vendored
4
.github/workflows/release-tip.yml
vendored
@ -110,8 +110,10 @@ jobs:
|
||||
with:
|
||||
name: ghostty
|
||||
authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
|
||||
- name: compile blueprints
|
||||
run: nix run .#compile-blueprints
|
||||
- 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
|
||||
run: |
|
||||
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
|
||||
- alejandra
|
||||
- typos
|
||||
- blueprint-compiler
|
||||
- translations
|
||||
- test-pkg-linux
|
||||
- test-debian-12
|
||||
@ -609,6 +610,35 @@ jobs:
|
||||
- name: 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:
|
||||
if: github.repository == 'ghostty-org/ghostty'
|
||||
runs-on: namespace-profile-ghostty-sm
|
||||
@ -742,6 +772,26 @@ jobs:
|
||||
- name: Checkout code
|
||||
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
|
||||
uses: namespacelabs/nscloud-setup@v0
|
||||
|
||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -14,6 +14,7 @@ zig-out/
|
||||
example/*.wasm
|
||||
test/ghostty
|
||||
test/cases/**/*.actual.png
|
||||
src/apprt/gtk/ui/**/*.ui
|
||||
|
||||
glad.zip
|
||||
/Box_test.ppm
|
||||
|
@ -52,6 +52,8 @@
|
||||
zig = zig.packages.${system}."0.14.0";
|
||||
wraptest = pkgs-stable.callPackage ./nix/wraptest.nix {};
|
||||
zon2nix = zon2nix;
|
||||
# revert once blueprint-compiler 0.16.0 is in nixpkgs-stable
|
||||
blueprint-compiler = pkgs-unstable.blueprint-compiler;
|
||||
};
|
||||
|
||||
packages.${system} = let
|
||||
@ -99,6 +101,10 @@
|
||||
x11-gnome = runVM ./nix/vm/x11-gnome.nix;
|
||||
x11-plasma6 = runVM ./nix/vm/x11-plasma6.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.
|
||||
|
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,
|
||||
zon2nix,
|
||||
system,
|
||||
cairo,
|
||||
gdk-pixbuf,
|
||||
graphene,
|
||||
pango,
|
||||
}: let
|
||||
gi_typelib_path = [
|
||||
cairo
|
||||
gdk-pixbuf
|
||||
glib
|
||||
gobject-introspection
|
||||
graphene
|
||||
gtk4
|
||||
gtk4-layer-shell
|
||||
harfbuzz
|
||||
libadwaita
|
||||
pango
|
||||
];
|
||||
# See package.nix. Keep in sync.
|
||||
rpathLibs =
|
||||
[
|
||||
@ -187,6 +203,7 @@ in
|
||||
# This should be set onto the rpath of the ghostty binary if you want
|
||||
# it to be "portable" across the system.
|
||||
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 =
|
||||
(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
|
||||
/// 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 .{
|
||||
|
@ -72,14 +72,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,
|
||||
};
|
||||
|
@ -1062,7 +1062,7 @@ pub fn promptTitle(self: *Surface) !void {
|
||||
if (!adwaita.versionAtLeast(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").?;
|
||||
|
@ -4,9 +4,12 @@ pub const c = @cImport({
|
||||
@cInclude("adwaita.h");
|
||||
});
|
||||
|
||||
const required_version = "0.16.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();
|
||||
@ -19,47 +22,125 @@ pub fn main() !void {
|
||||
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;
|
||||
std.log.err(
|
||||
\\`libadwaita` is too old.
|
||||
\\
|
||||
\\Ghostty requires a version {d}.{d} or newer of `libadwaita` to
|
||||
\\compile this blueprint. Please install it, ensure that it is
|
||||
\\available on your PATH, and then retry building Ghostty.
|
||||
, .{ major, minor });
|
||||
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 => {
|
||||
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.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(
|
||||
\\`blueprint-compiler` not found.
|
||||
\\`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 `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),
|
||||
{
|
||||
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.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 {
|
||||
major: u16,
|
||||
minor: u16,
|
||||
@ -75,27 +63,33 @@ pub const blueprint_files = [_]VersionedBlueprint{
|
||||
.{ .major = 1, .minor = 5, .name = "prompt-title-dialog" },
|
||||
.{ .major = 1, .minor = 0, .name = "menu-surface-context_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-write" },
|
||||
.{ .major = 1, .minor = 5, .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);
|
||||
defer it.deinit();
|
||||
|
||||
_ = it.next();
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
@ -129,16 +123,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 },
|
||||
@ -154,7 +143,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;
|
||||
var deps: [total][]const u8 = undefined;
|
||||
var index: usize = 0;
|
||||
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});
|
||||
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;
|
||||
};
|
||||
|
@ -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").?;
|
||||
|
@ -8,7 +8,7 @@ Adw.MessageDialog clipboard_confirmation_window {
|
||||
|
||||
responses [
|
||||
cancel: _("Deny") suggested,
|
||||
ok: _("Allow") destructive
|
||||
ok: _("Allow") destructive,
|
||||
]
|
||||
|
||||
default-response: "cancel";
|
||||
@ -16,7 +16,7 @@ Adw.MessageDialog clipboard_confirmation_window {
|
||||
|
||||
extra-child: Overlay {
|
||||
styles [
|
||||
"osd"
|
||||
"osd",
|
||||
]
|
||||
|
||||
ScrolledWindow text_view_scroll {
|
||||
@ -33,7 +33,7 @@ Adw.MessageDialog clipboard_confirmation_window {
|
||||
right-margin: 8;
|
||||
|
||||
styles [
|
||||
"clipboard-content-view"
|
||||
"clipboard-content-view",
|
||||
]
|
||||
}
|
||||
}
|
||||
@ -60,7 +60,7 @@ Adw.MessageDialog clipboard_confirmation_window {
|
||||
margin-top: 12;
|
||||
|
||||
styles [
|
||||
"opaque"
|
||||
"opaque",
|
||||
]
|
||||
|
||||
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 [
|
||||
cancel: _("Deny") suggested,
|
||||
ok: _("Allow") destructive
|
||||
ok: _("Allow") destructive,
|
||||
]
|
||||
|
||||
default-response: "cancel";
|
||||
@ -16,7 +16,7 @@ Adw.MessageDialog clipboard_confirmation_window {
|
||||
|
||||
extra-child: Overlay {
|
||||
styles [
|
||||
"osd"
|
||||
"osd",
|
||||
]
|
||||
|
||||
ScrolledWindow text_view_scroll {
|
||||
@ -33,7 +33,7 @@ Adw.MessageDialog clipboard_confirmation_window {
|
||||
right-margin: 8;
|
||||
|
||||
styles [
|
||||
"clipboard-content-view"
|
||||
"clipboard-content-view",
|
||||
]
|
||||
}
|
||||
}
|
||||
@ -60,7 +60,7 @@ Adw.MessageDialog clipboard_confirmation_window {
|
||||
margin-top: 12;
|
||||
|
||||
styles [
|
||||
"opaque"
|
||||
"opaque",
|
||||
]
|
||||
|
||||
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 [
|
||||
cancel: _("Cancel") suggested,
|
||||
ok: _("Paste") destructive
|
||||
ok: _("Paste") destructive,
|
||||
]
|
||||
|
||||
default-response: "cancel";
|
||||
@ -16,7 +16,7 @@ Adw.MessageDialog clipboard_confirmation_window {
|
||||
|
||||
extra-child: Overlay {
|
||||
styles [
|
||||
"osd"
|
||||
"osd",
|
||||
]
|
||||
|
||||
ScrolledWindow text_view_scroll {
|
||||
@ -33,7 +33,7 @@ Adw.MessageDialog clipboard_confirmation_window {
|
||||
right-margin: 8;
|
||||
|
||||
styles [
|
||||
"clipboard-content-view"
|
||||
"clipboard-content-view",
|
||||
]
|
||||
}
|
||||
}
|
||||
@ -60,7 +60,7 @@ Adw.MessageDialog clipboard_confirmation_window {
|
||||
margin-top: 12;
|
||||
|
||||
styles [
|
||||
"opaque"
|
||||
"opaque",
|
||||
]
|
||||
|
||||
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 [
|
||||
cancel: _("Deny") suggested,
|
||||
ok: _("Allow") destructive
|
||||
ok: _("Allow") destructive,
|
||||
]
|
||||
|
||||
default-response: "cancel";
|
||||
@ -16,7 +16,7 @@ Adw.AlertDialog clipboard_confirmation_window {
|
||||
|
||||
extra-child: Overlay {
|
||||
styles [
|
||||
"osd"
|
||||
"osd",
|
||||
]
|
||||
|
||||
ScrolledWindow text_view_scroll {
|
||||
@ -33,7 +33,7 @@ Adw.AlertDialog clipboard_confirmation_window {
|
||||
right-margin: 8;
|
||||
|
||||
styles [
|
||||
"clipboard-content-view"
|
||||
"clipboard-content-view",
|
||||
]
|
||||
}
|
||||
}
|
||||
@ -60,7 +60,7 @@ Adw.AlertDialog clipboard_confirmation_window {
|
||||
margin-top: 12;
|
||||
|
||||
styles [
|
||||
"opaque"
|
||||
"opaque",
|
||||
]
|
||||
|
||||
Image {
|
||||
|
@ -8,7 +8,7 @@ Adw.AlertDialog clipboard_confirmation_window {
|
||||
|
||||
responses [
|
||||
cancel: _("Deny") suggested,
|
||||
ok: _("Allow") destructive
|
||||
ok: _("Allow") destructive,
|
||||
]
|
||||
|
||||
default-response: "cancel";
|
||||
@ -16,7 +16,7 @@ Adw.AlertDialog clipboard_confirmation_window {
|
||||
|
||||
extra-child: Overlay {
|
||||
styles [
|
||||
"osd"
|
||||
"osd",
|
||||
]
|
||||
|
||||
ScrolledWindow text_view_scroll {
|
||||
@ -33,7 +33,7 @@ Adw.AlertDialog clipboard_confirmation_window {
|
||||
right-margin: 8;
|
||||
|
||||
styles [
|
||||
"clipboard-content-view"
|
||||
"clipboard-content-view",
|
||||
]
|
||||
}
|
||||
}
|
||||
@ -60,7 +60,7 @@ Adw.AlertDialog clipboard_confirmation_window {
|
||||
margin-top: 12;
|
||||
|
||||
styles [
|
||||
"opaque"
|
||||
"opaque",
|
||||
]
|
||||
|
||||
Image {
|
||||
|
@ -8,7 +8,7 @@ Adw.AlertDialog clipboard_confirmation_window {
|
||||
|
||||
responses [
|
||||
cancel: _("Cancel") suggested,
|
||||
ok: _("Paste") destructive
|
||||
ok: _("Paste") destructive,
|
||||
]
|
||||
|
||||
default-response: "cancel";
|
||||
@ -16,7 +16,7 @@ Adw.AlertDialog clipboard_confirmation_window {
|
||||
|
||||
extra-child: Overlay {
|
||||
styles [
|
||||
"osd"
|
||||
"osd",
|
||||
]
|
||||
|
||||
ScrolledWindow text_view_scroll {
|
||||
@ -33,7 +33,7 @@ Adw.AlertDialog clipboard_confirmation_window {
|
||||
right-margin: 8;
|
||||
|
||||
styles [
|
||||
"clipboard-content-view"
|
||||
"clipboard-content-view",
|
||||
]
|
||||
}
|
||||
}
|
||||
@ -60,7 +60,7 @@ Adw.AlertDialog clipboard_confirmation_window {
|
||||
margin-top: 12;
|
||||
|
||||
styles [
|
||||
"opaque"
|
||||
"opaque",
|
||||
]
|
||||
|
||||
Image {
|
||||
|
@ -7,7 +7,7 @@ Adw.AlertDialog prompt_title_dialog {
|
||||
|
||||
responses [
|
||||
cancel: _("Cancel") suggested,
|
||||
ok: _("OK") destructive
|
||||
ok: _("OK") destructive,
|
||||
]
|
||||
|
||||
focus-widget: title_entry;
|
||||
|
@ -1,21 +1,20 @@
|
||||
# GTK UI files
|
||||
|
||||
This directory is for storing GTK resource definitions. With one exception, the
|
||||
files should be be in the Blueprint markup language.
|
||||
This directory is for storing GTK resource definitions. All resource definitions
|
||||
_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
|
||||
Adwaita version needed to use that resource. Resource files should also be
|
||||
formatted using `blueprint-compiler format` as well to ensure consistency.
|
||||
Blueprint files should be stored in directories that represent the minimum
|
||||
Adwaita version needed to use that resource. Blueprint files should also be
|
||||
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
|
||||
features are used that the `blueprint-compiler` on a supported platform does not
|
||||
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.
|
||||
Blueprints can be formatted and compiled into resource definitions by running
|
||||
this command from the root of the source tree:
|
||||
|
||||
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`
|
||||
files necessary at runtime.
|
||||
```
|
||||
nix run .#compile-blueprints
|
||||
```
|
||||
|
||||
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 gtk_blueprint_compiler = b.addExecutable(.{
|
||||
const blueprint_compiler = b.addExecutable(.{
|
||||
.name = "gtk_blueprint_compiler",
|
||||
.root_source_file = b.path("src/apprt/gtk/blueprint_compiler.zig"),
|
||||
.target = b.graph.host,
|
||||
});
|
||||
gtk_blueprint_compiler.linkSystemLibrary2("gtk4", dynamic_link_opts);
|
||||
gtk_blueprint_compiler.linkSystemLibrary2("libadwaita-1", dynamic_link_opts);
|
||||
gtk_blueprint_compiler.linkLibC();
|
||||
blueprint_compiler.linkSystemLibrary2("gtk4", dynamic_link_opts);
|
||||
blueprint_compiler.linkSystemLibrary2("libadwaita-1", dynamic_link_opts);
|
||||
blueprint_compiler.linkLibC();
|
||||
|
||||
for (gresource.blueprint_files) |blueprint_file| {
|
||||
const blueprint_compiler = b.addRunArtifact(gtk_blueprint_compiler);
|
||||
blueprint_compiler.addArgs(&.{
|
||||
b.fmt("{d}", .{blueprint_file.major}),
|
||||
b.fmt("{d}", .{blueprint_file.minor}),
|
||||
});
|
||||
const ui_file = blueprint_compiler.addOutputFileArg(b.fmt(
|
||||
"{d}.{d}/{s}.ui",
|
||||
.{
|
||||
blueprint_file.major,
|
||||
blueprint_file.minor,
|
||||
blueprint_file.name,
|
||||
},
|
||||
));
|
||||
blueprint_compiler.addFileArg(b.path(b.fmt(
|
||||
"src/apprt/gtk/ui/{d}.{d}/{s}.blp",
|
||||
.{
|
||||
blueprint_file.major,
|
||||
blueprint_file.minor,
|
||||
blueprint_file.name,
|
||||
},
|
||||
)));
|
||||
generate.addFileArg(ui_file);
|
||||
if (b.systemIntegrationOption("blueprint-compiler", .{ .default = true })) {
|
||||
const blueprint_compile = b.addRunArtifact(blueprint_compiler);
|
||||
blueprint_compile.addArgs(&.{
|
||||
b.fmt("{d}", .{blueprint_file.major}),
|
||||
b.fmt("{d}", .{blueprint_file.minor}),
|
||||
});
|
||||
const blueprint_output = blueprint_compile.addOutputFileArg(b.fmt(
|
||||
"{[major]d}.{[minor]d}/{[name]s}.ui",
|
||||
blueprint_file,
|
||||
));
|
||||
blueprint_compile.addFileArg(b.path(b.fmt(
|
||||
"src/apprt/gtk/ui/{[major]d}.{[minor]d}/{[name]s}.blp",
|
||||
blueprint_file,
|
||||
)));
|
||||
generate.addFileArg(blueprint_output);
|
||||
} else {
|
||||
generate.addFileInput(b.path(b.fmt(
|
||||
"src/apprt/gtk/ui/{[major]d}.{[minor]d}/{[name]s}.ui",
|
||||
blueprint_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();
|
||||
};
|
||||
|
||||
{
|
||||
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(&.{
|
||||
"glib-compile-resources",
|
||||
"--c-name",
|
||||
|
@ -5,7 +5,6 @@ FROM docker.io/library/debian:${DISTRO_VERSION}
|
||||
RUN DEBIAN_FRONTEND="noninteractive" apt-get -qq update && \
|
||||
apt-get -qq -y --no-install-recommends install \
|
||||
# Build Tools
|
||||
blueprint-compiler \
|
||||
build-essential \
|
||||
libbz2-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
|
||||
|
||||
# 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