[epiphany] Use GtkFileChooserNative for open/save dialogs



commit 26ca8c658fa4b3ad9bc6077952a607d46c9b8cc7
Author: Adrian Perez de Castro <aperez igalia com>
Date:   Sun Mar 12 17:27:17 2017 +0200

    Use GtkFileChooserNative for open/save dialogs
    
    This fixes bug #779922, making Epiphany a better citizen in the world of
    sanboxed applications, and potentially when running under non-GNOME DEs
    as well.
    
    The ephy_file_chooser_new() function is turned into an utility function
    which instantiates a GtkFileChooserNative under the hood, returning it
    as a GtkFileChooser* to keep most of the rest of the Epiphany code
    unchanged, saving for:
    
    - Calls are changed to gtk_native_dialog_* where appropriate.
    
    - The preview widget is gone, as it is not supported by native dialogs.
    
    - All the calls to ephy_file_chooser_new() pass in a valid parent
      GtkWindow, so the code that handled NULL parents is gone.

 lib/widgets/ephy-file-chooser.c |  138 ++++++++------------------------------
 lib/widgets/ephy-file-chooser.h |   23 ++-----
 src/popup-commands.c            |   22 +++---
 src/prefs-dialog.c              |   14 +---
 src/window-commands.c           |   34 +++++-----
 5 files changed, 65 insertions(+), 166 deletions(-)
