[gtk/gbsneto/filechooser-column-view] filechooserwidget: Make context menus mostly work



commit 56e945946b2bbb17f6583b9e9c2123ac86d98047
Author: Matthias Clasen <mclasen redhat com>
Date:   Fri Oct 14 00:01:02 2022 -0400

    filechooserwidget: Make context menus mostly work
    
    Move the gestures to the individual cells, and
    make them trigger the context menu via an action
    that takes item position and coordinates.
    
    The semantics are changed slightly: the menu actions
    now operate on the clicked item, not on the selection.
    
    Still to do: Fix up keyboard activation.

 gtk/gtkfilechoosercell.c        | 179 ++++++++++++++++++++++++++++
 gtk/gtkfilechoosercellprivate.h |  37 ++++++
 gtk/gtkfilechooserwidget.c      | 256 ++++++++++++----------------------------
 gtk/meson.build                 |   1 +
 gtk/ui/gtkfilechooserwidget.ui  | 208 +++++++++++++++++---------------
 5 files changed, 405 insertions(+), 276 deletions(-)
---
diff --git a/gtk/gtkfilechoosercell.c b/gtk/gtkfilechoosercell.c
new file mode 100644
index 0000000000..b10c2cf02e
--- /dev/null
+++ b/gtk/gtkfilechoosercell.c
@@ -0,0 +1,179 @@
+/*
+ * Copyright © 2022 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Matthias Clasen <mclasen redhat com>
+ */
+
+#include "config.h"
+
+#include "gtkfilechoosercellprivate.h"
+
+#include "gtkprivate.h"
+#include "gtkbinlayout.h"
+#include "gtkgestureclick.h"
+#include "gtkgesturelongpress.h"
+#include "gtkfilechooserwidget.h"
+
+struct _GtkFileChooserCell
+{
+  GtkWidget parent_instance;
+
+  guint position;
+};
+
+struct _GtkFileChooserCellClass
+{
+  GtkWidgetClass parent_class;
+};
+
+G_DEFINE_TYPE (GtkFileChooserCell, gtk_file_chooser_cell, GTK_TYPE_WIDGET)
+
+enum
+{
+  PROP_POSITION = 1,
+};
+
+static void
+popup_menu (GtkFileChooserCell *self,
+            double              x,
+            double              y)
+{
+  GtkWidget *widget = GTK_WIDGET (self);
+  GtkWidget *impl;
+  double xx, yy;
+
+  impl = gtk_widget_get_ancestor (widget, GTK_TYPE_FILE_CHOOSER_WIDGET);
+
+  gtk_widget_translate_coordinates (widget, GTK_WIDGET (impl),
+                                    x, y, &xx, &yy);
+
+  gtk_widget_activate_action (widget, "item.popup-file-list-menu",
+                              "(udd)", self->position, xx, yy);
+}
+
+static void
+file_chooser_cell_clicked (GtkEventController *controller,
+                           int                 n_press,
+                           double              x,
+                           double              y)
+{
+  GtkWidget *widget = gtk_event_controller_get_widget (controller);
+  GtkFileChooserCell *self = GTK_FILE_CHOOSER_CELL (widget);
+
+  popup_menu (self, x, y);
+}
+
+static void
+file_chooser_cell_long_pressed (GtkEventController *controller,
+                                double              x,
+                                double              y)
+{
+  GtkWidget *widget = gtk_event_controller_get_widget (controller);
+  GtkFileChooserCell *self = GTK_FILE_CHOOSER_CELL (widget);
+
+  popup_menu (self, x, y);
+}
+
+static void
+gtk_file_chooser_cell_init (GtkFileChooserCell *self)
+{
+  GtkGesture *gesture;
+
+  gesture = gtk_gesture_click_new ();
+  gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (gesture), GDK_BUTTON_SECONDARY);
+  g_signal_connect (gesture, "pressed", G_CALLBACK (file_chooser_cell_clicked), NULL);
+  gtk_widget_add_controller (GTK_WIDGET (self), GTK_EVENT_CONTROLLER (gesture));
+
+  gesture = gtk_gesture_long_press_new ();
+  g_signal_connect (gesture, "pressed", G_CALLBACK (file_chooser_cell_long_pressed), NULL);
+}
+
+static void
+gtk_file_chooser_cell_dispose (GObject *object)
+{
+  GtkWidget *child;
+
+  while ((child = gtk_widget_get_first_child (GTK_WIDGET (object))))
+    gtk_widget_unparent (child);
+
+  G_OBJECT_CLASS (gtk_file_chooser_cell_parent_class)->dispose (object);
+}
+
+static void
+gtk_file_chooser_cell_set_property (GObject      *object,
+                                    guint         prop_id,
+                                    const GValue *value,
+                                    GParamSpec   *pspec)
+{
+  GtkFileChooserCell *self = GTK_FILE_CHOOSER_CELL (object);
+
+  switch (prop_id)
+    {
+    case PROP_POSITION:
+      self->position = g_value_get_uint (value);
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+static void
+gtk_file_chooser_cell_get_property (GObject    *object,
+                                    guint       prop_id,
+                                    GValue     *value,
+                                    GParamSpec *pspec)
+{
+  GtkFileChooserCell *self = GTK_FILE_CHOOSER_CELL (object);
+
+  switch (prop_id)
+    {
+    case PROP_POSITION:
+      g_value_set_uint (value, self->position);
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+
+static void
+gtk_file_chooser_cell_class_init (GtkFileChooserCellClass *klass)
+{
+  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  object_class->dispose = gtk_file_chooser_cell_dispose;
+  object_class->set_property = gtk_file_chooser_cell_set_property;
+  object_class->get_property = gtk_file_chooser_cell_get_property;
+
+  g_object_class_install_property (object_class, PROP_POSITION,
+                                   g_param_spec_uint ("position", NULL, NULL,
+                                                      0, G_MAXUINT, 0,
+                                                      GTK_PARAM_READWRITE));
+
+  gtk_widget_class_set_css_name (widget_class, I_("filelistcell"));
+  gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BIN_LAYOUT);
+}
+
+GtkFileChooserCell *
+gtk_file_chooser_cell_new (void)
+{
+  return g_object_new (GTK_TYPE_FILE_CHOOSER_CELL, NULL);
+}
diff --git a/gtk/gtkfilechoosercellprivate.h b/gtk/gtkfilechoosercellprivate.h
new file mode 100644
index 0000000000..b70371abec
--- /dev/null
+++ b/gtk/gtkfilechoosercellprivate.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright © 2022 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Matthias Clasen
+ */
+
+#ifndef __GTK_FILE_CHOOSER_CELL_PRIVATE_H__
+#define __GTK_FILE_CHOOSER_CELL_PRIVATE_H__
+
+#include <gtk/gtkwidget.h>
+#include <gtk/gtkexpression.h>
+
+G_BEGIN_DECLS
+
+#define GTK_TYPE_FILE_CHOOSER_CELL (gtk_file_chooser_cell_get_type ())
+
+GDK_AVAILABLE_IN_ALL
+G_DECLARE_FINAL_TYPE (GtkFileChooserCell, gtk_file_chooser_cell, GTK, FILE_CHOOSER_CELL, GtkWidget)
+
+GtkFileChooserCell * gtk_file_chooser_cell_new (void);
+
+G_END_DECLS
+
+#endif  /* __GTK_FILE_CHOOSER_CELL_PRIVATE_H__ */
diff --git a/gtk/gtkfilechooserwidget.c b/gtk/gtkfilechooserwidget.c
index 38e5df744a..20dceaae61 100644
--- a/gtk/gtkfilechooserwidget.c
+++ b/gtk/gtkfilechooserwidget.c
@@ -72,8 +72,6 @@
 #include "gtkspinner.h"
 #include "gtkseparator.h"
 #include "gtkmodelbuttonprivate.h"
-#include "gtkgesturelongpress.h"
-#include "gtkgestureclick.h"
 #include "gtkeventcontrollerkey.h"
 #include "gtkdebug.h"
 #include "gtkfilechoosererrorstackprivate.h"
@@ -208,6 +206,7 @@ struct _GtkFileChooserWidget
   GtkWidget *remote_warning_bar;
 
   GtkWidget *browse_files_popover;
+  guint browse_files_popover_item;
 
   GtkWidget *browse_new_folder_button;
   GtkSizeGroup *browse_path_bar_size_group;
@@ -472,7 +471,6 @@ static void stop_loading_and_clear_list_model (GtkFileChooserWidget *impl,
                                                gboolean remove_from_treeview);
 
 static GSList  *get_selected_files           (GtkFileChooserWidget *impl);
-static GSList  *get_selected_infos           (GtkFileChooserWidget *impl);
 
 static void     search_setup_widgets         (GtkFileChooserWidget *impl);
 static void     search_stop_searching        (GtkFileChooserWidget *impl,
@@ -1358,18 +1356,18 @@ copy_file_location_cb (GSimpleAction *action,
                        gpointer       data)
 {
   GtkFileChooserWidget *impl = data;
-  GSList *selected_files = NULL;
+  GFileInfo *info;
+  GFile *file;
+  GdkClipboard *clipboard;
 
-  selected_files = get_selected_files (impl);
+  info = g_list_model_get_item (G_LIST_MODEL (impl->selection_model), impl->browse_files_popover_item);
+  file = _gtk_file_info_get_file (info);
 
-  if (selected_files)
-    {
-      GdkClipboard *clipboard;
+  clipboard = gtk_widget_get_clipboard (GTK_WIDGET (impl));
 
-      clipboard = gtk_widget_get_clipboard (GTK_WIDGET (impl));
-      gdk_clipboard_set (clipboard, GDK_TYPE_FILE_LIST, selected_files);
-      g_slist_free_full (selected_files, g_object_unref);
-    }
+  gdk_clipboard_set (clipboard, G_TYPE_FILE, file);
+
+  g_clear_object (&info);
 }
 
 /* Callback used when the "Visit this file" menu item is activated */
@@ -1379,19 +1377,15 @@ visit_file_cb (GSimpleAction *action,
                gpointer       data)
 {
   GtkFileChooserWidget *impl = data;
-  GSList *files;
-
-  files = get_selected_files (impl);
+  GFileInfo *info;
+  GFile *file;
 
-  /* Sigh, just use the first one */
-  if (files)
-    {
-      GFile *file = files->data;
+  info = g_list_model_get_item (G_LIST_MODEL (impl->selection_model), impl->browse_files_popover_item);
+  file = _gtk_file_info_get_file (info);
 
-      gtk_file_chooser_widget_select_file (GTK_FILE_CHOOSER (impl), file, NULL); /* NULL-GError */
-    }
+  gtk_file_chooser_widget_select_file (GTK_FILE_CHOOSER (impl), file, NULL); /* NULL-GError */
 
-  g_slist_free_full (files, g_object_unref);
+  g_clear_object (&info);
 }
 
 /* Callback used when the "Open this folder" menu item is activated */
@@ -1402,14 +1396,14 @@ open_folder_cb (GSimpleAction *action,
 {
   GtkFileChooserWidget *impl = data;
   GtkWidget *toplevel = GTK_WIDGET (gtk_widget_get_root (GTK_WIDGET (impl)));
-  GSList *files;
+  GFileInfo *info;
+  GFile *file;
 
-  files = get_selected_files (impl);
+  info = g_list_model_get_item (G_LIST_MODEL (impl->selection_model), impl->browse_files_popover_item);
+  file = _gtk_file_info_get_file (info);
 
-  /* Sigh, just use the first one */
-  if (files && GTK_IS_WINDOW (toplevel))
+  if (GTK_IS_WINDOW (toplevel))
     {
-      GFile *file = files->data;
       char *uri;
 
       uri = g_file_get_uri (file);
@@ -1417,7 +1411,7 @@ open_folder_cb (GSimpleAction *action,
       g_free (uri);
     }
 
-  g_slist_free_full (files, g_object_unref);
+  g_clear_object (&info);
 }
 
 /* callback used when the "Show Hidden Files" menu item is toggled */
@@ -1613,87 +1607,75 @@ file_list_drag_drop_cb (GtkDropTarget        *dest,
   return TRUE;
 }
 
-/* Sensitizes the "Copy file’s location" and other context menu items if there is actually
- * a selection active.
- */
 static void
 check_file_list_popover_sensitivity (GtkFileChooserWidget *impl)
 {
-  int num_selected;
-  gboolean all_files;
-  gboolean all_folders;
-  gboolean active;
-  GAction *action, *action2;
-
-  selection_check (impl, &num_selected, &all_files, &all_folders);
+  GAction *action;
+  GFileInfo *info;
+  gboolean is_folder;
+  GSimpleAction *delete_action, *trash_action;
 
-  active = (num_selected != 0);
+  info = g_list_model_get_item (G_LIST_MODEL (impl->selection_model), impl->browse_files_popover_item);
+  is_folder = _gtk_file_info_consider_as_directory (info);
 
   action = g_action_map_lookup_action (G_ACTION_MAP (impl->item_actions), "copy-location");
-  g_simple_action_set_enabled (G_SIMPLE_ACTION (action), active);
+  g_simple_action_set_enabled (G_SIMPLE_ACTION (action), TRUE);
 
   action = g_action_map_lookup_action (G_ACTION_MAP (impl->item_actions), "add-shortcut");
-  g_simple_action_set_enabled (G_SIMPLE_ACTION (action), active && all_folders);
+  g_simple_action_set_enabled (G_SIMPLE_ACTION (action), is_folder);
 
   action = g_action_map_lookup_action (G_ACTION_MAP (impl->item_actions), "visit");
-  g_simple_action_set_enabled (G_SIMPLE_ACTION (action), active);
+  g_simple_action_set_enabled (G_SIMPLE_ACTION (action), TRUE);
 
   action = g_action_map_lookup_action (G_ACTION_MAP (impl->item_actions), "open");
-  g_simple_action_set_enabled (G_SIMPLE_ACTION (action), (num_selected == 1) && all_folders);
+  g_simple_action_set_enabled (G_SIMPLE_ACTION (action), is_folder);
 
   action = g_action_map_lookup_action (G_ACTION_MAP (impl->item_actions), "rename");
-  if (num_selected == 1)
-    {
-      GSList *infos;
-      GFileInfo *info;
+  g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
+                               g_file_info_get_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_RENAME));
 
-      infos = get_selected_infos (impl);
-      info = G_FILE_INFO (infos->data);
+  action = g_action_map_lookup_action (G_ACTION_MAP (impl->item_actions), "delete");
+  delete_action = G_SIMPLE_ACTION (action);
 
-      g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
-                                   g_file_info_get_attribute_boolean (info, 
G_FILE_ATTRIBUTE_ACCESS_CAN_RENAME));
+  action = g_action_map_lookup_action (G_ACTION_MAP (impl->item_actions), "trash");
+  trash_action = G_SIMPLE_ACTION (action);
 
-      g_slist_free_full (infos, g_object_unref);
+  if (g_file_info_get_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_TRASH))
+    {
+      g_simple_action_set_enabled (trash_action, TRUE);
+      g_simple_action_set_enabled (delete_action, FALSE);
+    }
+  else if (g_file_info_get_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_DELETE))
+    {
+      g_simple_action_set_enabled (delete_action, TRUE);
+      g_simple_action_set_enabled (trash_action, FALSE);
     }
   else
-    g_simple_action_set_enabled (G_SIMPLE_ACTION (action), FALSE);
+    {
+      g_simple_action_set_enabled (trash_action, FALSE);
+      g_simple_action_set_enabled (delete_action, FALSE);
+    }
+}
 
-  action = g_action_map_lookup_action (G_ACTION_MAP (impl->item_actions), "delete");
-  action2 = g_action_map_lookup_action (G_ACTION_MAP (impl->item_actions), "trash");
+static void
+file_list_show_popover (GtkFileChooserWidget *impl,
+                        double                x,
+                        double                y);
 
-  if (num_selected == 1)
-    {
-      GSimpleAction *delete_action = G_SIMPLE_ACTION (action);
-      GSimpleAction *trash_action = G_SIMPLE_ACTION (action2);
-      GSList *infos;
-      GFileInfo *info;
+static void
+popup_file_list_menu (GSimpleAction *action,
+                      GVariant      *parameter,
+                      gpointer       user_data)
+{
+  GtkFileChooserWidget *impl = user_data;
+  guint position;
+  double x, y;
 
-      infos = get_selected_infos (impl);
-      info = G_FILE_INFO (infos->data);
+  g_variant_get (parameter, "(udd)", &position, &x, &y);
 
-      if (g_file_info_get_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_TRASH))
-        {
-          g_simple_action_set_enabled (trash_action, TRUE);
-          g_simple_action_set_enabled (delete_action, FALSE);
-        }
-      else if (g_file_info_get_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_DELETE))
-        {
-          g_simple_action_set_enabled (delete_action, TRUE);
-          g_simple_action_set_enabled (trash_action, FALSE);
-        }
-      else
-        {
-          g_simple_action_set_enabled (trash_action, FALSE);
-          g_simple_action_set_enabled (delete_action, FALSE);
-        }
+  impl->browse_files_popover_item = position;
 
-      g_slist_free_full (infos, g_object_unref);
-    }
-  else
-    {
-      g_simple_action_set_enabled (G_SIMPLE_ACTION (action), FALSE);
-      g_simple_action_set_enabled (G_SIMPLE_ACTION (action2), FALSE);
-    }
+  file_list_show_popover (impl, x, y);
 }
 
 static GActionEntry entries[] = {
@@ -1704,6 +1686,7 @@ static GActionEntry entries[] = {
   { "rename", rename_file_cb, NULL, NULL, NULL },
   { "delete", delete_file_cb, NULL, NULL, NULL },
   { "trash", trash_file_cb, NULL, NULL, NULL },
+  { "popup-file-list-menu",  popup_file_list_menu, "(udd)", NULL, NULL },
   { "toggle-show-hidden", NULL, NULL, "false", change_show_hidden_state },
   { "toggle-show-size", NULL, NULL, "false", change_show_size_state },
   { "toggle-show-type", NULL, NULL, "false", change_show_type_state },
@@ -1796,18 +1779,17 @@ file_list_update_popover (GtkFileChooserWidget *impl)
   /* The sensitivity of the Add to Bookmarks item is set in
    * bookmarks_check_add_sensitivity()
    */
-  state = impl->action == GTK_FILE_CHOOSER_ACTION_OPEN ||
-          impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER ||
-          impl->operation_mode != OPERATION_MODE_BROWSE;
+  state = impl->action == GTK_FILE_CHOOSER_ACTION_SAVE &&
+          impl->operation_mode == OPERATION_MODE_BROWSE;
 
   action = g_action_map_lookup_action (G_ACTION_MAP (impl->item_actions), "rename");
-  g_simple_action_set_enabled (G_SIMPLE_ACTION (action), !state);
+  g_simple_action_set_enabled (G_SIMPLE_ACTION (action), state);
 
   action = g_action_map_lookup_action (G_ACTION_MAP (impl->item_actions), "delete");
-  g_simple_action_set_enabled (G_SIMPLE_ACTION (action), !state);
+  g_simple_action_set_enabled (G_SIMPLE_ACTION (action), state);
 
   action = g_action_map_lookup_action (G_ACTION_MAP (impl->item_actions), "trash");
-  g_simple_action_set_enabled (G_SIMPLE_ACTION (action), !state);
+  g_simple_action_set_enabled (G_SIMPLE_ACTION (action), state);
 
   action = g_action_map_lookup_action (G_ACTION_MAP (impl->item_actions), "visit");
   g_simple_action_set_enabled (G_SIMPLE_ACTION (action), (impl->operation_mode != OPERATION_MODE_BROWSE));
@@ -1864,27 +1846,6 @@ list_popup_menu_cb (GtkWidget *widget,
   return TRUE;
 }
 
-static void
-files_list_clicked (GtkGesture           *gesture,
-                    int                   n_press,
-                    double                x,
-                    double                y,
-                    GtkFileChooserWidget *impl)
-{
-  list_popup_menu_cb (NULL, NULL, impl);
-}
-
-static void
-files_list_restrict_clicking (GtkGestureClick      *gesture,
-                              int                   n_press,
-                              double                x,
-                              double                y,
-                              GtkFileChooserWidget *impl)
-{
-  if (impl->browse_files_interaction_frozen)
-    gtk_event_controller_reset (GTK_EVENT_CONTROLLER (gesture));
-}
-
 static gboolean
 files_list_restrict_key_presses (GtkEventControllerKey *controller,
                                  guint                  keyval,
@@ -1922,35 +1883,6 @@ file_list_show_popover_in_idle (gpointer data)
   return G_SOURCE_REMOVE;
 }
 
-static void
-click_cb (GtkGesture           *gesture,
-          int                   n_press,
-          double                x,
-          double                y,
-          GtkFileChooserWidget *impl)
-{
-  PopoverData *pd;
-
-  pd = g_new (PopoverData, 1);
-  pd->impl = impl;
-  gtk_widget_translate_coordinates (impl->browse_files_column_view,
-                                    GTK_WIDGET (impl),
-                                    x, y, &x, &y);
-  pd->x = x;
-  pd->y = y;
-
-  g_idle_add (file_list_show_popover_in_idle, pd);
-}
-
-static void
-long_press_cb (GtkGesture           *gesture,
-               double                x,
-               double                y,
-               GtkFileChooserWidget *impl)
-{
-  file_list_show_popover (impl, x, y);
-}
-
 static char *
 column_view_get_file_date (GtkListItem *item,
                            GFileInfo   *info)
@@ -5701,31 +5633,6 @@ get_selected_files (GtkFileChooserWidget *impl)
   return result;
 }
 
-static GSList *
-get_selected_infos (GtkFileChooserWidget *impl)
-{
-  GtkBitsetIter iter;
-  GtkBitset *bitset;
-  GSList *result = NULL;
-  guint i;
-
-  bitset = gtk_selection_model_get_selection (impl->selection_model);
-
-  for (gtk_bitset_iter_init_first (&iter, bitset, &i);
-       gtk_bitset_iter_is_valid (&iter);
-       gtk_bitset_iter_next (&iter, &i))
-    {
-      GFileInfo *info;
-
-      info = g_list_model_get_item (G_LIST_MODEL (impl->selection_model), i);
-      result = g_slist_prepend (result, g_object_ref (info));
-
-      g_clear_object (&info);
-    }
-
-  return result;
-}
-
 /* Callback used from GtkSearchEngine when we get new hits */
 static void
 search_engine_hits_added_cb (GtkSearchEngine      *engine,
@@ -6835,8 +6742,6 @@ gtk_file_chooser_widget_class_init (GtkFileChooserWidgetClass *class)
   gtk_widget_class_bind_template_callback (widget_class, rename_file_name_changed);
   gtk_widget_class_bind_template_callback (widget_class, rename_file_rename_clicked);
   gtk_widget_class_bind_template_callback (widget_class, rename_file_end);
-  gtk_widget_class_bind_template_callback (widget_class, click_cb);
-  gtk_widget_class_bind_template_callback (widget_class, long_press_cb);
   gtk_widget_class_bind_template_callback (widget_class, column_view_get_file_date);
   gtk_widget_class_bind_template_callback (widget_class, column_view_get_file_display_name);
   gtk_widget_class_bind_template_callback (widget_class, column_view_get_file_time);
@@ -6891,7 +6796,6 @@ post_process_ui (GtkFileChooserWidget *impl)
 {
   GFile            *file;
   GtkDropTarget *target;
-  GtkGesture *gesture;
   GtkEventController *controller;
   GtkShortcutTrigger *trigger;
   GtkShortcutAction *action;
@@ -6926,11 +6830,6 @@ post_process_ui (GtkFileChooserWidget *impl)
 
   gtk_widget_set_parent (impl->rename_file_popover, GTK_WIDGET (impl));
 
-  gesture = gtk_gesture_click_new ();
-  gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (gesture), GDK_BUTTON_SECONDARY);
-  g_signal_connect (gesture, "pressed", G_CALLBACK (files_list_clicked), impl);
-  gtk_widget_add_controller (GTK_WIDGET (impl->browse_files_column_view), GTK_EVENT_CONTROLLER (gesture));
-
   controller = gtk_shortcut_controller_new ();
   trigger = gtk_alternative_trigger_new (gtk_keyval_trigger_new (GDK_KEY_F10, GDK_SHIFT_MASK),
                                          gtk_keyval_trigger_new (GDK_KEY_Menu, 0));
@@ -6939,15 +6838,6 @@ post_process_ui (GtkFileChooserWidget *impl)
   gtk_shortcut_controller_add_shortcut (GTK_SHORTCUT_CONTROLLER (controller), shortcut);
   gtk_widget_add_controller (GTK_WIDGET (impl->browse_files_column_view), controller);
 
-  /* Add ability to restrict interaction on file list (click and key_press events),
-   * needed to prevent data loss bug #2288 */
-  gesture = gtk_gesture_click_new ();
-  gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (gesture), 0);
-  gtk_gesture_single_set_exclusive (GTK_GESTURE_SINGLE (gesture), TRUE);
-  gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (gesture), GTK_PHASE_CAPTURE);
-  g_signal_connect (gesture, "pressed", G_CALLBACK (files_list_restrict_clicking), impl);
-  gtk_widget_add_controller (impl->browse_files_column_view, GTK_EVENT_CONTROLLER (gesture));
-
   controller = gtk_event_controller_key_new ();
   gtk_event_controller_set_propagation_phase (controller, GTK_PHASE_CAPTURE);
   g_signal_connect (controller, "key-pressed", G_CALLBACK (files_list_restrict_key_presses), impl);
