mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-14 15:56:13 +03:00
Merge pull request #2095 from qwerasd205/flicker
Fix flickering when resizing surface.
This commit is contained in:
@ -1197,15 +1197,6 @@ fn resize(self: *Surface, size: renderer.ScreenSize) !void {
|
||||
// Save our screen size
|
||||
self.screen_size = size;
|
||||
|
||||
// Mail the renderer so that it can update the GPU and re-render
|
||||
_ = self.renderer_thread.mailbox.push(.{
|
||||
.resize = .{
|
||||
.screen_size = self.screen_size,
|
||||
.padding = self.padding,
|
||||
},
|
||||
}, .{ .forever = {} });
|
||||
try self.queueRender();
|
||||
|
||||
// Recalculate our grid size. Because Ghostty supports fluid resizing,
|
||||
// its possible the grid doesn't change at all even if the screen size changes.
|
||||
// We have to update the IO thread no matter what because we send
|
||||
|
@ -908,12 +908,14 @@ pub fn updateFrame(
|
||||
}
|
||||
|
||||
// If our terminal screen size doesn't match our expected renderer
|
||||
// size then we skip a frame. This can happen if we get resized
|
||||
// before the terminal gets resized. The terminal resize event also
|
||||
// wakes up the renderer so we'll get another chance to update frame
|
||||
// data.
|
||||
if (self.cells.size.rows < state.terminal.rows or
|
||||
self.cells.size.columns < state.terminal.cols)
|
||||
// size then we skip a frame. This can happen if the terminal state
|
||||
// is resized between when the renderer mailbox is drained and when
|
||||
// the state mutex is acquired inside this function.
|
||||
//
|
||||
// For some reason this doesn't seem to cause any significant issues
|
||||
// with flickering while resizing. '\_('-')_/'
|
||||
if (self.cells.size.rows != state.terminal.rows or
|
||||
self.cells.size.columns != state.terminal.cols)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@ -2012,11 +2014,13 @@ pub fn setScreenSize(
|
||||
.cursor_color = old.cursor_color,
|
||||
};
|
||||
|
||||
// Reset our cell contents.
|
||||
// Reset our cell contents if our grid size has changed.
|
||||
if (!self.cells.size.equals(grid_size)) {
|
||||
try self.cells.resize(self.alloc, grid_size);
|
||||
|
||||
// Reset our viewport to force a rebuild
|
||||
self.cells_viewport = null;
|
||||
}
|
||||
|
||||
// If we have custom shaders then we update the state
|
||||
if (self.custom_shader_state) |*state| {
|
||||
|
@ -739,6 +739,19 @@ pub fn updateFrame(
|
||||
self.foreground_color = bg;
|
||||
}
|
||||
|
||||
// If our terminal screen size doesn't match our expected renderer
|
||||
// size then we skip a frame. This can happen if the terminal state
|
||||
// is resized between when the renderer mailbox is drained and when
|
||||
// the state mutex is acquired inside this function.
|
||||
//
|
||||
// For some reason this doesn't seem to cause any significant issues
|
||||
// with flickering while resizing. '\_('-')_/'
|
||||
if (self.grid_size.rows != state.terminal.rows or
|
||||
self.grid_size.columns != state.terminal.cols)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the viewport pin so that we can compare it to the current.
|
||||
const viewport_pin = state.terminal.screen.pages.pin(.{ .viewport = .{} }).?;
|
||||
|
||||
|
@ -480,7 +480,7 @@ fn drawCallback(
|
||||
r: xev.Timer.RunError!void,
|
||||
) xev.CallbackAction {
|
||||
_ = r catch unreachable;
|
||||
const t = self_ orelse {
|
||||
const t: *Thread = self_ orelse {
|
||||
// This shouldn't happen so we log it.
|
||||
log.warn("render callback fired without data set", .{});
|
||||
return .disarm;
|
||||
@ -504,7 +504,7 @@ fn renderCallback(
|
||||
r: xev.Timer.RunError!void,
|
||||
) xev.CallbackAction {
|
||||
_ = r catch unreachable;
|
||||
const t = self_ orelse {
|
||||
const t: *Thread = self_ orelse {
|
||||
// This shouldn't happen so we log it.
|
||||
log.warn("render callback fired without data set", .{});
|
||||
return .disarm;
|
||||
@ -522,6 +522,8 @@ fn renderCallback(
|
||||
t.flags.cursor_blink_visible,
|
||||
) catch |err|
|
||||
log.warn("error rendering err={}", .{err});
|
||||
|
||||
// Draw
|
||||
t.drawFrame(false);
|
||||
|
||||
return .disarm;
|
||||
@ -543,7 +545,7 @@ fn cursorTimerCallback(
|
||||
},
|
||||
};
|
||||
|
||||
const t = self_ orelse {
|
||||
const t: *Thread = self_ orelse {
|
||||
// This shouldn't happen so we log it.
|
||||
log.warn("render callback fired without data set", .{});
|
||||
return .disarm;
|
||||
|
@ -378,14 +378,20 @@ pub fn resize(
|
||||
// immediately for a resize. This is allowed by the spec.
|
||||
self.terminal.modes.set(.synchronized_output, false);
|
||||
|
||||
// Wake up our renderer so any changes will be shown asap
|
||||
self.renderer_wakeup.notify() catch {};
|
||||
|
||||
// If we have size reporting enabled we need to send a report.
|
||||
if (self.terminal.modes.get(.in_band_size_reports)) {
|
||||
try self.sizeReportLocked(td, .mode_2048);
|
||||
}
|
||||
}
|
||||
|
||||
// Mail the renderer so that it can update the GPU and re-render
|
||||
_ = self.renderer_mailbox.push(.{
|
||||
.resize = .{
|
||||
.screen_size = screen_size,
|
||||
.padding = padding,
|
||||
},
|
||||
}, .{ .forever = {} });
|
||||
self.renderer_wakeup.notify() catch {};
|
||||
}
|
||||
|
||||
/// Make a size report.
|
||||
|
Reference in New Issue
Block a user