[evolution] I#165 - [Flatpak] Use GtkFileChooserNative for Flatpak portals support



commit 6cde71f954547bd05e36b08757b92735742f9da6
Author: Milan Crha <mcrha redhat com>
Date:   Fri Nov 30 12:25:02 2018 +0100

    I#165 - [Flatpak] Use GtkFileChooserNative for Flatpak portals support
    
    Closes https://gitlab.gnome.org/GNOME/evolution/issues/165

 src/addressbook/addressbook.error.xml              |   5 +
 .../gui/contact-editor/e-contact-editor.c          | 143 +++++----
 src/composer/e-composer-actions.c                  |  42 +--
 src/e-util/e-attachment-store.c                    | 335 +++++++++++----------
 src/e-util/e-category-editor.c                     | 119 +++++---
 src/e-util/e-html-editor-actions.c                 |  88 ++++--
 src/e-util/e-html-editor-cell-dialog.c             |  19 +-
 src/e-util/e-html-editor-image-dialog.c            |  21 +-
 src/e-util/e-html-editor-table-dialog.c            |  22 +-
 src/e-util/e-web-view.c                            |  16 +-
 src/e-util/test-html-editor.c                      |  20 +-
 .../backup-restore/evolution-backup-restore.c      |   8 +-
 src/plugins/face/face.c                            |  36 ++-
 src/plugins/save-calendar/save-calendar.c          |  31 +-
 src/shell/e-shell-utils.c                          |  50 ++-
 src/shell/e-shell-utils.h                          |   7 +-
 src/smime/gui/certificate-manager.c                |  90 +++---
 17 files changed, 586 insertions(+), 466 deletions(-)
---
diff --git a/src/addressbook/addressbook.error.xml b/src/addressbook/addressbook.error.xml
index 4b1872f950..f0a2ac17be 100644
--- a/src/addressbook/addressbook.error.xml
+++ b/src/addressbook/addressbook.error.xml
@@ -146,4 +146,9 @@
     <secondary>{0}</secondary>
   </error>
 
+  <error id="ask-unset-image" type="question" default="GTK_RESPONSE_CANCEL">
+    <_primary>Do you want to unset contact image?</_primary>
+    <button _label="Do _Not Unset" response="GTK_RESPONSE_CANCEL"/>
+    <button _label="_Unset" response="GTK_RESPONSE_ACCEPT"/>
+  </error>
 </error-list>
diff --git a/src/addressbook/gui/contact-editor/e-contact-editor.c 
b/src/addressbook/gui/contact-editor/e-contact-editor.c
index f506bd514d..f378bb0ad1 100644
--- a/src/addressbook/gui/contact-editor/e-contact-editor.c
+++ b/src/addressbook/gui/contact-editor/e-contact-editor.c
@@ -200,7 +200,8 @@ struct _EContactEditorPrivate
        GtkBuilder *builder;
        GtkWidget *app;
 
-       GtkWidget *file_selector;
+       GtkWidget *image_selector;
+       GtkFileChooserNative *image_selector_native;
 
        EContactName *name;
 
