[gtk/wip/otte/dnd: 20/21] stackswitcher: Use GdkDropControllerMotion



commit 785236b90543e4bfc1ba36c5fff8b3ea7aa18ecb
Author: Benjamin Otte <otte redhat com>
Date:   Sat Feb 22 04:16:42 2020 +0100

    stackswitcher: Use GdkDropControllerMotion
    
    ... and use one controller per button instead of using it on the
    switcher and then going through lots of pain attempting to find the
    right button for the location under the mouse.

 gtk/gtkstackswitcher.c | 113 ++++++++++++-------------------------------------
 1 file changed, 27 insertions(+), 86 deletions(-)
---
diff --git a/gtk/gtkstackswitcher.c b/gtk/gtkstackswitcher.c
index 699904627f..979d0cdd11 100644
--- a/gtk/gtkstackswitcher.c
+++ b/gtk/gtkstackswitcher.c
@@ -22,7 +22,7 @@
 #include "gtkstackswitcher.h"
 
 #include "gtkboxlayout.h"
-#include "gtkdragdest.h"
+#include "gtkdropcontrollermotion.h"
 #include "gtkimage.h"
 #include "gtkintl.h"
 #include "gtklabel.h"
@@ -85,8 +85,6 @@ struct _GtkStackSwitcherPrivate
   GtkStack *stack;
   GtkSelectionModel *pages;
   GHashTable *buttons;
-  GtkWidget *switch_button;
-  guint switch_timer;
 };
 
 enum {
@@ -94,36 +92,16 @@ enum {
   PROP_STACK
 };
 
-static void     gtk_stack_switcher_drag_leave  (GtkDropTarget    *dest,
-                                                GdkDrop          *drop,
-                                                GtkStackSwitcher *self);
-static gboolean gtk_stack_switcher_drag_accept (GtkDropTarget    *dest,
-                                                GdkDrop          *drop,
-                                                GtkStackSwitcher *self);
-static void     gtk_stack_switcher_drag_motion (GtkDropTarget    *dest,
-                                                GdkDrop          *drop,
-                                                int               x,
-                                                int               y,
-                                                GtkStackSwitcher *self);
-
-
 G_DEFINE_TYPE_WITH_PRIVATE (GtkStackSwitcher, gtk_stack_switcher, GTK_TYPE_WIDGET)
 
 static void
 gtk_stack_switcher_init (GtkStackSwitcher *switcher)
 {
   GtkStackSwitcherPrivate *priv = gtk_stack_switcher_get_instance_private (switcher);
-  GtkDropTarget *dest;
 
   priv->buttons = g_hash_table_new_full (g_direct_hash, g_direct_equal, g_object_unref, NULL);
 
   gtk_widget_add_css_class (GTK_WIDGET (switcher), "linked");
-
-  dest = gtk_drop_target_new (NULL, 0);
-  g_signal_connect (dest, "drag-leave", G_CALLBACK (gtk_stack_switcher_drag_leave), switcher);
-  g_signal_connect (dest, "accept", G_CALLBACK (gtk_stack_switcher_drag_accept), switcher);
-  g_signal_connect (dest, "drag-motion", G_CALLBACK (gtk_stack_switcher_drag_motion), switcher);
-  gtk_widget_add_controller (GTK_WIDGET (switcher), GTK_EVENT_CONTROLLER (dest));
 }
 
 static void
@@ -230,29 +208,12 @@ on_page_updated (GtkStackPage     *page,
   update_button (self, page, button);
 }
 
-static void
-remove_switch_timer (GtkStackSwitcher *self)
-{
-  GtkStackSwitcherPrivate *priv = gtk_stack_switcher_get_instance_private (self);
-
-  if (priv->switch_timer)
-    {
-      g_source_remove (priv->switch_timer);
-      priv->switch_timer = 0;
-    }
-}
-
 static gboolean
 gtk_stack_switcher_switch_timeout (gpointer data)
 {
-  GtkStackSwitcher *self = data;
-  GtkStackSwitcherPrivate *priv = gtk_stack_switcher_get_instance_private (self);
-  GtkWidget *button;
-
-  priv->switch_timer = 0;
+  GtkWidget *button = data;
 
-  button = priv->switch_button;
-  priv->switch_button = NULL;
+  g_object_steal_data (G_OBJECT (button), "-gtk-switch-timer");
 
   if (button)
     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
@@ -260,59 +221,34 @@ gtk_stack_switcher_switch_timeout (gpointer data)
   return G_SOURCE_REMOVE;
 }
 
-static gboolean
-gtk_stack_switcher_drag_accept (GtkDropTarget    *dest,
-                                GdkDrop          *drop,
-                                GtkStackSwitcher *self)
-{
-  return TRUE;
-}
-
 static void 
-gtk_stack_switcher_drag_motion (GtkDropTarget    *dest,
-                                GdkDrop          *drop,
-                                int               x,
-                                int               y,
-                                GtkStackSwitcher *self)
+gtk_stack_switcher_drag_enter (GtkDropControllerMotion *motion,
+                               double                   x,
+                               double                   y,
+                               gpointer                 unused)
 {
-  GtkStackSwitcherPrivate *priv = gtk_stack_switcher_get_instance_private (self);
-  GtkWidget *button;
-  GHashTableIter iter;
-  gpointer value;
-
-  button = NULL;
-  g_hash_table_iter_init (&iter, priv->buttons);
-  while (g_hash_table_iter_next (&iter, NULL, &value))
-    {
-      int cx, cy;
-      gtk_widget_translate_coordinates (GTK_WIDGET (self), value, x, y, &cx, &cy);
-      if (gtk_widget_contains (GTK_WIDGET (value), cx, cy))
-        {
-          button = GTK_WIDGET (value);
-          break;
-        }
-    }
-
-  if (button != priv->switch_button)
-    remove_switch_timer (self);
+  GtkWidget *button = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (motion));
 
-  priv->switch_button = button;
-
-  if (button && !priv->switch_timer)
+  if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button)))
     {
-      priv->switch_timer = g_timeout_add (TIMEOUT_EXPAND,
+      guint switch_timer = g_timeout_add (TIMEOUT_EXPAND,
                                           gtk_stack_switcher_switch_timeout,
-                                          self);
-      g_source_set_name_by_id (priv->switch_timer, "[gtk] gtk_stack_switcher_switch_timeout");
+                                          button);
+      g_source_set_name_by_id (switch_timer, "[gtk] gtk_stack_switcher_switch_timeout");
+      g_object_set_data (G_OBJECT (button), "-gtk-switch-timer", GUINT_TO_POINTER (switch_timer));
     }
 }
 
 static void
