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
|
// Save our screen size
|
||||||
self.screen_size = 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,
|
// Recalculate our grid size. Because Ghostty supports fluid resizing,
|
||||||
// its possible the grid doesn't change at all even if the screen size changes.
|
// 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
|
// 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
|
// If our terminal screen size doesn't match our expected renderer
|
||||||
// size then we skip a frame. This can happen if we get resized
|
// size then we skip a frame. This can happen if the terminal state
|
||||||
// before the terminal gets resized. The terminal resize event also
|
// is resized between when the renderer mailbox is drained and when
|
||||||
// wakes up the renderer so we'll get another chance to update frame
|
// the state mutex is acquired inside this function.
|
||||||
// data.
|
//
|
||||||
if (self.cells.size.rows < state.terminal.rows or
|
// For some reason this doesn't seem to cause any significant issues
|
||||||
self.cells.size.columns < state.terminal.cols)
|
// with flickering while resizing. '\_('-')_/'
|
||||||
|
if (self.cells.size.rows != state.terminal.rows or
|
||||||
|
self.cells.size.columns != state.terminal.cols)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -2012,11 +2014,13 @@ pub fn setScreenSize(
|
|||||||
.cursor_color = old.cursor_color,
|
.cursor_color = old.cursor_color,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Reset our cell contents.
|
// Reset our cell contents if our grid size has changed.
|
||||||
try self.cells.resize(self.alloc, grid_size);
|
if (!self.cells.size.equals(grid_size)) {
|
||||||
|
try self.cells.resize(self.alloc, grid_size);
|
||||||
|
|
||||||
// Reset our viewport to force a rebuild
|
// Reset our viewport to force a rebuild
|
||||||
self.cells_viewport = null;
|
self.cells_viewport = null;
|
||||||
|
}
|
||||||
|
|
||||||
// If we have custom shaders then we update the state
|
// If we have custom shaders then we update the state
|
||||||
if (self.custom_shader_state) |*state| {
|
if (self.custom_shader_state) |*state| {
|
||||||
|
@ -739,6 +739,19 @@ pub fn updateFrame(
|
|||||||
self.foreground_color = bg;
|
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.
|
// Get the viewport pin so that we can compare it to the current.
|
||||||
const viewport_pin = state.terminal.screen.pages.pin(.{ .viewport = .{} }).?;
|
const viewport_pin = state.terminal.screen.pages.pin(.{ .viewport = .{} }).?;
|
||||||
|
|
||||||
|
@ -480,7 +480,7 @@ fn drawCallback(
|
|||||||
r: xev.Timer.RunError!void,
|
r: xev.Timer.RunError!void,
|
||||||
) xev.CallbackAction {
|
) xev.CallbackAction {
|
||||||
_ = r catch unreachable;
|
_ = r catch unreachable;
|
||||||
const t = self_ orelse {
|
const t: *Thread = self_ orelse {
|
||||||
// This shouldn't happen so we log it.
|
// This shouldn't happen so we log it.
|
||||||
log.warn("render callback fired without data set", .{});
|
log.warn("render callback fired without data set", .{});
|
||||||
return .disarm;
|
return .disarm;
|
||||||
@ -504,7 +504,7 @@ fn renderCallback(
|
|||||||
r: xev.Timer.RunError!void,
|
r: xev.Timer.RunError!void,
|
||||||
) xev.CallbackAction {
|
) xev.CallbackAction {
|
||||||
_ = r catch unreachable;
|
_ = r catch unreachable;
|
||||||
const t = self_ orelse {
|
const t: *Thread = self_ orelse {
|
||||||
// This shouldn't happen so we log it.
|
// This shouldn't happen so we log it.
|
||||||
log.warn("render callback fired without data set", .{});
|
log.warn("render callback fired without data set", .{});
|
||||||
return .disarm;
|
return .disarm;
|
||||||
@ -522,6 +522,8 @@ fn renderCallback(
|
|||||||
t.flags.cursor_blink_visible,
|
t.flags.cursor_blink_visible,
|
||||||
) catch |err|
|
) catch |err|
|
||||||
log.warn("error rendering err={}", .{err});
|
log.warn("error rendering err={}", .{err});
|
||||||
|
|
||||||
|
// Draw
|
||||||
t.drawFrame(false);
|
t.drawFrame(false);
|
||||||
|
|
||||||
return .disarm;
|
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.
|
// This shouldn't happen so we log it.
|
||||||
log.warn("render callback fired without data set", .{});
|
log.warn("render callback fired without data set", .{});
|
||||||
return .disarm;
|
return .disarm;
|
||||||
|
@ -378,14 +378,20 @@ pub fn resize(
|
|||||||
// immediately for a resize. This is allowed by the spec.
|
// immediately for a resize. This is allowed by the spec.
|
||||||
self.terminal.modes.set(.synchronized_output, false);
|
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 we have size reporting enabled we need to send a report.
|
||||||
if (self.terminal.modes.get(.in_band_size_reports)) {
|
if (self.terminal.modes.get(.in_band_size_reports)) {
|
||||||
try self.sizeReportLocked(td, .mode_2048);
|
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.
|
/// Make a size report.
|
||||||
|
Reference in New Issue
Block a user