diff --git a/build.zig b/build.zig index 11344cbcd..72f06bf44 100644 --- a/build.zig +++ b/build.zig @@ -17,7 +17,6 @@ const glfw = @import("vendor/mach-glfw/build.zig"); const fontconfig = @import("pkg/fontconfig/build.zig"); const freetype = @import("pkg/freetype/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 libxev = @import("vendor/libxev/build.zig"); const libxml2 = @import("vendor/zig-libxml2/libxml2.zig"); @@ -722,16 +721,6 @@ fn addDeps( const utf8proc_step = try utf8proc.link(b, step); 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 if (!static) { step.addIncludePath(.{ .path = freetype.include_path_self }); @@ -818,10 +807,6 @@ fn addDeps( }); libxml2_lib.link(fontconfig_step); } - - // Imgui - imgui_opts.freetype.step = freetype_step; - imgui_opts.freetype.include = &freetype.include_paths; } if (!lib) { @@ -846,11 +831,6 @@ fn addDeps( .opengl = false, }; 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 => { @@ -863,11 +843,6 @@ fn addDeps( try glfw.link(b, step, glfw_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); }, } } diff --git a/pkg/imgui/build.zig b/pkg/imgui/build.zig deleted file mode 100644 index 293d25f2f..000000000 --- a/pkg/imgui/build.zig +++ /dev/null @@ -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", -}; diff --git a/pkg/imgui/c.zig b/pkg/imgui/c.zig deleted file mode 100644 index 621fd1335..000000000 --- a/pkg/imgui/c.zig +++ /dev/null @@ -1,4 +0,0 @@ -pub usingnamespace @cImport({ - @cDefine("CIMGUI_DEFINE_ENUMS_AND_STRUCTS", ""); - @cInclude("cimgui.h"); -}); diff --git a/pkg/imgui/context.zig b/pkg/imgui/context.zig deleted file mode 100644 index d9f403856..000000000 --- a/pkg/imgui/context.zig +++ /dev/null @@ -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(); -} diff --git a/pkg/imgui/core.zig b/pkg/imgui/core.zig deleted file mode 100644 index 17393f112..000000000 --- a/pkg/imgui/core.zig +++ /dev/null @@ -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()); -} diff --git a/pkg/imgui/draw_data.zig b/pkg/imgui/draw_data.zig deleted file mode 100644 index 65341472b..000000000 --- a/pkg/imgui/draw_data.zig +++ /dev/null @@ -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)); - } -}; diff --git a/pkg/imgui/font_atlas.zig b/pkg/imgui/font_atlas.zig deleted file mode 100644 index d880e33a5..000000000 --- a/pkg/imgui/font_atlas.zig +++ /dev/null @@ -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)); - } -}; diff --git a/pkg/imgui/impl_glfw.zig b/pkg/imgui/impl_glfw.zig deleted file mode 100644 index d8dd00a37..000000000 --- a/pkg/imgui/impl_glfw.zig +++ /dev/null @@ -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; -}; diff --git a/pkg/imgui/impl_metal.zig b/pkg/imgui/impl_metal.zig deleted file mode 100644 index 3b228f611..000000000 --- a/pkg/imgui/impl_metal.zig +++ /dev/null @@ -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; -}; diff --git a/pkg/imgui/impl_opengl3.zig b/pkg/imgui/impl_opengl3.zig deleted file mode 100644 index 1e6f6952f..000000000 --- a/pkg/imgui/impl_opengl3.zig +++ /dev/null @@ -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; -}; diff --git a/pkg/imgui/io.zig b/pkg/imgui/io.zig deleted file mode 100644 index 811796764..000000000 --- a/pkg/imgui/io.zig +++ /dev/null @@ -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(); -} diff --git a/pkg/imgui/main.zig b/pkg/imgui/main.zig deleted file mode 100644 index 424e015cb..000000000 --- a/pkg/imgui/main.zig +++ /dev/null @@ -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()); -} diff --git a/pkg/imgui/style.zig b/pkg/imgui/style.zig deleted file mode 100644 index 3d3d68145..000000000 --- a/pkg/imgui/style.zig +++ /dev/null @@ -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)); - } -}; diff --git a/src/DevMode.zig b/src/DevMode.zig deleted file mode 100644 index 5bb25952a..000000000 --- a/src/DevMode.zig +++ /dev/null @@ -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 }, - ); - } -} diff --git a/src/Surface.zig b/src/Surface.zig index 582c6cd71..04705dfbd 100644 --- a/src/Surface.zig +++ b/src/Surface.zig @@ -31,7 +31,6 @@ const trace = @import("tracy").trace; const terminal = @import("terminal/main.zig"); const configpkg = @import("config.zig"); const input = @import("input.zig"); -const DevMode = @import("DevMode.zig"); const App = @import("App.zig"); const internal_os = @import("os/main.zig"); @@ -54,9 +53,6 @@ font_lib: font.Library, font_group: *font.GroupCache, font_size: font.face.DesiredSize, -/// Imgui context -imgui_ctx: if (DevMode.enabled) *imgui.Context else void, - /// The renderer for this surface. renderer: Renderer, @@ -419,11 +415,6 @@ pub fn init( var io_thread = try termio.Thread.init(alloc, &self.io); 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.* = .{ .alloc = alloc, .app_mailbox = app_mailbox, @@ -440,7 +431,6 @@ pub fn init( .visible = true, }, .terminal = &self.io.terminal, - .devmode = if (!host_devmode) null else &DevMode.instance, }, .renderer_thr = undefined, .mouse = .{}, @@ -452,10 +442,7 @@ pub fn init( .cell_size = cell_size, .padding = padding, .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 // but is otherwise somewhat arbitrary. @@ -471,30 +458,6 @@ pub fn init( // to duplicate. 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 // setup on the main thread prior to spinning up the rendering thread. 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 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 @@ -1113,17 +1064,6 @@ pub fn scrollCallback( const tracy = trace(@src()); 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 }); const ScrollAmount = struct { @@ -1473,17 +1413,6 @@ pub fn mouseButtonCallback( const tracy = trace(@src()); 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 self.mouse.click_state[@intCast(@intFromEnum(button))] = action; self.mouse.mods = @bitCast(mods); @@ -1636,17 +1565,6 @@ pub fn cursorPosCallback( const tracy = trace(@src()); 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 self.renderer_state.mutex.lock(); 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(); }, - .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 => { _ = self.app_mailbox.push(.{ .new_window = .{ diff --git a/src/apprt/glfw.zig b/src/apprt/glfw.zig index e9706bfa7..8d96c99ef 100644 --- a/src/apprt/glfw.zig +++ b/src/apprt/glfw.zig @@ -20,7 +20,6 @@ const apprt = @import("../apprt.zig"); const CoreApp = @import("../App.zig"); const CoreSurface = @import("../Surface.zig"); const Config = @import("../config.zig").Config; -const DevMode = @import("../DevMode.zig"); // Get native API access on certain platforms so we can do more customization. const glfwNative = glfw.Native(.{ @@ -68,11 +67,6 @@ pub const App = struct { var config = try Config.load(core_app.alloc); 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 _ = core_app.mailbox.push(.{ .new_window = .{}, diff --git a/src/build_config.zig b/src/build_config.zig index 6bf9db740..b086ae0fa 100644 --- a/src/build_config.zig +++ b/src/build_config.zig @@ -29,10 +29,6 @@ pub const font_backend: font.Backend = std.meta.stringToEnum( @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. pub const flatpak = options.flatpak; diff --git a/src/config.zig b/src/config.zig index a39e29814..b16ead7c1 100644 --- a/src/config.zig +++ b/src/config.zig @@ -365,13 +365,6 @@ pub const Config = struct { .{ .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( alloc, .{ .key = .j, .mods = ctrlOrSuper(.{ .shift = true }) }, diff --git a/src/input/Binding.zig b/src/input/Binding.zig index 8e5e9ec1e..82315dbb0 100644 --- a/src/input/Binding.zig +++ b/src/input/Binding.zig @@ -201,9 +201,6 @@ pub const Action = union(enum) { /// path to the file to the tty. write_scrollback_file: void, - /// Dev mode - toggle_dev_mode: void, - /// Open a new window new_window: void, diff --git a/src/renderer/Metal.zig b/src/renderer/Metal.zig index 5dfe5e4f7..b36824db5 100644 --- a/src/renderer/Metal.zig +++ b/src/renderer/Metal.zig @@ -16,7 +16,6 @@ const font = @import("../font/main.zig"); const terminal = @import("../terminal/main.zig"); const renderer = @import("../renderer.zig"); const math = @import("../math.zig"); -const DevMode = @import("../DevMode.zig"); const Surface = @import("../Surface.zig"); const assert = std.debug.assert; const Allocator = std.mem.Allocator; @@ -393,25 +392,6 @@ pub fn finalizeSurfaceInit(self: *const Metal, surface: *apprt.Surface) !void { 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. pub fn threadEnter(self: *const Metal, surface: *apprt.Surface) !void { _ = self; @@ -517,7 +497,6 @@ pub fn render( // Data we extract out of the critical area. const Critical = struct { bg: terminal.color.RGB, - devmode: bool, selection: ?terminal.Selection, screen: terminal.Screen, draw_cursor: bool, @@ -596,7 +575,6 @@ pub fn render( break :critical .{ .bg = self.config.background, - .devmode = if (state.devmode) |dm| dm.visible else false, .selection = selection, .screen = screen_copy, .draw_cursor = draw_cursor, @@ -715,29 +693,6 @@ pub fn render( // 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, 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}); diff --git a/src/renderer/OpenGL.zig b/src/renderer/OpenGL.zig index e26492323..7994554ca 100644 --- a/src/renderer/OpenGL.zig +++ b/src/renderer/OpenGL.zig @@ -18,7 +18,6 @@ const gl = @import("opengl/main.zig"); const trace = @import("tracy").trace; const math = @import("../math.zig"); const lru = @import("../lru.zig"); -const DevMode = @import("../DevMode.zig"); const Surface = @import("../Surface.zig"); 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. pub fn threadEnter(self: *const OpenGL, surface: *apprt.Surface) !void { _ = self; @@ -716,7 +691,6 @@ pub fn render( // Data we extract out of the critical area. const Critical = struct { gl_bg: terminal.color.RGB, - devmode_data: ?*imgui.DrawData, active_screen: terminal.Terminal.ScreenType, selection: ?terminal.Selection, screen: terminal.Screen, @@ -769,22 +743,6 @@ pub fn render( 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 // analysis that it is faster to copy the terminal state than to // hold the lock wile rebuilding GPU cells. @@ -812,7 +770,6 @@ pub fn render( break :critical .{ .gl_bg = self.config.background, - .devmode_data = devmode_data, .active_screen = state.terminal.active_screen, .selection = selection, .screen = screen_copy, @@ -847,13 +804,6 @@ pub fn render( 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 switch (apprt.runtime) { else => @compileError("unsupported runtime"), diff --git a/src/renderer/State.zig b/src/renderer/State.zig index e73a88348..c216c7d9a 100644 --- a/src/renderer/State.zig +++ b/src/renderer/State.zig @@ -2,7 +2,6 @@ const std = @import("std"); const Allocator = std.mem.Allocator; -const DevMode = @import("../DevMode.zig"); const terminal = @import("../terminal/main.zig"); const renderer = @import("../renderer.zig"); @@ -24,9 +23,6 @@ terminal: *terminal.Terminal, /// a future exercise. preedit: ?Preedit = null, -/// The devmode data. -devmode: ?*const DevMode = null, - pub const Cursor = struct { /// Current cursor style. This can be set by escape sequences. To get /// the default style, the config has to be referenced.