start extracting core terminal zig module
parent
485b6b73bf
commit
a42193b997
47
build.zig
47
build.zig
|
|
@ -8,12 +8,25 @@ comptime {
|
|||
}
|
||||
|
||||
pub fn build(b: *std.Build) !void {
|
||||
// This defines all the available build options (e.g. `-D`).
|
||||
// This defines all the available build options (e.g. `-D`). If you
|
||||
// want to know what options are available, you can run `--help` or
|
||||
// you can read `src/build/Config.zig`.
|
||||
const config = try buildpkg.Config.init(b);
|
||||
const test_filter = b.option(
|
||||
[]const u8,
|
||||
const test_filters = b.option(
|
||||
[][]const u8,
|
||||
"test-filter",
|
||||
"Filter for test. Only applies to Zig tests.",
|
||||
) orelse &[0][]const u8{};
|
||||
|
||||
// Ghostty dependencies used by many artifacts.
|
||||
const deps = try buildpkg.SharedDeps.init(b, &config);
|
||||
|
||||
// The modules exported for Zig consumers of libghostty. If you're
|
||||
// writing a Zig program that uses libghostty, read this file.
|
||||
const mod = try buildpkg.GhosttyZig.init(
|
||||
b,
|
||||
&config,
|
||||
&deps,
|
||||
);
|
||||
|
||||
// All our steps which we'll hook up later. The steps are shown
|
||||
|
|
@ -24,6 +37,10 @@ pub fn build(b: *std.Build) !void {
|
|||
"Run the app under valgrind",
|
||||
);
|
||||
const test_step = b.step("test", "Run tests");
|
||||
const test_lib_vt_step = b.step(
|
||||
"test-lib-vt",
|
||||
"Run libghostty-vt tests",
|
||||
);
|
||||
const test_valgrind_step = b.step(
|
||||
"test-valgrind",
|
||||
"Run tests under valgrind",
|
||||
|
|
@ -37,10 +54,6 @@ pub fn build(b: *std.Build) !void {
|
|||
const resources = try buildpkg.GhosttyResources.init(b, &config);
|
||||
const i18n = if (config.i18n) try buildpkg.GhosttyI18n.init(b, &config) else null;
|
||||
|
||||
// Ghostty dependencies used by many artifacts.
|
||||
const deps = try buildpkg.SharedDeps.init(b, &config);
|
||||
if (config.emit_helpgen) deps.help_strings.install();
|
||||
|
||||
// Ghostty executable, the actual runnable Ghostty program.
|
||||
const exe = try buildpkg.GhosttyExe.init(b, &config, &deps);
|
||||
|
||||
|
|
@ -83,6 +96,9 @@ pub fn build(b: *std.Build) !void {
|
|||
&deps,
|
||||
);
|
||||
|
||||
// Helpgen
|
||||
if (config.emit_helpgen) deps.help_strings.install();
|
||||
|
||||
// Runtime "none" is libghostty, anything else is an executable.
|
||||
if (config.app_runtime != .none) {
|
||||
if (config.emit_exe) {
|
||||
|
|
@ -185,7 +201,7 @@ pub fn build(b: *std.Build) !void {
|
|||
run_step.dependOn(&macos_app_native_only.open.step);
|
||||
|
||||
// If we have no test filters, install the tests too
|
||||
if (test_filter == null) {
|
||||
if (test_filters.len == 0) {
|
||||
macos_app_native_only.addTestStepDependencies(test_step);
|
||||
}
|
||||
}
|
||||
|
|
@ -216,11 +232,23 @@ pub fn build(b: *std.Build) !void {
|
|||
run_valgrind_step.dependOn(&run_cmd.step);
|
||||
}
|
||||
|
||||
// Zig module tests
|
||||
{
|
||||
const mod_vt_test = b.addTest(.{
|
||||
.root_module = mod.vt,
|
||||
.target = config.target,
|
||||
.optimize = config.optimize,
|
||||
.filters = test_filters,
|
||||
});
|
||||
test_lib_vt_step.dependOn(&mod_vt_test.step);
|
||||
}
|
||||
|
||||
// Tests
|
||||
{
|
||||
// Full unit tests
|
||||
const test_exe = b.addTest(.{
|
||||
.name = "ghostty-test",
|
||||
.filters = if (test_filter) |v| &.{v} else &.{},
|
||||
.filters = test_filters,
|
||||
.root_module = b.createModule(.{
|
||||
.root_source_file = b.path("src/main.zig"),
|
||||
.target = config.baselineTarget(),
|
||||
|
|
@ -230,7 +258,6 @@ pub fn build(b: *std.Build) !void {
|
|||
.unwind_tables = .sync,
|
||||
}),
|
||||
});
|
||||
|
||||
if (config.emit_test_exe) b.installArtifact(test_exe);
|
||||
_ = try deps.add(test_exe);
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,36 @@
|
|||
//! GhosttyZig generates the Zig modules that Ghostty exports
|
||||
//! for downstream usage.
|
||||
const GhosttyZig = @This();
|
||||
|
||||
const std = @import("std");
|
||||
const Config = @import("Config.zig");
|
||||
const SharedDeps = @import("SharedDeps.zig");
|
||||
|
||||
const vt_options = @import("../terminal/build_options.zig");
|
||||
|
||||
vt: *std.Build.Module,
|
||||
|
||||
pub fn init(
|
||||
b: *std.Build,
|
||||
cfg: *const Config,
|
||||
deps: *const SharedDeps,
|
||||
) !GhosttyZig {
|
||||
const vt = b.addModule("ghostty-vt", .{
|
||||
.root_source_file = b.path("src/lib_vt.zig"),
|
||||
.target = cfg.target,
|
||||
.optimize = cfg.optimize,
|
||||
});
|
||||
deps.unicode_tables.addModuleImport(vt);
|
||||
vt_options.addOptions(b, vt, .{
|
||||
.artifact = .lib,
|
||||
.slow_runtime_safety = switch (cfg.optimize) {
|
||||
.Debug => true,
|
||||
.ReleaseSafe,
|
||||
.ReleaseSmall,
|
||||
.ReleaseFast,
|
||||
=> false,
|
||||
},
|
||||
});
|
||||
|
||||
return .{ .vt = vt };
|
||||
}
|
||||
|
|
@ -107,6 +107,21 @@ pub fn add(
|
|||
// Every exe gets build options populated
|
||||
step.root_module.addOptions("build_options", self.options);
|
||||
|
||||
// Every exe needs the terminal options
|
||||
{
|
||||
const vt_options = @import("../terminal/build_options.zig");
|
||||
vt_options.addOptions(b, step.root_module, .{
|
||||
.artifact = .ghostty,
|
||||
.slow_runtime_safety = switch (optimize) {
|
||||
.Debug => true,
|
||||
.ReleaseSafe,
|
||||
.ReleaseSmall,
|
||||
.ReleaseFast,
|
||||
=> false,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
// Freetype
|
||||
_ = b.systemIntegrationOption("freetype", .{}); // Shows it in help
|
||||
if (self.config.font_backend.hasFreetype()) {
|
||||
|
|
|
|||
|
|
@ -64,11 +64,19 @@ pub fn init(b: *std.Build) !UnicodeTables {
|
|||
/// Add the "unicode_tables" import.
|
||||
pub fn addImport(self: *const UnicodeTables, step: *std.Build.Step.Compile) void {
|
||||
self.props_output.addStepDependencies(&step.step);
|
||||
step.root_module.addAnonymousImport("unicode_tables", .{
|
||||
self.symbols_output.addStepDependencies(&step.step);
|
||||
self.addModuleImport(step.root_module);
|
||||
}
|
||||
|
||||
/// Add the "unicode_tables" import to a module.
|
||||
pub fn addModuleImport(
|
||||
self: *const UnicodeTables,
|
||||
module: *std.Build.Module,
|
||||
) void {
|
||||
module.addAnonymousImport("unicode_tables", .{
|
||||
.root_source_file = self.props_output,
|
||||
});
|
||||
self.symbols_output.addStepDependencies(&step.step);
|
||||
step.root_module.addAnonymousImport("symbols_tables", .{
|
||||
module.addAnonymousImport("symbols_tables", .{
|
||||
.root_source_file = self.symbols_output,
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ pub const GhosttyI18n = @import("GhosttyI18n.zig");
|
|||
pub const GhosttyXcodebuild = @import("GhosttyXcodebuild.zig");
|
||||
pub const GhosttyXCFramework = @import("GhosttyXCFramework.zig");
|
||||
pub const GhosttyWebdata = @import("GhosttyWebdata.zig");
|
||||
pub const GhosttyZig = @import("GhosttyZig.zig");
|
||||
pub const HelpStrings = @import("HelpStrings.zig");
|
||||
pub const SharedDeps = @import("SharedDeps.zig");
|
||||
pub const UnicodeTables = @import("UnicodeTables.zig");
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@ const ArenaAllocator = std.heap.ArenaAllocator;
|
|||
const global_state = &@import("../global.zig").state;
|
||||
const fontpkg = @import("../font/main.zig");
|
||||
const inputpkg = @import("../input.zig");
|
||||
const terminal = @import("../terminal/main.zig");
|
||||
const internal_os = @import("../os/main.zig");
|
||||
const cli = @import("../cli.zig");
|
||||
|
||||
|
|
@ -39,6 +38,16 @@ const RepeatableStringMap = @import("RepeatableStringMap.zig");
|
|||
pub const Path = @import("path.zig").Path;
|
||||
pub const RepeatablePath = @import("path.zig").RepeatablePath;
|
||||
|
||||
// We do this instead of importing all of terminal/main.zig to
|
||||
// limit the dependency graph. This is important because some things
|
||||
// like the `ghostty-build-data` binary depend on the Config but don't
|
||||
// want to include all the other stuff.
|
||||
const terminal = struct {
|
||||
const CursorStyle = @import("../terminal/cursor.zig").Style;
|
||||
const color = @import("../terminal/color.zig");
|
||||
const x11_color = @import("../terminal/x11_color.zig");
|
||||
};
|
||||
|
||||
const log = std.log.scoped(.config);
|
||||
|
||||
/// Used on Unixes for some defaults.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,5 @@
|
|||
const terminal = @import("terminal/main.zig");
|
||||
|
||||
test {
|
||||
_ = terminal;
|
||||
}
|
||||
|
|
@ -6,7 +6,8 @@ const std = @import("std");
|
|||
const builtin = @import("builtin");
|
||||
const testing = std.testing;
|
||||
const Dir = std.fs.Dir;
|
||||
const internal_os = @import("main.zig");
|
||||
const allocTmpDir = @import("file.zig").allocTmpDir;
|
||||
const freeTmpDir = @import("file.zig").freeTmpDir;
|
||||
|
||||
const log = std.log.scoped(.tempdir);
|
||||
|
||||
|
|
@ -31,8 +32,8 @@ pub fn init() !TempDir {
|
|||
|
||||
const dir = dir: {
|
||||
const cwd = std.fs.cwd();
|
||||
const tmp_dir = internal_os.allocTmpDir(std.heap.page_allocator) orelse break :dir cwd;
|
||||
defer internal_os.freeTmpDir(std.heap.page_allocator, tmp_dir);
|
||||
const tmp_dir = allocTmpDir(std.heap.page_allocator) orelse break :dir cwd;
|
||||
defer freeTmpDir(std.heap.page_allocator, tmp_dir);
|
||||
break :dir try cwd.openDir(tmp_dir, .{});
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
const PageList = @This();
|
||||
|
||||
const std = @import("std");
|
||||
const build_config = @import("../build_config.zig");
|
||||
const build_options = @import("terminal_options");
|
||||
const Allocator = std.mem.Allocator;
|
||||
const assert = std.debug.assert;
|
||||
const fastmem = @import("../fastmem.zig");
|
||||
|
|
@ -1492,7 +1492,7 @@ fn resizeWithoutReflow(self: *PageList, opts: Resize) !void {
|
|||
},
|
||||
}
|
||||
|
||||
if (build_config.slow_runtime_safety) {
|
||||
if (build_options.slow_runtime_safety) {
|
||||
assert(self.totalRows() >= self.rows);
|
||||
}
|
||||
}
|
||||
|
|
@ -2524,7 +2524,7 @@ pub fn pin(self: *const PageList, pt: point.Point) ?Pin {
|
|||
/// pin points to is removed completely, the tracked pin will be updated
|
||||
/// to the top-left of the screen.
|
||||
pub fn trackPin(self: *PageList, p: Pin) Allocator.Error!*Pin {
|
||||
if (build_config.slow_runtime_safety) assert(self.pinIsValid(p));
|
||||
if (build_options.slow_runtime_safety) assert(self.pinIsValid(p));
|
||||
|
||||
// Create our tracked pin
|
||||
const tracked = try self.pool.pins.create();
|
||||
|
|
@ -2556,7 +2556,7 @@ pub fn countTrackedPins(self: *const PageList) usize {
|
|||
pub fn pinIsValid(self: *const PageList, p: Pin) bool {
|
||||
// This is very slow so we want to ensure we only ever
|
||||
// call this during slow runtime safety builds.
|
||||
comptime assert(build_config.slow_runtime_safety);
|
||||
comptime assert(build_options.slow_runtime_safety);
|
||||
|
||||
var it = self.pages.first;
|
||||
while (it) |node| : (it = node.next) {
|
||||
|
|
@ -3234,7 +3234,7 @@ pub fn pageIterator(
|
|||
else
|
||||
self.getBottomRight(tl_pt) orelse return .{ .row = null };
|
||||
|
||||
if (build_config.slow_runtime_safety) {
|
||||
if (build_options.slow_runtime_safety) {
|
||||
assert(tl_pin.eql(bl_pin) or tl_pin.before(bl_pin));
|
||||
}
|
||||
|
||||
|
|
@ -3510,7 +3510,7 @@ pub const Pin = struct {
|
|||
direction: Direction,
|
||||
limit: ?Pin,
|
||||
) PageIterator {
|
||||
if (build_config.slow_runtime_safety) {
|
||||
if (build_options.slow_runtime_safety) {
|
||||
if (limit) |l| {
|
||||
// Check the order according to the iteration direction.
|
||||
switch (direction) {
|
||||
|
|
@ -3560,7 +3560,7 @@ pub const Pin = struct {
|
|||
// Note: this is primarily unit tested as part of the Kitty
|
||||
// graphics deletion code.
|
||||
pub fn isBetween(self: Pin, top: Pin, bottom: Pin) bool {
|
||||
if (build_config.slow_runtime_safety) {
|
||||
if (build_options.slow_runtime_safety) {
|
||||
if (top.node == bottom.node) {
|
||||
// If top is bottom, must be ordered.
|
||||
assert(top.y <= bottom.y);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
const Screen = @This();
|
||||
|
||||
const std = @import("std");
|
||||
const build_config = @import("../build_config.zig");
|
||||
const build_options = @import("terminal_options");
|
||||
const Allocator = std.mem.Allocator;
|
||||
const assert = std.debug.assert;
|
||||
const ansi = @import("ansi.zig");
|
||||
|
|
@ -24,6 +24,8 @@ const Row = pagepkg.Row;
|
|||
const Cell = pagepkg.Cell;
|
||||
const Pin = PageList.Pin;
|
||||
|
||||
pub const CursorStyle = @import("cursor.zig").Style;
|
||||
|
||||
const log = std.log.scoped(.screen);
|
||||
|
||||
/// The general purpose allocator to use for all memory allocations.
|
||||
|
|
@ -141,22 +143,6 @@ pub const Cursor = struct {
|
|||
}
|
||||
};
|
||||
|
||||
/// The visual style of the cursor. Whether or not it blinks
|
||||
/// is determined by mode 12 (modes.zig). This mode is synchronized
|
||||
/// with CSI q, the same as xterm.
|
||||
pub const CursorStyle = enum {
|
||||
bar, // DECSCUSR 5, 6
|
||||
block, // DECSCUSR 1, 2
|
||||
underline, // DECSCUSR 3, 4
|
||||
|
||||
/// The cursor styles below aren't known by DESCUSR and are custom
|
||||
/// implemented in Ghostty. They are reported as some standard style
|
||||
/// if requested, though.
|
||||
/// Hollow block cursor. This is a block cursor with the center empty.
|
||||
/// Reported as DECSCUSR 1 or 2 (block).
|
||||
block_hollow,
|
||||
};
|
||||
|
||||
/// Saved cursor state.
|
||||
pub const SavedCursor = struct {
|
||||
x: size.CellCountInt,
|
||||
|
|
@ -232,7 +218,7 @@ pub fn deinit(self: *Screen) void {
|
|||
/// tests. This only asserts the screen specific data so callers should
|
||||
/// ensure they're also calling page integrity checks if necessary.
|
||||
pub fn assertIntegrity(self: *const Screen) void {
|
||||
if (build_config.slow_runtime_safety) {
|
||||
if (build_options.slow_runtime_safety) {
|
||||
// We don't run integrity checks on Valgrind because its soooooo slow,
|
||||
// Valgrind is our integrity checker, and we run these during unit
|
||||
// tests (non-Valgrind) anyways so we're verifying anyways.
|
||||
|
|
@ -772,7 +758,7 @@ pub fn cursorDownScroll(self: *Screen) !void {
|
|||
|
||||
// These assertions help catch some pagelist math errors. Our
|
||||
// x/y should be unchanged after the grow.
|
||||
if (build_config.slow_runtime_safety) {
|
||||
if (build_options.slow_runtime_safety) {
|
||||
const active = self.pages.pointFromPin(
|
||||
.active,
|
||||
page_pin,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,31 @@
|
|||
const std = @import("std");
|
||||
|
||||
pub const Options = struct {
|
||||
/// The target artifact to build. This will gate some functionality.
|
||||
artifact: Artifact = .ghostty,
|
||||
|
||||
/// True if we should enable the "slow" runtime safety checks. These
|
||||
/// are runtime safety checks that are slower than typical and should
|
||||
/// generally be disabled in production builds.
|
||||
slow_runtime_safety: bool = false,
|
||||
};
|
||||
|
||||
pub const Artifact = enum {
|
||||
/// Ghostty application
|
||||
ghostty,
|
||||
|
||||
/// libghostty-vt, Zig module
|
||||
lib,
|
||||
};
|
||||
|
||||
/// Add the required build options for the terminal module.
|
||||
pub fn addOptions(
|
||||
b: *std.Build,
|
||||
m: *std.Build.Module,
|
||||
v: Options,
|
||||
) void {
|
||||
const opts = b.addOptions();
|
||||
opts.addOption(Artifact, "artifact", v.artifact);
|
||||
opts.addOption(bool, "slow_runtime_safety", v.slow_runtime_safety);
|
||||
m.addOptions("terminal_options", opts);
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
/// The visual style of the cursor. Whether or not it blinks
|
||||
/// is determined by mode 12 (modes.zig). This mode is synchronized
|
||||
/// with CSI q, the same as xterm.
|
||||
pub const Style = enum {
|
||||
bar, // DECSCUSR 5, 6
|
||||
block, // DECSCUSR 1, 2
|
||||
underline, // DECSCUSR 3, 4
|
||||
|
||||
/// The cursor styles below aren't known by DESCUSR and are custom
|
||||
/// implemented in Ghostty. They are reported as some standard style
|
||||
/// if requested, though.
|
||||
/// Hollow block cursor. This is a block cursor with the center empty.
|
||||
/// Reported as DECSCUSR 1 or 2 (block).
|
||||
block_hollow,
|
||||
};
|
||||
|
|
@ -9,9 +9,14 @@ const fastmem = @import("../../fastmem.zig");
|
|||
const command = @import("graphics_command.zig");
|
||||
const point = @import("../point.zig");
|
||||
const PageList = @import("../PageList.zig");
|
||||
const internal_os = @import("../../os/main.zig");
|
||||
const wuffs = @import("wuffs");
|
||||
|
||||
const temp_dir = struct {
|
||||
const TempDir = @import("../../os/TempDir.zig");
|
||||
const allocTmpDir = @import("../../os/file.zig").allocTmpDir;
|
||||
const freeTmpDir = @import("../../os/file.zig").freeTmpDir;
|
||||
};
|
||||
|
||||
const log = std.log.scoped(.kitty_gfx);
|
||||
|
||||
/// Maximum width or height of an image. Taken directly from Kitty.
|
||||
|
|
@ -276,8 +281,8 @@ pub const LoadingImage = struct {
|
|||
fn isPathInTempDir(path: []const u8) bool {
|
||||
if (std.mem.startsWith(u8, path, "/tmp")) return true;
|
||||
if (std.mem.startsWith(u8, path, "/dev/shm")) return true;
|
||||
if (internal_os.allocTmpDir(std.heap.page_allocator)) |dir| {
|
||||
defer internal_os.freeTmpDir(std.heap.page_allocator, dir);
|
||||
if (temp_dir.allocTmpDir(std.heap.page_allocator)) |dir| {
|
||||
defer temp_dir.freeTmpDir(std.heap.page_allocator, dir);
|
||||
if (std.mem.startsWith(u8, path, dir)) return true;
|
||||
|
||||
// The temporary dir is sometimes a symlink. On macOS for
|
||||
|
|
@ -690,7 +695,7 @@ test "image load: temporary file without correct path" {
|
|||
const testing = std.testing;
|
||||
const alloc = testing.allocator;
|
||||
|
||||
var tmp_dir = try internal_os.TempDir.init();
|
||||
var tmp_dir = try temp_dir.TempDir.init();
|
||||
defer tmp_dir.deinit();
|
||||
const data = @embedFile("testdata/image-rgb-none-20x15-2147483647-raw.data");
|
||||
try tmp_dir.dir.writeFile(.{
|
||||
|
|
@ -723,7 +728,7 @@ test "image load: rgb, not compressed, temporary file" {
|
|||
const testing = std.testing;
|
||||
const alloc = testing.allocator;
|
||||
|
||||
var tmp_dir = try internal_os.TempDir.init();
|
||||
var tmp_dir = try temp_dir.TempDir.init();
|
||||
defer tmp_dir.deinit();
|
||||
const data = @embedFile("testdata/image-rgb-none-20x15-2147483647-raw.data");
|
||||
try tmp_dir.dir.writeFile(.{
|
||||
|
|
@ -760,7 +765,7 @@ test "image load: rgb, not compressed, regular file" {
|
|||
const testing = std.testing;
|
||||
const alloc = testing.allocator;
|
||||
|
||||
var tmp_dir = try internal_os.TempDir.init();
|
||||
var tmp_dir = try temp_dir.TempDir.init();
|
||||
defer tmp_dir.deinit();
|
||||
const data = @embedFile("testdata/image-rgb-none-20x15-2147483647-raw.data");
|
||||
try tmp_dir.dir.writeFile(.{
|
||||
|
|
@ -795,7 +800,7 @@ test "image load: png, not compressed, regular file" {
|
|||
const testing = std.testing;
|
||||
const alloc = testing.allocator;
|
||||
|
||||
var tmp_dir = try internal_os.TempDir.init();
|
||||
var tmp_dir = try temp_dir.TempDir.init();
|
||||
defer tmp_dir.deinit();
|
||||
const data = @embedFile("testdata/image-png-none-50x76-2147483647-raw.data");
|
||||
try tmp_dir.dir.writeFile(.{
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
const std = @import("std");
|
||||
const build_config = @import("../build_config.zig");
|
||||
const build_options = @import("terminal_options");
|
||||
|
||||
/// The possible cursor shapes. Not all app runtimes support these shapes.
|
||||
/// The shapes are always based on the W3C supported cursor styles so we
|
||||
|
|
@ -48,13 +48,20 @@ pub const MouseShape = enum(c_int) {
|
|||
}
|
||||
|
||||
/// Make this a valid gobject if we're in a GTK environment.
|
||||
pub const getGObjectType = switch (build_config.app_runtime) {
|
||||
.gtk => @import("gobject").ext.defineEnum(
|
||||
MouseShape,
|
||||
.{ .name = "GhosttyMouseShape" },
|
||||
),
|
||||
pub const getGObjectType = gtk: {
|
||||
switch (build_options.artifact) {
|
||||
.ghostty => break :gtk void,
|
||||
.lib => {},
|
||||
}
|
||||
|
||||
.none => void,
|
||||
break :gtk switch (@import("../build_config.zig").app_runtime) {
|
||||
.gtk => @import("gobject").ext.defineEnum(
|
||||
MouseShape,
|
||||
.{ .name = "GhosttyMouseShape" },
|
||||
),
|
||||
|
||||
.none => void,
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
const std = @import("std");
|
||||
const builtin = @import("builtin");
|
||||
const build_config = @import("../build_config.zig");
|
||||
const build_options = @import("terminal_options");
|
||||
const Allocator = std.mem.Allocator;
|
||||
const ArenaAllocator = std.heap.ArenaAllocator;
|
||||
const assert = std.debug.assert;
|
||||
|
|
@ -182,8 +182,8 @@ pub const Page = struct {
|
|||
|
||||
/// If this is true then verifyIntegrity will do nothing. This is
|
||||
/// only present with runtime safety enabled.
|
||||
pause_integrity_checks: if (build_config.slow_runtime_safety) usize else void =
|
||||
if (build_config.slow_runtime_safety) 0 else {},
|
||||
pause_integrity_checks: if (build_options.slow_runtime_safety) usize else void =
|
||||
if (build_options.slow_runtime_safety) 0 else {},
|
||||
|
||||
/// Initialize a new page, allocating the required backing memory.
|
||||
/// The size of the initialized page defaults to the full capacity.
|
||||
|
|
@ -307,7 +307,7 @@ pub const Page = struct {
|
|||
/// doing a lot of operations that would trigger integrity check
|
||||
/// violations but you know the page will end up in a consistent state.
|
||||
pub fn pauseIntegrityChecks(self: *Page, v: bool) void {
|
||||
if (build_config.slow_runtime_safety) {
|
||||
if (build_options.slow_runtime_safety) {
|
||||
if (v) {
|
||||
self.pause_integrity_checks += 1;
|
||||
} else {
|
||||
|
|
@ -320,7 +320,7 @@ pub const Page = struct {
|
|||
/// when runtime safety is enabled. This is a no-op when runtime
|
||||
/// safety is disabled. This uses the libc allocator.
|
||||
pub fn assertIntegrity(self: *const Page) void {
|
||||
if (comptime build_config.slow_runtime_safety) {
|
||||
if (comptime build_options.slow_runtime_safety) {
|
||||
self.verifyIntegrity(std.heap.c_allocator) catch |err| {
|
||||
log.err("page integrity violation, crashing. err={}", .{err});
|
||||
@panic("page integrity violation");
|
||||
|
|
@ -351,7 +351,7 @@ pub const Page = struct {
|
|||
// tests (non-Valgrind) anyways so we're verifying anyways.
|
||||
if (std.valgrind.runningOnValgrind() > 0) return;
|
||||
|
||||
if (build_config.slow_runtime_safety) {
|
||||
if (build_options.slow_runtime_safety) {
|
||||
if (self.pause_integrity_checks > 0) return;
|
||||
}
|
||||
|
||||
|
|
@ -760,7 +760,7 @@ pub const Page = struct {
|
|||
// This is an integrity check: if the row claims it doesn't
|
||||
// have managed memory then all cells must also not have
|
||||
// managed memory.
|
||||
if (build_config.slow_runtime_safety) {
|
||||
if (build_options.slow_runtime_safety) {
|
||||
for (other_cells) |cell| {
|
||||
assert(!cell.hasGrapheme());
|
||||
assert(!cell.hyperlink);
|
||||
|
|
@ -787,7 +787,7 @@ pub const Page = struct {
|
|||
if (src_cell.hasGrapheme()) {
|
||||
// To prevent integrity checks flipping. This will
|
||||
// get fixed up when we check the style id below.
|
||||
if (build_config.slow_runtime_safety) {
|
||||
if (build_options.slow_runtime_safety) {
|
||||
dst_cell.style_id = style.default_id;
|
||||
}
|
||||
|
||||
|
|
@ -914,7 +914,7 @@ pub const Page = struct {
|
|||
|
||||
/// Get the cells for a row.
|
||||
pub fn getCells(self: *const Page, row: *Row) []Cell {
|
||||
if (build_config.slow_runtime_safety) {
|
||||
if (build_options.slow_runtime_safety) {
|
||||
const rows = self.rows.ptr(self.memory);
|
||||
const cells = self.cells.ptr(self.memory);
|
||||
assert(@intFromPtr(row) >= @intFromPtr(rows));
|
||||
|
|
@ -1363,7 +1363,7 @@ pub const Page = struct {
|
|||
pub fn appendGrapheme(self: *Page, row: *Row, cell: *Cell, cp: u21) Allocator.Error!void {
|
||||
defer self.assertIntegrity();
|
||||
|
||||
if (build_config.slow_runtime_safety) assert(cell.codepoint() != 0);
|
||||
if (build_options.slow_runtime_safety) assert(cell.codepoint() != 0);
|
||||
|
||||
const cell_offset = getOffset(Cell, self.memory, cell);
|
||||
var map = self.grapheme_map.map(self.memory);
|
||||
|
|
@ -1436,7 +1436,7 @@ pub const Page = struct {
|
|||
/// there are scenarios where we want to move graphemes without changing
|
||||
/// the content tag. Callers beware but assertIntegrity should catch this.
|
||||
fn moveGrapheme(self: *Page, src: *Cell, dst: *Cell) void {
|
||||
if (build_config.slow_runtime_safety) {
|
||||
if (build_options.slow_runtime_safety) {
|
||||
assert(src.hasGrapheme());
|
||||
assert(!dst.hasGrapheme());
|
||||
}
|
||||
|
|
@ -1453,7 +1453,7 @@ pub const Page = struct {
|
|||
/// Clear the graphemes for a given cell.
|
||||
pub fn clearGrapheme(self: *Page, row: *Row, cell: *Cell) void {
|
||||
defer self.assertIntegrity();
|
||||
if (build_config.slow_runtime_safety) assert(cell.hasGrapheme());
|
||||
if (build_options.slow_runtime_safety) assert(cell.hasGrapheme());
|
||||
|
||||
// Get our entry in the map, which must exist
|
||||
const cell_offset = getOffset(Cell, self.memory, cell);
|
||||
|
|
|
|||
Loading…
Reference in New Issue