[libhandy/tabs: 59/62] Extra drag dest targets




commit 835a176a8e933b87ddd9eaab4849495decf59be3
Author: Alexander Mikhaylenko <alexm gnome org>
Date:   Sat Sep 12 17:43:55 2020 +0500

    Extra drag dest targets

 examples/hdy-tab-view-demo-window.c  |  36 ++++++++-
 examples/hdy-tab-view-demo-window.ui |   3 +-
 src/hdy-tab-bar.c                    | 145 +++++++++++++++++++++++++++++++++++
 src/hdy-tab-bar.h                    |   6 ++
 src/hdy-tab-bar.ui                   |   2 +
 src/hdy-tab-box-private.h            |   3 +
 src/hdy-tab-box.c                    | 145 ++++++++++++++++++++++++++++++++---
 src/hdy-tab-view.c                   |   1 -
 8 files changed, 327 insertions(+), 14 deletions(-)
---
diff --git a/examples/hdy-tab-view-demo-window.c b/examples/hdy-tab-view-demo-window.c
index 46e724a1..15c33845 100644
--- a/examples/hdy-tab-view-demo-window.c
+++ b/examples/hdy-tab-view-demo-window.c
@@ -6,6 +6,7 @@ struct _HdyTabViewDemoWindow
 {
   HdyApplicationWindow parent_instance;
   HdyTabView *view;
+  HdyTabBar *tab_bar;
 
   GActionMap *tab_action_group;
 
@@ -86,10 +87,10 @@ tab_new (GSimpleAction *action,
 
   g_object_bind_property (content, "text",
                           page, "title",
-                          G_BINDING_SYNC_CREATE);
+                          G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL);
   g_object_bind_property_full (content, "text",
                                page, "tooltip",
-                               G_BINDING_SYNC_CREATE,
+                               G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL,
                                text_to_tooltip, NULL,
                                NULL, NULL);
 
@@ -360,6 +361,24 @@ secondary_icon_activated_cb (HdyTabViewDemoWindow *self,
   hdy_tab_page_set_secondary_icon (page, icon);
 }
 
+static void
+extra_drag_data_received_cb (HdyTabViewDemoWindow *self,
+                             HdyTabPage           *page,
+                             GdkDragContext       *context,
+                             GtkSelectionData     *selection_data,
+                             guint                 info,
+                             guint                 time)
+{
+  g_autofree gchar *text = NULL;
+
+  if (gtk_selection_data_get_length (selection_data) < 0)
+    return;
+
+  text = (gchar *) gtk_selection_data_get_text (selection_data);
+
+  hdy_tab_page_set_title (page, text);
+}
+
 static void
 hdy_tab_view_demo_window_class_init (HdyTabViewDemoWindowClass *klass)
 {
@@ -367,14 +386,18 @@ hdy_tab_view_demo_window_class_init (HdyTabViewDemoWindowClass *klass)
 
   gtk_widget_class_set_template_from_resource (widget_class, 
"/sm/puri/Handy/Demo/ui/hdy-tab-view-demo-window.ui");
   gtk_widget_class_bind_template_child (widget_class, HdyTabViewDemoWindow, view);
+  gtk_widget_class_bind_template_child (widget_class, HdyTabViewDemoWindow, tab_bar);
   gtk_widget_class_bind_template_callback (widget_class, setup_menu_cb);
   gtk_widget_class_bind_template_callback (widget_class, create_window_cb);
   gtk_widget_class_bind_template_callback (widget_class, secondary_icon_activated_cb);
+  gtk_widget_class_bind_template_callback (widget_class, extra_drag_data_received_cb);
 }
 
 static void
 hdy_tab_view_demo_window_init (HdyTabViewDemoWindow *self)
 {
+  GtkTargetList *target_list;
+
   gtk_widget_init_template (GTK_WIDGET (self));
 
   g_action_map_add_action_entries (G_ACTION_MAP (self),
@@ -391,6 +414,15 @@ hdy_tab_view_demo_window_init (HdyTabViewDemoWindow *self)
   gtk_widget_insert_action_group (GTK_WIDGET (self),
                                   "tab",
                                   G_ACTION_GROUP (self->tab_action_group));
+
+  target_list = gtk_target_list_new (NULL, 0);
+  gtk_target_list_add_text_targets (target_list, 0);
+
+  g_object_set (self->tab_bar,
+                "extra-drag-dest-targets", target_list,
+                NULL);
+
+  gtk_target_list_unref (target_list);
 }
 
 HdyTabViewDemoWindow *
diff --git a/examples/hdy-tab-view-demo-window.ui b/examples/hdy-tab-view-demo-window.ui
index 931518a0..2be6e2ef 100644
--- a/examples/hdy-tab-view-demo-window.ui
+++ b/examples/hdy-tab-view-demo-window.ui
@@ -47,9 +47,10 @@
           </object>
         </child>
         <child>
-          <object class="HdyTabBar">
+          <object class="HdyTabBar" id="tab_bar">
             <property name="visible">True</property>
             <property name="view">view</property>
+            <signal name="extra-drag-data-received" handler="extra_drag_data_received_cb" swapped="true"/>
           </object>
         </child>
         <child>
diff --git a/src/hdy-tab-bar.c b/src/hdy-tab-bar.c
index ed349e8c..497b79ce 100644
--- a/src/hdy-tab-bar.c
+++ b/src/hdy-tab-bar.c
@@ -62,6 +62,8 @@ struct _HdyTabBar
 
   HdyTabView *view;
   gboolean autohide;
+
+  GtkTargetList *extra_drag_dest_targets;
 };
 
 static void hdy_tab_bar_buildable_init (GtkBuildableIface *iface);
@@ -77,11 +79,19 @@ enum {
   PROP_END_ACTION_WIDGET,
   PROP_AUTOHIDE,
   PROP_TABS_REVEALED,
+  PROP_EXTRA_DRAG_DEST_TARGETS,
   LAST_PROP
 };
 
 static GParamSpec *props[LAST_PROP];
 
+enum {
+  SIGNAL_EXTRA_DRAG_DATA_RECEIVED,
+  SIGNAL_LAST_SIGNAL,
+};
+
+static guint signals[SIGNAL_LAST_SIGNAL];
+
 static void
 set_tabs_revealed (HdyTabBar *self,
                    gboolean   tabs_revealed)
@@ -226,6 +236,18 @@ stop_kinetic_scrolling_cb (HdyTabBar *self)
   gtk_scrolled_window_set_kinetic_scrolling (self->scrolled_window, TRUE);
 }
 
