[Xfce4-commits] [xfce/thunar] 01/02: Fix queued context menu popup

noreply at xfce.org noreply at xfce.org
Fri May 17 23:14:23 CEST 2019


This is an automated email from the git hooks/post-receive script.

a   l   e   x       p   u   s   h   e   d       a       c   o   m   m   i   t       t   o       b   r   a   n   c   h       m   a   s   t   e   r   
   in repository xfce/thunar.

commit 0601048a273e5adb7ad7875a78ef8b122ccc40dd
Author: Theo Linkspfeifer <lastonestanding at tutanota.com>
Date:   Sun May 12 12:41:17 2019 +0200

    Fix queued context menu popup
    
    Co-authored-by: Alexander Schwinn <alexxcons at xfce.org>
---
 thunar/thunar-gtk-extensions.c | 38 ++++++++++++++++++++++++++++++++------
 thunar/thunar-gtk-extensions.h |  3 +++
 thunar/thunar-standard-view.c  | 22 +++++++++++++++++++++-
 3 files changed, 56 insertions(+), 7 deletions(-)

diff --git a/thunar/thunar-gtk-extensions.c b/thunar/thunar-gtk-extensions.c
index 4852c11..dd349a3 100644
--- a/thunar/thunar-gtk-extensions.c
+++ b/thunar/thunar-gtk-extensions.c
@@ -131,27 +131,53 @@ thunar_gtk_label_set_a11y_relation (GtkLabel  *label,
  * thunar_gtk_menu_run:
  * @menu : a #GtkMenu.
  *
- * A simple wrapper around gtk_menu_popup_at_pointer(), which takes care on the
- * menu and returns only after the @menu was deactivated.
+ * Conveniance wrapper for thunar_gtk_menu_run_at_event_pointer, to run a menu for the current event
+ **/
+void
+thunar_gtk_menu_run (GtkMenu *menu)
+{
+  GdkEvent *event = gtk_get_current_event ();
+  thunar_gtk_menu_run_at_event (menu, event);
+  gdk_event_free (event);
+}
+
+
+
+/**
+ * thunar_gtk_menu_run_at_event:
+ * @menu  : a #GtkMenu.
+ * @event : a #GdkEvent which may be NULL if no previous event was stored.
+ *
+ * A simple wrapper around gtk_menu_popup_at_pointer(), which runs the @menu in a separate
+ * main loop and returns only after the @menu was deactivated.
  *
  * This method automatically takes over the floating reference of @menu if any and
  * releases it on return. That means if you created the menu via gtk_menu_new() you'll
  * not need to take care of destroying the menu later.
+ * 
  **/
 void
-thunar_gtk_menu_run (GtkMenu *menu)
+thunar_gtk_menu_run_at_event (GtkMenu *menu, GdkEvent *event)
 {
-  GdkEvent  *event;
+  GMainLoop *loop;
+  gulong     signal_id;
 
   _thunar_return_if_fail (GTK_IS_MENU (menu));
 
   /* take over the floating reference on the menu */
   g_object_ref_sink (G_OBJECT (menu));
 
-  event = gtk_get_current_event ();
+  /* run an internal main loop */
+  loop = g_main_loop_new (NULL, FALSE);
+  signal_id = g_signal_connect_swapped (G_OBJECT (menu), "deactivate", G_CALLBACK (g_main_loop_quit), loop);
   gtk_menu_popup_at_pointer (menu, event);
-  gdk_event_free (event);
   gtk_menu_reposition (menu);
+  gtk_grab_add (GTK_WIDGET (menu));
+  g_main_loop_run (loop);
+  g_main_loop_unref (loop);
+  gtk_grab_remove (GTK_WIDGET (menu));
+
+  g_signal_handler_disconnect (G_OBJECT (menu), signal_id);
 
   /* release the menu reference */
   g_object_unref (G_OBJECT (menu));
diff --git a/thunar/thunar-gtk-extensions.h b/thunar/thunar-gtk-extensions.h
index a264595..98e0c30 100644
--- a/thunar/thunar-gtk-extensions.h
+++ b/thunar/thunar-gtk-extensions.h
@@ -37,6 +37,9 @@ void             thunar_gtk_label_set_a11y_relation           (GtkLabel
 
 void             thunar_gtk_menu_run                          (GtkMenu            *menu);
 
+void             thunar_gtk_menu_run_at_event                 (GtkMenu            *menu,
+                                                               GdkEvent           *event);
+
 GtkAction       *thunar_gtk_ui_manager_get_action_by_name     (GtkUIManager       *ui_manager,
                                                                const gchar        *action_name);
 
diff --git a/thunar/thunar-standard-view.c b/thunar/thunar-standard-view.c
index af514dd..9b3d8b3 100644
--- a/thunar/thunar-standard-view.c
+++ b/thunar/thunar-standard-view.c
@@ -346,6 +346,7 @@ struct _ThunarStandardViewPrivate
   GList                  *drag_g_file_list;
   guint                   drag_scroll_timer_id;
   guint                   drag_timer_id;
+  GdkEvent               *drag_timer_event;
   gint                    drag_x;
   gint                    drag_y;
 
@@ -859,6 +860,13 @@ thunar_standard_view_dispose (GObject *object)
   if (G_UNLIKELY (standard_view->priv->drag_timer_id != 0))
     g_source_remove (standard_view->priv->drag_timer_id);
 
+  /* be sure to free any pending drag timer event */
+  if (G_UNLIKELY (standard_view->priv->drag_timer_event != NULL))
+    {
+      gdk_event_free (standard_view->priv->drag_timer_event);
+      standard_view->priv->drag_timer_event = NULL;
+    }
+
   /* reset the UI manager property */
   thunar_component_set_ui_manager (THUNAR_COMPONENT (standard_view), NULL);
 
@@ -3106,6 +3114,8 @@ thunar_standard_view_motion_notify_event (GtkWidget          *view,
     {
       /* cancel the drag timer, as we won't popup the menu anymore */
       g_source_remove (standard_view->priv->drag_timer_id);
+      gdk_event_free (standard_view->priv->drag_timer_event);
+      standard_view->priv->drag_timer_event = NULL;
 
       /* FIXME
        * - according to doc, the GdkWindow associated to the widget needs to enable the GDK_POINTER_MOTION_MASK mask to use this event.
@@ -4359,7 +4369,15 @@ G_GNUC_BEGIN_IGNORE_DEPRECATIONS
   /* run the menu (figuring out whether to use the file or the folder context menu) */
   menu = gtk_ui_manager_get_widget (standard_view->ui_manager, (selected_items != NULL) ? "/file-context-menu" : "/folder-context-menu");
 G_GNUC_END_IGNORE_DEPRECATIONS
-  thunar_gtk_menu_run (GTK_MENU (menu));
+  /* if there is a drag_timer_event (long press), we use it */
+  if (standard_view->priv->drag_timer_event != NULL)
+    {
+      thunar_gtk_menu_run_at_event (GTK_MENU (menu), standard_view->priv->drag_timer_event);
+      gdk_event_free (standard_view->priv->drag_timer_event);
+      standard_view->priv->drag_timer_event = NULL;
+    }
+  else
+    thunar_gtk_menu_run (GTK_MENU (menu));
 
   g_list_free_full (selected_items, (GDestroyNotify) gtk_tree_path_free);
 
@@ -4414,6 +4432,8 @@ thunar_standard_view_queue_popup (ThunarStandardView *standard_view,
       /* schedule the timer */
       standard_view->priv->drag_timer_id = g_timeout_add_full (G_PRIORITY_LOW, MAX (225, delay), thunar_standard_view_drag_timer,
                                                                standard_view, thunar_standard_view_drag_timer_destroy);
+      /* store current event data */
+      standard_view->priv->drag_timer_event = gtk_get_current_event ();
 
       /* register the motion notify and the button release events on the real view */
       g_signal_connect (G_OBJECT (view), "button-release-event", G_CALLBACK (thunar_standard_view_button_release_event), standard_view);

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the Xfce4-commits mailing list