@@ -3257,7 +3258,7 @@ cert_load_for_kind (EContactEditor *editor,
 {
        EContactCert *cert = NULL;
        GtkWindow *parent;
-       GtkWidget *dialog;
+       GtkFileChooserNative *native;
        GtkFileChooser *file_chooser;
        GError *error = NULL;
 
@@ -3265,21 +3266,18 @@ cert_load_for_kind (EContactEditor *editor,
        g_return_val_if_fail (kind == CERT_KIND_PGP || kind == CERT_KIND_X509, NULL);
 
        parent = eab_editor_get_window (EAB_EDITOR (editor));
-       dialog = gtk_file_chooser_dialog_new (
+       native = gtk_file_chooser_native_new (
                kind == CERT_KIND_PGP ? _("Open PGP key") : _("Open X.509 certificate"), parent,
                GTK_FILE_CHOOSER_ACTION_OPEN,
-               _("_Cancel"), GTK_RESPONSE_CANCEL,
-               _("_Open"), GTK_RESPONSE_OK,
-               NULL);
+               _("_Open"), _("_Cancel"));
 
-       file_chooser = GTK_FILE_CHOOSER (dialog);
+       file_chooser = GTK_FILE_CHOOSER (native);
        gtk_file_chooser_set_local_only (file_chooser, TRUE);
        gtk_file_chooser_set_select_multiple (file_chooser, FALSE);
-       gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
 
        cert_add_filters_for_kind (file_chooser, kind);
 
-       if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK) {
+       if (gtk_native_dialog_run (GTK_NATIVE_DIALOG (native)) == GTK_RESPONSE_ACCEPT) {
                gchar *filename;
                gchar *content = NULL;
                gsize length = 0;
@@ -3296,7 +3294,7 @@ cert_load_for_kind (EContactEditor *editor,
                g_free (filename);
        }
 
-       gtk_widget_destroy (dialog);
+       g_object_unref (native);
 
        if (error) {
                e_notice (parent, GTK_MESSAGE_ERROR, _("Failed to load certificate: %s"), error->message);
@@ -3477,7 +3475,7 @@ cert_save_btn_clicked_cb (GtkWidget *button,
        EContactCert *cert = NULL;
        gint kind = -1;
        GtkWindow *parent;
-       GtkWidget *dialog;
+       GtkFileChooserNative *native;
        GtkFileChooser *file_chooser;
        GError *error = NULL;
 
@@ -3498,21 +3496,18 @@ cert_save_btn_clicked_cb (GtkWidget *button,
        g_return_if_fail (cert != NULL);
 
        parent = eab_editor_get_window (EAB_EDITOR (editor));
-       dialog = gtk_file_chooser_dialog_new (
+       native = gtk_file_chooser_native_new (
                kind == CERT_KIND_PGP ? _("Save PGP key") : _("Save X.509 certificate"), parent,
                GTK_FILE_CHOOSER_ACTION_SAVE,
-               _("_Cancel"), GTK_RESPONSE_CANCEL,
-               _("_Save"), GTK_RESPONSE_OK,
-               NULL);
+               _("_Save"), _("_Cancel"));
 
-       file_chooser = GTK_FILE_CHOOSER (dialog);
+       file_chooser = GTK_FILE_CHOOSER (native);
        gtk_file_chooser_set_local_only (file_chooser, TRUE);
        gtk_file_chooser_set_select_multiple (file_chooser, FALSE);
-       gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
 
        cert_add_filters_for_kind (file_chooser, kind);
 
-       if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK) {
+       if (gtk_native_dialog_run (GTK_NATIVE_DIALOG (native)) == GTK_RESPONSE_ACCEPT) {
                gchar *filename;
 
                filename = gtk_file_chooser_get_filename (file_chooser);
@@ -3525,7 +3520,7 @@ cert_save_btn_clicked_cb (GtkWidget *button,
                g_free (filename);
        }
 
-       gtk_widget_destroy (dialog);
+       g_object_unref (native);
        e_contact_cert_free (cert);
 
        if (error) {
@@ -4208,8 +4203,10 @@ image_selected (EContactEditor *editor)
        gchar     *file_name;
        GtkWidget *image_chooser;
 
-       file_name = gtk_file_chooser_get_filename (
-               GTK_FILE_CHOOSER (editor->priv->file_selector));
+       if (editor->priv->image_selector)
+               file_name = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (editor->priv->image_selector));
+       else
+               file_name = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER 
(editor->priv->image_selector_native));
 
        if (!file_name)
                return;
@@ -4263,8 +4260,18 @@ file_chooser_response (GtkWidget *widget,
                image_selected (editor);
        else if (response == GTK_RESPONSE_NO)
                image_cleared (editor);
+       else if (editor->priv->image_selector_native &&
+                editor->priv->image_set) {
+               /* It doesn't support custom buttons, thus ask separately, which is a pita */
+               if (e_alert_run_dialog_for_args (GTK_WINDOW (editor->priv->app),
+                       "addressbook:ask-unset-image", NULL) == GTK_RESPONSE_ACCEPT)
+                       image_cleared (editor);
+       }
 
-       gtk_widget_hide (editor->priv->file_selector);
+       if (editor->priv->image_selector)
+               gtk_widget_hide (editor->priv->image_selector);
+       else
+               g_clear_object (&editor->priv->image_selector_native);
 }
 
 static gboolean
@@ -4310,51 +4317,69 @@ static void
 image_clicked (GtkWidget *button,
                EContactEditor *editor)
 {
-       if (!editor->priv->file_selector) {
+       if (!editor->priv->image_selector && !editor->priv->image_selector_native) {
                GtkImage *preview;
                GtkFileFilter *filter;
 
-               editor->priv->file_selector = gtk_file_chooser_dialog_new (
-                       _("Please select an image for this contact"),
-                       GTK_WINDOW (editor->priv->app),
-                       GTK_FILE_CHOOSER_ACTION_OPEN,
-                       _("_Cancel"), GTK_RESPONSE_CANCEL,
-                       _("_Open"), GTK_RESPONSE_ACCEPT,
-                       _("_No image"), GTK_RESPONSE_NO,
-                       NULL);
+               if (e_util_is_running_flatpak ()) {
+                       editor->priv->image_selector_native = gtk_file_chooser_native_new (
+                               _("Please select an image for this contact"),
+                               GTK_WINDOW (editor->priv->app),
+                               GTK_FILE_CHOOSER_ACTION_OPEN,
+                               _("_Open"), _("_Cancel"));
+               } else {
+                       editor->priv->image_selector = gtk_file_chooser_dialog_new (
+                               _("Please select an image for this contact"),
+                               GTK_WINDOW (editor->priv->app),
+                               GTK_FILE_CHOOSER_ACTION_OPEN,
+                               _("_Cancel"), GTK_RESPONSE_CANCEL,
+                               _("_Open"), GTK_RESPONSE_ACCEPT,
+                               _("_No image"), GTK_RESPONSE_NO,
+                               NULL);
+               }
 
                filter = gtk_file_filter_new ();
                gtk_file_filter_add_mime_type (filter, "image/*");
                gtk_file_chooser_set_filter (
-                       GTK_FILE_CHOOSER (editor->priv->file_selector),
+                       editor->priv->image_selector ? GTK_FILE_CHOOSER (editor->priv->image_selector) : 
GTK_FILE_CHOOSER (editor->priv->image_selector_native),
                        filter);
 
-               preview = GTK_IMAGE (gtk_image_new ());
-               gtk_file_chooser_set_preview_widget (
-                       GTK_FILE_CHOOSER (editor->priv->file_selector),
-                       GTK_WIDGET (preview));
-               g_signal_connect (
-                       editor->priv->file_selector, "update-preview",
-                       G_CALLBACK (update_preview_cb), preview);
-
-               gtk_dialog_set_default_response (
-                       GTK_DIALOG (editor->priv->file_selector),
-                       GTK_RESPONSE_ACCEPT);
-
-               g_signal_connect (
-                       editor->priv->file_selector, "response",
-                       G_CALLBACK (file_chooser_response), editor);
-
-               g_signal_connect_after (
-                       editor->priv->file_selector, "delete-event",
-                       G_CALLBACK (file_selector_deleted),
-                       editor->priv->file_selector);
+               if (editor->priv->image_selector) {
+                       preview = GTK_IMAGE (gtk_image_new ());
+                       gtk_file_chooser_set_preview_widget (
+                               GTK_FILE_CHOOSER (editor->priv->image_selector),
+                               GTK_WIDGET (preview));
+                       g_signal_connect (
+                               editor->priv->image_selector, "update-preview",
+                               G_CALLBACK (update_preview_cb), preview);
+
+                       gtk_dialog_set_default_response (
+                               GTK_DIALOG (editor->priv->image_selector),
+                               GTK_RESPONSE_ACCEPT);
+
+                       g_signal_connect (
+                               editor->priv->image_selector, "response",
+                               G_CALLBACK (file_chooser_response), editor);
+
+                       g_signal_connect_after (
+                               editor->priv->image_selector, "delete-event",
+                               G_CALLBACK (file_selector_deleted),
+                               editor->priv->image_selector);
+               } else {
+                       g_signal_connect (
+                               editor->priv->image_selector_native, "response",
+                               G_CALLBACK (file_chooser_response), editor);
+               }
        }
 
        /* Display the dialog */
-
-       gtk_window_set_modal (GTK_WINDOW (editor->priv->file_selector), TRUE);
-       gtk_window_present (GTK_WINDOW (editor->priv->file_selector));
+       if (editor->priv->image_selector) {
+               gtk_window_set_modal (GTK_WINDOW (editor->priv->image_selector), TRUE);
+               gtk_window_present (GTK_WINDOW (editor->priv->image_selector));
+       } else {
+               gtk_native_dialog_set_modal (GTK_NATIVE_DIALOG (editor->priv->image_selector_native), TRUE);
+               gtk_native_dialog_show (GTK_NATIVE_DIALOG (editor->priv->image_selector_native));
+       }
 }
 
 typedef struct {
@@ -5173,11 +5198,13 @@ e_contact_editor_dispose (GObject *object)
 {
        EContactEditor *e_contact_editor = E_CONTACT_EDITOR (object);
 
-       if (e_contact_editor->priv->file_selector != NULL) {
-               gtk_widget_destroy (e_contact_editor->priv->file_selector);
-               e_contact_editor->priv->file_selector = NULL;
+       if (e_contact_editor->priv->image_selector) {
+               gtk_widget_destroy (e_contact_editor->priv->image_selector);
+               e_contact_editor->priv->image_selector = NULL;
        }
 
+       g_clear_object (&e_contact_editor->priv->image_selector_native);
+
        g_slist_free_full (
                e_contact_editor->priv->writable_fields,
                (GDestroyNotify) g_free);
diff --git a/src/composer/e-composer-actions.c b/src/composer/e-composer-actions.c
index d305c6f5d6..9ac976d98c 100644
--- a/src/composer/e-composer-actions.c
+++ b/src/composer/e-composer-actions.c
@@ -219,41 +219,31 @@ action_save_as_cb (GtkAction *action,
                    EMsgComposer *composer)
 {
        EHTMLEditor *editor;
-       GtkWidget *dialog;
+       GtkFileChooserNative *native;
        gchar *filename;
-       gint response;
 
-       dialog = gtk_file_chooser_dialog_new (
+       native = gtk_file_chooser_native_new (
                _("Save as..."), GTK_WINDOW (composer),
                GTK_FILE_CHOOSER_ACTION_SAVE,
-               _("_Cancel"), GTK_RESPONSE_CANCEL,
-               _("_Save"), GTK_RESPONSE_OK,
-               NULL);
+               _("_Save"), _("_Cancel"));
 
-       gtk_dialog_set_default_response (
-               GTK_DIALOG (dialog), GTK_RESPONSE_OK);
-       gtk_file_chooser_set_local_only (
-               GTK_FILE_CHOOSER (dialog), FALSE);
-       gtk_window_set_icon_name (
-               GTK_WINDOW (dialog), "mail-message-new");
+       gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (native), FALSE);
+       if (GTK_IS_WINDOW (native))
+               gtk_window_set_icon_name (GTK_WINDOW (native), "mail-message-new");
 
-       e_util_load_file_chooser_folder (GTK_FILE_CHOOSER (dialog));
-       response = gtk_dialog_run (GTK_DIALOG (dialog));
+       e_util_load_file_chooser_folder (GTK_FILE_CHOOSER (native));
+       if (gtk_native_dialog_run (GTK_NATIVE_DIALOG (native)) == GTK_RESPONSE_ACCEPT) {
+               e_util_save_file_chooser_folder (GTK_FILE_CHOOSER (native));
 
-       if (response != GTK_RESPONSE_OK)
-               goto exit;
+               editor = e_msg_composer_get_editor (composer);
+               filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (native));
+               e_html_editor_set_filename (editor, filename);
+               g_free (filename);
 
-       e_util_save_file_chooser_folder (GTK_FILE_CHOOSER (dialog));
-
-       editor = e_msg_composer_get_editor (composer);
-       filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
-       e_html_editor_set_filename (editor, filename);
-       g_free (filename);
-
-       gtk_action_activate (ACTION (SAVE));
+               gtk_action_activate (ACTION (SAVE));
+       }
 
-exit:
-       gtk_widget_destroy (dialog);
+       g_object_unref (native);
 }
 
 static void
diff --git a/src/e-util/e-attachment-store.c b/src/e-util/e-attachment-store.c
index 226cbb503c..004ed9c75d 100644
--- a/src/e-util/e-attachment-store.c
+++ b/src/e-util/e-attachment-store.c
@@ -624,30 +624,24 @@ e_attachment_store_run_load_dialog (EAttachmentStore *store,
                                     GtkWindow *parent)
 {
        GtkFileChooser *file_chooser;
-       GtkWidget *dialog;
-
+       GtkWidget *dialog = NULL;
+       GtkFileChooserNative *native = NULL;
        GtkBox *extra_box;
        GtkWidget *extra_box_widget;
-       GtkWidget *option_display;
-
-#ifdef HAVE_AUTOAR
-       GtkBox *option_format_box;
-       GtkWidget *option_format_box_widget;
-       GtkWidget *option_format_label;
-       GtkWidget *option_format_combo;
-#endif
-
+       GtkWidget *option_display = NULL;
        GtkImage *preview;
-
        GSList *files, *iter;
        const gchar *disposition;
        gboolean active;
        gint response;
-
 #ifdef HAVE_AUTOAR
-       GSettings *settings;
-       char *format_string;
-       char *filter_string;
+       GtkBox *option_format_box;
+       GtkWidget *option_format_box_widget;
+       GtkWidget *option_format_label;
+       GtkWidget *option_format_combo;
+       GSettings *settings = NULL;
+       gchar *format_string = NULL;
+       gchar *filter_string = NULL;
        gint format;
        gint filter;
 #endif
@@ -655,110 +649,126 @@ e_attachment_store_run_load_dialog (EAttachmentStore *store,
        g_return_if_fail (E_IS_ATTACHMENT_STORE (store));
        g_return_if_fail (GTK_IS_WINDOW (parent));
 
-       dialog = gtk_file_chooser_dialog_new (
-               _("Add Attachment"), parent,
-               GTK_FILE_CHOOSER_ACTION_OPEN,
+       if (e_util_is_running_flatpak ()) {
+               native = gtk_file_chooser_native_new (
+                       _("Add Attachment"), parent,
+                       GTK_FILE_CHOOSER_ACTION_OPEN,
+                       _("A_ttach"), _("_Cancel"));
+
+               file_chooser = GTK_FILE_CHOOSER (native);
+       } else {
+               dialog = gtk_file_chooser_dialog_new (
+                       _("Add Attachment"), parent,
+                       GTK_FILE_CHOOSER_ACTION_OPEN,
 #ifdef HAVE_AUTOAR
-               _("_Open"), GTK_RESPONSE_OK,
+                       _("_Open"), GTK_RESPONSE_ACCEPT,
 #endif
-               _("_Cancel"), GTK_RESPONSE_CANCEL,
+                       _("_Cancel"), GTK_RESPONSE_CANCEL,
 #ifdef HAVE_AUTOAR
-               _("A_ttach"), GTK_RESPONSE_CLOSE,
+                       _("A_ttach"), GTK_RESPONSE_CLOSE,
 #else
-               _("A_ttach"), GTK_RESPONSE_OK,
+                       _("A_ttach"), GTK_RESPONSE_ACCEPT,
 #endif
-               NULL);
+                       NULL);
+
+               file_chooser = GTK_FILE_CHOOSER (dialog);
+       }
 
-       file_chooser = GTK_FILE_CHOOSER (dialog);
        gtk_file_chooser_set_local_only (file_chooser, FALSE);
        gtk_file_chooser_set_select_multiple (file_chooser, TRUE);
+
+       if (dialog) {
 #ifdef HAVE_AUTOAR
-       gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_CLOSE);
+               gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_CLOSE);
 #else
-       gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
+               gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT);
 #endif
-       gtk_window_set_icon_name (GTK_WINDOW (dialog), "mail-attachment");
+               gtk_window_set_icon_name (GTK_WINDOW (dialog), "mail-attachment");
 
-       preview = GTK_IMAGE (gtk_image_new ());
-       gtk_file_chooser_set_preview_widget (
-               GTK_FILE_CHOOSER (file_chooser),
-               GTK_WIDGET (preview));
-       g_signal_connect (
-               file_chooser, "update-preview",
-               G_CALLBACK (update_preview_cb), preview);
+               preview = GTK_IMAGE (gtk_image_new ());
+               gtk_file_chooser_set_preview_widget (file_chooser, GTK_WIDGET (preview));
+               g_signal_connect (
+                       file_chooser, "update-preview",
+                       G_CALLBACK (update_preview_cb), preview);
 
-       extra_box_widget = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
-       extra_box = GTK_BOX (extra_box_widget);
+               extra_box_widget = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
+               extra_box = GTK_BOX (extra_box_widget);
 
-       option_display = gtk_check_button_new_with_mnemonic (
-               _("_Suggest automatic display of attachment"));
-       gtk_box_pack_start (extra_box, option_display, FALSE, FALSE, 0);
+               option_display = gtk_check_button_new_with_mnemonic (
+                       _("_Suggest automatic display of attachment"));
+               gtk_box_pack_start (extra_box, option_display, FALSE, FALSE, 0);
 
 #ifdef HAVE_AUTOAR
-       option_format_box_widget = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
-       option_format_box = GTK_BOX (option_format_box_widget);
-       gtk_box_pack_start (extra_box, option_format_box_widget, FALSE, FALSE, 0);
+               option_format_box_widget = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
+               option_format_box = GTK_BOX (option_format_box_widget);
+               gtk_box_pack_start (extra_box, option_format_box_widget, FALSE, FALSE, 0);
 
-       settings = e_util_ref_settings ("org.gnome.evolution.shell");
+               settings = e_util_ref_settings ("org.gnome.evolution.shell");
 
-       format_string = g_settings_get_string (settings, "autoar-format");
-       filter_string = g_settings_get_string (settings, "autoar-filter");
+               format_string = g_settings_get_string (settings, "autoar-format");
+               filter_string = g_settings_get_string (settings, "autoar-filter");
 
-       if (!e_enum_from_string (AUTOAR_TYPE_FORMAT, format_string, &format)) {
-               format = AUTOAR_FORMAT_ZIP;
-       }
-       if (!e_enum_from_string (AUTOAR_TYPE_FILTER, filter_string, &filter)) {
-               filter = AUTOAR_FILTER_NONE;
-       }
+               if (!e_enum_from_string (AUTOAR_TYPE_FORMAT, format_string, &format)) {
+                       format = AUTOAR_FORMAT_ZIP;
+               }
+               if (!e_enum_from_string (AUTOAR_TYPE_FILTER, filter_string, &filter)) {
+                       filter = AUTOAR_FILTER_NONE;
+               }
 
-       option_format_label = gtk_label_new (
-               _("Archive selected directories using this format:"));
-       option_format_combo = autoar_gtk_chooser_simple_new (
-               format,
-               filter);
-       gtk_box_pack_start (option_format_box, option_format_label, FALSE, FALSE, 0);
-       gtk_box_pack_start (option_format_box, option_format_combo, FALSE, FALSE, 0);
+               option_format_label = gtk_label_new (
+                       _("Archive selected directories using this format:"));
+               option_format_combo = autoar_gtk_chooser_simple_new (
+                       format,
+                       filter);
+               gtk_box_pack_start (option_format_box, option_format_label, FALSE, FALSE, 0);
+               gtk_box_pack_start (option_format_box, option_format_combo, FALSE, FALSE, 0);
 #endif
 
-       gtk_file_chooser_set_extra_widget (file_chooser, extra_box_widget);
-       gtk_widget_show_all (extra_box_widget);
+               gtk_file_chooser_set_extra_widget (file_chooser, extra_box_widget);
+               gtk_widget_show_all (extra_box_widget);
+       }
 
        e_util_load_file_chooser_folder (file_chooser);
 
-       response = gtk_dialog_run (GTK_DIALOG (dialog));
+       if (dialog)
+               response = gtk_dialog_run (GTK_DIALOG (dialog));
+       else
+               response = gtk_native_dialog_run (GTK_NATIVE_DIALOG (native));
 
 #ifdef HAVE_AUTOAR
-       if (response != GTK_RESPONSE_OK && response != GTK_RESPONSE_CLOSE)
+       if (response != GTK_RESPONSE_ACCEPT && response != GTK_RESPONSE_CLOSE)
 #else
-       if (response != GTK_RESPONSE_OK)
+       if (response != GTK_RESPONSE_ACCEPT)
 #endif
                goto exit;
 
        e_util_save_file_chooser_folder (file_chooser);
 
        files = gtk_file_chooser_get_files (file_chooser);
-       active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (option_display));
+       active = option_display ? gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (option_display)) : FALSE;
        disposition = active ? "inline" : "attachment";
 
 #ifdef HAVE_AUTOAR
-       autoar_gtk_chooser_simple_get (option_format_combo, &format, &filter);
+       if (dialog) {
+               autoar_gtk_chooser_simple_get (option_format_combo, &format, &filter);
 
-       if (!e_enum_to_string (AUTOAR_TYPE_FORMAT, format)) {
-               format = AUTOAR_FORMAT_ZIP;
-       }
+               if (!e_enum_to_string (AUTOAR_TYPE_FORMAT, format)) {
+                       format = AUTOAR_FORMAT_ZIP;
+               }
 
-       if (!e_enum_to_string (AUTOAR_TYPE_FORMAT, filter)) {
-               filter = AUTOAR_FILTER_NONE;
-       }
+               if (!e_enum_to_string (AUTOAR_TYPE_FORMAT, filter)) {
+                       filter = AUTOAR_FILTER_NONE;
+               }
 
-       g_settings_set_string (
-               settings,
-               "autoar-format",
-               e_enum_to_string (AUTOAR_TYPE_FORMAT, format));
-       g_settings_set_string (
-               settings,
-               "autoar-filter",
-               e_enum_to_string (AUTOAR_TYPE_FILTER, filter));
+               g_settings_set_string (
+                       settings,
+                       "autoar-format",
+                       e_enum_to_string (AUTOAR_TYPE_FORMAT, format));
+               g_settings_set_string (
+                       settings,
+                       "autoar-filter",
+                       e_enum_to_string (AUTOAR_TYPE_FILTER, filter));
+       }
 #endif
 
        for (iter = files; iter != NULL; iter = g_slist_next (iter)) {
@@ -779,10 +789,14 @@ e_attachment_store_run_load_dialog (EAttachmentStore *store,
        g_slist_foreach (files, (GFunc) g_object_unref, NULL);
        g_slist_free (files);
 
-exit:
-       gtk_widget_destroy (dialog);
+ exit:
+       if (dialog)
+               gtk_widget_destroy (dialog);
+       else
+               g_clear_object (&native);
+
 #ifdef HAVE_AUTOAR
-       g_object_unref (settings);
+       g_clear_object (&settings);
        g_free (format_string);
        g_free (filter_string);
 #endif
@@ -795,11 +809,15 @@ e_attachment_store_run_save_dialog (EAttachmentStore *store,
 {
        GtkFileChooser *file_chooser;
        GtkFileChooserAction action;
-       GtkWidget *dialog;
-
+       GtkWidget *dialog = NULL;
+       GtkFileChooserNative *native = NULL;
+       GFile *destination;
+       const gchar *title;
+       gint response;
+       guint length;
 #ifdef HAVE_AUTOAR
        GtkBox *extra_box;
-       GtkWidget *extra_box_widget;
+       GtkWidget *extra_box_widget = NULL;
 
        GtkBox *extract_box;
        GtkWidget *extract_box_widget;
@@ -808,11 +826,6 @@ e_attachment_store_run_save_dialog (EAttachmentStore *store,
        GtkWidget *extract_dont, *extract_only, *extract_org;
 #endif
 
-       GFile *destination;
-       const gchar *title;
-       gint response;
-       guint length;
-
        g_return_val_if_fail (E_IS_ATTACHMENT_STORE (store), NULL);
 
        length = g_list_length (attachment_list);
@@ -827,44 +840,56 @@ e_attachment_store_run_save_dialog (EAttachmentStore *store,
        else
                action = GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER;
 
-       dialog = gtk_file_chooser_dialog_new (
-               title, parent, action,
-               _("_Cancel"), GTK_RESPONSE_CANCEL,
-               _("_Save"), GTK_RESPONSE_OK, NULL);
+       if (e_util_is_running_flatpak ()) {
+               native = gtk_file_chooser_native_new (
+                       title, GTK_WINDOW (parent), action,
+                       _("_Save"), _("_Cancel"));
+
+               file_chooser = GTK_FILE_CHOOSER (native);
+       } else {
+               dialog = gtk_file_chooser_dialog_new (
+                       title, parent, action,
+                       _("_Cancel"), GTK_RESPONSE_CANCEL,
+                       _("_Save"), GTK_RESPONSE_ACCEPT, NULL);
+
+               file_chooser = GTK_FILE_CHOOSER (dialog);
+       }
 
-       file_chooser = GTK_FILE_CHOOSER (dialog);
        gtk_file_chooser_set_local_only (file_chooser, FALSE);
        gtk_file_chooser_set_do_overwrite_confirmation (file_chooser, TRUE);
-       gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
-       gtk_window_set_icon_name (GTK_WINDOW (dialog), "mail-attachment");
+
+       if (dialog) {
+               gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT);
+               gtk_window_set_icon_name (GTK_WINDOW (dialog), "mail-attachment");
 
 #ifdef HAVE_AUTOAR
-       extra_box_widget = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
-       extra_box = GTK_BOX (extra_box_widget);
+               extra_box_widget = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
+               extra_box = GTK_BOX (extra_box_widget);
 
-       extract_box_widget = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
-       extract_box = GTK_BOX (extract_box_widget);
-       gtk_box_pack_start (extra_box, extract_box_widget, FALSE, FALSE, 5);
+               extract_box_widget = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
+               extract_box = GTK_BOX (extract_box_widget);
+               gtk_box_pack_start (extra_box, extract_box_widget, FALSE, FALSE, 5);
 
-       extract_dont = gtk_radio_button_new_with_mnemonic (NULL,
-               _("Do _not extract files from the attachment"));
-       gtk_box_pack_start (extract_box, extract_dont, FALSE, FALSE, 0);
+               extract_dont = gtk_radio_button_new_with_mnemonic (NULL,
+                       _("Do _not extract files from the attachment"));
+               gtk_box_pack_start (extract_box, extract_dont, FALSE, FALSE, 0);
 
-       extract_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (extract_dont));
-       extract_only = gtk_radio_button_new_with_mnemonic (extract_group,
-               _("Save extracted files _only"));
-       gtk_box_pack_start (extract_box, extract_only, FALSE, FALSE, 0);
+               extract_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (extract_dont));
+               extract_only = gtk_radio_button_new_with_mnemonic (extract_group,
+                       _("Save extracted files _only"));
+               gtk_box_pack_start (extract_box, extract_only, FALSE, FALSE, 0);
 
-       extract_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (extract_only));
-       extract_org = gtk_radio_button_new_with_mnemonic (extract_group,
-               _("Save extracted files and the original _archive"));
-       gtk_box_pack_start (extract_box, extract_org, FALSE, FALSE, 0);
+               extract_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (extract_only));
+               extract_org = gtk_radio_button_new_with_mnemonic (extract_group,
+                       _("Save extracted files and the original _archive"));
+               gtk_box_pack_start (extract_box, extract_org, FALSE, FALSE, 0);
 
-       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (extract_dont), TRUE);
+               gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (extract_dont), TRUE);
 
-       gtk_widget_show_all (extra_box_widget);
-       gtk_file_chooser_set_extra_widget (file_chooser, extra_box_widget);
+               gtk_widget_show_all (extra_box_widget);
+               gtk_file_chooser_set_extra_widget (file_chooser, extra_box_widget);
 #endif
+       }
 
        if (action == GTK_FILE_CHOOSER_ACTION_SAVE) {
                EAttachment *attachment;
@@ -895,7 +920,7 @@ e_attachment_store_run_save_dialog (EAttachmentStore *store,
 
 #ifdef HAVE_AUTOAR
                mime_type = e_attachment_dup_mime_type (attachment);
-               if (!autoar_check_mime_type_supported (mime_type)) {
+               if (dialog && !autoar_check_mime_type_supported (mime_type)) {
                        gtk_widget_hide (extra_box_widget);
                }
 
@@ -904,7 +929,7 @@ e_attachment_store_run_save_dialog (EAttachmentStore *store,
 
                g_clear_object (&file_info);
 #ifdef HAVE_AUTOAR
-       } else {
+       } else if (dialog) {
                GList *iter;
                gboolean any_supported = FALSE;
 
@@ -925,9 +950,12 @@ e_attachment_store_run_save_dialog (EAttachmentStore *store,
 
        e_util_load_file_chooser_folder (file_chooser);
 
-       response = gtk_dialog_run (GTK_DIALOG (dialog));
+       if (dialog)
+               response = gtk_dialog_run (GTK_DIALOG (dialog));
+       else
+               response = gtk_native_dialog_run (GTK_NATIVE_DIALOG (native));
 
-       if (response == GTK_RESPONSE_OK) {
+       if (response == GTK_RESPONSE_ACCEPT) {
 #ifdef HAVE_AUTOAR
                gboolean save_self, save_extracted;
 #endif
@@ -935,44 +963,49 @@ e_attachment_store_run_save_dialog (EAttachmentStore *store,
                e_util_save_file_chooser_folder (file_chooser);
                destination = gtk_file_chooser_get_file (file_chooser);
 
+               if (dialog) {
 #ifdef HAVE_AUTOAR
-               save_self =
-                       gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (extract_dont)) ||
-                       gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (extract_org));
-               save_extracted =
-                       gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (extract_only)) ||
-                       gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (extract_org));
-
-               if (action == GTK_FILE_CHOOSER_ACTION_SAVE) {
-                       e_attachment_set_save_self (attachment_list->data, save_self);
-                       e_attachment_set_save_extracted (attachment_list->data, save_extracted);
-               } else {
-                       GList *iter;
-
-                       for (iter = attachment_list; iter != NULL; iter = iter->next) {
-                               EAttachment *attachment;
-                               gchar *mime_type;
-
-                               attachment = iter->data;
-                               mime_type = e_attachment_dup_mime_type (attachment);
-
-                               if (autoar_check_mime_type_supported (mime_type)) {
-                                       e_attachment_set_save_self (attachment, save_self);
-                                       e_attachment_set_save_extracted (attachment, save_extracted);
-                               } else {
-                                       e_attachment_set_save_self (attachment, TRUE);
-                                       e_attachment_set_save_extracted (attachment, FALSE);
+                       save_self =
+                               gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (extract_dont)) ||
+                               gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (extract_org));
+                       save_extracted =
+                               gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (extract_only)) ||
+                               gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (extract_org));
+
+                       if (action == GTK_FILE_CHOOSER_ACTION_SAVE) {
+                               e_attachment_set_save_self (attachment_list->data, save_self);
+                               e_attachment_set_save_extracted (attachment_list->data, save_extracted);
+                       } else {
+                               GList *iter;
+
+                               for (iter = attachment_list; iter != NULL; iter = iter->next) {
+                                       EAttachment *attachment;
+                                       gchar *mime_type;
+
+                                       attachment = iter->data;
+                                       mime_type = e_attachment_dup_mime_type (attachment);
+
+                                       if (autoar_check_mime_type_supported (mime_type)) {
+                                               e_attachment_set_save_self (attachment, save_self);
+                                               e_attachment_set_save_extracted (attachment, save_extracted);
+                                       } else {
+                                               e_attachment_set_save_self (attachment, TRUE);
+                                               e_attachment_set_save_extracted (attachment, FALSE);
+                                       }
+
+                                       g_free (mime_type);
                                }
-
-                               g_free (mime_type);
                        }
-               }
 #endif
+               }
        } else {
                destination = NULL;
        }
 
-       gtk_widget_destroy (dialog);
+       if (dialog)
+               gtk_widget_destroy (dialog);
+       else
+               g_clear_object (&native);
 
        return destination;
 }
diff --git a/src/e-util/e-category-editor.c b/src/e-util/e-category-editor.c
index a49e4edeb5..b532d2091e 100644
--- a/src/e-util/e-category-editor.c
+++ b/src/e-util/e-category-editor.c
@@ -25,6 +25,7 @@
 
 #include "e-category-editor.h"
 #include "e-dialog-widgets.h"
+#include "e-misc-utils.h"
 
 #define E_CATEGORY_EDITOR_GET_PRIVATE(obj) \
        (G_TYPE_INSTANCE_GET_PRIVATE \
@@ -47,7 +48,8 @@ update_preview (GtkFileChooser *chooser,
        g_return_if_fail (chooser != NULL);
 
        image = GTK_IMAGE (gtk_file_chooser_get_preview_widget (chooser));
-       g_return_if_fail (image != NULL);
+       if (!image)
+               return;
 
        filename = gtk_file_chooser_get_preview_filename (chooser);
 
@@ -68,6 +70,34 @@ file_chooser_response (GtkDialog *dialog,
                gtk_file_chooser_unselect_all (button);
 }
 
+static void
+unset_icon_clicked_cb (GtkWidget *button,
+                      gpointer user_data)
+{
+       GtkFileChooser *file_chooser = user_data;
+
+       g_return_if_fail (GTK_IS_FILE_CHOOSER (file_chooser));
+
+       gtk_file_chooser_unselect_all (file_chooser);
+       gtk_widget_set_sensitive (button, FALSE);
+}
+
+static void
+chooser_button_file_set_cb (GtkFileChooser *chooser_button,
+                           gpointer user_data)
+{
+       GtkWidget *unset_button = user_data;
+       GSList *uris;
+
+       g_return_if_fail (GTK_IS_WIDGET (unset_button));
+
+       uris = gtk_file_chooser_get_uris (chooser_button);
+
+       gtk_widget_set_sensitive (unset_button, uris != NULL);
+
+       g_slist_free_full (uris, g_free);
+}
+
 static void
 category_editor_category_name_changed (GtkEntry *category_name_entry,
                                        ECategoryEditor *editor)
@@ -126,7 +156,7 @@ e_category_editor_init (ECategoryEditor *editor)
        GtkWidget *category_name;
        GtkWidget *chooser_button;
        GtkWidget *no_image_button;
-       GtkWidget *chooser_dialog;
+       GtkWidget *chooser_dialog = NULL;
        GtkWidget *preview;
 
        editor->priv = E_CATEGORY_EDITOR_GET_PRIVATE (editor);
@@ -134,32 +164,34 @@ e_category_editor_init (ECategoryEditor *editor)
        gtk_window_set_resizable (GTK_WINDOW (editor), FALSE);
        gtk_container_set_border_width (GTK_CONTAINER (editor), 6);
 
-       chooser_dialog = gtk_file_chooser_dialog_new (
-               _("Category Icon"),
-               NULL, GTK_FILE_CHOOSER_ACTION_OPEN,
-               _("_Cancel"), GTK_RESPONSE_CANCEL, NULL);
-
-       no_image_button = e_dialog_button_new_with_icon ("window-close", _("_No Image"));
-       gtk_dialog_add_action_widget (
-               GTK_DIALOG (chooser_dialog),
-               no_image_button, GTK_RESPONSE_NO);
-       gtk_dialog_add_button (
-               GTK_DIALOG (chooser_dialog),
-               _("_Open"), GTK_RESPONSE_ACCEPT);
-       gtk_file_chooser_set_local_only (
-               GTK_FILE_CHOOSER (chooser_dialog), TRUE);
-       gtk_widget_show (no_image_button);
-
-       g_signal_connect (
-               chooser_dialog, "update-preview",
-               G_CALLBACK (update_preview), NULL);
-
-       preview = gtk_image_new ();
-       gtk_file_chooser_set_preview_widget (
-               GTK_FILE_CHOOSER (chooser_dialog), preview);
-       gtk_file_chooser_set_preview_widget_active (
-               GTK_FILE_CHOOSER (chooser_dialog), TRUE);
-       gtk_widget_show_all (preview);
+       if (!e_util_is_running_flatpak ()) {
+               chooser_dialog = gtk_file_chooser_dialog_new (
+                       _("Category Icon"),
+                       NULL, GTK_FILE_CHOOSER_ACTION_OPEN,
+                       _("_Cancel"), GTK_RESPONSE_CANCEL, NULL);
+
+               no_image_button = e_dialog_button_new_with_icon ("window-close", _("_No Image"));
+               gtk_dialog_add_action_widget (
+                       GTK_DIALOG (chooser_dialog),
+                       no_image_button, GTK_RESPONSE_NO);
+               gtk_dialog_add_button (
+                       GTK_DIALOG (chooser_dialog),
+                       _("_Open"), GTK_RESPONSE_ACCEPT);
+               gtk_file_chooser_set_local_only (
+                       GTK_FILE_CHOOSER (chooser_dialog), TRUE);
+               gtk_widget_show (no_image_button);
+
+               g_signal_connect (
+                       chooser_dialog, "update-preview",
+                       G_CALLBACK (update_preview), NULL);
+
+               preview = gtk_image_new ();
+               gtk_file_chooser_set_preview_widget (
+                       GTK_FILE_CHOOSER (chooser_dialog), preview);
+               gtk_file_chooser_set_preview_widget_active (
+                       GTK_FILE_CHOOSER (chooser_dialog), TRUE);
+               gtk_widget_show_all (preview);
+       }
 
        dialog_content = gtk_dialog_get_content_area (GTK_DIALOG (editor));
 
@@ -190,18 +222,34 @@ e_category_editor_init (ECategoryEditor *editor)
        gtk_misc_set_alignment (GTK_MISC (label_icon), 0, 0.5);
        gtk_grid_attach (grid_category_properties, label_icon, 0, 1, 1, 1);
 
-       chooser_button = GTK_WIDGET (
-               gtk_file_chooser_button_new_with_dialog (chooser_dialog));
+       if (chooser_dialog) {
+               chooser_button = gtk_file_chooser_button_new_with_dialog (chooser_dialog);
+
+               g_signal_connect (
+                       chooser_dialog, "response",
+                       G_CALLBACK (file_chooser_response), chooser_button);
+       } else {
+               GtkWidget *unset_button;
+
+               chooser_button = gtk_file_chooser_button_new (_("Category Icon"), 
GTK_FILE_CHOOSER_ACTION_OPEN);
+
+               unset_button = gtk_button_new_with_mnemonic (_("_Unset icon"));
+               gtk_widget_set_sensitive (unset_button, FALSE);
+               gtk_grid_attach (grid_category_properties, unset_button, 1, 2, 1, 1);
+
+               g_signal_connect (unset_button, "clicked",
+                       G_CALLBACK (unset_icon_clicked_cb), chooser_button);
+
+               g_signal_connect (chooser_button, "file-set",
+                       G_CALLBACK (chooser_button_file_set_cb), unset_button);
+       }
+
        gtk_widget_set_hexpand (chooser_button, TRUE);
        gtk_widget_set_halign (chooser_button, GTK_ALIGN_FILL);
        gtk_label_set_mnemonic_widget (GTK_LABEL (label_icon), chooser_button);
        gtk_grid_attach (grid_category_properties, chooser_button, 1, 1, 1, 1);
        editor->priv->category_icon = chooser_button;
 
-       g_signal_connect (
-               chooser_dialog, "response",
-               G_CALLBACK (file_chooser_response), chooser_button);
-
        dialog_action_area = gtk_dialog_get_action_area (GTK_DIALOG (editor));
        gtk_button_box_set_layout (
                GTK_BUTTON_BOX (dialog_action_area), GTK_BUTTONBOX_END);
@@ -321,6 +369,9 @@ e_category_editor_edit_category (ECategoryEditor *editor,
        if (icon_file) {
                gtk_file_chooser_set_filename (file_chooser, icon_file);
                update_preview (file_chooser, NULL);
+
+               if (e_util_is_running_flatpak ())
+                       g_signal_emit_by_name (file_chooser, "file-set", NULL);
        }
        g_free (icon_file);
 
diff --git a/src/e-util/e-html-editor-actions.c b/src/e-util/e-html-editor-actions.c
index f2cd27636d..7f98500123 100644
--- a/src/e-util/e-html-editor-actions.c
+++ b/src/e-util/e-html-editor-actions.c
@@ -312,27 +312,29 @@ static void
 action_insert_html_file_cb (GtkToggleAction *action,
                             EHTMLEditor *editor)
 {
-       GtkWidget *dialog;
+       GtkFileChooserNative *native;
        GtkFileFilter *filter;
+       GtkWidget *toplevel;
 
-       dialog = gtk_file_chooser_dialog_new (
-               _("Insert HTML File"), NULL,
+       toplevel = gtk_widget_get_toplevel (GTK_WIDGET (editor));
+
+       native = gtk_file_chooser_native_new (
+               _("Insert HTML File"), GTK_IS_WINDOW (toplevel) ? GTK_WINDOW (toplevel) : NULL,
                GTK_FILE_CHOOSER_ACTION_OPEN,
-               _("_Cancel"), GTK_RESPONSE_CANCEL,
-               _("_Open"), GTK_RESPONSE_ACCEPT, NULL);
+               _("_Open"), _("_Cancel"));
 
        filter = gtk_file_filter_new ();
        gtk_file_filter_set_name (filter, _("HTML file"));
        gtk_file_filter_add_mime_type (filter, "text/html");
-       gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
+       gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (native), filter);
 
-       e_util_load_file_chooser_folder (GTK_FILE_CHOOSER (dialog));
+       e_util_load_file_chooser_folder (GTK_FILE_CHOOSER (native));
 
-       if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) {
+       if (gtk_native_dialog_run (GTK_NATIVE_DIALOG (native)) == GTK_RESPONSE_ACCEPT) {
                GFile *file;
 
-               e_util_save_file_chooser_folder (GTK_FILE_CHOOSER (dialog));
-               file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (dialog));
+               e_util_save_file_chooser_folder (GTK_FILE_CHOOSER (native));
+               file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (native));
 
                /* XXX Need a way to cancel this. */
                g_file_load_contents_async (
@@ -343,22 +345,49 @@ action_insert_html_file_cb (GtkToggleAction *action,
                g_object_unref (file);
        }
 
-       gtk_widget_destroy (dialog);
+       g_object_unref (native);
 }
 
 static void
 action_insert_image_cb (GtkAction *action,
                         EHTMLEditor *editor)
 {
-       GtkWidget *dialog;
+       GtkWidget *dialog = NULL;
+       GtkFileChooserNative *native = NULL;
+       GtkWidget *toplevel;
+       gint response;
+
+       toplevel = gtk_widget_get_toplevel (GTK_WIDGET (editor));
+       if (e_util_is_running_flatpak ()) {
+               GtkFileFilter *file_filter;
+
+               native = gtk_file_chooser_native_new (
+                       C_("dialog-title", "Insert Image"),
+                       GTK_IS_WINDOW (toplevel) ? GTK_WINDOW (toplevel) : NULL,
+                       GTK_FILE_CHOOSER_ACTION_OPEN,
+                       _("_Open"), _("_Cancel"));
+
+               file_filter = gtk_file_filter_new ();
+               gtk_file_filter_add_pixbuf_formats (file_filter);
+               gtk_file_filter_set_name (file_filter, _("Image file"));
+               gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (native), file_filter);
+       } else {
+               dialog = e_image_chooser_dialog_new (C_("dialog-title", "Insert Image"), GTK_IS_WINDOW 
(toplevel) ? GTK_WINDOW (toplevel) : NULL);
+       }
 
-       dialog = e_image_chooser_dialog_new (C_("dialog-title", "Insert Image"), NULL);
+       if (dialog)
+               response = gtk_dialog_run (GTK_DIALOG (dialog));
+       else
+               response = gtk_native_dialog_run (GTK_NATIVE_DIALOG (native));
 
-       if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) {
+       if (response == GTK_RESPONSE_ACCEPT) {
                EContentEditor *cnt_editor;
                gchar *uri;
 
-               uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (dialog));
+               if (dialog)
+                       uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (dialog));
+               else
+                       uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (native));
 
                cnt_editor = e_html_editor_get_content_editor (editor);
                e_content_editor_insert_image (cnt_editor, uri);
@@ -366,7 +395,10 @@ action_insert_image_cb (GtkAction *action,
                g_free (uri);
        }
 
-       gtk_widget_destroy (dialog);
+       if (dialog)
+               gtk_widget_destroy (dialog);
+       else
+               g_object_unref (native);
 }
 
 static void
@@ -406,27 +438,29 @@ static void
 action_insert_text_file_cb (GtkAction *action,
                             EHTMLEditor *editor)
 {
-       GtkWidget *dialog;
+       GtkFileChooserNative *native;
+       GtkWidget *toplevel;
        GtkFileFilter *filter;
 
-       dialog = gtk_file_chooser_dialog_new (
-               _("Insert text file"), NULL,
+       toplevel = gtk_widget_get_toplevel (GTK_WIDGET (editor));
+
+       native = gtk_file_chooser_native_new (
+               _("Insert text file"), GTK_IS_WINDOW (toplevel) ? GTK_WINDOW (toplevel) : NULL,
                GTK_FILE_CHOOSER_ACTION_OPEN,
-               _("_Cancel"), GTK_RESPONSE_CANCEL,
-               _("_Open"), GTK_RESPONSE_ACCEPT, NULL);
+               _("_Open"), _("_Cancel"));
 
        filter = gtk_file_filter_new ();
        gtk_file_filter_set_name (filter, _("Text file"));
        gtk_file_filter_add_mime_type (filter, "text/plain");
-       gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
+       gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (native), filter);
 
-       e_util_load_file_chooser_folder (GTK_FILE_CHOOSER (dialog));
+       e_util_load_file_chooser_folder (GTK_FILE_CHOOSER (native));
 
-       if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) {
+       if (gtk_native_dialog_run (GTK_NATIVE_DIALOG (native)) == GTK_RESPONSE_ACCEPT) {
                GFile *file;
 
-               e_util_save_file_chooser_folder (GTK_FILE_CHOOSER (dialog));
-               file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (dialog));
+               e_util_save_file_chooser_folder (GTK_FILE_CHOOSER (native));
+               file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (native));
 
                /* XXX Need a way to cancel this. */
                g_file_load_contents_async (
@@ -437,7 +471,7 @@ action_insert_text_file_cb (GtkAction *action,
                g_object_unref (file);
        }
 
-       gtk_widget_destroy (dialog);
+       g_object_unref (native);
 }
 
 static gboolean
diff --git a/src/e-util/e-html-editor-cell-dialog.c b/src/e-util/e-html-editor-cell-dialog.c
index b06f6b23ab..9f218e9b1f 100644
--- a/src/e-util/e-html-editor-cell-dialog.c
+++ b/src/e-util/e-html-editor-cell-dialog.c
@@ -636,18 +636,21 @@ e_html_editor_cell_dialog_init (EHTMLEditorCellDialog *dialog)
                GTK_LABEL (widget), dialog->priv->background_color_picker);
        gtk_grid_attach (grid, widget, 0, 0, 1, 1);
 
-       /* Image */
-       widget = e_image_chooser_dialog_new (
-                       _("Choose Background Image"),
-                       GTK_WINDOW (dialog));
-       dialog->priv->background_image_chooser = widget;
-
        file_filter = gtk_file_filter_new ();
        gtk_file_filter_set_name (file_filter, _("Images"));
        gtk_file_filter_add_mime_type (file_filter, "image/*");
 
-       widget = gtk_file_chooser_button_new_with_dialog (
-                       dialog->priv->background_image_chooser);
+       /* Image */
+       if (e_util_is_running_flatpak ()) {
+               widget = gtk_file_chooser_button_new (_("Choose Background Image"), 
GTK_FILE_CHOOSER_ACTION_OPEN);
+       } else {
+               widget = e_image_chooser_dialog_new (
+                               _("Choose Background Image"),
+                               GTK_WINDOW (dialog));
+
+               widget = gtk_file_chooser_button_new_with_dialog (widget);
+       }
+
        gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (widget), file_filter);
        gtk_widget_set_hexpand (widget, TRUE);
        gtk_grid_attach (grid, widget, 1, 1, 1, 1);
diff --git a/src/e-util/e-html-editor-image-dialog.c b/src/e-util/e-html-editor-image-dialog.c
index 9ea18537e9..46e5ad74db 100644
--- a/src/e-util/e-html-editor-image-dialog.c
+++ b/src/e-util/e-html-editor-image-dialog.c
@@ -472,18 +472,23 @@ e_html_editor_image_dialog_init (EHTMLEditorImageDialog *dialog)
        gtk_grid_attach (main_layout, GTK_WIDGET (grid), 0, 1, 1, 1);
        gtk_widget_set_margin_left (GTK_WIDGET (grid), 10);
 
-       /* Source */
-       widget = e_image_chooser_dialog_new (
-                       _("Choose Background Image"),
-                       GTK_WINDOW (dialog));
-       gtk_file_chooser_set_action (
-               GTK_FILE_CHOOSER (widget), GTK_FILE_CHOOSER_ACTION_OPEN);
-
        file_filter = gtk_file_filter_new ();
        gtk_file_filter_set_name (file_filter, _("Images"));
        gtk_file_filter_add_mime_type (file_filter, "image/*");
 
-       widget = gtk_file_chooser_button_new_with_dialog (widget);
+       /* Source */
+       if (e_util_is_running_flatpak ()) {
+               widget = gtk_file_chooser_button_new (_("Choose Background Image"), 
GTK_FILE_CHOOSER_ACTION_OPEN);
+       } else {
+               widget = e_image_chooser_dialog_new (
+                               _("Choose Background Image"),
+                               GTK_WINDOW (dialog));
+               gtk_file_chooser_set_action (
+                       GTK_FILE_CHOOSER (widget), GTK_FILE_CHOOSER_ACTION_OPEN);
+
+               widget = gtk_file_chooser_button_new_with_dialog (widget);
+       }
+
        gtk_widget_set_hexpand (widget, TRUE);
        gtk_grid_attach (grid, widget, 1, 0, 1, 1);
        g_signal_connect_swapped (
diff --git a/src/e-util/e-html-editor-table-dialog.c b/src/e-util/e-html-editor-table-dialog.c
index 484975b536..d613104856 100644
--- a/src/e-util/e-html-editor-table-dialog.c
+++ b/src/e-util/e-html-editor-table-dialog.c
@@ -49,7 +49,6 @@ struct _EHTMLEditorTableDialogPrivate {
 
        GtkWidget *background_color_picker;
        GtkWidget *background_image_chooser;
-       GtkWidget *image_chooser_dialog;
 
        GtkWidget *remove_image_button;
 };
@@ -689,18 +688,23 @@ e_html_editor_table_dialog_init (EHTMLEditorTableDialog *dialog)
                GTK_LABEL (widget), dialog->priv->background_color_picker);
        gtk_grid_attach (grid, widget, 0, 0, 1, 1);
 
-       /* Image */
-       widget = e_image_chooser_dialog_new (
-                       _("Choose Background Image"),
-                       GTK_WINDOW (dialog));
-       dialog->priv->image_chooser_dialog = widget;
-
        file_filter = gtk_file_filter_new ();
        gtk_file_filter_set_name (file_filter, _("Images"));
        gtk_file_filter_add_mime_type (file_filter, "image/*");
 
-       widget = gtk_file_chooser_button_new_with_dialog (
-                       dialog->priv->image_chooser_dialog);
+       /* Image */
+       if (e_util_is_running_flatpak ()) {
+               widget = gtk_file_chooser_button_new (_("Choose Background Image"), 
GTK_FILE_CHOOSER_ACTION_OPEN);
+       } else {
+               GtkWidget *image_chooser_dialog;
+
+               image_chooser_dialog = e_image_chooser_dialog_new (
+                               _("Choose Background Image"),
+                               GTK_WINDOW (dialog));
+
+               widget = gtk_file_chooser_button_new_with_dialog (image_chooser_dialog);
+       }
+
        gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (widget), file_filter);
        gtk_widget_set_hexpand (widget, TRUE);
        gtk_grid_attach (grid, widget, 1, 1, 1, 1);
