mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-16 16:56:09 +03:00
move to new renderstate, new render method
This commit is contained in:
@ -27,7 +27,7 @@ window: ?*Window = null,
|
|||||||
/// Update the state associated with the dev mode. This should generally
|
/// Update the state associated with the dev mode. This should generally
|
||||||
/// only be called paired with a render since it otherwise wastes CPU
|
/// only be called paired with a render since it otherwise wastes CPU
|
||||||
/// cycles.
|
/// cycles.
|
||||||
pub fn update(self: *DevMode) !void {
|
pub fn update(self: *const DevMode) !void {
|
||||||
imgui.ImplOpenGL3.newFrame();
|
imgui.ImplOpenGL3.newFrame();
|
||||||
imgui.ImplGlfw.newFrame();
|
imgui.ImplGlfw.newFrame();
|
||||||
imgui.newFrame();
|
imgui.newFrame();
|
||||||
@ -82,7 +82,7 @@ fn helpMarker(desc: [:0]const u8) void {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn atlasInfo(self: *DevMode, atlas: *Atlas, tex: ?usize) !void {
|
fn atlasInfo(self: *const DevMode, atlas: *Atlas, tex: ?usize) !void {
|
||||||
_ = self;
|
_ = self;
|
||||||
|
|
||||||
imgui.text("Dimensions: %d x %d", atlas.size, atlas.size);
|
imgui.text("Dimensions: %d x %d", atlas.size, atlas.size);
|
||||||
|
102
src/Window.zig
102
src/Window.zig
@ -120,19 +120,6 @@ const Cursor = struct {
|
|||||||
/// Timer for cursor blinking.
|
/// Timer for cursor blinking.
|
||||||
timer: libuv.Timer,
|
timer: libuv.Timer,
|
||||||
|
|
||||||
/// Current cursor style. This can be set by escape sequences. To get
|
|
||||||
/// the default style, the config has to be referenced.
|
|
||||||
style: terminal.CursorStyle = .default,
|
|
||||||
|
|
||||||
/// Whether the cursor is visible at all. This should not be used for
|
|
||||||
/// "blink" settings, see "blink" for that. This is used to turn the
|
|
||||||
/// cursor ON or OFF.
|
|
||||||
visible: bool = true,
|
|
||||||
|
|
||||||
/// Whether the cursor is currently blinking. If it is blinking, then
|
|
||||||
/// the cursor will not be rendered.
|
|
||||||
blink: bool = false,
|
|
||||||
|
|
||||||
/// Start (or restart) the timer. This is idempotent.
|
/// Start (or restart) the timer. This is idempotent.
|
||||||
pub fn startTimer(self: Cursor) !void {
|
pub fn startTimer(self: Cursor) !void {
|
||||||
try self.timer.start(
|
try self.timer.start(
|
||||||
@ -460,6 +447,7 @@ pub fn create(alloc: Allocator, loop: libuv.Loop, config: *const Config) !*Windo
|
|||||||
|
|
||||||
// The mutex used to protect our renderer state.
|
// The mutex used to protect our renderer state.
|
||||||
var mutex = try alloc.create(std.Thread.Mutex);
|
var mutex = try alloc.create(std.Thread.Mutex);
|
||||||
|
mutex.* = .{};
|
||||||
errdefer alloc.destroy(mutex);
|
errdefer alloc.destroy(mutex);
|
||||||
|
|
||||||
self.* = .{
|
self.* = .{
|
||||||
@ -486,10 +474,7 @@ pub fn create(alloc: Allocator, loop: libuv.Loop, config: *const Config) !*Windo
|
|||||||
.mouse = .{},
|
.mouse = .{},
|
||||||
.terminal = term,
|
.terminal = term,
|
||||||
.terminal_stream = .{ .handler = self },
|
.terminal_stream = .{ .handler = self },
|
||||||
.terminal_cursor = .{
|
.terminal_cursor = .{ .timer = timer },
|
||||||
.timer = timer,
|
|
||||||
.style = .blinking_block,
|
|
||||||
},
|
|
||||||
.render_timer = try RenderTimer.init(loop, self, 6, 12),
|
.render_timer = try RenderTimer.init(loop, self, 6, 12),
|
||||||
.pty_stream = stream,
|
.pty_stream = stream,
|
||||||
.config = config,
|
.config = config,
|
||||||
@ -1487,10 +1472,10 @@ fn cursorTimerCallback(t: *libuv.Timer) void {
|
|||||||
|
|
||||||
// If the cursor is currently invisible, then we do nothing. Ideally
|
// If the cursor is currently invisible, then we do nothing. Ideally
|
||||||
// in this state the timer would be cancelled but no big deal.
|
// in this state the timer would be cancelled but no big deal.
|
||||||
if (!win.terminal_cursor.visible) return;
|
if (!win.renderer_state.cursor.visible) return;
|
||||||
|
|
||||||
// Swap blink state and schedule a render
|
// Swap blink state and schedule a render
|
||||||
win.terminal_cursor.blink = !win.terminal_cursor.blink;
|
win.renderer_state.cursor.blink = !win.renderer_state.cursor.blink;
|
||||||
win.render_timer.schedule() catch unreachable;
|
win.render_timer.schedule() catch unreachable;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1528,9 +1513,13 @@ fn ttyRead(t: *libuv.Tty, n: isize, buf: []const u8) void {
|
|||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// We are modifying terminal state from here on out
|
||||||
|
win.renderer_state.mutex.lock();
|
||||||
|
defer win.renderer_state.mutex.unlock();
|
||||||
|
|
||||||
// Whenever a character is typed, we ensure the cursor is in the
|
// Whenever a character is typed, we ensure the cursor is in the
|
||||||
// non-blink state so it is rendered if visible.
|
// non-blink state so it is rendered if visible.
|
||||||
win.terminal_cursor.blink = false;
|
win.renderer_state.cursor.blink = false;
|
||||||
if (win.terminal_cursor.timer.isActive() catch false) {
|
if (win.terminal_cursor.timer.isActive() catch false) {
|
||||||
_ = win.terminal_cursor.timer.again() catch null;
|
_ = win.terminal_cursor.timer.again() catch null;
|
||||||
}
|
}
|
||||||
@ -1600,72 +1589,9 @@ fn renderTimerCallback(t: *libuv.Timer) void {
|
|||||||
|
|
||||||
const win = t.getData(Window).?;
|
const win = t.getData(Window).?;
|
||||||
|
|
||||||
// Setup our cursor settings
|
// Render
|
||||||
if (win.focused) {
|
win.renderer.render(win.window, win.renderer_state) catch |err|
|
||||||
win.renderer.cursor_visible = win.terminal_cursor.visible and !win.terminal_cursor.blink;
|
log.warn("error rendering err={}", .{err});
|
||||||
win.renderer.cursor_style = renderer.OpenGL.CursorStyle.fromTerminal(win.terminal_cursor.style) orelse .box;
|
|
||||||
} else {
|
|
||||||
win.renderer.cursor_visible = true;
|
|
||||||
win.renderer.cursor_style = .box_hollow;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Calculate foreground and background colors
|
|
||||||
const bg = win.renderer.background;
|
|
||||||
const fg = win.renderer.foreground;
|
|
||||||
defer {
|
|
||||||
win.renderer.background = bg;
|
|
||||||
win.renderer.foreground = fg;
|
|
||||||
}
|
|
||||||
if (win.terminal.modes.reverse_colors) {
|
|
||||||
win.renderer.background = fg;
|
|
||||||
win.renderer.foreground = bg;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set our background
|
|
||||||
const gl_bg: struct {
|
|
||||||
r: f32,
|
|
||||||
g: f32,
|
|
||||||
b: f32,
|
|
||||||
a: f32,
|
|
||||||
} = if (win.terminal.modes.reverse_colors) .{
|
|
||||||
.r = @intToFloat(f32, fg.r) / 255,
|
|
||||||
.g = @intToFloat(f32, fg.g) / 255,
|
|
||||||
.b = @intToFloat(f32, fg.b) / 255,
|
|
||||||
.a = 1.0,
|
|
||||||
} else .{
|
|
||||||
.r = win.bg_r,
|
|
||||||
.g = win.bg_g,
|
|
||||||
.b = win.bg_b,
|
|
||||||
.a = win.bg_a,
|
|
||||||
};
|
|
||||||
gl.clearColor(gl_bg.r, gl_bg.g, gl_bg.b, gl_bg.a);
|
|
||||||
gl.clear(gl.c.GL_COLOR_BUFFER_BIT);
|
|
||||||
|
|
||||||
// For now, rebuild all cells
|
|
||||||
win.renderer.rebuildCells(&win.terminal) catch |err|
|
|
||||||
log.err("error calling rebuildCells in render timer err={}", .{err});
|
|
||||||
|
|
||||||
// Finalize the cells prior to render
|
|
||||||
win.renderer.finalizeCells(&win.terminal) catch |err|
|
|
||||||
log.err("error calling updateCells in render timer err={}", .{err});
|
|
||||||
|
|
||||||
// Render the grid
|
|
||||||
win.renderer.draw() catch |err| {
|
|
||||||
log.err("error rendering grid: {}", .{err});
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
|
|
||||||
if (DevMode.enabled and DevMode.instance.visible) {
|
|
||||||
DevMode.instance.update() catch unreachable;
|
|
||||||
const data = DevMode.instance.render() catch unreachable;
|
|
||||||
imgui.ImplOpenGL3.renderDrawData(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Swap
|
|
||||||
win.window.swapBuffers() catch |err| {
|
|
||||||
log.err("error swapping buffers: {}", .{err});
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Record our run
|
// Record our run
|
||||||
win.render_timer.tick();
|
win.render_timer.tick();
|
||||||
@ -1805,7 +1731,7 @@ pub fn setMode(self: *Window, mode: terminal.Mode, enabled: bool) !void {
|
|||||||
},
|
},
|
||||||
|
|
||||||
.cursor_visible => {
|
.cursor_visible => {
|
||||||
self.terminal_cursor.visible = enabled;
|
self.renderer_state.cursor.visible = enabled;
|
||||||
},
|
},
|
||||||
|
|
||||||
.alt_screen_save_cursor_clear_enter => {
|
.alt_screen_save_cursor_clear_enter => {
|
||||||
@ -1918,7 +1844,7 @@ pub fn setCursorStyle(
|
|||||||
self: *Window,
|
self: *Window,
|
||||||
style: terminal.CursorStyle,
|
style: terminal.CursorStyle,
|
||||||
) !void {
|
) !void {
|
||||||
self.terminal_cursor.style = style;
|
self.renderer_state.cursor.style = style;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn decaln(self: *Window) !void {
|
pub fn decaln(self: *Window) !void {
|
||||||
|
@ -386,7 +386,7 @@ pub fn render(
|
|||||||
|
|
||||||
try self.rebuildCells(state.terminal);
|
try self.rebuildCells(state.terminal);
|
||||||
try self.finalizeCells(state.terminal);
|
try self.finalizeCells(state.terminal);
|
||||||
if (state.devmode) |dm| try dm.update();
|
if (state.devmode) |dm| if (dm.visible) try dm.update();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear the surface
|
// Clear the surface
|
||||||
@ -403,8 +403,10 @@ pub fn render(
|
|||||||
|
|
||||||
// If we have devmode, then render that
|
// If we have devmode, then render that
|
||||||
if (state.devmode) |dm| {
|
if (state.devmode) |dm| {
|
||||||
const data = try dm.render();
|
if (dm.visible) {
|
||||||
imgui.ImplOpenGL3.renderDrawData(data);
|
const data = try dm.render();
|
||||||
|
imgui.ImplOpenGL3.renderDrawData(data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Swap our window buffers
|
// Swap our window buffers
|
||||||
|
Reference in New Issue
Block a user