---
diff --git a/lib/widgets/ephy-file-chooser.c b/lib/widgets/ephy-file-chooser.c
index 5016800..aeec06d 100644
--- a/lib/widgets/ephy-file-chooser.c
+++ b/lib/widgets/ephy-file-chooser.c
@@ -2,6 +2,7 @@
 /*
  *  Copyright © 2003 Marco Pesenti Gritti
  *  Copyright © 2003, 2004 Christian Persch
+ *  Copyright © 2017 Igalia S.L.
  *
  *  This file is part of Epiphany.
  *
@@ -31,40 +32,11 @@
 #include <gtk/gtk.h>
 #include <glib/gi18n.h>
 
-static void ephy_file_chooser_image_preview (GtkFileChooser *file_chooser,
-                                             gpointer        user_data);
 
-#define PREVIEW_WIDTH 150
-#define PREVIEW_HEIGHT 150
-
-struct _EphyFileChooser {
-  GtkFileChooserDialog parent_instance;
-};
-
-G_DEFINE_TYPE (EphyFileChooser, ephy_file_chooser, GTK_TYPE_FILE_CHOOSER_DIALOG)
-
-static void
-ephy_file_chooser_init (EphyFileChooser *dialog)
-{
-}
-
-static void
-ephy_file_chooser_constructed (GObject *object)
-
-{
-  char *downloads_dir;
-
-  G_OBJECT_CLASS (ephy_file_chooser_parent_class)->constructed (object);
-
-  downloads_dir = ephy_file_get_downloads_dir ();
-  gtk_file_chooser_add_shortcut_folder (GTK_FILE_CHOOSER (object), downloads_dir, NULL);
-  g_free (downloads_dir);
-}
-
-GtkFileFilter *
-ephy_file_chooser_add_pattern_filter (EphyFileChooser *dialog,
-                                      const char      *title,
-                                      const char      *first_pattern,
+static GtkFileFilter *
+ephy_file_chooser_add_pattern_filter (GtkFileChooser *dialog,
+                                      const char     *title,
+                                      const char     *first_pattern,
                                       ...)
 {
   GtkFileFilter *filth;
@@ -89,10 +61,10 @@ ephy_file_chooser_add_pattern_filter (EphyFileChooser *dialog,
   return filth;
 }
 
-GtkFileFilter *
-ephy_file_chooser_add_mime_filter (EphyFileChooser *dialog,
-                                   const char      *title,
-                                   const char      *first_mimetype,
+static GtkFileFilter *
+ephy_file_chooser_add_mime_filter (GtkFileChooser *dialog,
+                                   const char     *title,
+                                   const char     *first_mimetype,
                                    ...)
 {
   GtkFileFilter *filth;
@@ -117,81 +89,38 @@ ephy_file_chooser_add_mime_filter (EphyFileChooser *dialog,
   return filth;
 }
 
-static void
-ephy_file_chooser_class_init (EphyFileChooserClass *klass)
-{
-  GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
-  object_class->constructed = ephy_file_chooser_constructed;
-}
-
-static void
-ephy_file_chooser_image_preview (GtkFileChooser *file_chooser,
-                                 gpointer        user_data)
+GtkFileChooser *
+ephy_create_file_chooser (const char           *title,
+                          GtkWidget            *parent,
+                          GtkFileChooserAction  action,
+                          EphyFileFilterDefault default_filter)
 {
-  char *filename;
-  GtkWidget *preview;
-  GdkPixbuf *pixbuf;
-  gboolean have_preview;
-
-  pixbuf = NULL;
-  preview = GTK_WIDGET (user_data);
-  filename = gtk_file_chooser_get_preview_filename (file_chooser);
-
-  if (filename)
-    pixbuf = gdk_pixbuf_new_from_file_at_size (filename,
-                                               PREVIEW_WIDTH, PREVIEW_HEIGHT, NULL);
-  g_free (filename);
-
-  have_preview = (pixbuf != NULL);
-  gtk_image_set_from_pixbuf (GTK_IMAGE (preview), pixbuf);
-
-  if (pixbuf)
-    g_object_unref (pixbuf);
-
-  gtk_file_chooser_set_preview_widget_active (file_chooser, have_preview);
-}
-
-EphyFileChooser *
-ephy_file_chooser_new (const char           *title,
-                       GtkWidget            *parent,
-                       GtkFileChooserAction  action,
-                       EphyFileFilterDefault default_filter)
-{
-  EphyFileChooser *dialog;
+  GtkFileChooser *dialog;
   GtkFileFilter *filter[EPHY_FILE_FILTER_LAST];
-  GtkWidget *preview;
+  char *downloads_dir;
 
+  g_return_val_if_fail (GTK_IS_WINDOW (parent), NULL);
   g_return_val_if_fail (default_filter >= 0 && default_filter <= EPHY_FILE_FILTER_LAST, NULL);
 
-  dialog = EPHY_FILE_CHOOSER (g_object_new (EPHY_TYPE_FILE_CHOOSER,
-                                            "title", title,
-                                            "action", action,
-                                            NULL));
+  dialog = GTK_FILE_CHOOSER (gtk_file_chooser_native_new (title,
+                                                          GTK_WINDOW (parent),
+                                                          action,
+                                                          NULL,
+                                                          _("_Cancel")));
+  gtk_native_dialog_set_modal (GTK_NATIVE_DIALOG (dialog), TRUE);
+
+  downloads_dir = ephy_file_get_downloads_dir ();
+  gtk_file_chooser_add_shortcut_folder (dialog, downloads_dir, NULL);
+  g_free (downloads_dir);
 
   if (action == GTK_FILE_CHOOSER_ACTION_OPEN ||
       action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER ||
       action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER) {
-    gtk_dialog_add_buttons (GTK_DIALOG (dialog),
-                            _("_Cancel"), GTK_RESPONSE_CANCEL,
-                            _("_Open"), GTK_RESPONSE_ACCEPT,
-                            NULL);
-    gtk_dialog_set_default_response (GTK_DIALOG (dialog),
-                                     GTK_RESPONSE_ACCEPT);
+    gtk_file_chooser_native_set_accept_label (GTK_FILE_CHOOSER_NATIVE (dialog), _("_Open"));
   } else if (action == GTK_FILE_CHOOSER_ACTION_SAVE) {
-    gtk_dialog_add_buttons (GTK_DIALOG (dialog),
-                            _("_Cancel"), GTK_RESPONSE_CANCEL,
-                            _("_Save"), GTK_RESPONSE_ACCEPT,
-                            NULL);
-    gtk_dialog_set_default_response (GTK_DIALOG (dialog),
-                                     GTK_RESPONSE_ACCEPT);
+    gtk_file_chooser_native_set_accept_label (GTK_FILE_CHOOSER_NATIVE (dialog), _("_Save"));
   }
 
-  preview = gtk_image_new ();
-  gtk_file_chooser_set_preview_widget (GTK_FILE_CHOOSER (dialog), preview);
-  gtk_file_chooser_set_preview_widget_active (GTK_FILE_CHOOSER (dialog), FALSE);
-  g_signal_connect (dialog, "update-preview", G_CALLBACK (ephy_file_chooser_image_preview), preview);
-
   if (default_filter != EPHY_FILE_FILTER_NONE) {
     filter[EPHY_FILE_FILTER_ALL_SUPPORTED] =
       ephy_file_chooser_add_mime_filter
@@ -237,14 +166,5 @@ ephy_file_chooser_new (const char           *title,
                                  filter[default_filter]);
   }
 
-  if (parent != NULL) {
-    gtk_window_set_transient_for (GTK_WINDOW (dialog),
-                                  GTK_WINDOW (parent));
-    gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
-    gtk_window_group_add_window (ephy_gui_ensure_window_group (GTK_WINDOW (parent)),
-                                 GTK_WINDOW (dialog));
-    gtk_window_set_destroy_with_parent (GTK_WINDOW (dialog), TRUE);
-  }
-
   return dialog;
 }
diff --git a/lib/widgets/ephy-file-chooser.h b/lib/widgets/ephy-file-chooser.h
index 6738d53..9621b02 100644
--- a/lib/widgets/ephy-file-chooser.h
+++ b/lib/widgets/ephy-file-chooser.h
@@ -1,6 +1,7 @@
 /* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /*
  *  Copyright © 2003, 2004 Christian Persch
+ *  Copyright © 2017 Igalia S.L.
  *  
  *  This file is part of Epiphany.
  *
@@ -26,10 +27,6 @@
 
 G_BEGIN_DECLS
 
-#define EPHY_TYPE_FILE_CHOOSER (ephy_file_chooser_get_type ())
-
-G_DECLARE_FINAL_TYPE (EphyFileChooser, ephy_file_chooser, EPHY, FILE_CHOOSER, GtkFileChooserDialog)
-
 typedef enum
 {
         EPHY_FILE_FILTER_ALL_SUPPORTED,
@@ -40,19 +37,9 @@ typedef enum
         EPHY_FILE_FILTER_LAST = EPHY_FILE_FILTER_NONE
 } EphyFileFilterDefault;
 
-EphyFileChooser        *ephy_file_chooser_new              (const char *title,
-                                                            GtkWidget *parent,
-                                                            GtkFileChooserAction action,
-                                                            EphyFileFilterDefault default_filter);
-
-GtkFileFilter        *ephy_file_chooser_add_pattern_filter (EphyFileChooser *dialog,
-                                                            const char *title,
-                                                            const char *first_pattern,
-                                                            ...);
-
-GtkFileFilter        *ephy_file_chooser_add_mime_filter    (EphyFileChooser *dialog,
-                                                            const char *title,
-                                                            const char *first_mimetype,
-                                                            ...);
+GtkFileChooser *ephy_create_file_chooser (const char *title,
+                                          GtkWidget *parent,
+                                          GtkFileChooserAction action,
+                                          EphyFileFilterDefault default_filter);
 
 G_END_DECLS
diff --git a/src/popup-commands.c b/src/popup-commands.c
index ac11513..ad8304a 100644
--- a/src/popup-commands.c
+++ b/src/popup-commands.c
@@ -1,6 +1,7 @@
 /* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /*
  *  Copyright © 2000-2003 Marco Pesenti Gritti
+ *  Copyright © 2017 Igalia S.L.
  *
  *  This file is part of Epiphany.
  *
@@ -154,25 +155,24 @@ filename_suggested_cb (EphyDownload        *download,
                        const char          *suggested_filename,
                        SavePropertyURLData *data)
 {
-  EphyFileChooser *dialog;
+  GtkFileChooser *dialog;
   char *sanitized_filename;
 
-  dialog = ephy_file_chooser_new (data->title,
-                                  GTK_WIDGET (data->window),
-                                  GTK_FILE_CHOOSER_ACTION_SAVE,
-                                  EPHY_FILE_FILTER_NONE);
-  gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
-  gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dialog), TRUE);
+  dialog = ephy_create_file_chooser (data->title,
+                                     GTK_WIDGET (data->window),
+                                     GTK_FILE_CHOOSER_ACTION_SAVE,
+                                     EPHY_FILE_FILTER_NONE);
+  gtk_file_chooser_set_do_overwrite_confirmation (dialog, TRUE);
 
   sanitized_filename = ephy_sanitize_filename (g_strdup (suggested_filename));
-  gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog), sanitized_filename);
+  gtk_file_chooser_set_current_name (dialog, sanitized_filename);
   g_free (sanitized_filename);
 
-  if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) {
+  if (gtk_native_dialog_run (GTK_NATIVE_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) {
     char *uri;
     WebKitDownload *webkit_download;
 
-    uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (dialog));
+    uri = gtk_file_chooser_get_uri (dialog);
     ephy_download_set_destination_uri (download, uri);
     g_free (uri);
 
@@ -188,7 +188,7 @@ filename_suggested_cb (EphyDownload        *download,
                      g_object_unref);
   }
 
-  gtk_widget_destroy (GTK_WIDGET (dialog));
+  g_object_unref (dialog);
   g_free (data->title);
   g_object_unref (data->window);
   g_free (data);
diff --git a/src/prefs-dialog.c b/src/prefs-dialog.c
index 1cd610a..b74beb8 100644
--- a/src/prefs-dialog.c
+++ b/src/prefs-dialog.c
@@ -2,7 +2,7 @@
 /*
  *  Copyright © 200-2003 Marco Pesenti Gritti
  *  Copyright © 2003, 2004, 2005 Christian Persch
- *  Copyright © 2010 Igalia S.L.
+ *  Copyright © 2010, 2017 Igalia S.L.
  *
  *  This file is part of Epiphany.
  *
@@ -1194,21 +1194,13 @@ static void
 create_download_path_button (PrefsDialog *dialog)
 {
   GtkWidget *button;
-  EphyFileChooser *fc;
   char *dir;
 
   dir = ephy_file_get_downloads_dir ();
 
-  fc = ephy_file_chooser_new (_("Select a Directory"),
-                              GTK_WIDGET (dialog),
-                              GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
-                              EPHY_FILE_FILTER_NONE);
+  button = gtk_file_chooser_button_new (_("Select a Directory"),
+                                        GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER);
 
-  /* Unset the destroy-with-parent, since gtkfilechooserbutton doesn't
-   * expect this */
-  gtk_window_set_destroy_with_parent (GTK_WINDOW (fc), FALSE);
-
-  button = gtk_file_chooser_button_new_with_dialog (GTK_WIDGET (fc));
   gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (button), dir);
   gtk_file_chooser_button_set_width_chars (GTK_FILE_CHOOSER_BUTTON (button),
                                            DOWNLOAD_BUTTON_WIDTH);
