mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-16 08:46:08 +03:00
core: hook up all the inspector activation state and such
This commit is contained in:
@ -3,6 +3,19 @@
|
|||||||
//! debugging issues in Ghostty itself.
|
//! debugging issues in Ghostty itself.
|
||||||
const Inspector = @This();
|
const Inspector = @This();
|
||||||
|
|
||||||
|
const cimgui = @import("cimgui");
|
||||||
|
|
||||||
pub fn init() Inspector {
|
pub fn init() Inspector {
|
||||||
return .{};
|
return .{};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn deinit(self: *Inspector) void {
|
||||||
|
_ = self;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn render(self: *Inspector) void {
|
||||||
|
_ = self;
|
||||||
|
|
||||||
|
var show: bool = true;
|
||||||
|
cimgui.c.igShowDemoWindow(&show);
|
||||||
|
}
|
||||||
|
@ -20,6 +20,7 @@ const builtin = @import("builtin");
|
|||||||
const assert = std.debug.assert;
|
const assert = std.debug.assert;
|
||||||
const Allocator = std.mem.Allocator;
|
const Allocator = std.mem.Allocator;
|
||||||
const ArenaAllocator = std.heap.ArenaAllocator;
|
const ArenaAllocator = std.heap.ArenaAllocator;
|
||||||
|
const Inspector = @import("Inspector.zig");
|
||||||
const renderer = @import("renderer.zig");
|
const renderer = @import("renderer.zig");
|
||||||
const termio = @import("termio.zig");
|
const termio = @import("termio.zig");
|
||||||
const objc = @import("objc");
|
const objc = @import("objc");
|
||||||
@ -74,6 +75,9 @@ io: termio.Impl,
|
|||||||
io_thread: termio.Thread,
|
io_thread: termio.Thread,
|
||||||
io_thr: std.Thread,
|
io_thr: std.Thread,
|
||||||
|
|
||||||
|
/// Terminal inspector
|
||||||
|
inspector: ?*Inspector = null,
|
||||||
|
|
||||||
/// All the cached sizes since we need them at various times.
|
/// All the cached sizes since we need them at various times.
|
||||||
screen_size: renderer.ScreenSize,
|
screen_size: renderer.ScreenSize,
|
||||||
grid_size: renderer.GridSize,
|
grid_size: renderer.GridSize,
|
||||||
@ -550,8 +554,14 @@ pub fn deinit(self: *Surface) void {
|
|||||||
self.font_lib.deinit();
|
self.font_lib.deinit();
|
||||||
self.alloc.destroy(self.font_group);
|
self.alloc.destroy(self.font_group);
|
||||||
|
|
||||||
|
if (self.inspector) |v| {
|
||||||
|
v.deinit();
|
||||||
|
self.alloc.destroy(v);
|
||||||
|
}
|
||||||
|
|
||||||
self.alloc.destroy(self.renderer_state.mutex);
|
self.alloc.destroy(self.renderer_state.mutex);
|
||||||
self.config.deinit();
|
self.config.deinit();
|
||||||
|
|
||||||
log.info("surface closed addr={x}", .{@intFromPtr(self)});
|
log.info("surface closed addr={x}", .{@intFromPtr(self)});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -561,6 +571,51 @@ pub fn close(self: *Surface) void {
|
|||||||
self.rt_surface.close(self.needsConfirmQuit());
|
self.rt_surface.close(self.needsConfirmQuit());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Activate the inspector. This will begin collecting inspection data.
|
||||||
|
/// This will not affect the GUI. The GUI must use performAction to
|
||||||
|
/// show/hide the inspector UI.
|
||||||
|
pub fn activateInspector(self: *Surface) !void {
|
||||||
|
if (self.inspector != null) return;
|
||||||
|
|
||||||
|
// Setup the inspector
|
||||||
|
var ptr = try self.alloc.create(Inspector);
|
||||||
|
errdefer self.alloc.destroy(ptr);
|
||||||
|
ptr.* = Inspector.init();
|
||||||
|
self.inspector = ptr;
|
||||||
|
|
||||||
|
// Put the inspector onto the render state
|
||||||
|
self.renderer_state.mutex.lock();
|
||||||
|
defer self.renderer_state.mutex.unlock();
|
||||||
|
assert(self.renderer_state.inspector == null);
|
||||||
|
self.renderer_state.inspector = self.inspector;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Deactivate the inspector and stop collecting any information.
|
||||||
|
pub fn deactivateInspector(self: *Surface) void {
|
||||||
|
const inspector = self.inspector orelse return;
|
||||||
|
|
||||||
|
// Remove the inspector from the render state
|
||||||
|
{
|
||||||
|
self.renderer_state.mutex.lock();
|
||||||
|
defer self.renderer_state.mutex.unlock();
|
||||||
|
assert(self.renderer_state.inspector != null);
|
||||||
|
self.renderer_state.inspector = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deinit the inspector
|
||||||
|
inspector.deinit();
|
||||||
|
self.alloc.destroy(inspector);
|
||||||
|
self.inspector = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Render the inspector. This requires an active ImGui context.
|
||||||
|
pub fn renderInspector(self: *Surface) void {
|
||||||
|
const inspector = self.inspector orelse return;
|
||||||
|
self.renderer_state.mutex.lock();
|
||||||
|
defer self.renderer_state.mutex.unlock();
|
||||||
|
inspector.render();
|
||||||
|
}
|
||||||
|
|
||||||
/// True if the surface requires confirmation to quit. This should be called
|
/// True if the surface requires confirmation to quit. This should be called
|
||||||
/// by apprt to determine if the surface should confirm before quitting.
|
/// by apprt to determine if the surface should confirm before quitting.
|
||||||
pub fn needsConfirmQuit(self: *Surface) bool {
|
pub fn needsConfirmQuit(self: *Surface) bool {
|
||||||
|
@ -209,8 +209,6 @@ fn gtkRender(area: *c.GtkGLArea, ctx: *c.GdkGLContext, ud: ?*anyopaque) callconv
|
|||||||
cimgui.c.igNewFrame();
|
cimgui.c.igNewFrame();
|
||||||
|
|
||||||
// Build our UI
|
// Build our UI
|
||||||
var show: bool = true;
|
|
||||||
cimgui.c.igShowDemoWindow(&show);
|
|
||||||
if (self.render_callback) |cb| cb(self.render_userdata);
|
if (self.render_callback) |cb| cb(self.render_userdata);
|
||||||
|
|
||||||
// Render
|
// Render
|
||||||
|
@ -74,6 +74,12 @@ pub const Inspector = struct {
|
|||||||
.location = undefined,
|
.location = undefined,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Activate the inspector. If it doesn't work we ignore the error
|
||||||
|
// because we can just show an error in the inspector window.
|
||||||
|
self.surface.core_surface.activateInspector() catch |err| {
|
||||||
|
log.err("failed to activate inspector err={}", .{err});
|
||||||
|
};
|
||||||
|
|
||||||
switch (location) {
|
switch (location) {
|
||||||
.hidden => self.location = .{ .hidden = {} },
|
.hidden => self.location = .{ .hidden = {} },
|
||||||
.window => try self.initWindow(),
|
.window => try self.initWindow(),
|
||||||
@ -81,7 +87,7 @@ pub const Inspector = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn deinit(self: *Inspector) void {
|
fn deinit(self: *Inspector) void {
|
||||||
_ = self;
|
self.surface.core_surface.deactivateInspector();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Request the inspector is closed.
|
/// Request the inspector is closed.
|
||||||
@ -136,6 +142,8 @@ const Window = struct {
|
|||||||
// Initialize our imgui widget
|
// Initialize our imgui widget
|
||||||
try self.imgui_widget.init();
|
try self.imgui_widget.init();
|
||||||
errdefer self.imgui_widget.deinit();
|
errdefer self.imgui_widget.deinit();
|
||||||
|
self.imgui_widget.render_callback = &imguiRender;
|
||||||
|
self.imgui_widget.render_userdata = self;
|
||||||
|
|
||||||
// Signals
|
// Signals
|
||||||
_ = c.g_signal_connect_data(window, "destroy", c.G_CALLBACK(>kDestroy), self, null, c.G_CONNECT_DEFAULT);
|
_ = c.g_signal_connect_data(window, "destroy", c.G_CALLBACK(>kDestroy), self, null, c.G_CONNECT_DEFAULT);
|
||||||
@ -154,6 +162,11 @@ const Window = struct {
|
|||||||
c.gtk_window_destroy(self.window);
|
c.gtk_window_destroy(self.window);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn imguiRender(ud: ?*anyopaque) void {
|
||||||
|
const self: *Window = @ptrCast(@alignCast(ud orelse return));
|
||||||
|
self.inspector.surface.core_surface.renderInspector();
|
||||||
|
}
|
||||||
|
|
||||||
/// "destroy" signal for the window
|
/// "destroy" signal for the window
|
||||||
fn gtkDestroy(v: *c.GtkWidget, ud: ?*anyopaque) callconv(.C) void {
|
fn gtkDestroy(v: *c.GtkWidget, ud: ?*anyopaque) callconv(.C) void {
|
||||||
_ = v;
|
_ = v;
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const Allocator = std.mem.Allocator;
|
const Allocator = std.mem.Allocator;
|
||||||
|
const Inspector = @import("../Inspector.zig");
|
||||||
const terminal = @import("../terminal/main.zig");
|
const terminal = @import("../terminal/main.zig");
|
||||||
const renderer = @import("../renderer.zig");
|
const renderer = @import("../renderer.zig");
|
||||||
|
|
||||||
@ -14,6 +15,10 @@ mutex: *std.Thread.Mutex,
|
|||||||
/// The terminal data.
|
/// The terminal data.
|
||||||
terminal: *terminal.Terminal,
|
terminal: *terminal.Terminal,
|
||||||
|
|
||||||
|
/// The terminal inspector, if any. This will be null while the inspector
|
||||||
|
/// is not active and will be set when it is active.
|
||||||
|
inspector: ?*Inspector = null,
|
||||||
|
|
||||||
/// Dead key state. This will render the current dead key preedit text
|
/// Dead key state. This will render the current dead key preedit text
|
||||||
/// over the cursor. This currently only ever renders a single codepoint.
|
/// over the cursor. This currently only ever renders a single codepoint.
|
||||||
/// Preedit can in theory be multiple codepoints long but that is left as
|
/// Preedit can in theory be multiple codepoints long but that is left as
|
||||||
|
Reference in New Issue
Block a user