-gtk_stack_switcher_drag_leave (GtkDropTarget    *dest,
-                               GdkDrop          *drop,
-                               GtkStackSwitcher *self)
+gtk_stack_switcher_drag_leave (GtkDropControllerMotion *motion,
+                               gpointer                 unused)
 {
-  remove_switch_timer (self);
+  GtkWidget *button = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (motion));
+  guint switch_timer;
+
+  switch_timer = GPOINTER_TO_UINT (g_object_steal_data (G_OBJECT (button), "-gtk-switch-timer"));
+  if (switch_timer)
+    g_source_remove (switch_timer);
 }
 
 static void
@@ -323,10 +259,16 @@ add_child (guint             position,
   GtkWidget *button;
   gboolean selected;
   GtkStackPage *page;
+  GtkEventController *controller;
 
   button = gtk_toggle_button_new ();
   gtk_widget_set_focus_on_click (button, FALSE);
 
+  controller = gtk_drop_controller_motion_new ();
+  g_signal_connect (controller, "enter", G_CALLBACK (gtk_stack_switcher_drag_enter), NULL);
+  g_signal_connect (controller, "leave", G_CALLBACK (gtk_stack_switcher_drag_leave), NULL);
+  gtk_widget_add_controller (button, controller);
+
   page = g_list_model_get_item (G_LIST_MODEL (priv->pages), position);
   update_button (self, page, button);
 
@@ -549,7 +491,6 @@ gtk_stack_switcher_dispose (GObject *object)
 {
   GtkStackSwitcher *switcher = GTK_STACK_SWITCHER (object);
 
-  remove_switch_timer (switcher);
   unset_stack (switcher);
 
   G_OBJECT_CLASS (gtk_stack_switcher_parent_class)->dispose (object);


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