mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-16 08:46:08 +03:00
Merge pull request #1760 from jcollie/notification-suppression
Rate limit desktop notifications
This commit is contained in:
@ -45,6 +45,12 @@ quit: bool,
|
||||
/// same font configuration.
|
||||
font_grid_set: font.SharedGridSet,
|
||||
|
||||
// Used to rate limit desktop notifications. Some platforms (notably macOS) will
|
||||
// run out of resources if desktop notifications are sent too fast and the OS
|
||||
// will kill Ghostty.
|
||||
last_notification_time: ?std.time.Instant = null,
|
||||
last_notification_digest: u64 = 0,
|
||||
|
||||
/// Initialize the main app instance. This creates the main window, sets
|
||||
/// up the renderer state, compiles the shaders, etc. This is the primary
|
||||
/// "startup" logic.
|
||||
|
@ -3512,9 +3512,47 @@ fn completeClipboardReadOSC52(
|
||||
}
|
||||
|
||||
fn showDesktopNotification(self: *Surface, title: [:0]const u8, body: [:0]const u8) !void {
|
||||
if (@hasDecl(apprt.Surface, "showDesktopNotification")) {
|
||||
try self.rt_surface.showDesktopNotification(title, body);
|
||||
} else log.warn("runtime doesn't support desktop notifications", .{});
|
||||
if (comptime !@hasDecl(apprt.Surface, "showDesktopNotification")) {
|
||||
log.warn("runtime doesn't support desktop notifications", .{});
|
||||
return;
|
||||
}
|
||||
|
||||
// Wyhash is used to hash the contents of the desktop notification to limit
|
||||
// how fast identical notifications can be sent sequentially.
|
||||
const hash_algorithm = std.hash.Wyhash;
|
||||
|
||||
const now = try std.time.Instant.now();
|
||||
|
||||
// Set a limit of one desktop notification per second so that the OS
|
||||
// doesn't kill us when we run out of resources.
|
||||
if (self.app.last_notification_time) |last| {
|
||||
if (now.since(last) < 1 * std.time.ns_per_s) {
|
||||
log.warn("rate limiting desktop notifications", .{});
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const new_digest = d: {
|
||||
var hash = hash_algorithm.init(0);
|
||||
hash.update(title);
|
||||
hash.update(body);
|
||||
break :d hash.final();
|
||||
};
|
||||
|
||||
// Set a limit of one notification per five seconds for desktop
|
||||
// notifications with identical content.
|
||||
if (self.app.last_notification_time) |last| {
|
||||
if (self.app.last_notification_digest == new_digest) {
|
||||
if (now.since(last) < 5 * std.time.ns_per_s) {
|
||||
log.warn("suppressing identical desktop notification", .{});
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self.app.last_notification_time = now;
|
||||
self.app.last_notification_digest = new_digest;
|
||||
try self.rt_surface.showDesktopNotification(title, body);
|
||||
}
|
||||
|
||||
pub const face_ttf = @embedFile("font/res/JetBrainsMono-Regular.ttf");
|
||||
|
Reference in New Issue
Block a user