From ce2da6f6895ae4e4c8c708102d33982342383a4b Mon Sep 17 00:00:00 2001 From: Javier Trujillo Date: Sat, 8 Aug 2026 18:50:27 +0200 Subject: [PATCH 1/2] PlayerList: guard default_widget against null before MPRIS events default_widget is only created when the sound indicator popover is opened, but MPRIS/DBus scanning starts at session start. When a media player appears before the popover has been opened, add_iface() and destroy_iface() access default_widget while it is still null, causing a wingpanel crash. Fixes #324 --- src/Widgets/PlayerList.vala | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/src/Widgets/PlayerList.vala b/src/Widgets/PlayerList.vala index afcf207d..e88e2ce3 100644 --- a/src/Widgets/PlayerList.vala +++ b/src/Widgets/PlayerList.vala @@ -65,7 +65,8 @@ public class Sound.Widgets.PlayerList : Gtk.Bin { object_manager.media_player_status_changed.connect ((status, title, artist) => { bluetooth_widget.update_play (status, title, artist); - if (status == "playing" && default_widget.client.player.playback_status == "Playing") { + if (status == "playing" && default_widget != null && default_widget.client != null + && default_widget.client.player.playback_status == "Playing") { try { default_widget.client.player.play_pause (); } catch (Error e) { @@ -114,16 +115,19 @@ public class Sound.Widgets.PlayerList : Gtk.Bin { * @param iface The constructed MprisClient instance */ private void add_iface (string name, Services.MprisClient iface) { - if ((default_player != null) && (iface.player.desktop_entry == default_player.get_id ().replace (".desktop", ""))) { + if ((default_player != null) && default_widget != null + && (iface.player.desktop_entry == default_player.get_id ().replace (".desktop", ""))) { default_widget.mpris_name = name; default_widget.client = iface; ifaces.insert (name, default_widget); default_widget.no_show_all = false; default_widget.visible = true; } else { - if (default_widget.mpris_name == "") { - default_widget.no_show_all = true; - default_widget.visible = false; + if (default_widget == null || default_widget.mpris_name == "") { + if (default_widget != null) { + default_widget.no_show_all = true; + default_widget.visible = false; + } } PlayerRow widg = new PlayerRow (iface); @@ -142,7 +146,7 @@ public class Sound.Widgets.PlayerList : Gtk.Bin { * @param name DBUS name to remove handler for */ private void destroy_iface (string name) { - if (default_widget.mpris_name == name) { + if (default_widget != null && default_widget.mpris_name == name) { default_widget.client = null; } else { var widg = ifaces[name]; @@ -154,13 +158,15 @@ public class Sound.Widgets.PlayerList : Gtk.Bin { ifaces.remove (name); - if (ifaces.length != 0 && default_widget.mpris_name == "") { - default_widget.no_show_all = true; - default_widget.visible = false; - } else { - default_widget.no_show_all = false; - default_widget.visible = true; - show_all (); + if (default_widget != null) { + if (ifaces.length != 0 && default_widget.mpris_name == "") { + default_widget.no_show_all = true; + default_widget.visible = false; + } else { + default_widget.no_show_all = false; + default_widget.visible = true; + show_all (); + } } } From 69a3ba86b7406afc7058a85cc3b039dacd134873 Mon Sep 17 00:00:00 2001 From: Javier Trujillo Date: Sun, 9 Aug 2026 12:09:14 +0200 Subject: [PATCH 2/2] Address review: make default_widget nullable and simplify guard --- src/Widgets/PlayerList.vala | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/Widgets/PlayerList.vala b/src/Widgets/PlayerList.vala index e88e2ce3..1b74ce07 100644 --- a/src/Widgets/PlayerList.vala +++ b/src/Widgets/PlayerList.vala @@ -23,7 +23,7 @@ public class Sound.Widgets.PlayerList : Gtk.Bin { private AppInfo? default_player; private PlayerRow bluetooth_widget; - private PlayerRow default_widget; + private PlayerRow? default_widget; private HashTable ifaces; private Services.DBusImpl impl; @@ -123,11 +123,9 @@ public class Sound.Widgets.PlayerList : Gtk.Bin { default_widget.no_show_all = false; default_widget.visible = true; } else { - if (default_widget == null || default_widget.mpris_name == "") { - if (default_widget != null) { - default_widget.no_show_all = true; - default_widget.visible = false; - } + if (default_widget != null && default_widget.mpris_name == "") { + default_widget.no_show_all = true; + default_widget.visible = false; } PlayerRow widg = new PlayerRow (iface);