+static void
+extra_drag_data_received_cb (HdyTabBar        *self,
+                             HdyTabPage       *page,
+                             GdkDragContext   *context,
+                             GtkSelectionData *selection_data,
+                             guint             info,
+                             guint             time)
+{
+  g_signal_emit (self, signals[SIGNAL_EXTRA_DRAG_DATA_RECEIVED], 0,
+                 page, context, selection_data, info, time);
+}
+
 static void
 view_destroy_cb (HdyTabBar *self)
 {
@@ -365,6 +387,10 @@ hdy_tab_bar_get_property (GObject    *object,
     g_value_set_boolean (value, hdy_tab_bar_get_tabs_revealed (self));
     break;
 
+  case PROP_EXTRA_DRAG_DEST_TARGETS:
+    g_value_set_boxed (value, hdy_tab_bar_get_extra_drag_dest_targets (self));
+    break;
+
   default:
     G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
   }
@@ -394,6 +420,11 @@ hdy_tab_bar_set_property (GObject      *object,
   case PROP_AUTOHIDE:
     hdy_tab_bar_set_autohide (self, g_value_get_boolean (value));
     break;
+
+  case PROP_EXTRA_DRAG_DEST_TARGETS:
+    hdy_tab_bar_set_extra_drag_dest_targets (self, g_value_get_boxed (value));
+    break;
+
   default:
     G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
   }
@@ -493,8 +524,61 @@ hdy_tab_bar_class_init (HdyTabBarClass *klass)
                           FALSE,
                           G_PARAM_READABLE | G_PARAM_EXPLICIT_NOTIFY);
 
