From 4ed8306b02499dbc0cf1be1899b726b0b0202be5 Mon Sep 17 00:00:00 2001 From: Maciej Bartczak <39600846+maciekbartczak@users.noreply.github.com> Date: Sat, 28 Dec 2024 17:18:15 +0100 Subject: [PATCH 1/2] Add delay before updating the title --- src/apprt/gtk/Surface.zig | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/apprt/gtk/Surface.zig b/src/apprt/gtk/Surface.zig index 3d80d92595..115b7e13bf 100644 --- a/src/apprt/gtk/Surface.zig +++ b/src/apprt/gtk/Surface.zig @@ -346,6 +346,9 @@ cursor: ?*c.GdkCursor = null, /// pass it to GTK. title_text: ?[:0]const u8 = null, +/// The timer used to delay title updates in order to prevent flickering. +update_title_timer: ?c.guint = null, + /// The core surface backing this surface core_surface: CoreSurface, @@ -894,7 +897,23 @@ pub fn setTitle(self: *Surface, slice: [:0]const u8) !void { if (self.title_text) |old| alloc.free(old); self.title_text = copy; + // delay the title update to prevent flickering + if (self.update_title_timer) |timer| { + if (c.g_source_remove(timer) == c.FALSE) { + log.warn("unable to remove update title timer", .{}); + } + self.update_title_timer = null; + } + self.update_title_timer = c.g_timeout_add(75, updateTitleTimerExpired, self); +} + +fn updateTitleTimerExpired(ctx: ?*anyopaque) callconv(.C) c.gboolean { + const self: *Surface = @ptrCast(@alignCast(ctx)); + self.updateTitleLabels(); + self.update_title_timer = null; + + return c.FALSE; } pub fn getTitle(self: *Surface) ?[:0]const u8 { From 2b245c965c6c6dcfa55a8a77b967b90fac9bcb8b Mon Sep 17 00:00:00 2001 From: Maciej Bartczak <39600846+maciekbartczak@users.noreply.github.com> Date: Sun, 29 Dec 2024 09:27:59 +0100 Subject: [PATCH 2/2] Invalidate the timer when the surface is destroyed --- src/apprt/gtk/Surface.zig | 1 + 1 file changed, 1 insertion(+) diff --git a/src/apprt/gtk/Surface.zig b/src/apprt/gtk/Surface.zig index 115b7e13bf..81564f1a33 100644 --- a/src/apprt/gtk/Surface.zig +++ b/src/apprt/gtk/Surface.zig @@ -650,6 +650,7 @@ pub fn deinit(self: *Surface) void { // and therefore the unfocused_overlay has been destroyed as well. c.g_object_unref(self.im_context); if (self.cursor) |cursor| c.g_object_unref(cursor); + if (self.update_title_timer) |timer| _ = c.g_source_remove(timer); self.resize_overlay.deinit(); }