diff --git a/python_payload/st3m/ui/elements/overlays.py b/python_payload/st3m/ui/elements/overlays.py
index 5ab91ab76917c0f2ed957fc9715f691e9690f17f..8260ef8453f13246f11bbb6faa4df6f64f31f825 100644
--- a/python_payload/st3m/ui/elements/overlays.py
+++ b/python_payload/st3m/ui/elements/overlays.py
@@ -128,6 +128,10 @@ class Compositor(Responder):
         self._last_fps_string = ""
         self._clip_rect = Region()
         self._last_clip = Region()
+        self._display_mode = None
+        self._enabled: List[Responder] = []
+        self._last_enabled: List[Responder] = []
+        self._redraw_pending = 0
 
     def _enabled_overlays(self) -> List[Responder]:
         res: List[Responder] = []
@@ -147,18 +151,25 @@ class Compositor(Responder):
             or settings.onoff_show_fps.value
         ):
             return
-        overlays = self._enabled_overlays()
-        for i in range(len(overlays)):
-            overlays[i].think(ins, delta_ms)
+        self._enabled = self._enabled_overlays()
+        for i in range(len(self._enabled)):
+            self._enabled[i].think(ins, delta_ms)
 
     def draw(self, ctx: Context) -> None:
         self.main.draw(ctx)
-        if (sys_display.get_mode() & sys_display.osd) == 0:
+        display_mode = sys_display.get_mode()
+        redraw = False
+        if self._redraw_pending:
+            redraw = True
+            self._redraw_pending -= 1
+        if display_mode != self._display_mode:
+            self._redraw_pending = 2
+        self._display_mode = display_mode
+        if (display_mode & sys_display.osd) == 0:
             return
-        overlays = self._enabled_overlays()
         if settings.onoff_show_fps.value:
             fps_string = "{0:.1f}".format(sys_display.fps())
-            if fps_string != self._last_fps_string:
+            if redraw or fps_string != self._last_fps_string:
                 octx = sys_display.ctx(sys_display.osd)
                 self._last_fps_string = fps_string
                 self._clip_rect.set(-120, -120, 120, -96)
@@ -182,11 +193,18 @@ class Compositor(Responder):
                 sys_display.update(octx)
                 self._clip_rect.set_clip()
                 self._last_clip.copy(self._clip_rect)
+            self._last_enabled = []
         else:
             self._clip_rect.clear()
-            redraw = False
-            for i in range(len(overlays)):
-                redraw = overlays[i].needs_redraw(self._clip_rect) or redraw
+            for i in range(len(self._enabled)):
+                redraw = (
+                    self._enabled[i].needs_redraw(self._clip_rect)
+                    or redraw
+                    or self._enabled[i] not in self._last_enabled
+                )
+            for i in range(len(self._last_enabled)):
+                redraw = redraw or self._last_enabled[i] not in self._enabled
+            self._last_enabled = self._enabled
             if self._clip_rect.is_empty():
                 self._clip_rect.set_clip()
                 return
@@ -200,8 +218,8 @@ class Compositor(Responder):
             self._last_clip.add_region(self._clip_rect)
             self._last_clip.fill(octx)
             octx.restore()
-            for i in range(len(overlays)):
-                overlays[i].draw(octx)
+            for i in range(len(self._enabled)):
+                self._enabled[i].draw(octx)
             sys_display.update(octx)
             self._clip_rect.set_clip()
             self._last_clip.copy(self._clip_rect)
@@ -466,7 +484,7 @@ class Icon(Responder):
     """
 
     WIDTH: int = 25
-    _changed: bool = True
+    _changed: bool = False
 
     @abstractmethod
     def visible(self) -> bool:
@@ -485,15 +503,8 @@ class USBIcon(Icon):
 
     WIDTH: int = 30
 
-    def __init__(self):
-        self._visible = sys_kernel.usb_connected()
-
     def visible(self) -> bool:
-        visible = sys_kernel.usb_connected()
-        if self._visible != visible:
-            self._changed = True
-            self._visible = visible
-        return self._visible
+        return sys_kernel.usb_connected()
 
     def draw(self, ctx: Context) -> None:
         ctx.gray(1.0)
@@ -509,12 +520,6 @@ class USBIcon(Icon):
     def think(self, ins: InputState, delta_ms: int) -> None:
         pass
 
-    def changed(self) -> bool:
-        if self._changed:
-            self._changed = False
-            return True
-        return False
-
 
 class WifiIcon(Icon):
     WIDTH: int = 30
@@ -522,7 +527,6 @@ class WifiIcon(Icon):
     def __init__(self) -> None:
         super().__init__()
         self._rssi: float = -120
-        self._changed = True
 
     def visible(self) -> bool:
         return st3m.wifi.enabled()
@@ -558,7 +562,6 @@ class BatteryIcon(Icon):
         super().__init__()
         self._percent = 100.0
         self._charging = False
-        self._changed = False
 
     def visible(self) -> bool:
         return True
@@ -620,6 +623,7 @@ class IconTray(Overlay):
             WifiIcon(),
         ]
         self.visible: List[Icon] = []
+        self.last_visible: List[Icon] = []
 
     def think(self, ins: InputState, delta_ms: int) -> None:
         self.visible = [i for i in self.icons if i.visible()]
@@ -627,6 +631,7 @@ class IconTray(Overlay):
             self.visible[i].think(ins, delta_ms)
 
     def draw(self, ctx: Context) -> None:
+        self.last_visible = self.visible
         if not self.visible:
             return
         width = 0
@@ -645,6 +650,12 @@ class IconTray(Overlay):
         if self.visible:
             rect.add(-40, -120, 40, -88)
             for i in range(len(self.visible)):
-                if self.visible[i].changed():
+                if (
+                    self.visible[i].changed()
+                    or self.visible[i] not in self.last_visible
+                ):
+                    return True
+            for i in range(len(self.last_visible)):
+                if self.last_visible[i] not in self.visible:
                     return True
         return False