mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-22 11:46:11 +03:00
renderer: use a DerivedConfig to avoid the main Config pointer
This commit is contained in:
@ -322,7 +322,7 @@ pub fn init(
|
||||
|
||||
// Create our terminal grid with the initial size
|
||||
var renderer_impl = try Renderer.init(alloc, .{
|
||||
.config = config,
|
||||
.config = try Renderer.DerivedConfig.init(alloc, config),
|
||||
.font_group = font_group,
|
||||
.padding = .{
|
||||
.explicit = padding,
|
||||
|
@ -11,6 +11,7 @@ const objc = @import("objc");
|
||||
const macos = @import("macos");
|
||||
const imgui = @import("imgui");
|
||||
const apprt = @import("../apprt.zig");
|
||||
const configpkg = @import("../config.zig");
|
||||
const font = @import("../font/main.zig");
|
||||
const terminal = @import("../terminal/main.zig");
|
||||
const renderer = @import("../renderer.zig");
|
||||
@ -31,6 +32,9 @@ const log = std.log.scoped(.metal);
|
||||
/// Allocator that can be used
|
||||
alloc: std.mem.Allocator,
|
||||
|
||||
/// The configuration we need derived from the main config.
|
||||
config: DerivedConfig,
|
||||
|
||||
/// The mailbox for communicating with the window.
|
||||
surface_mailbox: apprt.surface.Mailbox,
|
||||
|
||||
@ -51,17 +55,6 @@ focused: bool,
|
||||
/// blinking.
|
||||
cursor_visible: bool,
|
||||
cursor_style: renderer.CursorStyle,
|
||||
cursor_color: ?terminal.color.RGB,
|
||||
|
||||
/// Default foreground color
|
||||
foreground: terminal.color.RGB,
|
||||
|
||||
/// Default background color
|
||||
background: terminal.color.RGB,
|
||||
|
||||
/// Default selection color
|
||||
selection_background: ?terminal.color.RGB,
|
||||
selection_foreground: ?terminal.color.RGB,
|
||||
|
||||
/// The current set of cells to render. This is rebuilt on every frame
|
||||
/// but we keep this around so that we don't reallocate. Each set of
|
||||
@ -117,6 +110,48 @@ const GPUCellMode = enum(u8) {
|
||||
strikethrough = 8,
|
||||
};
|
||||
|
||||
/// The configuration for this renderer that is derived from the main
|
||||
/// configuration. This must be exported so that we don't need to
|
||||
/// pass around Config pointers which makes memory management a pain.
|
||||
pub const DerivedConfig = struct {
|
||||
cursor_color: ?terminal.color.RGB,
|
||||
background: terminal.color.RGB,
|
||||
foreground: terminal.color.RGB,
|
||||
selection_background: ?terminal.color.RGB,
|
||||
selection_foreground: ?terminal.color.RGB,
|
||||
|
||||
pub fn init(
|
||||
alloc_gpa: Allocator,
|
||||
config: *const configpkg.Config,
|
||||
) !DerivedConfig {
|
||||
_ = alloc_gpa;
|
||||
|
||||
return .{
|
||||
.cursor_color = if (config.@"cursor-color") |col|
|
||||
col.toTerminalRGB()
|
||||
else
|
||||
null,
|
||||
|
||||
.background = config.background.toTerminalRGB(),
|
||||
.foreground = config.foreground.toTerminalRGB(),
|
||||
|
||||
.selection_background = if (config.@"selection-background") |bg|
|
||||
bg.toTerminalRGB()
|
||||
else
|
||||
null,
|
||||
|
||||
.selection_foreground = if (config.@"selection-foreground") |bg|
|
||||
bg.toTerminalRGB()
|
||||
else
|
||||
null,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn deinit(self: *DerivedConfig) void {
|
||||
_ = self;
|
||||
}
|
||||
};
|
||||
|
||||
/// Returns the hints that we want for this
|
||||
pub fn glfwWindowHints() glfw.Window.Hints {
|
||||
return .{
|
||||
@ -233,6 +268,7 @@ pub fn init(alloc: Allocator, options: renderer.Options) !Metal {
|
||||
|
||||
return Metal{
|
||||
.alloc = alloc,
|
||||
.config = options.config,
|
||||
.surface_mailbox = options.surface_mailbox,
|
||||
.cell_size = .{ .width = metrics.cell_width, .height = metrics.cell_height },
|
||||
.screen_size = null,
|
||||
@ -240,17 +276,6 @@ pub fn init(alloc: Allocator, options: renderer.Options) !Metal {
|
||||
.focused = true,
|
||||
.cursor_visible = true,
|
||||
.cursor_style = .box,
|
||||
.cursor_color = if (options.config.@"cursor-color") |col| col.toTerminalRGB() else null,
|
||||
.background = options.config.background.toTerminalRGB(),
|
||||
.foreground = options.config.foreground.toTerminalRGB(),
|
||||
.selection_background = if (options.config.@"selection-background") |bg|
|
||||
bg.toTerminalRGB()
|
||||
else
|
||||
null,
|
||||
.selection_foreground = if (options.config.@"selection-foreground") |bg|
|
||||
bg.toTerminalRGB()
|
||||
else
|
||||
null,
|
||||
|
||||
// Render state
|
||||
.cells_bg = .{},
|
||||
@ -286,6 +311,8 @@ pub fn deinit(self: *Metal) void {
|
||||
self.font_shaper.deinit();
|
||||
self.alloc.free(self.font_shaper.cell_buf);
|
||||
|
||||
self.config.deinit();
|
||||
|
||||
deinitMTLResource(self.buf_cells_bg);
|
||||
deinitMTLResource(self.buf_cells);
|
||||
deinitMTLResource(self.buf_instance);
|
||||
@ -482,15 +509,15 @@ pub fn render(
|
||||
}
|
||||
|
||||
// Swap bg/fg if the terminal is reversed
|
||||
const bg = self.background;
|
||||
const fg = self.foreground;
|
||||
const bg = self.config.background;
|
||||
const fg = self.config.foreground;
|
||||
defer {
|
||||
self.background = bg;
|
||||
self.foreground = fg;
|
||||
self.config.background = bg;
|
||||
self.config.foreground = fg;
|
||||
}
|
||||
if (state.terminal.modes.reverse_colors) {
|
||||
self.background = fg;
|
||||
self.foreground = bg;
|
||||
self.config.background = fg;
|
||||
self.config.foreground = bg;
|
||||
}
|
||||
|
||||
// We used to share terminal state, but we've since learned through
|
||||
@ -516,7 +543,7 @@ pub fn render(
|
||||
null;
|
||||
|
||||
break :critical .{
|
||||
.bg = self.background,
|
||||
.bg = self.config.background,
|
||||
.devmode = if (state.devmode) |dm| dm.visible else false,
|
||||
.selection = selection,
|
||||
.screen = screen_copy,
|
||||
@ -878,8 +905,8 @@ pub fn updateCell(
|
||||
// If we are selected, we our colors are just inverted fg/bg
|
||||
if (sel.contains(screen_point)) {
|
||||
break :colors BgFg{
|
||||
.bg = self.selection_background orelse self.foreground,
|
||||
.fg = self.selection_foreground orelse self.background,
|
||||
.bg = self.config.selection_background orelse self.config.foreground,
|
||||
.fg = self.config.selection_foreground orelse self.config.background,
|
||||
};
|
||||
}
|
||||
}
|
||||
@ -888,13 +915,13 @@ pub fn updateCell(
|
||||
// In normal mode, background and fg match the cell. We
|
||||
// un-optionalize the fg by defaulting to our fg color.
|
||||
.bg = if (cell.attrs.has_bg) cell.bg else null,
|
||||
.fg = if (cell.attrs.has_fg) cell.fg else self.foreground,
|
||||
.fg = if (cell.attrs.has_fg) cell.fg else self.config.foreground,
|
||||
} else .{
|
||||
// In inverted mode, the background MUST be set to something
|
||||
// (is never null) so it is either the fg or default fg. The
|
||||
// fg is either the bg or default background.
|
||||
.bg = if (cell.attrs.has_fg) cell.fg else self.foreground,
|
||||
.fg = if (cell.attrs.has_bg) cell.bg else self.background,
|
||||
.bg = if (cell.attrs.has_fg) cell.fg else self.config.foreground,
|
||||
.fg = if (cell.attrs.has_bg) cell.bg else self.config.background,
|
||||
};
|
||||
break :colors res;
|
||||
};
|
||||
@ -988,7 +1015,7 @@ fn addCursor(self: *Metal, screen: *terminal.Screen) void {
|
||||
screen.cursor.x,
|
||||
);
|
||||
|
||||
const color = self.cursor_color orelse terminal.color.RGB{
|
||||
const color = self.config.cursor_color orelse terminal.color.RGB{
|
||||
.r = 0xFF,
|
||||
.g = 0xFF,
|
||||
.b = 0xFF,
|
||||
|
@ -8,6 +8,7 @@ const assert = std.debug.assert;
|
||||
const testing = std.testing;
|
||||
const Allocator = std.mem.Allocator;
|
||||
const apprt = @import("../apprt.zig");
|
||||
const configpkg = @import("../config.zig");
|
||||
const font = @import("../font/main.zig");
|
||||
const imgui = @import("imgui");
|
||||
const renderer = @import("../renderer.zig");
|
||||
@ -43,6 +44,9 @@ const drawMutexZero = if (DrawMutex == void) void{} else .{};
|
||||
|
||||
alloc: std.mem.Allocator,
|
||||
|
||||
/// The configuration we need derived from the main config.
|
||||
config: DerivedConfig,
|
||||
|
||||
/// Current cell dimensions for this grid.
|
||||
cell_size: renderer.CellSize,
|
||||
|
||||
@ -84,17 +88,6 @@ font_shaper: font.Shaper,
|
||||
/// blinking.
|
||||
cursor_visible: bool,
|
||||
cursor_style: renderer.CursorStyle,
|
||||
cursor_color: ?terminal.color.RGB,
|
||||
|
||||
/// Default foreground color
|
||||
foreground: terminal.color.RGB,
|
||||
|
||||
/// Default background color
|
||||
background: terminal.color.RGB,
|
||||
|
||||
/// Default selection color
|
||||
selection_background: ?terminal.color.RGB,
|
||||
selection_foreground: ?terminal.color.RGB,
|
||||
|
||||
/// True if the window is focused
|
||||
focused: bool,
|
||||
@ -232,6 +225,48 @@ const GPUCellMode = enum(u8) {
|
||||
}
|
||||
};
|
||||
|
||||
/// The configuration for this renderer that is derived from the main
|
||||
/// configuration. This must be exported so that we don't need to
|
||||
/// pass around Config pointers which makes memory management a pain.
|
||||
pub const DerivedConfig = struct {
|
||||
cursor_color: ?terminal.color.RGB,
|
||||
background: terminal.color.RGB,
|
||||
foreground: terminal.color.RGB,
|
||||
selection_background: ?terminal.color.RGB,
|
||||
selection_foreground: ?terminal.color.RGB,
|
||||
|
||||
pub fn init(
|
||||
alloc_gpa: Allocator,
|
||||
config: *const configpkg.Config,
|
||||
) !DerivedConfig {
|
||||
_ = alloc_gpa;
|
||||
|
||||
return .{
|
||||
.cursor_color = if (config.@"cursor-color") |col|
|
||||
col.toTerminalRGB()
|
||||
else
|
||||
null,
|
||||
|
||||
.background = config.background.toTerminalRGB(),
|
||||
.foreground = config.foreground.toTerminalRGB(),
|
||||
|
||||
.selection_background = if (config.@"selection-background") |bg|
|
||||
bg.toTerminalRGB()
|
||||
else
|
||||
null,
|
||||
|
||||
.selection_foreground = if (config.@"selection-foreground") |bg|
|
||||
bg.toTerminalRGB()
|
||||
else
|
||||
null,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn deinit(self: *DerivedConfig) void {
|
||||
_ = self;
|
||||
}
|
||||
};
|
||||
|
||||
pub fn init(alloc: Allocator, options: renderer.Options) !OpenGL {
|
||||
// Create the initial font shaper
|
||||
var shape_buf = try alloc.alloc(font.shape.Cell, 1);
|
||||
@ -354,6 +389,7 @@ pub fn init(alloc: Allocator, options: renderer.Options) !OpenGL {
|
||||
|
||||
return OpenGL{
|
||||
.alloc = alloc,
|
||||
.config = options.config,
|
||||
.cells_bg = .{},
|
||||
.cells = .{},
|
||||
.cells_lru = CellsLRU.init(0),
|
||||
@ -369,18 +405,7 @@ pub fn init(alloc: Allocator, options: renderer.Options) !OpenGL {
|
||||
.font_shaper = shaper,
|
||||
.cursor_visible = true,
|
||||
.cursor_style = .box,
|
||||
.cursor_color = if (options.config.@"cursor-color") |col| col.toTerminalRGB() else null,
|
||||
.background = options.config.background.toTerminalRGB(),
|
||||
.foreground = options.config.foreground.toTerminalRGB(),
|
||||
.draw_background = options.config.background.toTerminalRGB(),
|
||||
.selection_background = if (options.config.@"selection-background") |bg|
|
||||
bg.toTerminalRGB()
|
||||
else
|
||||
null,
|
||||
.selection_foreground = if (options.config.@"selection-foreground") |bg|
|
||||
bg.toTerminalRGB()
|
||||
else
|
||||
null,
|
||||
.draw_background = options.config.background,
|
||||
.focused = true,
|
||||
.padding = options.padding,
|
||||
.surface_mailbox = options.surface_mailbox,
|
||||
@ -404,6 +429,9 @@ pub fn deinit(self: *OpenGL) void {
|
||||
|
||||
self.cells.deinit(self.alloc);
|
||||
self.cells_bg.deinit(self.alloc);
|
||||
|
||||
self.config.deinit();
|
||||
|
||||
self.* = undefined;
|
||||
}
|
||||
|
||||
@ -673,15 +701,15 @@ pub fn render(
|
||||
}
|
||||
|
||||
// Swap bg/fg if the terminal is reversed
|
||||
const bg = self.background;
|
||||
const fg = self.foreground;
|
||||
const bg = self.config.background;
|
||||
const fg = self.config.foreground;
|
||||
defer {
|
||||
self.background = bg;
|
||||
self.foreground = fg;
|
||||
self.config.background = bg;
|
||||
self.config.foreground = fg;
|
||||
}
|
||||
if (state.terminal.modes.reverse_colors) {
|
||||
self.background = fg;
|
||||
self.foreground = bg;
|
||||
self.config.background = fg;
|
||||
self.config.foreground = bg;
|
||||
}
|
||||
|
||||
// Build our devmode draw data
|
||||
@ -723,7 +751,7 @@ pub fn render(
|
||||
null;
|
||||
|
||||
break :critical .{
|
||||
.gl_bg = self.background,
|
||||
.gl_bg = self.config.background,
|
||||
.devmode_data = devmode_data,
|
||||
.active_screen = state.terminal.active_screen,
|
||||
.selection = selection,
|
||||
@ -944,7 +972,7 @@ fn addCursor(self: *OpenGL, screen: *terminal.Screen) void {
|
||||
screen.cursor.x,
|
||||
);
|
||||
|
||||
const color = self.cursor_color orelse terminal.color.RGB{
|
||||
const color = self.config.cursor_color orelse terminal.color.RGB{
|
||||
.r = 0xFF,
|
||||
.g = 0xFF,
|
||||
.b = 0xFF,
|
||||
@ -1031,8 +1059,8 @@ pub fn updateCell(
|
||||
// If we are selected, we use the selection colors
|
||||
if (sel.contains(screen_point)) {
|
||||
break :colors BgFg{
|
||||
.bg = self.selection_background orelse self.foreground,
|
||||
.fg = self.selection_foreground orelse self.background,
|
||||
.bg = self.config.selection_background orelse self.config.foreground,
|
||||
.fg = self.config.selection_foreground orelse self.config.background,
|
||||
};
|
||||
}
|
||||
}
|
||||
@ -1041,13 +1069,13 @@ pub fn updateCell(
|
||||
// In normal mode, background and fg match the cell. We
|
||||
// un-optionalize the fg by defaulting to our fg color.
|
||||
.bg = if (cell.attrs.has_bg) cell.bg else null,
|
||||
.fg = if (cell.attrs.has_fg) cell.fg else self.foreground,
|
||||
.fg = if (cell.attrs.has_fg) cell.fg else self.config.foreground,
|
||||
} else .{
|
||||
// In inverted mode, the background MUST be set to something
|
||||
// (is never null) so it is either the fg or default fg. The
|
||||
// fg is either the bg or default background.
|
||||
.bg = if (cell.attrs.has_fg) cell.fg else self.foreground,
|
||||
.fg = if (cell.attrs.has_bg) cell.bg else self.background,
|
||||
.bg = if (cell.attrs.has_fg) cell.fg else self.config.foreground,
|
||||
.fg = if (cell.attrs.has_bg) cell.bg else self.config.background,
|
||||
};
|
||||
break :colors res;
|
||||
};
|
||||
|
@ -5,10 +5,8 @@ const font = @import("../font/main.zig");
|
||||
const renderer = @import("../renderer.zig");
|
||||
const Config = @import("../config.zig").Config;
|
||||
|
||||
/// The app configuration. This must NOT be stored by any termio implementation.
|
||||
/// The memory it points to is NOT stable after the init call so any values
|
||||
/// in here must be copied.
|
||||
config: *const Config,
|
||||
/// The derived configuration for this renderer implementation.
|
||||
config: renderer.Renderer.DerivedConfig,
|
||||
|
||||
/// The font group that should be used.
|
||||
font_group: *font.GroupCache,
|
||||
|
Reference in New Issue
Block a user