]> git.ipfire.org Git - thirdparty/plymouth.git/commitdiff
ply-capslock-icon: Do not draw on free
authorHans de Goede <hdegoede@redhat.com>
Tue, 18 Feb 2020 10:45:55 +0000 (11:45 +0100)
committerRay Strode <halfline@gmail.com>
Tue, 10 Mar 2020 23:51:38 +0000 (23:51 +0000)
One case where the various widgets are being freed is the pixel-display-s
being removed because of a monitor being hot(un)plugged. When the monitor
configuration changes ply-device-manager removes all old pixel-displays
and then adds the pixel-displays from the new config.

Calling ply_pixel_display_draw_area on a pixel-display which is about to be
freed is a bad idea, if the monitor was actually unplugged this leads to
various sort of errors, including crashes in some cases.

ply-capslock-icon is a recently added widget, none of the other
(older) widgets redraw themselves as hidden on free because there is
no reason to do this.

This commit adds a new stop_polling helper and replaces the troublesome
hide call (which involves redrawing) with this. This fixes plymouth
sometimes crashing when monitors are hot(un)plugged while plymouth is
running.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
src/libply-splash-graphics/ply-capslock-icon.c

index 7d19a18724c242faec35c0fed7e1660577d569f7..e60457f562bad9623a4dc4d88cace91559c359ed 100644 (file)
@@ -52,6 +52,8 @@ struct _ply_capslock_icon
         bool                 is_on;
 };
 
+static void ply_capslock_stop_polling (ply_capslock_icon_t *capslock_icon);
+
 ply_capslock_icon_t *
 ply_capslock_icon_new (const char *image_dir)
 {
@@ -74,7 +76,7 @@ ply_capslock_icon_free (ply_capslock_icon_t *capslock_icon)
                 return;
 
         if (!capslock_icon->is_hidden)
-                ply_capslock_icon_hide (capslock_icon);
+                ply_capslock_stop_polling (capslock_icon);
 
         if (capslock_icon->buffer != NULL)
                 ply_pixel_buffer_free (capslock_icon->buffer);
@@ -121,6 +123,14 @@ on_timeout (void             *user_data,
                                           on_timeout, capslock_icon);
 }
 
+static void
+ply_capslock_stop_polling (ply_capslock_icon_t *capslock_icon)
+{
+        ply_event_loop_stop_watching_for_timeout (capslock_icon->loop,
+                                                  (ply_event_loop_timeout_handler_t)
+                                                  on_timeout, capslock_icon);
+}
+
 bool
 ply_capslock_icon_load (ply_capslock_icon_t *capslock_icon)
 {
@@ -183,10 +193,8 @@ ply_capslock_icon_hide (ply_capslock_icon_t *capslock_icon)
         capslock_icon->is_hidden = true;
 
         ply_capslock_icon_draw (capslock_icon);
+        ply_capslock_stop_polling (capslock_icon);
 
-        ply_event_loop_stop_watching_for_timeout (capslock_icon->loop,
-                                                  (ply_event_loop_timeout_handler_t)
-                                                  on_timeout, capslock_icon);
         capslock_icon->loop = NULL;
         capslock_icon->display = NULL;
 }