+  /**
+   * HdyTabBar:extra-drag-dest-targets:
+   *
+   * Extra drag destination targets.
+   *
+   * Allows to drag arbitrary content onto tabs, for example URLs in a web
+   * browser.
+   *
+   * If a tab is hovered for a certain period of time while dragging the
+   * content, it will be automatically selected.
+   *
+   * After content is dropped, the #HdyTabBar::extra-drag-data-received signal
+   * can be used to retrieve and process the drag data.
+   *
+   * Since: 1.2
+   */
+  props[PROP_EXTRA_DRAG_DEST_TARGETS] =
+    g_param_spec_boxed ("extra-drag-dest-targets",
+                        _("Extra drag destination targets"),
+                        _("Extra drag destination targets"),
+                        GTK_TYPE_TARGET_LIST,
+                        G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
+
   g_object_class_install_properties (object_class, LAST_PROP, props);
 
+  /**
+   * HdyTabBar::extra-drag-data-received:
+   * @self: a #HdyTabBar
+   * @page: the #HdyTabPage matching the tab the content was dropped onto
+   * @context: the drag context
+   * @data: the received data
+   * @info: the info that has been registered with the target in the #GtkTargetList
+   * @time: the timestamp at which the data was received
+   *
+   * This signal is emitted when content allowed via
+   * #HdyTabBar:extra-drag-dest-targets is dropped onto a tab.
+   *
+   * See #GtkWidget::drag-data-received.
+   *
+   * Since: 1.2
+   */
+  signals[SIGNAL_EXTRA_DRAG_DATA_RECEIVED] =
+    g_signal_new ("extra-drag-data-received",
+                  G_TYPE_FROM_CLASS (klass),
+                  G_SIGNAL_RUN_LAST,
+                  0,
+                  NULL, NULL, NULL,
+                  G_TYPE_NONE,
+                  5,
+                  HDY_TYPE_TAB_PAGE,
+                  GDK_TYPE_DRAG_CONTEXT,
+                  GTK_TYPE_SELECTION_DATA,
+                  G_TYPE_UINT,
+                  G_TYPE_UINT);
+
   gtk_widget_class_set_template_from_resource (widget_class,
                                                "/sm/puri/handy/ui/hdy-tab-bar.ui");
   gtk_widget_class_bind_template_child (widget_class, HdyTabBar, revealer);
@@ -506,6 +590,7 @@ hdy_tab_bar_class_init (HdyTabBarClass *klass)
   gtk_widget_class_bind_template_child (widget_class, HdyTabBar, end_action_bin);
   gtk_widget_class_bind_template_callback (widget_class, notify_needs_attention_cb);
   gtk_widget_class_bind_template_callback (widget_class, stop_kinetic_scrolling_cb);
+  gtk_widget_class_bind_template_callback (widget_class, extra_drag_data_received_cb);
 
   gtk_widget_class_set_css_name (widget_class, "tabbar");
 }
@@ -850,3 +935,63 @@ hdy_tab_bar_get_tabs_revealed (HdyTabBar *self)
 
   return gtk_revealer_get_reveal_child (self->revealer);
 }
