[gnome-boxes/list-view-row-fix-crash-on-delete: 2/2] list-view: Use a single context_popover for the ListView




commit c9856cabaf63488214ba5643e8fdb47ac82b1526
Author: Felipe Borges <felipeborges gnome org>
Date:   Tue Jan 11 16:12:31 2022 +0100

    list-view: Use a single context_popover for the ListView
    
    This fixes a crash while deleting a VM.
    
    Before we had a context_popover for each row in the ListView. This
    is less code but causes a race condition when the row gets deleted.
    
    It seems that when the row gets deleted the context_popover gets
    disposed. The dispose() method then attempts to disconnect the
    menu model which is already disposed, causing a double-free. Crash!

 src/list-view-row.vala | 9 +++------
 src/list-view.vala     | 9 ++++++++-
 2 files changed, 11 insertions(+), 7 deletions(-)
---
diff --git a/src/list-view-row.vala b/src/list-view-row.vala
index 4f97d053..490e3026 100644
--- a/src/list-view-row.vala
+++ b/src/list-view-row.vala
@@ -12,7 +12,8 @@
     public unowned Boxes.Thumbnail thumbnail;
     [GtkChild]
     public unowned Gtk.Button menu_button;
-    private Boxes.ActionsPopover context_popover;
+
+    public signal void pop_context_menu ();
 
     public ListViewRow (CollectionItem item) {
         this.item = item;
@@ -30,8 +31,6 @@ public ListViewRow (CollectionItem item) {
 
         // This is a hack to align the "title" next to the "thumbnail".
         activatable_widget.get_parent ().hexpand = false;
-
-        context_popover = new Boxes.ActionsPopover (machine.window);
     }
 
     private void update_thumbnail () {
@@ -62,8 +61,6 @@ private void update_status () {
 
     [GtkCallback]
     public void pop_menu () {
-        context_popover.update_for_item (item);
-        context_popover.relative_to = menu_button;
-        context_popover.show ();
+        pop_context_menu ();
     }
 }
diff --git a/src/list-view.vala b/src/list-view.vala
index 505bf0b7..6fc89f36 100644
--- a/src/list-view.vala
+++ b/src/list-view.vala
@@ -86,6 +86,10 @@ private void setup_list_box () {
             var view_row = new ListViewRow (item as CollectionItem);
             box_row.add (view_row);
 
+            view_row.pop_context_menu.connect (() => {
+                launch_context_popover_for_row (box_row);
+            });
+
             box_row.visible = true;
             view_row.visible = true;
 
@@ -98,6 +102,8 @@ private void setup_list_box () {
         container.remove.connect (remove_row);
     }
 
+
+
     private CollectionItem? get_item_for_row (Gtk.ListBoxRow box_row) {
         var view = box_row.get_child () as ListViewRow;
         if (view == null)
@@ -166,8 +172,9 @@ private bool launch_context_popover_for_row (Gtk.ListBoxRow box_row) {
         if (item == null)
             return false;
 
+        var row = box_row.get_child () as Boxes.ListViewRow;
         context_popover.update_for_item (item);
-        context_popover.relative_to = box_row;
+        context_popover.relative_to = row.menu_button;
         context_popover.show ();
 
         return true;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]