diff --git a/src/e-util/e-web-view.c b/src/e-util/e-web-view.c
index 78b7ebc9af..eac643e000 100644
--- a/src/e-util/e-web-view.c
+++ b/src/e-util/e-web-view.c
@@ -4124,8 +4124,8 @@ void
 e_web_view_cursor_image_save (EWebView *web_view)
 {
        GtkFileChooser *file_chooser;
+       GtkFileChooserNative *native;
        GFile *destination = NULL;
-       GtkWidget *dialog;
        gchar *suggestion;
        gpointer toplevel;
 
@@ -4137,16 +4137,12 @@ e_web_view_cursor_image_save (EWebView *web_view)
        toplevel = gtk_widget_get_toplevel (GTK_WIDGET (web_view));
        toplevel = gtk_widget_is_toplevel (toplevel) ? toplevel : NULL;
 
-       dialog = gtk_file_chooser_dialog_new (
+       native = gtk_file_chooser_native_new (
                _("Save Image"), toplevel,
                GTK_FILE_CHOOSER_ACTION_SAVE,
-               _("_Cancel"), GTK_RESPONSE_CANCEL,
-               _("_Save"), GTK_RESPONSE_ACCEPT, NULL);
-
-       gtk_dialog_set_default_response (
-               GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT);
+               _("_Save"), _("_Cancel"));
 
-       file_chooser = GTK_FILE_CHOOSER (dialog);
+       file_chooser = GTK_FILE_CHOOSER (native);
        gtk_file_chooser_set_local_only (file_chooser, FALSE);
        gtk_file_chooser_set_do_overwrite_confirmation (file_chooser, TRUE);
 
@@ -4160,13 +4156,13 @@ e_web_view_cursor_image_save (EWebView *web_view)
 
        e_util_load_file_chooser_folder (file_chooser);
 
-       if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) {
+       if (gtk_native_dialog_run (GTK_NATIVE_DIALOG (native)) == GTK_RESPONSE_ACCEPT) {
                e_util_save_file_chooser_folder (file_chooser);
 
                destination = gtk_file_chooser_get_file (file_chooser);
        }
 
-       gtk_widget_destroy (dialog);
+       g_object_unref (native);
 
        if (destination != NULL) {
                EActivity *activity;
diff --git a/src/e-util/test-html-editor.c b/src/e-util/test-html-editor.c
index 1e40fa0120..339658260d 100644
--- a/src/e-util/test-html-editor.c
+++ b/src/e-util/test-html-editor.c
@@ -100,42 +100,40 @@ print (EHTMLEditor *editor,
 static gint
 save_dialog (EHTMLEditor *editor)
 {
-       GtkWidget *dialog;
+       GtkFileChooserNative *native;
        const gchar *filename;
        gint response;
 
-       dialog = gtk_file_chooser_dialog_new (
+       native = gtk_file_chooser_native_new (
                _("Save As"),
                GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (editor))),
                GTK_FILE_CHOOSER_ACTION_SAVE,
-               _("_Cancel"), GTK_RESPONSE_CANCEL,
-               _("_Save"), GTK_RESPONSE_ACCEPT,
-               NULL);
+               _("_Save"), _("_Cancel"));
 
        gtk_file_chooser_set_do_overwrite_confirmation (
-               GTK_FILE_CHOOSER (dialog), TRUE);
+               GTK_FILE_CHOOSER (native), TRUE);
 
        filename = e_html_editor_get_filename (editor);
 
        if (filename != NULL)
                gtk_file_chooser_set_filename (
-                       GTK_FILE_CHOOSER (dialog), filename);
+                       GTK_FILE_CHOOSER (native), filename);
        else
                gtk_file_chooser_set_current_name (
-                       GTK_FILE_CHOOSER (dialog), _("Untitled document"));
+                       GTK_FILE_CHOOSER (native), _("Untitled document"));
 
