mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-04-20 00:18:53 +03:00
remove imgui and devmode
imgui has been a source of compilation challenges (our fault not theirs) and devmode hasn't worked in awhile, so drop it.
This commit is contained in:
25
build.zig
25
build.zig
@ -17,7 +17,6 @@ const glfw = @import("vendor/mach-glfw/build.zig");
|
|||||||
const fontconfig = @import("pkg/fontconfig/build.zig");
|
const fontconfig = @import("pkg/fontconfig/build.zig");
|
||||||
const freetype = @import("pkg/freetype/build.zig");
|
const freetype = @import("pkg/freetype/build.zig");
|
||||||
const harfbuzz = @import("pkg/harfbuzz/build.zig");
|
const harfbuzz = @import("pkg/harfbuzz/build.zig");
|
||||||
const imgui = @import("pkg/imgui/build.zig");
|
|
||||||
const js = @import("vendor/zig-js/build.zig");
|
const js = @import("vendor/zig-js/build.zig");
|
||||||
const libxev = @import("vendor/libxev/build.zig");
|
const libxev = @import("vendor/libxev/build.zig");
|
||||||
const libxml2 = @import("vendor/zig-libxml2/libxml2.zig");
|
const libxml2 = @import("vendor/zig-libxml2/libxml2.zig");
|
||||||
@ -722,16 +721,6 @@ fn addDeps(
|
|||||||
const utf8proc_step = try utf8proc.link(b, step);
|
const utf8proc_step = try utf8proc.link(b, step);
|
||||||
try static_libs.append(utf8proc_step.getEmittedBin());
|
try static_libs.append(utf8proc_step.getEmittedBin());
|
||||||
|
|
||||||
// Imgui, we have to do this later since we need some information
|
|
||||||
const imgui_backends = if (step.target.isDarwin())
|
|
||||||
&[_][]const u8{ "glfw", "opengl3", "metal" }
|
|
||||||
else
|
|
||||||
&[_][]const u8{ "glfw", "opengl3" };
|
|
||||||
var imgui_opts: imgui.Options = .{
|
|
||||||
.backends = imgui_backends,
|
|
||||||
.freetype = .{ .enabled = true },
|
|
||||||
};
|
|
||||||
|
|
||||||
// Dynamic link
|
// Dynamic link
|
||||||
if (!static) {
|
if (!static) {
|
||||||
step.addIncludePath(.{ .path = freetype.include_path_self });
|
step.addIncludePath(.{ .path = freetype.include_path_self });
|
||||||
@ -818,10 +807,6 @@ fn addDeps(
|
|||||||
});
|
});
|
||||||
libxml2_lib.link(fontconfig_step);
|
libxml2_lib.link(fontconfig_step);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Imgui
|
|
||||||
imgui_opts.freetype.step = freetype_step;
|
|
||||||
imgui_opts.freetype.include = &freetype.include_paths;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!lib) {
|
if (!lib) {
|
||||||
@ -846,11 +831,6 @@ fn addDeps(
|
|||||||
.opengl = false,
|
.opengl = false,
|
||||||
};
|
};
|
||||||
try glfw.link(b, step, glfw_opts);
|
try glfw.link(b, step, glfw_opts);
|
||||||
|
|
||||||
// Must also link to imgui
|
|
||||||
step.addModule("imgui", imgui.module(b));
|
|
||||||
const imgui_step = try imgui.link(b, step, imgui_opts);
|
|
||||||
try glfw.link(b, imgui_step, glfw_opts);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
.gtk => {
|
.gtk => {
|
||||||
@ -863,11 +843,6 @@ fn addDeps(
|
|||||||
try glfw.link(b, step, glfw_opts);
|
try glfw.link(b, step, glfw_opts);
|
||||||
|
|
||||||
step.linkSystemLibrary2("gtk4", dynamic_link_opts);
|
step.linkSystemLibrary2("gtk4", dynamic_link_opts);
|
||||||
|
|
||||||
// Must also link to imgui but only for tests.
|
|
||||||
step.addModule("imgui", imgui.module(b));
|
|
||||||
const imgui_step = try imgui.link(b, step, imgui_opts);
|
|
||||||
try glfw.link(b, imgui_step, glfw_opts);
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,140 +0,0 @@
|
|||||||
const std = @import("std");
|
|
||||||
|
|
||||||
/// Directories with our includes.
|
|
||||||
const root = thisDir() ++ "../../../vendor/cimgui/";
|
|
||||||
pub const include_paths = [_][]const u8{
|
|
||||||
root,
|
|
||||||
root ++ "imgui",
|
|
||||||
root ++ "imgui/backends",
|
|
||||||
};
|
|
||||||
|
|
||||||
pub fn module(b: *std.Build) *std.build.Module {
|
|
||||||
return b.createModule(.{
|
|
||||||
.source_file = .{ .path = (comptime thisDir()) ++ "/main.zig" },
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
fn thisDir() []const u8 {
|
|
||||||
return std.fs.path.dirname(@src().file) orelse ".";
|
|
||||||
}
|
|
||||||
|
|
||||||
pub const Options = struct {
|
|
||||||
backends: ?[]const []const u8 = null,
|
|
||||||
|
|
||||||
freetype: Freetype = .{},
|
|
||||||
|
|
||||||
pub const Freetype = struct {
|
|
||||||
enabled: bool = false,
|
|
||||||
step: ?*std.build.LibExeObjStep = null,
|
|
||||||
include: ?[]const []const u8 = null,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
pub fn link(
|
|
||||||
b: *std.Build,
|
|
||||||
step: *std.build.LibExeObjStep,
|
|
||||||
opt: Options,
|
|
||||||
) !*std.build.LibExeObjStep {
|
|
||||||
const lib = try buildImgui(b, step, opt);
|
|
||||||
step.linkLibrary(lib);
|
|
||||||
inline for (include_paths) |path| step.addIncludePath(.{ .path = path });
|
|
||||||
return lib;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn buildImgui(
|
|
||||||
b: *std.Build,
|
|
||||||
step: *std.build.LibExeObjStep,
|
|
||||||
opt: Options,
|
|
||||||
) !*std.build.LibExeObjStep {
|
|
||||||
const target = step.target;
|
|
||||||
const lib = b.addStaticLibrary(.{
|
|
||||||
.name = "imgui",
|
|
||||||
.target = step.target,
|
|
||||||
.optimize = step.optimize,
|
|
||||||
});
|
|
||||||
|
|
||||||
// Include
|
|
||||||
inline for (include_paths) |path| lib.addIncludePath(.{ .path = path });
|
|
||||||
|
|
||||||
// Link
|
|
||||||
lib.linkLibC();
|
|
||||||
|
|
||||||
// Compile
|
|
||||||
var flags = std.ArrayList([]const u8).init(b.allocator);
|
|
||||||
defer flags.deinit();
|
|
||||||
try flags.appendSlice(&.{
|
|
||||||
"-DIMGUI_DISABLE_OBSOLETE_FUNCTIONS=1",
|
|
||||||
|
|
||||||
// We want to always have STB in addition to Freetype to
|
|
||||||
// fix compilation issues with cimgui.
|
|
||||||
"-DIMGUI_ENABLE_STB_TRUETYPE=1",
|
|
||||||
|
|
||||||
//"-fno-sanitize=undefined",
|
|
||||||
});
|
|
||||||
switch (target.getOsTag()) {
|
|
||||||
.windows => try flags.appendSlice(&.{
|
|
||||||
"-DIMGUI_IMPL_API=extern\t\"C\"\t__declspec(dllexport)",
|
|
||||||
}),
|
|
||||||
else => try flags.appendSlice(&.{
|
|
||||||
"-DIMGUI_IMPL_API=extern\t\"C\"\t",
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
|
|
||||||
// Freetype
|
|
||||||
if (opt.freetype.enabled) {
|
|
||||||
if (opt.freetype.step) |freetype|
|
|
||||||
lib.linkLibrary(freetype)
|
|
||||||
else
|
|
||||||
lib.linkSystemLibrary("freetype2");
|
|
||||||
|
|
||||||
if (opt.freetype.include) |dirs|
|
|
||||||
for (dirs) |dir| lib.addIncludePath(.{ .path = dir });
|
|
||||||
|
|
||||||
// Enable in defines
|
|
||||||
try flags.appendSlice(&.{
|
|
||||||
"-DIMGUI_ENABLE_FREETYPE=1",
|
|
||||||
"-DCIMGUI_FREETYPE=1",
|
|
||||||
});
|
|
||||||
|
|
||||||
// Add necessary C file
|
|
||||||
lib.addCSourceFile(.{
|
|
||||||
.file = .{ .path = root ++ "imgui/misc/freetype/imgui_freetype.cpp" },
|
|
||||||
.flags = flags.items,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// C files
|
|
||||||
lib.addCSourceFiles(srcs, flags.items);
|
|
||||||
if (opt.backends) |backends| {
|
|
||||||
for (backends) |backend| {
|
|
||||||
const ext = if (std.mem.eql(u8, "metal", backend)) ext: {
|
|
||||||
// Metal requires some extra frameworks
|
|
||||||
step.linkFramework("QuartzCore");
|
|
||||||
break :ext "mm";
|
|
||||||
} else "cpp";
|
|
||||||
|
|
||||||
var buf: [4096]u8 = undefined;
|
|
||||||
const path = try std.fmt.bufPrint(
|
|
||||||
&buf,
|
|
||||||
"{s}imgui/backends/imgui_impl_{s}.{s}",
|
|
||||||
.{ root, backend, ext },
|
|
||||||
);
|
|
||||||
|
|
||||||
lib.addCSourceFile(.{
|
|
||||||
.file = .{ .path = path },
|
|
||||||
.flags = flags.items,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return lib;
|
|
||||||
}
|
|
||||||
|
|
||||||
const srcs = &.{
|
|
||||||
root ++ "cimgui.cpp",
|
|
||||||
root ++ "imgui/imgui.cpp",
|
|
||||||
root ++ "imgui/imgui_demo.cpp",
|
|
||||||
root ++ "imgui/imgui_draw.cpp",
|
|
||||||
root ++ "imgui/imgui_tables.cpp",
|
|
||||||
root ++ "imgui/imgui_widgets.cpp",
|
|
||||||
};
|
|
@ -1,4 +0,0 @@
|
|||||||
pub usingnamespace @cImport({
|
|
||||||
@cDefine("CIMGUI_DEFINE_ENUMS_AND_STRUCTS", "");
|
|
||||||
@cInclude("cimgui.h");
|
|
||||||
});
|
|
@ -1,31 +0,0 @@
|
|||||||
const std = @import("std");
|
|
||||||
const c = @import("c.zig");
|
|
||||||
const Allocator = std.mem.Allocator;
|
|
||||||
|
|
||||||
pub const Context = opaque {
|
|
||||||
pub fn create() Allocator.Error!*Context {
|
|
||||||
return @as(
|
|
||||||
?*Context,
|
|
||||||
@ptrCast(c.igCreateContext(null)),
|
|
||||||
) orelse Allocator.Error.OutOfMemory;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn destroy(self: *Context) void {
|
|
||||||
c.igDestroyContext(self.cval());
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn setCurrent(self: *Context) void {
|
|
||||||
c.igSetCurrentContext(self.cval());
|
|
||||||
}
|
|
||||||
|
|
||||||
pub inline fn cval(self: *Context) *c.ImGuiContext {
|
|
||||||
return @ptrCast(@alignCast(self));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
test {
|
|
||||||
var ctx = try Context.create();
|
|
||||||
defer ctx.destroy();
|
|
||||||
|
|
||||||
ctx.setCurrent();
|
|
||||||
}
|
|
@ -1,283 +0,0 @@
|
|||||||
const std = @import("std");
|
|
||||||
const c = @import("c.zig");
|
|
||||||
const imgui = @import("main.zig");
|
|
||||||
const Allocator = std.mem.Allocator;
|
|
||||||
|
|
||||||
pub const fltMax = c.igGET_FLT_MAX;
|
|
||||||
pub const fltMin = c.igGET_FLT_MIN;
|
|
||||||
pub const newFrame = c.igNewFrame;
|
|
||||||
pub const endFrame = c.igEndFrame;
|
|
||||||
pub const getTextLineHeight = c.igGetTextLineHeight;
|
|
||||||
pub const render = c.igRender;
|
|
||||||
pub const end = c.igEnd;
|
|
||||||
pub const endTable = c.igEndTable;
|
|
||||||
pub const beginTooltip = c.igBeginTooltip;
|
|
||||||
pub const endTooltip = c.igEndTooltip;
|
|
||||||
pub const spacing = c.igSpacing;
|
|
||||||
pub const text = c.igText;
|
|
||||||
pub const textDisabled = c.igTextDisabled;
|
|
||||||
pub const textWrapped = c.igTextWrapped;
|
|
||||||
pub const button = c.igButton;
|
|
||||||
pub const sameLine = c.igSameLine;
|
|
||||||
pub const getFontSize = c.igGetFontSize;
|
|
||||||
pub const pushTextWrapPos = c.igPushTextWrapPos;
|
|
||||||
pub const popTextWrapPos = c.igPopTextWrapPos;
|
|
||||||
pub const treePop = c.igTreePop;
|
|
||||||
pub const tableHeadersRow = c.igTableHeadersRow;
|
|
||||||
pub const tableNextColumn = c.igTableNextColumn;
|
|
||||||
|
|
||||||
pub fn showDemoWindow(open: ?*bool) void {
|
|
||||||
c.igShowDemoWindow(@ptrCast(if (open) |v| v else null));
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn begin(name: [:0]const u8, open: ?*bool, flags: WindowFlags) bool {
|
|
||||||
return c.igBegin(
|
|
||||||
name.ptr,
|
|
||||||
@ptrCast(if (open) |v| v else null),
|
|
||||||
@bitCast(flags),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn collapsingHeader(
|
|
||||||
label: [:0]const u8,
|
|
||||||
visible: ?*bool,
|
|
||||||
flags: TreeNodeFlags,
|
|
||||||
) bool {
|
|
||||||
return c.igCollapsingHeader_BoolPtr(
|
|
||||||
label.ptr,
|
|
||||||
@ptrCast(if (visible) |v| v else null),
|
|
||||||
@bitCast(flags),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn isItemHovered(flags: HoveredFlags) bool {
|
|
||||||
return c.igIsItemHovered(
|
|
||||||
@bitCast(flags),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn treeNode(
|
|
||||||
label: [:0]const u8,
|
|
||||||
flags: TreeNodeFlags,
|
|
||||||
) bool {
|
|
||||||
return c.igTreeNodeEx_Str(
|
|
||||||
label.ptr,
|
|
||||||
@bitCast(flags),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn beginTable(
|
|
||||||
id: [:0]const u8,
|
|
||||||
cols: c_int,
|
|
||||||
flags: TableFlags,
|
|
||||||
) bool {
|
|
||||||
return c.igBeginTable(
|
|
||||||
id.ptr,
|
|
||||||
cols,
|
|
||||||
@bitCast(flags),
|
|
||||||
.{ .x = 0, .y = 0 },
|
|
||||||
0,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn tableNextRow(min_height: f32) void {
|
|
||||||
c.igTableNextRow(0, min_height);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn tableSetupColumn(
|
|
||||||
label: [:0]const u8,
|
|
||||||
flags: TableColumnFlags,
|
|
||||||
init_size: f32,
|
|
||||||
) void {
|
|
||||||
c.igTableSetupColumn(
|
|
||||||
label.ptr,
|
|
||||||
@bitCast(flags),
|
|
||||||
init_size,
|
|
||||||
0,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn inputTextMultiline(
|
|
||||||
label: [:0]const u8,
|
|
||||||
buf: []u8,
|
|
||||||
size: c.ImVec2,
|
|
||||||
flags: InputTextFlags,
|
|
||||||
) bool {
|
|
||||||
return c.igInputTextMultiline(
|
|
||||||
label.ptr,
|
|
||||||
buf.ptr,
|
|
||||||
buf.len,
|
|
||||||
size,
|
|
||||||
@bitCast(flags),
|
|
||||||
null,
|
|
||||||
null,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub const WindowFlags = packed struct {
|
|
||||||
no_title_bar: bool = false,
|
|
||||||
no_resize: bool = false,
|
|
||||||
no_move: bool = false,
|
|
||||||
no_scrollbar: bool = false,
|
|
||||||
no_scrollbar_with_mouse: bool = false,
|
|
||||||
no_collapse: bool = false,
|
|
||||||
always_auto_resize: bool = false,
|
|
||||||
no_background: bool = false,
|
|
||||||
no_saved_settings: bool = false,
|
|
||||||
no_mouse_inputs: bool = false,
|
|
||||||
menu_bar: bool = false,
|
|
||||||
horizontal_scroll_bar: bool = false,
|
|
||||||
no_focus_on_appearing: bool = false,
|
|
||||||
no_bring_to_front_on_focus: bool = false,
|
|
||||||
always_vertical_scrollbar: bool = false,
|
|
||||||
always_horizontal_scrollbar: bool = false,
|
|
||||||
always_use_window_padding: bool = false,
|
|
||||||
no_nav_inputs: bool = false,
|
|
||||||
no_nav_focus: bool = false,
|
|
||||||
unsaved_document: bool = false,
|
|
||||||
no_docking: bool = false,
|
|
||||||
_unusued_1: u1 = 0,
|
|
||||||
nav_flattened: bool = false,
|
|
||||||
child_window: bool = false,
|
|
||||||
tooltip: bool = false,
|
|
||||||
popup: bool = false,
|
|
||||||
modal: bool = false,
|
|
||||||
child_menu: bool = false,
|
|
||||||
dock_node_host: bool = false,
|
|
||||||
_padding: u3 = 0,
|
|
||||||
|
|
||||||
test {
|
|
||||||
try std.testing.expectEqual(@bitSizeOf(c_int), @bitSizeOf(WindowFlags));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
pub const TreeNodeFlags = packed struct {
|
|
||||||
selected: bool = false,
|
|
||||||
framed: bool = false,
|
|
||||||
allow_item_overlap: bool = false,
|
|
||||||
no_tree_push_on_open: bool = false,
|
|
||||||
no_auto_open_on_log: bool = false,
|
|
||||||
default_open: bool = false,
|
|
||||||
open_on_double_click: bool = false,
|
|
||||||
open_on_arrow: bool = false,
|
|
||||||
leaf: bool = false,
|
|
||||||
bullet: bool = false,
|
|
||||||
frame_padding: bool = false,
|
|
||||||
span_avail_width: bool = false,
|
|
||||||
span_full_width: bool = false,
|
|
||||||
nav_left_jumps_back_here: bool = false,
|
|
||||||
_padding: u18 = 0,
|
|
||||||
|
|
||||||
test {
|
|
||||||
try std.testing.expectEqual(@bitSizeOf(c_int), @bitSizeOf(TreeNodeFlags));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
pub const TableFlags = packed struct(u32) {
|
|
||||||
resizable: bool = false,
|
|
||||||
reorderable: bool = false,
|
|
||||||
hideable: bool = false,
|
|
||||||
sortable: bool = false,
|
|
||||||
no_saved_settings: bool = false,
|
|
||||||
context_menu_in_body: bool = false,
|
|
||||||
row_bg: bool = false,
|
|
||||||
borders_inner_h: bool = false,
|
|
||||||
borders_outer_h: bool = false,
|
|
||||||
borders_inner_v: bool = false,
|
|
||||||
borders_outer_v: bool = false,
|
|
||||||
no_borders_in_body: bool = false,
|
|
||||||
no_borders_in_body_until_resize: bool = false,
|
|
||||||
sizing_fixed_fit: bool = false,
|
|
||||||
sizing_fixed_same: bool = false,
|
|
||||||
sizing_stretch_prop: bool = false,
|
|
||||||
sizing_stretch_same: bool = false,
|
|
||||||
no_host_extend_x: bool = false,
|
|
||||||
no_host_extend_y: bool = false,
|
|
||||||
no_keep_columns_visible: bool = false,
|
|
||||||
precise_widths: bool = false,
|
|
||||||
no_clip: bool = false,
|
|
||||||
pad_outer_x: bool = false,
|
|
||||||
no_pad_outer_x: bool = false,
|
|
||||||
no_pad_inner_x: bool = false,
|
|
||||||
scroll_x: bool = false,
|
|
||||||
scroll_y: bool = false,
|
|
||||||
sort_multi: bool = false,
|
|
||||||
sort_tristate: bool = false,
|
|
||||||
_padding: u3 = 0,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub const TableColumnFlags = packed struct(u32) {
|
|
||||||
disabled: bool = false,
|
|
||||||
default_hide: bool = false,
|
|
||||||
default_sort: bool = false,
|
|
||||||
width_stretch: bool = false,
|
|
||||||
width_fixed: bool = false,
|
|
||||||
no_resize: bool = false,
|
|
||||||
no_reorder: bool = false,
|
|
||||||
no_hide: bool = false,
|
|
||||||
no_clip: bool = false,
|
|
||||||
no_sort: bool = false,
|
|
||||||
no_sort_ascending: bool = false,
|
|
||||||
no_sort_descending: bool = false,
|
|
||||||
no_header_label: bool = false,
|
|
||||||
no_header_width: bool = false,
|
|
||||||
prefer_sort_ascending: bool = false,
|
|
||||||
prefer_sort_descending: bool = false,
|
|
||||||
indent_enable: bool = false,
|
|
||||||
indent_disable: bool = false,
|
|
||||||
is_enabled: bool = false,
|
|
||||||
is_visible: bool = false,
|
|
||||||
is_sorted: bool = false,
|
|
||||||
is_hovered: bool = false,
|
|
||||||
_unused: u10 = 0,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub const InputTextFlags = packed struct(c_int) {
|
|
||||||
chars_decimal: bool = false,
|
|
||||||
chars_hexadecimal: bool = false,
|
|
||||||
chars_uppercase: bool = false,
|
|
||||||
chars_no_blank: bool = false,
|
|
||||||
auto_select_all: bool = false,
|
|
||||||
enter_returns_true: bool = false,
|
|
||||||
callback_completion: bool = false,
|
|
||||||
callback_history: bool = false,
|
|
||||||
callback_always: bool = false,
|
|
||||||
callback_char_filter: bool = false,
|
|
||||||
allow_tab_input: bool = false,
|
|
||||||
ctrl_enter_for_newline: bool = false,
|
|
||||||
no_horizontal_scroll: bool = false,
|
|
||||||
always_overwrite: bool = false,
|
|
||||||
read_only: bool = false,
|
|
||||||
password: bool = false,
|
|
||||||
no_undo_redo: bool = false,
|
|
||||||
chars_scientific: bool = false,
|
|
||||||
callback_resize: bool = false,
|
|
||||||
callback_edit: bool = false,
|
|
||||||
_padding: u12 = 0,
|
|
||||||
|
|
||||||
test {
|
|
||||||
try std.testing.expectEqual(@bitSizeOf(c_int), @bitSizeOf(InputTextFlags));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
pub const HoveredFlags = packed struct {
|
|
||||||
child_windows: bool = false,
|
|
||||||
root_window: bool = false,
|
|
||||||
any_window: bool = false,
|
|
||||||
no_popup_hierarchy: bool = false,
|
|
||||||
dock_hierarchy: bool = false,
|
|
||||||
allow_when_blocked_by_popup: bool = false,
|
|
||||||
allow_when_blocked_by_active_item: bool = false,
|
|
||||||
allow_when_overlapped: bool = false,
|
|
||||||
allow_when_disabled: bool = false,
|
|
||||||
no_nav_override: bool = false,
|
|
||||||
_padding: u22 = 0,
|
|
||||||
|
|
||||||
test {
|
|
||||||
try std.testing.expectEqual(@bitSizeOf(c_int), @bitSizeOf(HoveredFlags));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
test {
|
|
||||||
@import("std").testing.refAllDecls(@This());
|
|
||||||
}
|
|
@ -1,17 +0,0 @@
|
|||||||
const std = @import("std");
|
|
||||||
const c = @import("c.zig");
|
|
||||||
const imgui = @import("main.zig");
|
|
||||||
const Allocator = std.mem.Allocator;
|
|
||||||
|
|
||||||
pub const DrawData = opaque {
|
|
||||||
pub fn get() Allocator.Error!*DrawData {
|
|
||||||
return @as(
|
|
||||||
?*DrawData,
|
|
||||||
@ptrCast(c.igGetDrawData()),
|
|
||||||
) orelse Allocator.Error.OutOfMemory;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub inline fn cval(self: *DrawData) *c.ImGuiDrawData {
|
|
||||||
return @ptrCast(@alignCast(self));
|
|
||||||
}
|
|
||||||
};
|
|
@ -1,31 +0,0 @@
|
|||||||
const std = @import("std");
|
|
||||||
const c = @import("c.zig");
|
|
||||||
const imgui = @import("main.zig");
|
|
||||||
const Allocator = std.mem.Allocator;
|
|
||||||
|
|
||||||
pub const FontAtlas = opaque {
|
|
||||||
pub fn addFontFromMemoryTTF(
|
|
||||||
self: *FontAtlas,
|
|
||||||
data: []const u8,
|
|
||||||
size_px: f32,
|
|
||||||
) void {
|
|
||||||
// We never want the data to be copied by the Atlas, its not
|
|
||||||
// very Zig-like, so we just always set this to false.
|
|
||||||
var cfg = c.ImFontConfig_ImFontConfig();
|
|
||||||
cfg.*.FontDataOwnedByAtlas = false;
|
|
||||||
defer c.ImFontConfig_destroy(cfg);
|
|
||||||
|
|
||||||
_ = c.ImFontAtlas_AddFontFromMemoryTTF(
|
|
||||||
self.cval(),
|
|
||||||
@ptrFromInt(@intFromPtr(data.ptr)),
|
|
||||||
@intCast(data.len),
|
|
||||||
size_px,
|
|
||||||
cfg,
|
|
||||||
null,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub inline fn cval(self: *FontAtlas) *c.ImFontAtlas {
|
|
||||||
return @ptrCast(@alignCast(self));
|
|
||||||
}
|
|
||||||
};
|
|
@ -1,33 +0,0 @@
|
|||||||
const std = @import("std");
|
|
||||||
const c = @import("c.zig");
|
|
||||||
const imgui = @import("main.zig");
|
|
||||||
const Allocator = std.mem.Allocator;
|
|
||||||
|
|
||||||
pub const ImplGlfw = struct {
|
|
||||||
pub const GLFWWindow = opaque {};
|
|
||||||
|
|
||||||
pub fn initForOpenGL(win: *GLFWWindow, install_callbacks: bool) bool {
|
|
||||||
// https://github.com/ocornut/imgui/issues/5785
|
|
||||||
defer _ = glfwGetError(null);
|
|
||||||
|
|
||||||
return ImGui_ImplGlfw_InitForOpenGL(win, install_callbacks);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn initForOther(win: *GLFWWindow, install_callbacks: bool) bool {
|
|
||||||
return ImGui_ImplGlfw_InitForOther(win, install_callbacks);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn shutdown() void {
|
|
||||||
return ImGui_ImplGlfw_Shutdown();
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn newFrame() void {
|
|
||||||
return ImGui_ImplGlfw_NewFrame();
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "c" fn glfwGetError(?*const anyopaque) c_int;
|
|
||||||
extern "c" fn ImGui_ImplGlfw_InitForOpenGL(*GLFWWindow, bool) bool;
|
|
||||||
extern "c" fn ImGui_ImplGlfw_InitForOther(*GLFWWindow, bool) bool;
|
|
||||||
extern "c" fn ImGui_ImplGlfw_Shutdown() void;
|
|
||||||
extern "c" fn ImGui_ImplGlfw_NewFrame() void;
|
|
||||||
};
|
|
@ -1,31 +0,0 @@
|
|||||||
const std = @import("std");
|
|
||||||
const c = @import("c.zig");
|
|
||||||
const imgui = @import("main.zig");
|
|
||||||
const Allocator = std.mem.Allocator;
|
|
||||||
|
|
||||||
pub const ImplMetal = struct {
|
|
||||||
pub fn init(device: ?*anyopaque) bool {
|
|
||||||
return ImGui_ImplMetal_Init(device);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn shutdown() void {
|
|
||||||
return ImGui_ImplMetal_Shutdown();
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn newFrame(render_pass_desc: ?*anyopaque) void {
|
|
||||||
return ImGui_ImplMetal_NewFrame(render_pass_desc);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn renderDrawData(
|
|
||||||
data: *imgui.DrawData,
|
|
||||||
command_buffer: ?*anyopaque,
|
|
||||||
command_encoder: ?*anyopaque,
|
|
||||||
) void {
|
|
||||||
ImGui_ImplMetal_RenderDrawData(data, command_buffer, command_encoder);
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "c" fn ImGui_ImplMetal_Init(?*anyopaque) bool;
|
|
||||||
extern "c" fn ImGui_ImplMetal_Shutdown() void;
|
|
||||||
extern "c" fn ImGui_ImplMetal_NewFrame(?*anyopaque) void;
|
|
||||||
extern "c" fn ImGui_ImplMetal_RenderDrawData(*imgui.DrawData, ?*anyopaque, ?*anyopaque) void;
|
|
||||||
};
|
|
@ -1,30 +0,0 @@
|
|||||||
const std = @import("std");
|
|
||||||
const c = @import("c.zig");
|
|
||||||
const imgui = @import("main.zig");
|
|
||||||
const Allocator = std.mem.Allocator;
|
|
||||||
|
|
||||||
pub const ImplOpenGL3 = struct {
|
|
||||||
pub fn init(glsl_version: ?[:0]const u8) bool {
|
|
||||||
return ImGui_ImplOpenGL3_Init(
|
|
||||||
if (glsl_version) |s| s.ptr else null,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn shutdown() void {
|
|
||||||
return ImGui_ImplOpenGL3_Shutdown();
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn newFrame() void {
|
|
||||||
return ImGui_ImplOpenGL3_NewFrame();
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn renderDrawData(data: *imgui.DrawData) void {
|
|
||||||
ImGui_ImplOpenGL3_RenderDrawData(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "c" fn glfwGetError(?*const anyopaque) c_int;
|
|
||||||
extern "c" fn ImGui_ImplOpenGL3_Init([*c]const u8) bool;
|
|
||||||
extern "c" fn ImGui_ImplOpenGL3_Shutdown() void;
|
|
||||||
extern "c" fn ImGui_ImplOpenGL3_NewFrame() void;
|
|
||||||
extern "c" fn ImGui_ImplOpenGL3_RenderDrawData(*imgui.DrawData) void;
|
|
||||||
};
|
|
@ -1,23 +0,0 @@
|
|||||||
const std = @import("std");
|
|
||||||
const c = @import("c.zig");
|
|
||||||
const imgui = @import("main.zig");
|
|
||||||
const Allocator = std.mem.Allocator;
|
|
||||||
|
|
||||||
pub const IO = opaque {
|
|
||||||
pub fn get() Allocator.Error!*IO {
|
|
||||||
return @as(
|
|
||||||
?*IO,
|
|
||||||
@ptrCast(c.igGetIO()),
|
|
||||||
) orelse Allocator.Error.OutOfMemory;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub inline fn cval(self: *IO) *c.ImGuiIO {
|
|
||||||
return @ptrCast(@alignCast(self));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
test {
|
|
||||||
const ctx = try imgui.Context.create();
|
|
||||||
defer ctx.destroy();
|
|
||||||
_ = try IO.get();
|
|
||||||
}
|
|
@ -1,15 +0,0 @@
|
|||||||
pub const c = @import("c.zig");
|
|
||||||
pub usingnamespace @import("context.zig");
|
|
||||||
pub usingnamespace @import("core.zig");
|
|
||||||
pub usingnamespace @import("draw_data.zig");
|
|
||||||
pub usingnamespace @import("font_atlas.zig");
|
|
||||||
pub usingnamespace @import("io.zig");
|
|
||||||
pub usingnamespace @import("style.zig");
|
|
||||||
|
|
||||||
pub usingnamespace @import("impl_glfw.zig");
|
|
||||||
pub usingnamespace @import("impl_metal.zig");
|
|
||||||
pub usingnamespace @import("impl_opengl3.zig");
|
|
||||||
|
|
||||||
test {
|
|
||||||
@import("std").testing.refAllDecls(@This());
|
|
||||||
}
|
|
@ -1,32 +0,0 @@
|
|||||||
const std = @import("std");
|
|
||||||
const c = @import("c.zig");
|
|
||||||
const Allocator = std.mem.Allocator;
|
|
||||||
|
|
||||||
pub const Style = opaque {
|
|
||||||
pub fn get() Allocator.Error!*Style {
|
|
||||||
return @as(
|
|
||||||
?*Style,
|
|
||||||
@ptrCast(c.igGetStyle()),
|
|
||||||
) orelse Allocator.Error.OutOfMemory;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn colorsDark(self: *Style) void {
|
|
||||||
c.igStyleColorsDark(self.cval());
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn colorsLight(self: *Style) void {
|
|
||||||
c.igStyleColorsLight(self.cval());
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn colorsClassic(self: *Style) void {
|
|
||||||
c.igStyleColorsClassic(self.cval());
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn scaleAllSizes(self: *Style, factor: f32) void {
|
|
||||||
c.ImGuiStyle_ScaleAllSizes(self.cval(), factor);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub inline fn cval(self: *Style) *c.ImGuiStyle {
|
|
||||||
return @ptrCast(@alignCast(self));
|
|
||||||
}
|
|
||||||
};
|
|
180
src/DevMode.zig
180
src/DevMode.zig
@ -1,180 +0,0 @@
|
|||||||
//! This file implements the "dev mode" interface for the terminal. This
|
|
||||||
//! includes state managements and rendering.
|
|
||||||
const DevMode = @This();
|
|
||||||
|
|
||||||
const std = @import("std");
|
|
||||||
const builtin = @import("builtin");
|
|
||||||
const build_config = @import("build_config.zig");
|
|
||||||
const imgui = @import("imgui");
|
|
||||||
const Allocator = std.mem.Allocator;
|
|
||||||
const assert = std.debug.assert;
|
|
||||||
|
|
||||||
const font = @import("font/main.zig");
|
|
||||||
const Surface = @import("Surface.zig");
|
|
||||||
const renderer = @import("renderer.zig");
|
|
||||||
const Config = @import("config.zig").Config;
|
|
||||||
|
|
||||||
/// If this is false, the rest of the terminal will be compiled without
|
|
||||||
/// dev mode support at all.
|
|
||||||
/// TODO: remove this and use build_config everywhere
|
|
||||||
pub const enabled = build_config.devmode_enabled;
|
|
||||||
|
|
||||||
/// The global DevMode instance that can be used app-wide. Assume all functions
|
|
||||||
/// are NOT thread-safe unless otherwise noted.
|
|
||||||
pub var instance: DevMode = .{};
|
|
||||||
|
|
||||||
/// Whether to show the dev mode UI currently.
|
|
||||||
visible: bool = false,
|
|
||||||
|
|
||||||
/// Our app config
|
|
||||||
config: ?Config = null,
|
|
||||||
|
|
||||||
/// The surface we're tracking.
|
|
||||||
surface: ?*Surface = null,
|
|
||||||
|
|
||||||
/// Update the state associated with the dev mode. This should generally
|
|
||||||
/// only be called paired with a render since it otherwise wastes CPU
|
|
||||||
/// cycles.
|
|
||||||
///
|
|
||||||
/// Note: renderers should call their implementation "newFrame" functions
|
|
||||||
/// prior to this.
|
|
||||||
pub fn update(self: *const DevMode) !void {
|
|
||||||
// Buffer that can be used for stuff...
|
|
||||||
var buf: [1024 * 32]u8 = undefined;
|
|
||||||
|
|
||||||
imgui.newFrame();
|
|
||||||
|
|
||||||
if (imgui.begin("dev mode", null, .{})) {
|
|
||||||
defer imgui.end();
|
|
||||||
|
|
||||||
if (self.config) |config| {
|
|
||||||
if (imgui.collapsingHeader("Ghostty Configuration", null, .{})) {
|
|
||||||
if (imgui.beginTable("config", 2, .{
|
|
||||||
.row_bg = true,
|
|
||||||
.borders_inner_h = true,
|
|
||||||
.borders_outer_h = true,
|
|
||||||
.borders_inner_v = true,
|
|
||||||
.borders_outer_v = true,
|
|
||||||
})) {
|
|
||||||
defer imgui.endTable();
|
|
||||||
|
|
||||||
// Setup headers
|
|
||||||
imgui.tableSetupColumn("Key", .{}, 0);
|
|
||||||
imgui.tableSetupColumn("Value", .{}, 0);
|
|
||||||
imgui.tableHeadersRow();
|
|
||||||
|
|
||||||
// Values
|
|
||||||
imgui.tableNextRow(0);
|
|
||||||
_ = imgui.tableNextColumn();
|
|
||||||
imgui.text("font-family");
|
|
||||||
_ = imgui.tableNextColumn();
|
|
||||||
imgui.text((try std.fmt.bufPrintZ(&buf, "{any}", .{config.@"font-family"})).ptr);
|
|
||||||
|
|
||||||
imgui.tableNextRow(0);
|
|
||||||
_ = imgui.tableNextColumn();
|
|
||||||
imgui.text("click-repeat-interval");
|
|
||||||
_ = imgui.tableNextColumn();
|
|
||||||
imgui.text((try std.fmt.bufPrintZ(&buf, "{d}", .{config.@"click-repeat-interval"})).ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (imgui.treeNode("Raw Config (Advanced & Ugly)", .{})) {
|
|
||||||
defer imgui.treePop();
|
|
||||||
|
|
||||||
var raw = try std.fmt.bufPrintZ(&buf, "{}", .{config});
|
|
||||||
imgui.textWrapped("%s", raw.ptr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (self.surface) |surface| {
|
|
||||||
if (imgui.collapsingHeader("Font Manager", null, .{})) {
|
|
||||||
imgui.text("Glyphs: %d", surface.font_group.glyphs.count());
|
|
||||||
imgui.sameLine(0, -1);
|
|
||||||
helpMarker("The number of glyphs loaded and rendered into a " ++
|
|
||||||
"font atlas currently.");
|
|
||||||
|
|
||||||
const Renderer = @TypeOf(surface.renderer);
|
|
||||||
if (imgui.treeNode("Atlas: Greyscale", .{ .default_open = true })) {
|
|
||||||
defer imgui.treePop();
|
|
||||||
const atlas = &surface.font_group.atlas_greyscale;
|
|
||||||
const tex: usize = switch (Renderer) {
|
|
||||||
renderer.OpenGL => @intCast(surface.renderer.texture.id),
|
|
||||||
renderer.Metal => @intFromPtr(surface.renderer.texture_greyscale.value),
|
|
||||||
else => @compileError("renderer unsupported, add it!"),
|
|
||||||
};
|
|
||||||
try self.atlasInfo(atlas, tex);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (imgui.treeNode("Atlas: Color (Emoji)", .{ .default_open = true })) {
|
|
||||||
defer imgui.treePop();
|
|
||||||
const atlas = &surface.font_group.atlas_color;
|
|
||||||
const tex: usize = switch (Renderer) {
|
|
||||||
renderer.OpenGL => @intCast(surface.renderer.texture_color.id),
|
|
||||||
renderer.Metal => @intFromPtr(surface.renderer.texture_color.value),
|
|
||||||
else => @compileError("renderer unsupported, add it!"),
|
|
||||||
};
|
|
||||||
try self.atlasInfo(atlas, tex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Just demo for now
|
|
||||||
// imgui.showDemoWindow(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Render the scene and return the draw data. The caller must be imgui-aware
|
|
||||||
/// in order to render the draw data. This lets this file be renderer/backend
|
|
||||||
/// agnostic.
|
|
||||||
pub fn render(self: DevMode) !*imgui.DrawData {
|
|
||||||
_ = self;
|
|
||||||
imgui.render();
|
|
||||||
return try imgui.DrawData.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Helper to render a tooltip.
|
|
||||||
fn helpMarker(desc: [:0]const u8) void {
|
|
||||||
imgui.textDisabled("(?)");
|
|
||||||
if (imgui.isItemHovered(.{})) {
|
|
||||||
imgui.beginTooltip();
|
|
||||||
defer imgui.endTooltip();
|
|
||||||
imgui.pushTextWrapPos(imgui.getFontSize() * 35);
|
|
||||||
defer imgui.popTextWrapPos();
|
|
||||||
imgui.text(desc.ptr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn atlasInfo(self: *const DevMode, atlas: *font.Atlas, tex: ?usize) !void {
|
|
||||||
_ = self;
|
|
||||||
|
|
||||||
imgui.text("Dimensions: %d x %d", atlas.size, atlas.size);
|
|
||||||
imgui.sameLine(0, -1);
|
|
||||||
helpMarker("The pixel dimensions of the atlas texture.");
|
|
||||||
|
|
||||||
imgui.text("Size: %d KB", atlas.data.len >> 10);
|
|
||||||
imgui.sameLine(0, -1);
|
|
||||||
helpMarker("The byte size of the atlas texture.");
|
|
||||||
|
|
||||||
var buf: [1024]u8 = undefined;
|
|
||||||
imgui.text(
|
|
||||||
"Format: %s (depth = %d)",
|
|
||||||
(try std.fmt.bufPrintZ(&buf, "{}", .{atlas.format})).ptr,
|
|
||||||
atlas.format.depth(),
|
|
||||||
);
|
|
||||||
imgui.sameLine(0, -1);
|
|
||||||
helpMarker("The internal storage format of this atlas.");
|
|
||||||
|
|
||||||
if (tex) |id| {
|
|
||||||
imgui.c.igImage(
|
|
||||||
@ptrFromInt(id),
|
|
||||||
.{
|
|
||||||
.x = @floatFromInt(atlas.size),
|
|
||||||
.y = @floatFromInt(atlas.size),
|
|
||||||
},
|
|
||||||
.{ .x = 0, .y = 0 },
|
|
||||||
.{ .x = 1, .y = 1 },
|
|
||||||
.{ .x = 1, .y = 1, .z = 1, .w = 1 },
|
|
||||||
.{ .x = 0, .y = 0, .z = 0, .w = 0 },
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
@ -31,7 +31,6 @@ const trace = @import("tracy").trace;
|
|||||||
const terminal = @import("terminal/main.zig");
|
const terminal = @import("terminal/main.zig");
|
||||||
const configpkg = @import("config.zig");
|
const configpkg = @import("config.zig");
|
||||||
const input = @import("input.zig");
|
const input = @import("input.zig");
|
||||||
const DevMode = @import("DevMode.zig");
|
|
||||||
const App = @import("App.zig");
|
const App = @import("App.zig");
|
||||||
const internal_os = @import("os/main.zig");
|
const internal_os = @import("os/main.zig");
|
||||||
|
|
||||||
@ -54,9 +53,6 @@ font_lib: font.Library,
|
|||||||
font_group: *font.GroupCache,
|
font_group: *font.GroupCache,
|
||||||
font_size: font.face.DesiredSize,
|
font_size: font.face.DesiredSize,
|
||||||
|
|
||||||
/// Imgui context
|
|
||||||
imgui_ctx: if (DevMode.enabled) *imgui.Context else void,
|
|
||||||
|
|
||||||
/// The renderer for this surface.
|
/// The renderer for this surface.
|
||||||
renderer: Renderer,
|
renderer: Renderer,
|
||||||
|
|
||||||
@ -419,11 +415,6 @@ pub fn init(
|
|||||||
var io_thread = try termio.Thread.init(alloc, &self.io);
|
var io_thread = try termio.Thread.init(alloc, &self.io);
|
||||||
errdefer io_thread.deinit();
|
errdefer io_thread.deinit();
|
||||||
|
|
||||||
// True if this surface is hosting devmode. We only host devmode on
|
|
||||||
// the first surface since imgui is not threadsafe. We need to do some
|
|
||||||
// work to make DevMode work with multiple threads.
|
|
||||||
const host_devmode = DevMode.enabled and DevMode.instance.surface == null;
|
|
||||||
|
|
||||||
self.* = .{
|
self.* = .{
|
||||||
.alloc = alloc,
|
.alloc = alloc,
|
||||||
.app_mailbox = app_mailbox,
|
.app_mailbox = app_mailbox,
|
||||||
@ -440,7 +431,6 @@ pub fn init(
|
|||||||
.visible = true,
|
.visible = true,
|
||||||
},
|
},
|
||||||
.terminal = &self.io.terminal,
|
.terminal = &self.io.terminal,
|
||||||
.devmode = if (!host_devmode) null else &DevMode.instance,
|
|
||||||
},
|
},
|
||||||
.renderer_thr = undefined,
|
.renderer_thr = undefined,
|
||||||
.mouse = .{},
|
.mouse = .{},
|
||||||
@ -452,10 +442,7 @@ pub fn init(
|
|||||||
.cell_size = cell_size,
|
.cell_size = cell_size,
|
||||||
.padding = padding,
|
.padding = padding,
|
||||||
.config = try DerivedConfig.init(alloc, config),
|
.config = try DerivedConfig.init(alloc, config),
|
||||||
|
|
||||||
.imgui_ctx = if (!DevMode.enabled) {} else try imgui.Context.create(),
|
|
||||||
};
|
};
|
||||||
errdefer if (DevMode.enabled) self.imgui_ctx.destroy();
|
|
||||||
|
|
||||||
// Set a minimum size that is cols=10 h=4. This matches Mac's Terminal.app
|
// Set a minimum size that is cols=10 h=4. This matches Mac's Terminal.app
|
||||||
// but is otherwise somewhat arbitrary.
|
// but is otherwise somewhat arbitrary.
|
||||||
@ -471,30 +458,6 @@ pub fn init(
|
|||||||
// to duplicate.
|
// to duplicate.
|
||||||
try self.sizeCallback(surface_size);
|
try self.sizeCallback(surface_size);
|
||||||
|
|
||||||
// Load imgui. This must be done LAST because it has to be done after
|
|
||||||
// all our GLFW setup is complete.
|
|
||||||
if (DevMode.enabled and DevMode.instance.surface == null) {
|
|
||||||
const dev_io = try imgui.IO.get();
|
|
||||||
dev_io.cval().IniFilename = "ghostty_dev_mode.ini";
|
|
||||||
|
|
||||||
// Add our built-in fonts so it looks slightly better
|
|
||||||
const dev_atlas: *imgui.FontAtlas = @ptrCast(dev_io.cval().Fonts);
|
|
||||||
dev_atlas.addFontFromMemoryTTF(
|
|
||||||
face_ttf,
|
|
||||||
@floatFromInt(font_size.pixels()),
|
|
||||||
);
|
|
||||||
|
|
||||||
// Default dark style
|
|
||||||
const style = try imgui.Style.get();
|
|
||||||
style.colorsDark();
|
|
||||||
|
|
||||||
// Add our surface to the instance if it isn't set.
|
|
||||||
DevMode.instance.surface = self;
|
|
||||||
|
|
||||||
// Let our renderer setup
|
|
||||||
try renderer_impl.initDevMode(rt_surface);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Give the renderer one more opportunity to finalize any surface
|
// Give the renderer one more opportunity to finalize any surface
|
||||||
// setup on the main thread prior to spinning up the rendering thread.
|
// setup on the main thread prior to spinning up the rendering thread.
|
||||||
try renderer_impl.finalizeSurfaceInit(rt_surface);
|
try renderer_impl.finalizeSurfaceInit(rt_surface);
|
||||||
@ -525,18 +488,6 @@ pub fn deinit(self: *Surface) void {
|
|||||||
|
|
||||||
// We need to become the active rendering thread again
|
// We need to become the active rendering thread again
|
||||||
self.renderer.threadEnter(self.rt_surface) catch unreachable;
|
self.renderer.threadEnter(self.rt_surface) catch unreachable;
|
||||||
|
|
||||||
// If we are devmode-owning, clean that up.
|
|
||||||
if (DevMode.enabled and DevMode.instance.surface == self) {
|
|
||||||
// Let our renderer clean up
|
|
||||||
self.renderer.deinitDevMode();
|
|
||||||
|
|
||||||
// Clear the surface
|
|
||||||
DevMode.instance.surface = null;
|
|
||||||
|
|
||||||
// Uninitialize imgui
|
|
||||||
self.imgui_ctx.destroy();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop our IO thread
|
// Stop our IO thread
|
||||||
@ -1113,17 +1064,6 @@ pub fn scrollCallback(
|
|||||||
const tracy = trace(@src());
|
const tracy = trace(@src());
|
||||||
defer tracy.end();
|
defer tracy.end();
|
||||||
|
|
||||||
// If our dev mode surface is visible then we always schedule a render on
|
|
||||||
// cursor move because the cursor might touch our surfaces.
|
|
||||||
if (DevMode.enabled and DevMode.instance.visible) {
|
|
||||||
try self.queueRender();
|
|
||||||
|
|
||||||
// If the mouse event was handled by imgui, ignore it.
|
|
||||||
if (imgui.IO.get()) |io| {
|
|
||||||
if (io.cval().WantCaptureMouse) return;
|
|
||||||
} else |_| {}
|
|
||||||
}
|
|
||||||
|
|
||||||
// log.info("SCROLL: xoff={} yoff={} mods={}", .{ xoff, yoff, scroll_mods });
|
// log.info("SCROLL: xoff={} yoff={} mods={}", .{ xoff, yoff, scroll_mods });
|
||||||
|
|
||||||
const ScrollAmount = struct {
|
const ScrollAmount = struct {
|
||||||
@ -1473,17 +1413,6 @@ pub fn mouseButtonCallback(
|
|||||||
const tracy = trace(@src());
|
const tracy = trace(@src());
|
||||||
defer tracy.end();
|
defer tracy.end();
|
||||||
|
|
||||||
// If our dev mode surface is visible then we always schedule a render on
|
|
||||||
// cursor move because the cursor might touch our surfaces.
|
|
||||||
if (DevMode.enabled and DevMode.instance.visible) {
|
|
||||||
try self.queueRender();
|
|
||||||
|
|
||||||
// If the mouse event was handled by imgui, ignore it.
|
|
||||||
if (imgui.IO.get()) |io| {
|
|
||||||
if (io.cval().WantCaptureMouse) return;
|
|
||||||
} else |_| {}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Always record our latest mouse state
|
// Always record our latest mouse state
|
||||||
self.mouse.click_state[@intCast(@intFromEnum(button))] = action;
|
self.mouse.click_state[@intCast(@intFromEnum(button))] = action;
|
||||||
self.mouse.mods = @bitCast(mods);
|
self.mouse.mods = @bitCast(mods);
|
||||||
@ -1636,17 +1565,6 @@ pub fn cursorPosCallback(
|
|||||||
const tracy = trace(@src());
|
const tracy = trace(@src());
|
||||||
defer tracy.end();
|
defer tracy.end();
|
||||||
|
|
||||||
// If our dev mode surface is visible then we always schedule a render on
|
|
||||||
// cursor move because the cursor might touch our surfaces.
|
|
||||||
if (DevMode.enabled and DevMode.instance.visible) {
|
|
||||||
try self.queueRender();
|
|
||||||
|
|
||||||
// If the mouse event was handled by imgui, ignore it.
|
|
||||||
if (imgui.IO.get()) |io| {
|
|
||||||
if (io.cval().WantCaptureMouse) return;
|
|
||||||
} else |_| {}
|
|
||||||
}
|
|
||||||
|
|
||||||
// We are reading/writing state for the remainder
|
// We are reading/writing state for the remainder
|
||||||
self.renderer_state.mutex.lock();
|
self.renderer_state.mutex.lock();
|
||||||
defer self.renderer_state.mutex.unlock();
|
defer self.renderer_state.mutex.unlock();
|
||||||
@ -2113,11 +2031,6 @@ pub fn performBindingAction(self: *Surface, action: input.Binding.Action) !void
|
|||||||
try self.io_thread.wakeup.notify();
|
try self.io_thread.wakeup.notify();
|
||||||
},
|
},
|
||||||
|
|
||||||
.toggle_dev_mode => if (DevMode.enabled) {
|
|
||||||
DevMode.instance.visible = !DevMode.instance.visible;
|
|
||||||
try self.queueRender();
|
|
||||||
} else log.warn("dev mode was not compiled into this binary", .{}),
|
|
||||||
|
|
||||||
.new_window => {
|
.new_window => {
|
||||||
_ = self.app_mailbox.push(.{
|
_ = self.app_mailbox.push(.{
|
||||||
.new_window = .{
|
.new_window = .{
|
||||||
|
@ -20,7 +20,6 @@ const apprt = @import("../apprt.zig");
|
|||||||
const CoreApp = @import("../App.zig");
|
const CoreApp = @import("../App.zig");
|
||||||
const CoreSurface = @import("../Surface.zig");
|
const CoreSurface = @import("../Surface.zig");
|
||||||
const Config = @import("../config.zig").Config;
|
const Config = @import("../config.zig").Config;
|
||||||
const DevMode = @import("../DevMode.zig");
|
|
||||||
|
|
||||||
// Get native API access on certain platforms so we can do more customization.
|
// Get native API access on certain platforms so we can do more customization.
|
||||||
const glfwNative = glfw.Native(.{
|
const glfwNative = glfw.Native(.{
|
||||||
@ -68,11 +67,6 @@ pub const App = struct {
|
|||||||
var config = try Config.load(core_app.alloc);
|
var config = try Config.load(core_app.alloc);
|
||||||
errdefer config.deinit();
|
errdefer config.deinit();
|
||||||
|
|
||||||
// If we have DevMode on, store the config so we can show it. This
|
|
||||||
// is messy because we're copying a thing here. We should clean this
|
|
||||||
// up when we take a pass at cleaning up the dev mode.
|
|
||||||
if (DevMode.enabled) DevMode.instance.config = config;
|
|
||||||
|
|
||||||
// Queue a single new window that starts on launch
|
// Queue a single new window that starts on launch
|
||||||
_ = core_app.mailbox.push(.{
|
_ = core_app.mailbox.push(.{
|
||||||
.new_window = .{},
|
.new_window = .{},
|
||||||
|
@ -29,10 +29,6 @@ pub const font_backend: font.Backend = std.meta.stringToEnum(
|
|||||||
@tagName(options.font_backend),
|
@tagName(options.font_backend),
|
||||||
).?;
|
).?;
|
||||||
|
|
||||||
/// Whether our devmode UI is enabled or not. This requires imgui to be
|
|
||||||
/// compiled.
|
|
||||||
pub const devmode_enabled = artifact == .exe and app_runtime == .glfw;
|
|
||||||
|
|
||||||
/// We want to integrate with Flatpak APIs.
|
/// We want to integrate with Flatpak APIs.
|
||||||
pub const flatpak = options.flatpak;
|
pub const flatpak = options.flatpak;
|
||||||
|
|
||||||
|
@ -365,13 +365,6 @@ pub const Config = struct {
|
|||||||
.{ .reset_font_size = {} },
|
.{ .reset_font_size = {} },
|
||||||
);
|
);
|
||||||
|
|
||||||
// Dev Mode
|
|
||||||
try result.keybind.set.put(
|
|
||||||
alloc,
|
|
||||||
.{ .key = .down, .mods = .{ .shift = true, .super = true } },
|
|
||||||
.{ .toggle_dev_mode = {} },
|
|
||||||
);
|
|
||||||
|
|
||||||
try result.keybind.set.put(
|
try result.keybind.set.put(
|
||||||
alloc,
|
alloc,
|
||||||
.{ .key = .j, .mods = ctrlOrSuper(.{ .shift = true }) },
|
.{ .key = .j, .mods = ctrlOrSuper(.{ .shift = true }) },
|
||||||
|
@ -201,9 +201,6 @@ pub const Action = union(enum) {
|
|||||||
/// path to the file to the tty.
|
/// path to the file to the tty.
|
||||||
write_scrollback_file: void,
|
write_scrollback_file: void,
|
||||||
|
|
||||||
/// Dev mode
|
|
||||||
toggle_dev_mode: void,
|
|
||||||
|
|
||||||
/// Open a new window
|
/// Open a new window
|
||||||
new_window: void,
|
new_window: void,
|
||||||
|
|
||||||
|
@ -16,7 +16,6 @@ const font = @import("../font/main.zig");
|
|||||||
const terminal = @import("../terminal/main.zig");
|
const terminal = @import("../terminal/main.zig");
|
||||||
const renderer = @import("../renderer.zig");
|
const renderer = @import("../renderer.zig");
|
||||||
const math = @import("../math.zig");
|
const math = @import("../math.zig");
|
||||||
const DevMode = @import("../DevMode.zig");
|
|
||||||
const Surface = @import("../Surface.zig");
|
const Surface = @import("../Surface.zig");
|
||||||
const assert = std.debug.assert;
|
const assert = std.debug.assert;
|
||||||
const Allocator = std.mem.Allocator;
|
const Allocator = std.mem.Allocator;
|
||||||
@ -393,25 +392,6 @@ pub fn finalizeSurfaceInit(self: *const Metal, surface: *apprt.Surface) !void {
|
|||||||
layer.setProperty("contentsScale", info.scaleFactor);
|
layer.setProperty("contentsScale", info.scaleFactor);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This is called if this renderer runs DevMode.
|
|
||||||
pub fn initDevMode(self: *const Metal, surface: *apprt.Surface) !void {
|
|
||||||
if (DevMode.enabled) {
|
|
||||||
// Initialize for our window
|
|
||||||
assert(imgui.ImplGlfw.initForOther(@ptrCast(surface.window.handle), true));
|
|
||||||
assert(imgui.ImplMetal.init(self.device.value));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// This is called if this renderer runs DevMode.
|
|
||||||
pub fn deinitDevMode(self: *const Metal) void {
|
|
||||||
_ = self;
|
|
||||||
|
|
||||||
if (DevMode.enabled) {
|
|
||||||
imgui.ImplMetal.shutdown();
|
|
||||||
imgui.ImplGlfw.shutdown();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Callback called by renderer.Thread when it begins.
|
/// Callback called by renderer.Thread when it begins.
|
||||||
pub fn threadEnter(self: *const Metal, surface: *apprt.Surface) !void {
|
pub fn threadEnter(self: *const Metal, surface: *apprt.Surface) !void {
|
||||||
_ = self;
|
_ = self;
|
||||||
@ -517,7 +497,6 @@ pub fn render(
|
|||||||
// Data we extract out of the critical area.
|
// Data we extract out of the critical area.
|
||||||
const Critical = struct {
|
const Critical = struct {
|
||||||
bg: terminal.color.RGB,
|
bg: terminal.color.RGB,
|
||||||
devmode: bool,
|
|
||||||
selection: ?terminal.Selection,
|
selection: ?terminal.Selection,
|
||||||
screen: terminal.Screen,
|
screen: terminal.Screen,
|
||||||
draw_cursor: bool,
|
draw_cursor: bool,
|
||||||
@ -596,7 +575,6 @@ pub fn render(
|
|||||||
|
|
||||||
break :critical .{
|
break :critical .{
|
||||||
.bg = self.config.background,
|
.bg = self.config.background,
|
||||||
.devmode = if (state.devmode) |dm| dm.visible else false,
|
|
||||||
.selection = selection,
|
.selection = selection,
|
||||||
.screen = screen_copy,
|
.screen = screen_copy,
|
||||||
.draw_cursor = draw_cursor,
|
.draw_cursor = draw_cursor,
|
||||||
@ -715,29 +693,6 @@ pub fn render(
|
|||||||
// Issue the draw calls for this shader
|
// Issue the draw calls for this shader
|
||||||
try self.drawCells(encoder, &self.buf_cells_bg, self.cells_bg);
|
try self.drawCells(encoder, &self.buf_cells_bg, self.cells_bg);
|
||||||
try self.drawCells(encoder, &self.buf_cells, self.cells);
|
try self.drawCells(encoder, &self.buf_cells, self.cells);
|
||||||
|
|
||||||
// Build our devmode draw data. This sucks because it requires we
|
|
||||||
// lock our state mutex but the metal imgui implementation requires
|
|
||||||
// access to all this stuff.
|
|
||||||
if (critical.devmode) {
|
|
||||||
state.mutex.lock();
|
|
||||||
defer state.mutex.unlock();
|
|
||||||
|
|
||||||
if (DevMode.enabled) {
|
|
||||||
if (state.devmode) |dm| {
|
|
||||||
if (dm.visible) {
|
|
||||||
imgui.ImplMetal.newFrame(desc.value);
|
|
||||||
imgui.ImplGlfw.newFrame();
|
|
||||||
try dm.update();
|
|
||||||
imgui.ImplMetal.renderDrawData(
|
|
||||||
try dm.render(),
|
|
||||||
buffer.value,
|
|
||||||
encoder.value,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer.msgSend(void, objc.sel("presentDrawable:"), .{drawable.value});
|
buffer.msgSend(void, objc.sel("presentDrawable:"), .{drawable.value});
|
||||||
|
@ -18,7 +18,6 @@ const gl = @import("opengl/main.zig");
|
|||||||
const trace = @import("tracy").trace;
|
const trace = @import("tracy").trace;
|
||||||
const math = @import("../math.zig");
|
const math = @import("../math.zig");
|
||||||
const lru = @import("../lru.zig");
|
const lru = @import("../lru.zig");
|
||||||
const DevMode = @import("../DevMode.zig");
|
|
||||||
const Surface = @import("../Surface.zig");
|
const Surface = @import("../Surface.zig");
|
||||||
|
|
||||||
const log = std.log.scoped(.grid);
|
const log = std.log.scoped(.grid);
|
||||||
@ -540,30 +539,6 @@ pub fn finalizeSurfaceInit(self: *const OpenGL, surface: *apprt.Surface) !void {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This is called if this renderer runs DevMode.
|
|
||||||
pub fn initDevMode(self: *const OpenGL, surface: *apprt.Surface) !void {
|
|
||||||
_ = self;
|
|
||||||
|
|
||||||
if (DevMode.enabled) {
|
|
||||||
// Initialize for our window
|
|
||||||
assert(imgui.ImplGlfw.initForOpenGL(
|
|
||||||
@ptrCast(surface.window.handle),
|
|
||||||
true,
|
|
||||||
));
|
|
||||||
assert(imgui.ImplOpenGL3.init("#version 330 core"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// This is called if this renderer runs DevMode.
|
|
||||||
pub fn deinitDevMode(self: *const OpenGL) void {
|
|
||||||
_ = self;
|
|
||||||
|
|
||||||
if (DevMode.enabled) {
|
|
||||||
imgui.ImplOpenGL3.shutdown();
|
|
||||||
imgui.ImplGlfw.shutdown();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Callback called by renderer.Thread when it begins.
|
/// Callback called by renderer.Thread when it begins.
|
||||||
pub fn threadEnter(self: *const OpenGL, surface: *apprt.Surface) !void {
|
pub fn threadEnter(self: *const OpenGL, surface: *apprt.Surface) !void {
|
||||||
_ = self;
|
_ = self;
|
||||||
@ -716,7 +691,6 @@ pub fn render(
|
|||||||
// Data we extract out of the critical area.
|
// Data we extract out of the critical area.
|
||||||
const Critical = struct {
|
const Critical = struct {
|
||||||
gl_bg: terminal.color.RGB,
|
gl_bg: terminal.color.RGB,
|
||||||
devmode_data: ?*imgui.DrawData,
|
|
||||||
active_screen: terminal.Terminal.ScreenType,
|
active_screen: terminal.Terminal.ScreenType,
|
||||||
selection: ?terminal.Selection,
|
selection: ?terminal.Selection,
|
||||||
screen: terminal.Screen,
|
screen: terminal.Screen,
|
||||||
@ -769,22 +743,6 @@ pub fn render(
|
|||||||
self.config.foreground = bg;
|
self.config.foreground = bg;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build our devmode draw data
|
|
||||||
const devmode_data = devmode_data: {
|
|
||||||
if (DevMode.enabled) {
|
|
||||||
if (state.devmode) |dm| {
|
|
||||||
if (dm.visible) {
|
|
||||||
imgui.ImplOpenGL3.newFrame();
|
|
||||||
imgui.ImplGlfw.newFrame();
|
|
||||||
try dm.update();
|
|
||||||
break :devmode_data try dm.render();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
break :devmode_data null;
|
|
||||||
};
|
|
||||||
|
|
||||||
// We used to share terminal state, but we've since learned through
|
// We used to share terminal state, but we've since learned through
|
||||||
// analysis that it is faster to copy the terminal state than to
|
// analysis that it is faster to copy the terminal state than to
|
||||||
// hold the lock wile rebuilding GPU cells.
|
// hold the lock wile rebuilding GPU cells.
|
||||||
@ -812,7 +770,6 @@ pub fn render(
|
|||||||
|
|
||||||
break :critical .{
|
break :critical .{
|
||||||
.gl_bg = self.config.background,
|
.gl_bg = self.config.background,
|
||||||
.devmode_data = devmode_data,
|
|
||||||
.active_screen = state.terminal.active_screen,
|
.active_screen = state.terminal.active_screen,
|
||||||
.selection = selection,
|
.selection = selection,
|
||||||
.screen = screen_copy,
|
.screen = screen_copy,
|
||||||
@ -847,13 +804,6 @@ pub fn render(
|
|||||||
|
|
||||||
try self.draw();
|
try self.draw();
|
||||||
|
|
||||||
// If we have devmode, then render that
|
|
||||||
if (DevMode.enabled) {
|
|
||||||
if (critical.devmode_data) |data| {
|
|
||||||
imgui.ImplOpenGL3.renderDrawData(data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Swap our window buffers
|
// Swap our window buffers
|
||||||
switch (apprt.runtime) {
|
switch (apprt.runtime) {
|
||||||
else => @compileError("unsupported runtime"),
|
else => @compileError("unsupported runtime"),
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const Allocator = std.mem.Allocator;
|
const Allocator = std.mem.Allocator;
|
||||||
const DevMode = @import("../DevMode.zig");
|
|
||||||
const terminal = @import("../terminal/main.zig");
|
const terminal = @import("../terminal/main.zig");
|
||||||
const renderer = @import("../renderer.zig");
|
const renderer = @import("../renderer.zig");
|
||||||
|
|
||||||
@ -24,9 +23,6 @@ terminal: *terminal.Terminal,
|
|||||||
/// a future exercise.
|
/// a future exercise.
|
||||||
preedit: ?Preedit = null,
|
preedit: ?Preedit = null,
|
||||||
|
|
||||||
/// The devmode data.
|
|
||||||
devmode: ?*const DevMode = null,
|
|
||||||
|
|
||||||
pub const Cursor = struct {
|
pub const Cursor = struct {
|
||||||
/// Current cursor style. This can be set by escape sequences. To get
|
/// Current cursor style. This can be set by escape sequences. To get
|
||||||
/// the default style, the config has to be referenced.
|
/// the default style, the config has to be referenced.
|
||||||
|
Reference in New Issue
Block a user