+
+/**
+ * hdy_tab_bar_get_extra_drag_dest_targets:
+ * @self: a #HdyTabBar
+ *
+ * Gets extra drag destination targets, see
+ * hdy_tab_bar_set_extra_drag_dest_targets().
+ *
+ * Returns: (transfer none) (nullable): extra drag targets, or %NULL
+ *
+ * Since: 1.2
+ */
+GtkTargetList *
+hdy_tab_bar_get_extra_drag_dest_targets (HdyTabBar *self)
+{
+  g_return_val_if_fail (HDY_IS_TAB_BAR (self), NULL);
+
+  return self->extra_drag_dest_targets;
+}
+
+/**
+ * hdy_tab_bar_set_extra_drag_dest_targets:
+ * @self: a #HdyTabBar
+ * @extra_drag_dest_targets: (transfer none) (nullable): extra drag targets, or %NULL
+ *
+ * Sets extra drag destination targets.
+ *
+ * This allows to drag arbitrary content onto tabs, for example URLs in a web
+ * browser.
+ *
+ * If a tab is hovered for a certain period of time while dragging the content,
+ * it will be automatically selected.
+ *
+ * After content is dropped, the #HdyTabBar::extra-drag-data-received signal can
+ * be used to retrieve and process the drag data.
+ *
+ * Since: 1.2
+ */
+void
+hdy_tab_bar_set_extra_drag_dest_targets (HdyTabBar     *self,
+                                         GtkTargetList *extra_drag_dest_targets)
+{
+  g_return_if_fail (HDY_IS_TAB_BAR (self));
+
+  if (extra_drag_dest_targets == self->extra_drag_dest_targets)
+    return;
+
+  if (self->extra_drag_dest_targets)
+    gtk_target_list_unref (self->extra_drag_dest_targets);
+
+  if (extra_drag_dest_targets)
+    gtk_target_list_ref (extra_drag_dest_targets);
+
+  self->extra_drag_dest_targets = extra_drag_dest_targets;
+
+  hdy_tab_box_set_extra_drag_dest_targets (self->scroll_box, extra_drag_dest_targets);
+  hdy_tab_box_set_extra_drag_dest_targets (self->pinned_box, extra_drag_dest_targets);
+
+  g_object_notify_by_pspec (G_OBJECT (self), props[PROP_EXTRA_DRAG_DEST_TARGETS]);
+}
diff --git a/src/hdy-tab-bar.h b/src/hdy-tab-bar.h
index 97da8e7d..45125b9e 100644
--- a/src/hdy-tab-bar.h
+++ b/src/hdy-tab-bar.h
@@ -53,4 +53,10 @@ void     hdy_tab_bar_set_autohide (HdyTabBar *self,
 HDY_AVAILABLE_IN_ALL
 gboolean hdy_tab_bar_get_tabs_revealed (HdyTabBar *self);
 
+HDY_AVAILABLE_IN_ALL
+GtkTargetList *hdy_tab_bar_get_extra_drag_dest_targets (HdyTabBar     *self);
+HDY_AVAILABLE_IN_ALL
+void           hdy_tab_bar_set_extra_drag_dest_targets (HdyTabBar     *self,
+                                                        GtkTargetList *extra_drag_dest_targets);
+
 G_END_DECLS
diff --git a/src/hdy-tab-bar.ui b/src/hdy-tab-bar.ui
index deef9b45..d46f9c19 100644
--- a/src/hdy-tab-bar.ui
+++ b/src/hdy-tab-bar.ui
@@ -27,6 +27,7 @@
                 <property name="pinned">True</property>
                 <property name="hexpand">False</property>
                 <property name="tab-bar">HdyTabBar</property>
+                <signal name="extra-drag-data-received" handler="extra_drag_data_received_cb" 
swapped="true"/>
                 <style>
                   <class name="pinned"/>
                 </style>
@@ -50,6 +51,7 @@
                         <signal name="notify::needs-attention-left" handler="notify_needs_attention_cb" 
swapped="true"/>
                         <signal name="notify::needs-attention-right" handler="notify_needs_attention_cb" 
swapped="true"/>
                         <signal name="stop-kinetic-scrolling" handler="stop_kinetic_scrolling_cb" 
swapped="true"/>
+                        <signal name="extra-drag-data-received" handler="extra_drag_data_received_cb" 
swapped="true"/>
                       </object>
                     </child>
                   </object>
diff --git a/src/hdy-tab-box-private.h b/src/hdy-tab-box-private.h
index 313a325f..41f8bd7a 100644
--- a/src/hdy-tab-box-private.h
+++ b/src/hdy-tab-box-private.h
@@ -38,4 +38,7 @@ void hdy_tab_box_try_focus_selected_tab (HdyTabBox  *self);
 gboolean hdy_tab_box_is_page_focused (HdyTabBox  *self,
                                       HdyTabPage *page);
 
+void hdy_tab_box_set_extra_drag_dest_targets (HdyTabBox     *self,
+                                              GtkTargetList *extra_drag_dest_targets);
+
 G_END_DECLS
diff --git a/src/hdy-tab-box.c b/src/hdy-tab-box.c
index de50ea91..63409387 100644
--- a/src/hdy-tab-box.c
+++ b/src/hdy-tab-box.c
@@ -18,6 +18,7 @@
 /* Border collapsing without glitches */
 #define OVERLAP 1
 #define DND_THRESHOLD_MULTIPLIER 4
+#define DROP_SWITCH_TIMEOUT 500
 
 #define AUTOSCROLL_AREA_WIDTH 65
 #define AUTOSCROLL_SPEED 2.5
@@ -147,6 +148,10 @@ struct _HdyTabBox
   gboolean should_detach_into_new_window;
   GtkTargetList *source_targets;
 
+  TabInfo *drop_target_tab;
+  guint drop_switch_timeout_id;
+  guint reset_drop_target_tab_id;
+
   HdyAnimation *scroll_animation;
   gboolean scroll_animation_done;
   gdouble scroll_animation_from;
@@ -173,6 +178,7 @@ static GParamSpec *props[LAST_PROP];
 
 enum {
   SIGNAL_STOP_KINETIC_SCROLLING,
+  SIGNAL_EXTRA_DRAG_DATA_RECEIVED,
   SIGNAL_ACTIVATE_TAB,
   SIGNAL_FOCUS_TAB,
   SIGNAL_REORDER_TAB,
@@ -2833,6 +2839,41 @@ hdy_tab_box_drag_end (GtkWidget      *widget,
   g_clear_pointer (&self->drag_icon, g_free);
 }
 
+static gboolean
+drop_switch_timeout_cb (HdyTabBox *self)
+{
+  self->drop_switch_timeout_id = 0;
+  hdy_tab_view_set_selected_page (self->view,
+                                  self->drop_target_tab->page);
+
+  return G_SOURCE_REMOVE;
+}
+
+static void
+set_drop_target_tab (HdyTabBox *self,
+                     TabInfo   *info)
+{
+  if (self->drop_target_tab == info)
+    return;
+
+  if (self->drop_target_tab) {
+    g_clear_handle_id (&self->drop_switch_timeout_id, g_source_remove);
+
+    gtk_drag_unhighlight (GTK_WIDGET (self->drop_target_tab->tab));
+  }
+
+  self->drop_target_tab = info;
+
+  if (self->drop_target_tab) {
+    gtk_drag_highlight (GTK_WIDGET (info->tab));
+
+    self->drop_switch_timeout_id =
+      g_timeout_add (DROP_SWITCH_TIMEOUT,
+                     (GSourceFunc) drop_switch_timeout_cb,
+                     self);
+  }
+}
+
 static gboolean
 hdy_tab_box_drag_motion (GtkWidget      *widget,
                          GdkDragContext *context,
@@ -2845,13 +2886,16 @@ hdy_tab_box_drag_motion (GtkWidget      *widget,
   GdkAtom target, tab_target;
   gdouble center, display_width;
 
-  if (self->pinned)
-    return GDK_EVENT_PROPAGATE;
-
   target = gtk_drag_dest_find_target (GTK_WIDGET (self), context, NULL);
   tab_target = gdk_atom_intern_static_string ("HDY_TAB");
 
-  if (target != tab_target)
+  if (target != tab_target) {
+    set_drop_target_tab (self, find_tab_info_at (self, x));
+
+    return GDK_EVENT_STOP;
+  }
+
+  if (self->pinned)
     return GDK_EVENT_PROPAGATE;
 
   source_tab_box = get_source_tab_box (context);
@@ -2898,6 +2942,15 @@ hdy_tab_box_drag_motion (GtkWidget      *widget,
   return GDK_EVENT_PROPAGATE;
 }
 
+static gboolean
+reset_drop_target_tab_cb (HdyTabBox *self)
+{
+  self->reset_drop_target_tab_id = 0;
+  set_drop_target_tab (self, NULL);
+
+  return G_SOURCE_REMOVE;
+}
+
 static void
 hdy_tab_box_drag_leave (GtkWidget      *widget,
                         GdkDragContext *context,
@@ -2907,6 +2960,16 @@ hdy_tab_box_drag_leave (GtkWidget      *widget,
   HdyTabBox *source_tab_box;
   GdkAtom target, tab_target;
 
+  target = gtk_drag_dest_find_target (GTK_WIDGET (self), context, NULL);
+  tab_target = gdk_atom_intern_static_string ("HDY_TAB");
+
+  if (target != tab_target) {
+    self->reset_drop_target_tab_id =
+      g_idle_add ((GSourceFunc) reset_drop_target_tab_cb, self);
+
+    return;
+  }
+
   if (self->pinned)
     return;
 
@@ -2918,12 +2981,6 @@ hdy_tab_box_drag_leave (GtkWidget      *widget,
   if (!self->view || !is_view_in_the_same_group (self, source_tab_box->view))
     return;
 
-  target = gtk_drag_dest_find_target (GTK_WIDGET (self), context, NULL);
-  tab_target = gdk_atom_intern_static_string ("HDY_TAB");
-
-  if (target != tab_target)
-    return;
-
   self->can_remove_placeholder = TRUE;
 
   end_dragging (self);
@@ -2941,6 +2998,18 @@ hdy_tab_box_drag_drop (GtkWidget      *widget,
 {
   HdyTabBox *self = HDY_TAB_BOX (widget);
   HdyTabBox *source_tab_box;
+  GdkAtom target, tab_target;
+
+  target = gtk_drag_dest_find_target (GTK_WIDGET (self), context, NULL);
+  tab_target = gdk_atom_intern_static_string ("HDY_TAB");
+
+  if (target != tab_target) {
+    g_clear_handle_id (&self->reset_drop_target_tab_id, g_source_remove);
+
+    gtk_drag_get_data (widget, context, target, time);
+
+    return GDK_EVENT_STOP;
+  }
 
   if (self->pinned)
     return GDK_EVENT_PROPAGATE;
@@ -2999,6 +3068,24 @@ hdy_tab_box_drag_data_get (GtkWidget        *widget,
   }
 }
 
+static void
+hdy_tab_box_drag_data_received (GtkWidget        *widget,
+                                GdkDragContext   *context,
+                                int               x,
+                                int               y,
+                                GtkSelectionData *selection_data,
+                                guint             info,
+                                guint             time)
+{
+  HdyTabBox *self = HDY_TAB_BOX (widget);
+
+  g_signal_emit (self, signals[SIGNAL_EXTRA_DRAG_DATA_RECEIVED], 0,
+                 self->drop_target_tab->page,
+                 context, selection_data, info, time);
+
+  set_drop_target_tab (self, NULL);
+}
+
 static void
 hdy_tab_box_forall (GtkContainer *container,
                     gboolean      include_internals,
@@ -3023,6 +3110,8 @@ hdy_tab_box_dispose (GObject *object)
 {
   HdyTabBox *self = HDY_TAB_BOX (object);
 
+  g_clear_handle_id (&self->drop_switch_timeout_id, g_source_remove);
+
   self->tab_bar = NULL;
   hdy_tab_box_set_view (self, NULL);
   hdy_tab_box_set_adjustment (self, NULL);
@@ -3148,6 +3237,7 @@ hdy_tab_box_class_init (HdyTabBoxClass *klass)
   widget_class->drag_drop = hdy_tab_box_drag_drop;
   widget_class->drag_failed = hdy_tab_box_drag_failed;
   widget_class->drag_data_get = hdy_tab_box_drag_data_get;
+  widget_class->drag_data_received = hdy_tab_box_drag_data_received;
 
   container_class->forall = hdy_tab_box_forall;
 
@@ -3204,6 +3294,20 @@ hdy_tab_box_class_init (HdyTabBoxClass *klass)
                   G_TYPE_NONE,
                   0);
 
+  signals[SIGNAL_EXTRA_DRAG_DATA_RECEIVED] =
+    g_signal_new ("extra-drag-data-received",
+                  G_TYPE_FROM_CLASS (klass),
+                  G_SIGNAL_RUN_LAST,
+                  0,
+                  NULL, NULL, NULL,
+                  G_TYPE_NONE,
+                  5,
+                  HDY_TYPE_TAB_PAGE,
+                  GDK_TYPE_DRAG_CONTEXT,
+                  GTK_TYPE_SELECTION_DATA,
+                  G_TYPE_UINT,
+                  G_TYPE_UINT);
+
   signals[SIGNAL_ACTIVATE_TAB] =
     g_signal_new ("activate-tab",
                   G_TYPE_FROM_CLASS (klass),
@@ -3419,3 +3523,24 @@ hdy_tab_box_is_page_focused (HdyTabBox  *self,
 
   return info && gtk_widget_is_focus (GTK_WIDGET (info->tab));
 }
+
+void
+hdy_tab_box_set_extra_drag_dest_targets (HdyTabBox     *self,
+                                         GtkTargetList *extra_drag_dest_targets)
+{
+  GtkTargetList *list;
+  GtkTargetEntry *table;
+  gint n_targets;
+
+  list = gtk_target_list_new (NULL, 0);
+  table = gtk_target_table_new_from_list (extra_drag_dest_targets, &n_targets);
+
+  gtk_target_list_add_table (list, dst_targets, G_N_ELEMENTS (dst_targets));
+  gtk_target_list_add_table (list, table, n_targets);
+
+  gtk_drag_dest_set_target_list (GTK_WIDGET (self), list);
+
+  gtk_target_list_unref (list);
+  gtk_target_table_free (table, n_targets);
+}
+
diff --git a/src/hdy-tab-view.c b/src/hdy-tab-view.c
index ea78521f..94848862 100644
--- a/src/hdy-tab-view.c
+++ b/src/hdy-tab-view.c
@@ -756,7 +756,6 @@ static void
 hdy_tab_view_dispose (GObject *object)
 {
   HdyTabView *self = HDY_TAB_VIEW (object);
-  GSList *l;
 
   if (self->pages) {
     while (self->n_pages) {


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