diff --git a/src/window-commands.c b/src/window-commands.c
index 4eccd96..073c12e 100644
--- a/src/window-commands.c
+++ b/src/window-commands.c
@@ -2,8 +2,8 @@
 /*
  *  Copyright © 2000-2004 Marco Pesenti Gritti
  *  Copyright © 2009 Collabora Ltd.
- *  Copyright © 2011 Igalia S.L.
  *  Copyright © 2016 Iulian-Gabriel Radu
+ *  Copyright © 2011, 2017 Igalia S.L.
  *
  *  This file is part of Epiphany.
  *
@@ -871,7 +871,7 @@ window_cmd_new_tab (GSimpleAction *action,
 }
 
 static void
-open_response_cb (GtkDialog *dialog, int response, EphyWindow *window)
+open_response_cb (GtkNativeDialog *dialog, int response, EphyWindow *window)
 {
   if (response == GTK_RESPONSE_ACCEPT) {
     char *uri, *converted;
@@ -889,7 +889,7 @@ open_response_cb (GtkDialog *dialog, int response, EphyWindow *window)
     }
   }
 
-  gtk_widget_destroy (GTK_WIDGET (dialog));
+  g_object_unref (dialog);
 }
 
 void
@@ -898,17 +898,17 @@ window_cmd_open (GSimpleAction *action,
                  gpointer       user_data)
 {
   EphyWindow *window = user_data;
-  EphyFileChooser *dialog;
+  GtkFileChooser *dialog;
 
-  dialog = ephy_file_chooser_new (_("Open"),
-                                  GTK_WIDGET (window),
-                                  GTK_FILE_CHOOSER_ACTION_OPEN,
-                                  EPHY_FILE_FILTER_ALL_SUPPORTED);
+  dialog = ephy_create_file_chooser (_("Open"),
+                                     GTK_WIDGET (window),
+                                     GTK_FILE_CHOOSER_ACTION_OPEN,
+                                     EPHY_FILE_FILTER_ALL_SUPPORTED);
 
   g_signal_connect (dialog, "response",
                     G_CALLBACK (open_response_cb), window);
 
-  gtk_widget_show (GTK_WIDGET (dialog));
+  gtk_native_dialog_show (GTK_NATIVE_DIALOG (dialog));
 }
 
 typedef struct {
@@ -1458,7 +1458,7 @@ get_suggested_filename (EphyEmbed *embed)
 }
 
 static void
-save_response_cb (GtkDialog *dialog, int response, EphyEmbed *embed)
+save_response_cb (GtkNativeDialog *dialog, int response, EphyEmbed *embed)
 {
   if (response == GTK_RESPONSE_ACCEPT) {
     char *uri, *converted;
@@ -1477,7 +1477,7 @@ save_response_cb (GtkDialog *dialog, int response, EphyEmbed *embed)
     }
   }
 
-  gtk_widget_destroy (GTK_WIDGET (dialog));
+  g_object_unref (dialog);
 }
 
 void
@@ -1487,16 +1487,16 @@ window_cmd_save_as (GSimpleAction *action,
 {
   EphyWindow *window = user_data;
   EphyEmbed *embed;
-  EphyFileChooser *dialog;
+  GtkFileChooser *dialog;
   char *suggested_filename;
 
   embed = ephy_embed_container_get_active_child (EPHY_EMBED_CONTAINER (window));
   g_return_if_fail (embed != NULL);
 
-  dialog = ephy_file_chooser_new (_("Save"),
-                                  GTK_WIDGET (window),
-                                  GTK_FILE_CHOOSER_ACTION_SAVE,
-                                  EPHY_FILE_FILTER_NONE);
+  dialog = ephy_create_file_chooser (_("Save"),
+                                     GTK_WIDGET (window),
+                                     GTK_FILE_CHOOSER_ACTION_SAVE,
+                                     EPHY_FILE_FILTER_NONE);
 
   gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dialog), TRUE);
 
@@ -1508,7 +1508,7 @@ window_cmd_save_as (GSimpleAction *action,
   g_signal_connect (dialog, "response",
                     G_CALLBACK (save_response_cb), embed);
 
-  gtk_widget_show (GTK_WIDGET (dialog));
+  gtk_native_dialog_show (GTK_NATIVE_DIALOG (dialog));
 }
 
 void


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