core: rate limit BEL character processing (#9810)

If the BEL character is received too frequently, the GUI thread can be
starved and Ghostty will lock up and eventually crash. This PR limits
BEL handling to 1 per 100ms.

Fixes #9800.
pull/9813/head
Mitchell Hashimoto 2025-12-04 15:29:58 -08:00 committed by GitHub
commit cf23d1c39d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 9 additions and 1 deletions

View File

@ -155,6 +155,9 @@ command_timer: ?std.time.Instant = null,
/// Search state
search: ?Search = null,
/// Used to rate limit BEL handling.
last_bell_time: ?std.time.Instant = null,
/// The effect of an input event. This can be used by callers to take
/// the appropriate action after an input event. For example, key
/// input can be forwarded to the OS for further processing if it
@ -1026,7 +1029,12 @@ pub fn handleMessage(self: *Surface, msg: Message) !void {
.password_input => |v| try self.passwordInput(v),
.ring_bell => {
.ring_bell => bell: {
const now = std.time.Instant.now() catch unreachable;
if (self.last_bell_time) |last| {
if (now.since(last) < 100 * std.time.ns_per_ms) break :bell;
}
self.last_bell_time = now;
_ = self.rt_app.performAction(
.{ .surface = self },
.ring_bell,