mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-16 08:46:08 +03:00
hook up scrolling, kind of works, kind of broke
This commit is contained in:
@ -250,6 +250,7 @@ pub fn create(alloc: Allocator, loop: libuv.Loop, config: *const Config) !*Windo
|
||||
window.setKeyCallback(keyCallback);
|
||||
window.setFocusCallback(focusCallback);
|
||||
window.setRefreshCallback(refreshCallback);
|
||||
window.setScrollCallback(scrollCallback);
|
||||
|
||||
return self;
|
||||
}
|
||||
@ -505,6 +506,24 @@ fn refreshCallback(window: glfw.Window) void {
|
||||
win.render_timer.schedule() catch unreachable;
|
||||
}
|
||||
|
||||
fn scrollCallback(window: glfw.Window, xoff: f64, yoff: f64) void {
|
||||
const win = window.getUserPointer(Window) orelse return;
|
||||
|
||||
//log.info("SCROLL: {} {}", .{ xoff, yoff });
|
||||
_ = xoff;
|
||||
|
||||
// Positive is up
|
||||
const sign: isize = if (yoff < 0) -1 else 1;
|
||||
const delta: isize = sign * @maximum(@divFloor(win.grid.size.rows, 15), 1);
|
||||
log.info("scroll: delta={}", .{delta});
|
||||
win.terminal.scrollViewport(.{ .delta = delta });
|
||||
|
||||
// Schedule render since scrolling usually does something.
|
||||
// TODO(perf): we can only schedule render if we know scrolling
|
||||
// did something
|
||||
win.render_timer.schedule() catch unreachable;
|
||||
}
|
||||
|
||||
fn cursorTimerCallback(t: *libuv.Timer) void {
|
||||
const tracy = trace(@src());
|
||||
defer tracy.end();
|
||||
|
@ -187,12 +187,25 @@ pub fn scroll(self: *Screen, behavior: Scroll) void {
|
||||
.bottom => self.visible_offset = self.bottom - self.rows,
|
||||
|
||||
// TODO: deltas greater than the entire scrollback
|
||||
.delta => |delta| self.scrollDown(delta, true),
|
||||
.delta_no_grow => |delta| self.scrollDown(delta, false),
|
||||
.delta => |delta| self.scrollDelta(delta, true),
|
||||
.delta_no_grow => |delta| self.scrollDelta(delta, false),
|
||||
}
|
||||
}
|
||||
|
||||
fn scrollDown(self: *Screen, delta: isize, grow: bool) void {
|
||||
fn scrollDelta(self: *Screen, delta: isize, grow: bool) void {
|
||||
log.info("offsets before: top={} bottom={} visible={}", .{
|
||||
self.top,
|
||||
self.bottom,
|
||||
self.visible_offset,
|
||||
});
|
||||
defer {
|
||||
log.info("offsets after: top={} bottom={} visible={}", .{
|
||||
self.top,
|
||||
self.bottom,
|
||||
self.visible_offset,
|
||||
});
|
||||
}
|
||||
|
||||
// If we're scrolling up, then we just subtract and we're done.
|
||||
if (delta < 0) {
|
||||
self.visible_offset -|= @intCast(usize, -delta);
|
||||
@ -255,22 +268,6 @@ fn scrollDown(self: *Screen, delta: isize, grow: bool) void {
|
||||
self.visible_offset -= rows_overlapped;
|
||||
}
|
||||
|
||||
/// Scroll the screen up (positive) or down (negative). Scrolling direction
|
||||
/// is the direction text would move. For example, scrolling down would
|
||||
/// move existing text downward.
|
||||
pub fn scrollOld(self: *Screen, count: isize) void {
|
||||
if (count < 0) {
|
||||
const amount = @mod(@intCast(usize, -count), self.rows);
|
||||
if (amount > self.top) {
|
||||
self.top = self.rows - amount;
|
||||
} else {
|
||||
self.top -|= amount;
|
||||
}
|
||||
} else {
|
||||
self.top = @mod(self.top + @intCast(usize, count), self.rows);
|
||||
}
|
||||
}
|
||||
|
||||
/// Copy row at src to dst.
|
||||
pub fn copyRow(self: *Screen, dst: usize, src: usize) void {
|
||||
const src_row = self.getRow(src);
|
||||
@ -289,7 +286,7 @@ pub fn resize(self: *Screen, alloc: Allocator, rows: usize, cols: usize) !void {
|
||||
const old = self.*;
|
||||
|
||||
// Reallocate the storage
|
||||
self.storage = try alloc.alloc(Cell, rows * cols);
|
||||
self.storage = try alloc.alloc(Cell, (rows + self.max_scrollback) * cols);
|
||||
self.top = 0;
|
||||
self.bottom = rows - 1;
|
||||
self.rows = rows;
|
||||
|
@ -73,7 +73,8 @@ pub fn init(alloc: Allocator, cols: usize, rows: usize) !Terminal {
|
||||
return Terminal{
|
||||
.cols = cols,
|
||||
.rows = rows,
|
||||
.screen = try Screen.init(alloc, rows, cols, 0),
|
||||
// TODO: configurable scrollback
|
||||
.screen = try Screen.init(alloc, rows, cols, 1000),
|
||||
.cursor = .{},
|
||||
.saved_cursor = .{},
|
||||
.tabstops = try Tabstops.init(alloc, cols, TABSTOP_INTERVAL),
|
||||
@ -276,7 +277,7 @@ pub fn index(self: *Terminal) void {
|
||||
if (self.cursor.y < self.scrolling_region.top or
|
||||
self.cursor.y > self.scrolling_region.bottom) return;
|
||||
|
||||
self.scrollUp();
|
||||
self.screen.scroll(.{ .delta = 1 });
|
||||
return;
|
||||
}
|
||||
|
||||
@ -673,16 +674,6 @@ pub fn deleteLines(self: *Terminal, count: usize) void {
|
||||
}
|
||||
}
|
||||
|
||||
/// Scroll the text up by one row.
|
||||
pub fn scrollUp(self: *Terminal) void {
|
||||
const tracy = trace(@src());
|
||||
defer tracy.end();
|
||||
|
||||
self.screen.scroll(.{ .delta = 1 });
|
||||
const last = self.screen.getRow(self.rows - 1);
|
||||
for (last) |*cell| cell.char = 0;
|
||||
}
|
||||
|
||||
/// Scroll the text down by one row.
|
||||
/// TODO: test
|
||||
pub fn scrollDown(self: *Terminal, count: usize) void {
|
||||
@ -698,6 +689,18 @@ pub fn scrollDown(self: *Terminal, count: usize) void {
|
||||
self.insertLines(count);
|
||||
}
|
||||
|
||||
/// Options for scrolling the viewport of the terminal grid.
|
||||
pub const ScrollViewport = union(enum) {
|
||||
delta: isize,
|
||||
};
|
||||
|
||||
/// Scroll the viewport of the terminal grid.
|
||||
pub fn scrollViewport(self: *Terminal, behavior: ScrollViewport) void {
|
||||
self.screen.scroll(switch (behavior) {
|
||||
.delta => |delta| .{ .delta_no_grow = delta },
|
||||
});
|
||||
}
|
||||
|
||||
/// Set Top and Bottom Margins If bottom is not specified, 0 or bigger than
|
||||
/// the number of the bottom-most row, it is adjusted to the number of the
|
||||
/// bottom most row.
|
||||
|
Reference in New Issue
Block a user