diff --git a/gtk/meson.build b/gtk/meson.build
index 4acc62e223..f0b87e09d2 100644
--- a/gtk/meson.build
+++ b/gtk/meson.build
@@ -108,6 +108,7 @@ gtk_private_sources = files([
   'gtkfilechoosererrorstack.c',
   'gtkfilechoosernativeportal.c',
   'gtkfilechooserutils.c',
+  'gtkfilechoosercell.c',
   'gtkfilesystemmodel.c',
   'gtkfilethumbnail.c',
   'gtkgizmo.c',
diff --git a/gtk/ui/gtkfilechooserwidget.ui b/gtk/ui/gtkfilechooserwidget.ui
index ab8d446367..bfd4a0e9db 100644
--- a/gtk/ui/gtkfilechooserwidget.ui
+++ b/gtk/ui/gtkfilechooserwidget.ui
@@ -143,19 +143,6 @@
                                           <object class="GtkColumnView" id="browse_files_column_view">
                                             <signal name="activate" handler="column_view_row_activated_cb" 
swapped="no"/>
                                             <signal name="keynav-failed" 
handler="browse_files_column_view_keynav_failed_cb"/>
-                                            <child>
-                                              <object class="GtkGestureLongPress">
-                                                <property name="touch-only">1</property>
-                                                <signal name="pressed" handler="long_press_cb" swapped="no"/>
-                                              </object>
-                                            </child>
-                                            <child>
-                                              <object class="GtkGestureClick">
-                                                <property name="button">3</property>
-                                                <signal name="pressed" handler="click_cb" swapped="no"/>
-                                              </object>
-                                            </child>
-
                                             <child>
                                               <object class="GtkColumnViewColumn" 
id="column_view_name_column">
                                                 <property name="title" translatable="yes">Name</property>
@@ -168,31 +155,38 @@
 <interface>
   <template class="GtkListItem">
     <property name="child">
-      <object class="GtkBox">
-        <binding name="tooltip-text">
-          <closure type="gchararray" function="column_view_get_tooltip_text">
-            <lookup name="item">GtkListItem</lookup>
-          </closure>
+      <object class="GtkFileChooserCell">
+        <binding name="position">
+          <lookup name="position">GtkListItem</lookup>
         </binding>
         <child>
-          <object class="GtkFileThumbnail">
-            <property name="margin-start">6</property>
-            <property name="margin-end">6</property>
-            <binding name="file-info">
-              <lookup name="item">GtkListItem</lookup>
-            </binding>
-          </object>
-        </child>
-        <child>
-          <object class="GtkInscription">
-            <property name="hexpand">1</property>
-            <property name="xalign">0</property>
-            <property name="min-chars">10</property>
-            <binding name="text">
-              <closure type="gchararray" function="column_view_get_file_display_name">
+          <object class="GtkBox">
+            <binding name="tooltip-text">
+              <closure type="gchararray" function="column_view_get_tooltip_text">
                 <lookup name="item">GtkListItem</lookup>
               </closure>
             </binding>
+            <child>
+              <object class="GtkFileThumbnail">
+                <property name="margin-start">6</property>
+                <property name="margin-end">6</property>
+                <binding name="file-info">
+                  <lookup name="item">GtkListItem</lookup>
+                </binding>
+              </object>
+            </child>
+            <child>
+              <object class="GtkInscription">
+                <property name="hexpand">1</property>
+                <property name="xalign">0</property>
+                <property name="min-chars">10</property>
+                <binding name="text">
+                  <closure type="gchararray" function="column_view_get_file_display_name">
+                    <lookup name="item">GtkListItem</lookup>
+                  </closure>
+                </binding>
+              </object>
+            </child>
           </object>
         </child>
       </object>
@@ -218,22 +212,29 @@
 <interface>
   <template class="GtkListItem">
     <property name="child">
-      <object class="GtkInscription">
-        <property name="hexpand">1</property>
-        <property name="xalign">0</property>
-        <property name="min-chars">10</property>
-        <property name="margin-start">6</property>
-        <property name="margin-end">6</property>
-        <binding name="text">
-          <closure type="gchararray" function="column_view_get_location">
-            <lookup name="item">GtkListItem</lookup>
-          </closure>
-        </binding>
-        <binding name="tooltip-text">
-          <closure type="gchararray" function="column_view_get_tooltip_text">
-            <lookup name="item">GtkListItem</lookup>
-          </closure>
+      <object class="GtkFileChooserCell">
+        <binding name="position">
+          <lookup name="position">GtkListItem</lookup>
         </binding>
+        <child>
+          <object class="GtkInscription">
+            <property name="hexpand">1</property>
+            <property name="xalign">0</property>
+            <property name="min-chars">10</property>
+            <property name="margin-start">6</property>
+            <property name="margin-end">6</property>
+            <binding name="text">
+              <closure type="gchararray" function="column_view_get_location">
+                <lookup name="item">GtkListItem</lookup>
+              </closure>
+            </binding>
+            <binding name="tooltip-text">
+              <closure type="gchararray" function="column_view_get_tooltip_text">
+                <lookup name="item">GtkListItem</lookup>
+              </closure>
+            </binding>
+          </object>
+        </child>
       </object>
     </property>
   </template>
@@ -254,19 +255,26 @@
 <interface>
   <template class="GtkListItem">
     <property name="child">
-      <object class="GtkLabel">
-        <property name="hexpand">1</property>
-        <property name="xalign">0</property>
-        <binding name="label">
-          <closure type="gchararray" function="column_view_get_size">
-            <lookup name="item">GtkListItem</lookup>
-          </closure>
-        </binding>
-        <binding name="tooltip-text">
-          <closure type="gchararray" function="column_view_get_tooltip_text">
-            <lookup name="item">GtkListItem</lookup>
-          </closure>
+      <object class="GtkFileChooserCell">
+        <binding name="position">
+          <lookup name="position">GtkListItem</lookup>
         </binding>
+        <child>
+          <object class="GtkLabel">
+            <property name="hexpand">1</property>
+            <property name="xalign">0</property>
+            <binding name="label">
+              <closure type="gchararray" function="column_view_get_size">
+                <lookup name="item">GtkListItem</lookup>
+              </closure>
+            </binding>
+            <binding name="tooltip-text">
+              <closure type="gchararray" function="column_view_get_tooltip_text">
+                <lookup name="item">GtkListItem</lookup>
+              </closure>
+            </binding>
+          </object>
+        </child>
       </object>
     </property>
   </template>
@@ -288,19 +296,26 @@
 <interface>
   <template class="GtkListItem">
     <property name="child">
-      <object class="GtkLabel">
-        <property name="hexpand">1</property>
-        <property name="xalign">0</property>
-        <binding name="label">
-          <closure type="gchararray" function="column_view_get_file_type">
-            <lookup name="item">GtkListItem</lookup>
-          </closure>
-        </binding>
-        <binding name="tooltip-text">
-          <closure type="gchararray" function="column_view_get_tooltip_text">
-            <lookup name="item">GtkListItem</lookup>
-          </closure>
+      <object class="GtkFileChooserCell">
+        <binding name="position">
+          <lookup name="position">GtkListItem</lookup>
         </binding>
+        <child>
+          <object class="GtkLabel">
+            <property name="hexpand">1</property>
+            <property name="xalign">0</property>
+            <binding name="label">
+              <closure type="gchararray" function="column_view_get_file_type">
+                <lookup name="item">GtkListItem</lookup>
+              </closure>
+            </binding>
+            <binding name="tooltip-text">
+              <closure type="gchararray" function="column_view_get_tooltip_text">
+                <lookup name="item">GtkListItem</lookup>
+              </closure>
+            </binding>
+          </object>
+        </child>
       </object>
     </property>
   </template>
@@ -321,32 +336,39 @@
 <interface>
   <template class="GtkListItem">
     <property name="child">
-      <object class="GtkBox">
-        <property name="spacing">6</property>
-        <binding name="tooltip-text">
-          <closure type="gchararray" function="column_view_get_tooltip_text">
-            <lookup name="item">GtkListItem</lookup>
-          </closure>
+      <object class="GtkFileChooserCell">
+        <binding name="position">
+          <lookup name="position">GtkListItem</lookup>
         </binding>
         <child>
-          <object class="GtkLabel">
-            <binding name="label">
-              <closure type="gchararray" function="column_view_get_file_date">
-                <lookup name="item">GtkListItem</lookup>
-              </closure>
-            </binding>
-          </object>
-        </child>
-        <child>
-          <object class="GtkLabel">
-            <binding name="visible">
-              <closure type="gboolean" function="column_view_get_time_visible" />
-            </binding>
-            <binding name="label">
-              <closure type="gchararray" function="column_view_get_file_time">
+          <object class="GtkBox">
+            <property name="spacing">6</property>
+            <binding name="tooltip-text">
+              <closure type="gchararray" function="column_view_get_tooltip_text">
                 <lookup name="item">GtkListItem</lookup>
               </closure>
             </binding>
+            <child>
+              <object class="GtkLabel">
+                <binding name="label">
+                  <closure type="gchararray" function="column_view_get_file_date">
+                    <lookup name="item">GtkListItem</lookup>
+                  </closure>
+                </binding>
+              </object>
+            </child>
+            <child>
+              <object class="GtkLabel">
+                <binding name="visible">
+                  <closure type="gboolean" function="column_view_get_time_visible" />
+                </binding>
+                <binding name="label">
+                  <closure type="gchararray" function="column_view_get_file_time">
+                    <lookup name="item">GtkListItem</lookup>
+                  </closure>
+                </binding>
+              </object>
+            </child>
           </object>
         </child>
       </object>


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