gi.require_version('Gtk', '3.0')
 from gi.repository import Gtk, GObject, Gio
+import time
 
 import math
 import colorsys
         self.set_size_request(width, height)
         self.connect('draw', self.do_draw_cb)
         self.connect('configure-event', self.do_configure_event_cb)
+        self.connect('destroy', self.on_destroy)
 
-        fps = 30
-        GObject.timeout_add(1000 / fps, self.update)
+        self.fps = 30
+        GObject.timeout_add(50, self.mainloop)
+
+    def on_destroy(self, event):
+        self.running = False
+
+    def tick(self):
+        self.update()
+        self.queue_draw()
+
+    def mainloop(self):
+        self.running = True
+        while self.running:
+            time.sleep(1.0 / self.fps)
+            self.tick()
+            while Gtk.events_pending():
+                Gtk.main_iteration()
+
+        return False
 
     def update(self):
         if self.x - self.radius - self.border < 0 or \
         self.x += self.x_offset
         self.y += self.y_offset
 
-        self.queue_draw()
-        return True
-
     def do_configure_event_cb(self, widget, event):
         self.width = event.width
         self.height = event.height