[evince] view: use a hashtable to map annots to their popups.



commit 387e4e4324e2efdc42df6ee1242a75ce87d4b355
Author: Jose Aliste <jaliste src gnome org>
Date:   Tue Jul 19 23:23:36 2016 -0400

    view: use a hashtable to map annots to their popups.
    
    This prevents a crash when using "Open Copy" function
    because the popup is set to a window widget which is a child of another
    EvView.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=760299

 libview/ev-view-private.h |    1 +
 libview/ev-view.c         |   41 ++++++++++++++++++++++++++++++++++++-----
 2 files changed, 37 insertions(+), 5 deletions(-)
---
diff --git a/libview/ev-view-private.h b/libview/ev-view-private.h
index a6862b1..7bf9adc 100644
--- a/libview/ev-view-private.h
+++ b/libview/ev-view-private.h
@@ -226,6 +226,7 @@ struct _EvView {
        EvViewWindowChild *window_child_focus;
        AddingAnnotInfo    adding_annot_info;
        MovingAnnotInfo    moving_annot_info;
+       GHashTable        *annot_window_map;
 
        /* Focus */
        EvMapping *focused_element;
diff --git a/libview/ev-view.c b/libview/ev-view.c
index 9ef60d7..2361958 100644
--- a/libview/ev-view.c
+++ b/libview/ev-view.c
@@ -151,6 +151,11 @@ static EvMedia     *ev_view_get_media_at_location            (EvView
 static gboolean     ev_view_find_player_for_media            (EvView             *view,
                                                              EvMedia            *media);
 /*** Annotations ***/
+static GtkWidget    *get_window_for_annot                   (EvView             *view,
+                                                             EvAnnotation       *annot);
+static void          map_annot_to_window                    (EvView             *view,
+                                                             EvAnnotation       *annot,
+                                                             GtkWidget          *window);
 static EvAnnotation *ev_view_get_annotation_at_location      (EvView             *view,
                                                              gdouble             x,
                                                              gdouble             y);
@@ -2876,6 +2881,27 @@ ev_view_handle_media (EvView  *view,
 }
 
 /* Annotations */
+static GtkWidget *
+get_window_for_annot (EvView       *view,
+                     EvAnnotation *annot)
+{
+       if (view->annot_window_map == NULL)
+               return NULL;
+
+       return g_hash_table_lookup (view->annot_window_map, annot);
+}
+
+static void
+map_annot_to_window (EvView       *view,
+                     EvAnnotation *annot,
+                    GtkWidget    *window)
+{
+       if (view->annot_window_map == NULL)
+               view->annot_window_map = g_hash_table_new (g_direct_hash, NULL);
+
+       g_hash_table_insert (view->annot_window_map, annot, window);
+}
+
 static EvViewWindowChild *
 ev_view_get_window_child (EvView    *view,
                          GtkWidget *window)
@@ -3110,7 +3136,7 @@ ev_view_create_annotation_window (EvView       *view,
        g_signal_connect_swapped (annot, "notify::contents",
                                  G_CALLBACK (ev_view_annotation_save_contents),
                                  view);
-       g_object_set_data (G_OBJECT (annot), "popup", window);
+       map_annot_to_window (view, annot, window);
 
        page = ev_annotation_get_page_index (annot);
        ev_annotation_window_get_rectangle (EV_ANNOTATION_WINDOW (window), &doc_rect);
@@ -3150,7 +3176,7 @@ show_annotation_windows (EvView *view,
                if (!ev_annotation_markup_has_popup (EV_ANNOTATION_MARKUP (annot)))
                        continue;
 
-               window = g_object_get_data (G_OBJECT (annot), "popup");
+               window = get_window_for_annot (view, annot);
                if (window) {
                        ev_view_window_child_move_with_parent (view, window);
                        continue;
@@ -3161,7 +3187,7 @@ show_annotation_windows (EvView *view,
                window = child ? child->window : NULL;
                if (window) {
                        ev_annotation_window_set_annotation (EV_ANNOTATION_WINDOW (window), annot);
-                       g_object_set_data (G_OBJECT (annot), "popup", window);
+                       map_annot_to_window (view, annot, window);
                        ev_view_window_child_move_with_parent (view, window);
                } else {
                        ev_view_create_annotation_window (view, annot, parent);
@@ -3187,7 +3213,7 @@ hide_annotation_windows (EvView *view,
                if (!EV_IS_ANNOTATION_MARKUP (annot))
                        continue;
 
-               window = g_object_get_data (G_OBJECT (annot), "popup");
+               window = get_window_for_annot (view, annot);
                if (window)
                        gtk_widget_hide (window);
        }
@@ -3256,7 +3282,7 @@ ev_view_handle_annotation (EvView       *view,
        if (EV_IS_ANNOTATION_MARKUP (annot)) {
                GtkWidget *window;
 
-               window = g_object_get_data (G_OBJECT (annot), "popup");
+               window = get_window_for_annot (view, annot);
                if (!window && ev_annotation_markup_can_have_popup (EV_ANNOTATION_MARKUP (annot))) {
                        EvRectangle    popup_rect;
                        GtkWindow     *parent;
@@ -3457,6 +3483,9 @@ ev_view_remove_annotation (EvView       *view,
                        g_free (child);
                }
         }
+       if (view->annot_window_map != NULL)
+               g_hash_table_remove (view->annot_window_map, annot);
+
         _ev_view_set_focused_element (view, NULL, -1);
 
         ev_document_doc_mutex_lock ();
@@ -6827,6 +6856,8 @@ ev_view_finalize (GObject *object)
        if (view->image_dnd_info.image)
                g_object_unref (view->image_dnd_info.image);
        view->image_dnd_info.image = NULL;
+       if (view->annot_window_map)
+               g_hash_table_destroy (view->annot_window_map);
 
        g_object_unref (view->zoom_gesture);
 


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