-       response = gtk_dialog_run (GTK_DIALOG (dialog));
+       response = gtk_native_dialog_run (GTK_NATIVE_DIALOG (native));
 
        if (response == GTK_RESPONSE_ACCEPT) {
                gchar *new_filename;
 
                new_filename = gtk_file_chooser_get_filename (
-                       GTK_FILE_CHOOSER (dialog));
+                       GTK_FILE_CHOOSER (native));
                e_html_editor_set_filename (editor, new_filename);
                g_free (new_filename);
        }
 
-       gtk_widget_destroy (dialog);
+       g_object_unref (native);
 
        return response;
 }
diff --git a/src/modules/backup-restore/evolution-backup-restore.c 
b/src/modules/backup-restore/evolution-backup-restore.c
index 0e8e61420e..5e4b19fc77 100644
--- a/src/modules/backup-restore/evolution-backup-restore.c
+++ b/src/modules/backup-restore/evolution-backup-restore.c
@@ -224,9 +224,11 @@ file_chooser_filter_changed_cb (GtkFileChooser *file_chooser,
 }
 
 static void
-set_local_only (GtkFileChooser *file_chooser,
+set_local_only (GtkFileChooserNative *file_chooser_native,
                gpointer user_data)
 {
+       GtkFileChooser *file_chooser = GTK_FILE_CHOOSER (file_chooser_native);
+
        /* XXX Has to be a local file, since the backup utility
         *     takes a filename argument, not a URI. */
        gtk_file_chooser_set_local_only (file_chooser, TRUE);
@@ -302,7 +304,7 @@ action_settings_backup_cb (GtkAction *action,
        file = e_shell_run_save_dialog (
                e_shell_window_get_shell (shell_window),
                _("Select name of the Evolution backup file"),
-               suggest, has_xz ? "*.tar.xz;*.tar.gz" : "*.tar.gz", (GtkCallback)
+               suggest, has_xz ? "*.tar.xz;*.tar.gz" : "*.tar.gz",
                set_local_only, has_xz ? suggest : NULL);
 
        g_free (suggest);
@@ -424,7 +426,7 @@ action_settings_restore_cb (GtkAction *action,
        file = e_shell_run_open_dialog (
                e_shell_window_get_shell (shell_window),
                _("Select name of the Evolution backup file to restore"),
-               (GtkCallback) set_local_only, NULL);
+               set_local_only, NULL);
 
        if (file == NULL)
                return;
diff --git a/src/plugins/face/face.c b/src/plugins/face/face.c
index 7953bfd4b6..2290f23f84 100644
--- a/src/plugins/face/face.c
+++ b/src/plugins/face/face.c
@@ -282,39 +282,37 @@ update_preview_cb (GtkFileChooser *file_chooser,
 }
 
 static GdkPixbuf *
-choose_new_face (gsize *image_data_length)
+choose_new_face (GtkWidget *parent,
+                gsize *image_data_length)
 {
+       GtkFileChooserNative *native;
        GdkPixbuf *res = NULL;
-       GtkWidget *filesel, *preview;
+       GtkWidget *preview;
        GtkFileFilter *filter;
 
-       filesel = gtk_file_chooser_dialog_new (
+       native = gtk_file_chooser_native_new (
                _("Select a Face Picture"),
-               NULL,
+               GTK_IS_WINDOW (parent) ? GTK_WINDOW (parent) : NULL,
                GTK_FILE_CHOOSER_ACTION_OPEN,
-               _("_Cancel"), GTK_RESPONSE_CANCEL,
-               _("_Open"), GTK_RESPONSE_OK,
-               NULL);
-
-       gtk_dialog_set_default_response (GTK_DIALOG (filesel), GTK_RESPONSE_OK);
+               _("_Open"), _("_Cancel"));
 
        filter = gtk_file_filter_new ();
        gtk_file_filter_set_name (filter, _("Image files"));
        gtk_file_filter_add_mime_type (filter, "image/*");
-       gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (filesel), filter);
+       gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (native), filter);
 
        preview = gtk_image_new ();
-       gtk_file_chooser_set_preview_widget (GTK_FILE_CHOOSER (filesel), preview);
+       gtk_file_chooser_set_preview_widget (GTK_FILE_CHOOSER (native), preview);
        g_signal_connect (
-               filesel, "update-preview",
+               native, "update-preview",
                G_CALLBACK (update_preview_cb), preview);
 
-       if (GTK_RESPONSE_OK == gtk_dialog_run (GTK_DIALOG (filesel))) {
+       if (GTK_RESPONSE_ACCEPT == gtk_native_dialog_run (GTK_NATIVE_DIALOG (native))) {
                gchar *image_filename, *file_contents = NULL;
                gsize length = 0;
 
-               image_filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (filesel));
-               gtk_widget_destroy (filesel);
+               image_filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (native));
+               g_object_unref (native);
 
                if (prepare_image (image_filename, &file_contents, &length, &res, TRUE)) {
                        set_face_raw (file_contents, length);
@@ -325,7 +323,7 @@ choose_new_face (gsize *image_data_length)
                g_free (file_contents);
                g_free (image_filename);
        } else {
-               gtk_widget_destroy (filesel);
+               g_object_unref (native);
        }
 
        return res;
@@ -362,7 +360,7 @@ click_load_face_cb (GtkButton *butt,
        alert_bar = g_object_get_data (G_OBJECT (butt), "alert-bar");
        e_alert_bar_clear (alert_bar);
 
-       face = choose_new_face (&image_data_length);
+       face = choose_new_face (gtk_widget_get_toplevel (GTK_WIDGET (butt)), &image_data_length);
 
        if (face) {
                gtk_image_set_from_pixbuf (image, face);
@@ -470,7 +468,7 @@ face_change_image_in_composer_cb (GtkButton *button,
        /* Hide any previous alerts first */
        face_manage_composer_alert (composer, 0);
 
-       pixbuf = choose_new_face (&image_data_length);
+       pixbuf = choose_new_face (GTK_WIDGET (composer), &image_data_length);
 
        if (pixbuf) {
                g_object_unref (pixbuf);
@@ -488,7 +486,7 @@ action_toggle_face_cb (GtkToggleAction *action,
                gchar *face = get_face_base64 ();
 
                if (!face) {
-                       GdkPixbuf *pixbuf = choose_new_face (&image_data_length);
+                       GdkPixbuf *pixbuf = choose_new_face (GTK_WIDGET (composer), &image_data_length);
 
                        if (pixbuf) {
                                g_object_unref (pixbuf);
diff --git a/src/plugins/save-calendar/save-calendar.c b/src/plugins/save-calendar/save-calendar.c
index 7ffd4975de..50d25b6e7d 100644
--- a/src/plugins/save-calendar/save-calendar.c
+++ b/src/plugins/save-calendar/save-calendar.c
@@ -111,7 +111,6 @@ ask_destination_and_save (ESourceSelector *selector,
                          EClientCache *client_cache)
 {
        FormatHandler *handler = NULL;
-
        GtkWidget *extra_widget = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
        GtkWidget *hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
        GtkLabel *label = GTK_LABEL (gtk_label_new_with_mnemonic (_("_Format:")));
@@ -121,9 +120,9 @@ ask_destination_and_save (ESourceSelector *selector,
        GtkCellRenderer *renderer = NULL;
        GtkListStore *store = GTK_LIST_STORE (model);
        GtkTreeIter iter;
-       GtkWidget *dialog = NULL;
+       GtkFileChooserNative *native;
+       GtkWidget *toplevel;
        gchar *dest_uri = NULL;
-
        GList *format_handlers = NULL, *link;
 
        /* The available formathandlers */
@@ -178,28 +177,27 @@ ask_destination_and_save (ESourceSelector *selector,
                G_CALLBACK (on_type_combobox_changed), extra_widget);
        g_object_set_data (G_OBJECT (combo), "format-box", hbox);
 
-       dialog = gtk_file_chooser_dialog_new (
+       toplevel = gtk_widget_get_toplevel (GTK_WIDGET (selector));
+
+       native = gtk_file_chooser_native_new (
                _("Select destination file"),
-               NULL,
+               GTK_IS_WINDOW (toplevel) ? GTK_WINDOW (toplevel) : NULL,
                GTK_FILE_CHOOSER_ACTION_SAVE,
-               _("_Cancel"), GTK_RESPONSE_CANCEL,
-               _("_Save As"), GTK_RESPONSE_OK,
-               NULL);
+               _("_Save As"), _("_Cancel"));
 
-       gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
-       gtk_file_chooser_set_extra_widget (GTK_FILE_CHOOSER (dialog), extra_widget);
-       gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (dialog), FALSE);
+       gtk_file_chooser_set_extra_widget (GTK_FILE_CHOOSER (native), extra_widget);
+       gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (native), FALSE);
        gtk_widget_show (hbox);
        gtk_widget_show (GTK_WIDGET (label));
        gtk_widget_show (GTK_WIDGET (combo));
        gtk_widget_show (extra_widget);
 
-       e_util_load_file_chooser_folder (GTK_FILE_CHOOSER (dialog));
+       e_util_load_file_chooser_folder (GTK_FILE_CHOOSER (native));
 
-       if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK) {
+       if (gtk_native_dialog_run (GTK_NATIVE_DIALOG (native)) == GTK_RESPONSE_ACCEPT) {
                gchar *tmp = NULL;
 
-               e_util_save_file_chooser_folder (GTK_FILE_CHOOSER (dialog));
+               e_util_save_file_chooser_folder (GTK_FILE_CHOOSER (native));
 
                if (gtk_combo_box_get_active_iter (combo, &iter))
                        gtk_tree_model_get (
@@ -208,7 +206,7 @@ ask_destination_and_save (ESourceSelector *selector,
                else
                        handler = NULL;
 
-               dest_uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (dialog));
+               dest_uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (native));
 
                if (handler) {
                        tmp = strstr (dest_uri, handler->filename_ext);
@@ -231,9 +229,8 @@ ask_destination_and_save (ESourceSelector *selector,
        g_list_free_full (format_handlers, format_handlers_foreach_free);
 
        /* Now we can destroy it */
-       gtk_widget_destroy (dialog);
+       g_object_unref (native);
        g_free (dest_uri);
-
 }
 
 /* Returns output stream for the uri, or NULL on any error.
diff --git a/src/shell/e-shell-utils.c b/src/shell/e-shell-utils.c
index d2c104095b..fe5b9b0cdf 100644
--- a/src/shell/e-shell-utils.c
+++ b/src/shell/e-shell-utils.c
@@ -41,10 +41,9 @@
  * @customize_func: optional dialog customization function
  * @customize_data: optional data to pass to @customize_func
  *
- * Runs a #GtkFileChooserDialog in open mode with the given title and
+ * Runs a #GtkFileChooserNative in open mode with the given title and
  * returns the selected #GFile.  If @customize_func is provided, the
- * function is called just prior to running the dialog (the file chooser
- * is the first argument, @customize data is the second).  If the user
+ * function is called just prior to running the dialog.  If the user
  * cancels the dialog the function will return %NULL.
  *
  * Returns: the #GFile to open, or %NULL
@@ -52,28 +51,24 @@
 GFile *
 e_shell_run_open_dialog (EShell *shell,
                          const gchar *title,
-                         GtkCallback customize_func,
+                         EShellOepnSaveCustomizeFunc customize_func,
                          gpointer customize_data)
 {
        GtkFileChooser *file_chooser;
        GFile *chosen_file = NULL;
-       GtkWidget *dialog;
+       GtkFileChooserNative *native;
        GtkWindow *parent;
 
        g_return_val_if_fail (E_IS_SHELL (shell), NULL);
 
        parent = e_shell_get_active_window (shell);
 
-       dialog = gtk_file_chooser_dialog_new (
+       native = gtk_file_chooser_native_new (
                title, parent,
                GTK_FILE_CHOOSER_ACTION_OPEN,
-               _("_Cancel"), GTK_RESPONSE_CANCEL,
-               _("_Open"), GTK_RESPONSE_ACCEPT, NULL);
+               _("_Open"), _("_Cancel"));
 
-       file_chooser = GTK_FILE_CHOOSER (dialog);
-
-       gtk_dialog_set_default_response (
-               GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT);
+       file_chooser = GTK_FILE_CHOOSER (native);
 
        gtk_file_chooser_set_local_only (file_chooser, FALSE);
 
@@ -81,15 +76,15 @@ e_shell_run_open_dialog (EShell *shell,
 
        /* Allow further customizations before running the dialog. */
        if (customize_func != NULL)
-               customize_func (dialog, customize_data);
+               customize_func (native, customize_data);
 
-       if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) {
+       if (gtk_native_dialog_run (GTK_NATIVE_DIALOG (native)) == GTK_RESPONSE_ACCEPT) {
                e_util_save_file_chooser_folder (file_chooser);
 
                chosen_file = gtk_file_chooser_get_file (file_chooser);
        }
 
-       gtk_widget_destroy (dialog);
+       g_object_unref (native);
 
        return chosen_file;
 }
@@ -103,10 +98,9 @@ e_shell_run_open_dialog (EShell *shell,
  * @customize_func: optional dialog customization function
  * @customize_data: optional data to pass to @customize_func
  *
- * Runs a #GtkFileChooserDialog in save mode with the given title and
+ * Runs a #GtkFileChooserNative in save mode with the given title and
  * returns the selected #GFile.  If @customize_func is provided, the
- * function is called just prior to running the dialog (the file chooser
- * is the first argument, @customize_data is the second).  If the user
+ * function is called just prior to running the dialog.  If the user
  * cancels the dialog the function will return %NULL.
  *
  * With non-%NULL @filters will be added also file filters to the dialog.
@@ -121,28 +115,24 @@ e_shell_run_save_dialog (EShell *shell,
                          const gchar *title,
                          const gchar *suggestion,
                          const gchar *filters,
-                         GtkCallback customize_func,
+                         EShellOepnSaveCustomizeFunc customize_func,
                          gpointer customize_data)
 {
        GtkFileChooser *file_chooser;
        GFile *chosen_file = NULL;
-       GtkWidget *dialog;
+       GtkFileChooserNative *native;
        GtkWindow *parent;
 
        g_return_val_if_fail (E_IS_SHELL (shell), NULL);
 
        parent = e_shell_get_active_window (shell);
 
-       dialog = gtk_file_chooser_dialog_new (
+       native = gtk_file_chooser_native_new (
                title, parent,
                GTK_FILE_CHOOSER_ACTION_SAVE,
-               _("_Cancel"), GTK_RESPONSE_CANCEL,
-               _("_Save"), GTK_RESPONSE_ACCEPT, NULL);
-
-       file_chooser = GTK_FILE_CHOOSER (dialog);
+               _("_Save"), _("_Cancel"));
 
-       gtk_dialog_set_default_response (
-               GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT);
+       file_chooser = GTK_FILE_CHOOSER (native);
 
        gtk_file_chooser_set_local_only (file_chooser, FALSE);
        gtk_file_chooser_set_do_overwrite_confirmation (file_chooser, TRUE);
@@ -213,15 +203,15 @@ e_shell_run_save_dialog (EShell *shell,
 
        /* Allow further customizations before running the dialog. */
        if (customize_func != NULL)
-               customize_func (dialog, customize_data);
+               customize_func (native, customize_data);
 
-       if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) {
+       if (gtk_native_dialog_run (GTK_NATIVE_DIALOG (native)) == GTK_RESPONSE_ACCEPT) {
                e_util_save_file_chooser_folder (file_chooser);
 
                chosen_file = gtk_file_chooser_get_file (file_chooser);
        }
 
-       gtk_widget_destroy (dialog);
+       g_object_unref (native);
 
        return chosen_file;
 }
diff --git a/src/shell/e-shell-utils.h b/src/shell/e-shell-utils.h
index 7564b559c2..32c3e6e05e 100644
--- a/src/shell/e-shell-utils.h
+++ b/src/shell/e-shell-utils.h
@@ -25,16 +25,19 @@
 
 G_BEGIN_DECLS
 
+typedef void (* EShellOepnSaveCustomizeFunc)   (GtkFileChooserNative *file_chooser_native,
+                                                gpointer user_data);
+
 GFile *                e_shell_run_open_dialog         (EShell *shell,
                                                 const gchar *title,
-                                                GtkCallback customize_func,
+                                                EShellOepnSaveCustomizeFunc customize_func,
                                                 gpointer customize_data);
 
 GFile *                e_shell_run_save_dialog         (EShell *shell,
                                                 const gchar *title,
                                                 const gchar *suggestion,
                                                 const gchar *filters,
-                                                GtkCallback customize_func,
+                                                EShellOepnSaveCustomizeFunc customize_func,
                                                 gpointer customize_data);
 
 guint          e_shell_utils_import_uris       (EShell *shell,
diff --git a/src/smime/gui/certificate-manager.c b/src/smime/gui/certificate-manager.c
index bb6d3b9c93..534663fc08 100644
--- a/src/smime/gui/certificate-manager.c
+++ b/src/smime/gui/certificate-manager.c
@@ -634,77 +634,56 @@ cert_backup_dialog_maybe_correct_extension (GtkFileChooser *file_chooser)
        g_free (name);
 }
 
-static void
-cert_backup_dialog_file_chooser_save_activate_cb (GtkWidget *button,
-                                                 GtkFileChooser *file_chooser)
-{
-       cert_backup_dialog_maybe_correct_extension (file_chooser);
-}
-
-static gboolean
-cert_backup_dialog_file_chooser_save_event_cb (GtkWidget *button,
-                                              GdkEvent *event,
-                                              GtkFileChooser *file_chooser)
-{
-       cert_backup_dialog_maybe_correct_extension (file_chooser);
-
-       return FALSE;
-}
-
 static void
 run_cert_backup_dialog_file_chooser (GtkButton *file_button,
                                      BackupData *data)
 {
-       GtkWidget *filesel, *button;
+       GtkFileChooserNative *native;
        GtkFileFilter *filter;
+       GtkWidget *toplevel;
        gchar *filename;
 
-       filesel = gtk_file_chooser_dialog_new (
-               _("Select a file to backup your key and certificate..."), NULL,
+       toplevel = gtk_widget_get_toplevel (GTK_WIDGET (file_button));
+       native = gtk_file_chooser_native_new (
+               _("Select a file to backup your key and certificate..."),
+               GTK_IS_WINDOW (toplevel) ? GTK_WINDOW (toplevel) : NULL,
                GTK_FILE_CHOOSER_ACTION_SAVE,
-               _("_Cancel"), GTK_RESPONSE_CANCEL,
-               _("_Save"), GTK_RESPONSE_OK,
-               NULL);
-       gtk_dialog_set_default_response (GTK_DIALOG (filesel), GTK_RESPONSE_OK);
-       gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (filesel), TRUE);
+               _("_Save"), _("_Cancel"));
+       gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (native), TRUE);
        /* To Translators:
         * %s-backup.p12 is the default file name suggested by the file selection dialog,
         * when a user wants to backup one of her/his private keys/certificates.
         * For example: gnomedev-backup.p12
         */
        filename = g_strdup_printf (_("%s-backup.p12"), e_cert_get_nickname (data->cert));
-       gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (filesel), filename);
+       gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (native), filename);
        g_free (filename);
 
        if (*data->file) {
-               gtk_file_chooser_set_file (GTK_FILE_CHOOSER (filesel), *data->file, NULL);
+               gtk_file_chooser_set_file (GTK_FILE_CHOOSER (native), *data->file, NULL);
        }
 
        filter = gtk_file_filter_new ();
        gtk_file_filter_set_name (filter, data->cp->cert_filter_name);
        gtk_file_filter_add_mime_type (filter, "application/x-pkcs12");
-       gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (filesel), filter);
+       gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (native), filter);
 
        filter = gtk_file_filter_new ();
        gtk_file_filter_set_name (filter, _("All files"));
        gtk_file_filter_add_pattern (filter, "*");
-       gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (filesel), filter);
+       gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (native), filter);
 
-       button = gtk_dialog_get_widget_for_response (GTK_DIALOG (filesel), GTK_RESPONSE_OK);
-       g_signal_connect (button, "activate",
-               G_CALLBACK (cert_backup_dialog_file_chooser_save_activate_cb), filesel);
-       g_signal_connect (button, "enter-notify-event",
-               G_CALLBACK (cert_backup_dialog_file_chooser_save_event_cb), filesel);
-
-       if (gtk_dialog_run (GTK_DIALOG (filesel)) == GTK_RESPONSE_OK) {
+       if (gtk_native_dialog_run (GTK_NATIVE_DIALOG (native)) == GTK_RESPONSE_ACCEPT) {
                gchar *basename;
 
+               cert_backup_dialog_maybe_correct_extension (GTK_FILE_CHOOSER (native));
+
                if (*data->file) {
                        g_object_unref (*data->file);
                        *data->file = NULL;
                }
 
-               *data->file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (filesel));
+               *data->file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (native));
 
                basename = g_file_get_basename (*data->file);
                gtk_button_set_label (file_button, basename);
@@ -712,7 +691,7 @@ run_cert_backup_dialog_file_chooser (GtkButton *file_button,
        }
 
        /* destroy dialog to get rid of it in the GUI */
-       gtk_widget_destroy (filesel);
+       g_object_unref (native);
 
        cert_backup_dialog_sensitize (GTK_WIDGET (file_button), NULL, data);
        gtk_widget_grab_focus (GTK_WIDGET (data->entry1));
@@ -720,6 +699,7 @@ run_cert_backup_dialog_file_chooser (GtkButton *file_button,
 
 static gint
 run_cert_backup_dialog (CertPage *cp,
+                       GtkWidget *parent,
                         ECert *cert,
                         GFile **file,
                         gchar **password,
@@ -738,7 +718,8 @@ run_cert_backup_dialog (CertPage *cp,
        data.file = file;
 
        dialog = gtk_dialog_new_with_buttons (
-               _("Backup Certificate"), NULL, flags,
+               _("Backup Certificate"),
+               GTK_IS_WINDOW (parent) ? GTK_WINDOW (parent) : NULL, flags,
                _("_Cancel"), GTK_RESPONSE_CANCEL,
                _("_Save"), GTK_RESPONSE_OK,
                NULL);
@@ -864,7 +845,7 @@ backup_cert (GtkWidget *button,
                        gchar *password = NULL;
                        gboolean save_chain = FALSE;
 
-                       if (run_cert_backup_dialog (cp, cert, &file, &password, &save_chain) == 
GTK_RESPONSE_OK) {
+                       if (run_cert_backup_dialog (cp, gtk_widget_get_toplevel (button), cert, &file, 
&password, &save_chain) == GTK_RESPONSE_OK) {
                                if (!file) {
                                        e_notice (
                                                gtk_widget_get_toplevel (GTK_WIDGET (cp->treeview)),
@@ -956,37 +937,39 @@ static void
 import_cert (GtkWidget *button,
              CertPage *cp)
 {
-       GtkWidget *filesel;
+       GtkFileChooserNative *native;
        GtkFileFilter *filter;
+       GtkWidget *toplevel;
        gint i;
 
-       filesel = gtk_file_chooser_dialog_new (
-               _("Select a certificate to import..."), NULL,
+       toplevel = gtk_widget_get_toplevel (button);
+
+       native = gtk_file_chooser_native_new (
+               _("Select a certificate to import..."),
+               GTK_IS_WINDOW (toplevel) ? GTK_WINDOW (toplevel) : NULL,
                GTK_FILE_CHOOSER_ACTION_OPEN,
-               _("_Cancel"), GTK_RESPONSE_CANCEL,
-               _("_Open"), GTK_RESPONSE_OK, NULL);
-       gtk_dialog_set_default_response (GTK_DIALOG (filesel), GTK_RESPONSE_OK);
+               _("_Open"), _("_Cancel"));
 
        filter = gtk_file_filter_new ();
        gtk_file_filter_set_name (filter, cp->cert_filter_name);
        for (i = 0; cp->cert_mime_types[i] != NULL; i++) {
                gtk_file_filter_add_mime_type (filter, cp->cert_mime_types[i]);
        }
-       gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (filesel), filter);
+       gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (native), filter);
 
        filter = gtk_file_filter_new ();
        gtk_file_filter_set_name (filter, _("All files"));
        gtk_file_filter_add_pattern (filter, "*");
-       gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (filesel), filter);
+       gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (native), filter);
 
-       if (gtk_dialog_run (GTK_DIALOG (filesel)) == GTK_RESPONSE_OK) {
-               gchar *filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (filesel));
+       if (gtk_native_dialog_run (GTK_NATIVE_DIALOG (native)) == GTK_RESPONSE_ACCEPT) {
+               gchar *filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (native));
                GSList *imported_certs = NULL;
                GError *error = NULL;
                gboolean import;
 
                /* destroy dialog to get rid of it in the GUI */
-               gtk_widget_destroy (filesel);
+               g_object_unref (native);
 
                switch (cp->cert_type) {
                        case E_CERT_USER:
@@ -1017,8 +1000,9 @@ import_cert (GtkWidget *button,
                g_slist_foreach (imported_certs, (GFunc) g_object_unref, NULL);
                g_slist_free (imported_certs);
                g_free (filename);
-       } else
-               gtk_widget_destroy (filesel);
+       } else {
+               g_object_unref (native);
+       }
 }
 
 static void


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