fix(date): update label in place to avoid GTK3 visibility glitch

Repeated set_label() on every tick destroys and recreates the button's
internal label; after enough redraws GTK3 drops its visibility. Capture
the label once and update via set_text() instead.
This commit is contained in:
sankalp committed 2026-08-02 12:10:11 +05:45
1 parent 9e992578f8
commit 98c3181541
1 file changed
+24 -6
+24 -6
View File
@@ -1,5 +1,6 @@
from fabric.widgets.box import Box from fabric.widgets.box import Box
from fabric.widgets.datetime import DateTime from fabric.widgets.datetime import DateTime
from gi.repository import Gtk
from window.desktop.registry import DesktopWidgetRegistry from window.desktop.registry import DesktopWidgetRegistry
@@ -12,8 +13,27 @@ class _DraggableDateTime(DateTime):
G_SIGNAL_RUN_FIRST, which stops the accumulator before DateTime's own G_SIGNAL_RUN_FIRST, which stops the accumulator before DateTime's own
connected handler ever runs. Both must return False for the event to connected handler ever runs. Both must return False for the event to
reach the EventBox where drag_source_set lives. reach the EventBox where drag_source_set lives.
It also avoids the GtkButton label visibility glitch: calling
set_label() on every tick destroys and recreates the internal child
label, and after enough redraws GTK3 stops showing it. Instead the
internal label is captured once and updated in place via set_text().
""" """
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
child = self.get_child()
if isinstance(child, Gtk.Label):
self._text_label = child
def do_update_label(self):
text = self.do_format()
label = getattr(self, "_text_label", None)
if label is None:
return super().do_update_label()
label.set_text(text)
return True
def do_button_press_event(self, event): def do_button_press_event(self, event):
match event.button: match event.button:
case 1: case 1:
@@ -39,12 +59,10 @@ class DesktopDateWidget(Box):
**kwargs, **kwargs,
) )
self.top = Box(orientation="h", name="date-top", h_expand=True) self.top = Box(orientation="h", name="date-top", h_expand=True)
# Using a highly frequent interval (e.g. 10000ms/10s) causes the DateTime widget # Update interval is generous (100s) since the date only changes
# (which inherits from Gtk.Button) to repeatedly call set_label. # daily; _DraggableDateTime updates its label in place so the
# In GTK3, repeatedly replacing a button's label can cause rendering glitches # frequent set_label() glitch that drops label visibility in GTK3
# where the layout engine drops the child label's visibility after some time. # is avoided entirely.
# Since this is just a date widget, we increase the interval to 100000ms (100 seconds)
# which easily avoids the continuous redraw glitch while keeping the date accurate.
date_interval = 100000 date_interval = 100000
self.dateone = _DraggableDateTime( self.dateone = _DraggableDateTime(
formatters=["%a"], interval=date_interval, name="day" formatters=["%a"], interval=date_interval, name="day"