summaryrefslogtreecommitdiff
path: root/gtk/gtkmountoperation.c
diff options
context:
space:
mode:
authorCosimo Cecchi <cosimoc@gnome.org>2012-06-20 21:36:09 -0400
committerCosimo Cecchi <cosimoc@gnome.org>2012-06-22 16:49:05 -0400
commit44fd03eb47b9492ffaf32ae6dfcca00b7d5a7618 (patch)
tree2e8925910f97f09d2ac29a5e9cd501392ba1fdf0 /gtk/gtkmountoperation.c
parentfb91fa2fbd5ca93afd44744d23c47518cef55ef4 (diff)
downloadgtk+-44fd03eb47b9492ffaf32ae6dfcca00b7d5a7618.tar.gz
mountoperation: use the Shell DBus proxy if available
Make GMountOperation look for an owner of org.Gtk.MountOperationHandler if possible, and use it instead of the GTK-based dialogs. This allows applications to use the implementation offered by the desktop shell, if available, through a DBus private interface: org.Gtk.MountOperationHandler. https://bugzilla.gnome.org/show_bug.cgi?id=674963
Diffstat (limited to 'gtk/gtkmountoperation.c')
-rw-r--r--gtk/gtkmountoperation.c343
1 files changed, 312 insertions, 31 deletions
diff --git a/gtk/gtkmountoperation.c b/gtk/gtkmountoperation.c
index 4f070a73cd..38aadcaef0 100644
--- a/gtk/gtkmountoperation.c
+++ b/gtk/gtkmountoperation.c
@@ -29,6 +29,7 @@
#include "gtkmountoperationprivate.h"
#include "gtkbox.h"
+#include "gtkdbusgenerated.h"
#include "gtkentry.h"
#include "gtkbox.h"
#include "gtkintl.h"
@@ -49,6 +50,8 @@
#include "gtkimagemenuitem.h"
#include "gtkmain.h"
+#include <glib/gprintf.h>
+
/**
* SECTION:filesystem
* @short_description: Functions for working with GIO
@@ -115,6 +118,11 @@ struct _GtkMountOperationPrivate {
GtkDialog *dialog;
GdkScreen *screen;
+ /* bus proxy */
+ GtkMountOperationHandler *handler;
+ GCancellable *cancellable;
+ gboolean handler_showing;
+
/* for the ask-password dialog */
GtkWidget *entry_container;
GtkWidget *username_entry;
@@ -176,9 +184,22 @@ gtk_mount_operation_class_init (GtkMountOperationClass *klass)
static void
gtk_mount_operation_init (GtkMountOperation *operation)
{
+ gchar *name_owner;
+
operation->priv = G_TYPE_INSTANCE_GET_PRIVATE (operation,
GTK_TYPE_MOUNT_OPERATION,
GtkMountOperationPrivate);
+
+ operation->priv->handler =
+ gtk_mount_operation_handler_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION,
+ G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
+ "org.gtk.MountOperationHandler",
+ "/org/gtk/MountOperationHandler",
+ NULL, NULL);
+ name_owner = g_dbus_proxy_get_name_owner (G_DBUS_PROXY (operation->priv->handler));
+ if (!name_owner)
+ g_clear_object (&operation->priv->handler);
+ g_free (name_owner);
}
static void
@@ -193,6 +214,9 @@ gtk_mount_operation_finalize (GObject *object)
if (priv->screen)
g_object_unref (priv->screen);
+ if (priv->handler)
+ g_object_unref (priv->handler);
+
G_OBJECT_CLASS (gtk_mount_operation_parent_class)->finalize (object);
}
@@ -237,7 +261,7 @@ gtk_mount_operation_get_property (GObject *object,
break;
case PROP_IS_SHOWING:
- g_value_set_boolean (value, priv->dialog != NULL);
+ g_value_set_boolean (value, priv->dialog != NULL || priv->handler_showing);
break;
case PROP_SCREEN:
@@ -251,6 +275,21 @@ gtk_mount_operation_get_property (GObject *object,
}
static void
+gtk_mount_operation_proxy_finish (GtkMountOperation *op,
+ GMountOperationResult result)
+{
+ gtk_mount_operation_handler_call_close (op->priv->handler, NULL, NULL, NULL);
+
+ op->priv->handler_showing = FALSE;
+ g_object_notify (G_OBJECT (op), "is-showing");
+
+ g_mount_operation_reply (G_MOUNT_OPERATION (op), result);
+
+ /* drop the reference acquired when calling the proxy method */
+ g_object_unref (op);
+}
+
+static void
remember_button_toggled (GtkToggleButton *button,
GtkMountOperation *operation)
{
@@ -436,13 +475,11 @@ table_add_entry (GtkWidget *table,
}
static void
-gtk_mount_operation_ask_password (GMountOperation *mount_op,
- const char *message,
- const char *default_user,
- const char *default_domain,
- GAskPasswordFlags flags)
+gtk_mount_operation_ask_password_do_gtk (GtkMountOperation *operation,
+ const gchar *message,
+ const gchar *default_user,
+ const gchar *default_domain)
{
- GtkMountOperation *operation;
GtkMountOperationPrivate *priv;
GtkWidget *widget;
GtkDialog *dialog;
@@ -455,11 +492,8 @@ gtk_mount_operation_ask_password (GMountOperation *mount_op,
guint rows;
const gchar *secondary;
- operation = GTK_MOUNT_OPERATION (mount_op);
priv = operation->priv;
- priv->ask_flags = flags;
-
widget = gtk_dialog_new ();
dialog = GTK_DIALOG (widget);
window = GTK_WINDOW (widget);
@@ -538,7 +572,7 @@ gtk_mount_operation_ask_password (GMountOperation *mount_op,
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
gtk_box_pack_start (GTK_BOX (main_vbox), vbox, FALSE, FALSE, 0);
- can_anonymous = flags & G_ASK_PASSWORD_ANONYMOUS_SUPPORTED;
+ can_anonymous = priv->ask_flags & G_ASK_PASSWORD_ANONYMOUS_SUPPORTED;
priv->anonymous_toggle = NULL;
if (can_anonymous)
@@ -570,13 +604,13 @@ gtk_mount_operation_ask_password (GMountOperation *mount_op,
rows = 0;
- if (flags & G_ASK_PASSWORD_NEED_PASSWORD)
+ if (priv->ask_flags & G_ASK_PASSWORD_NEED_PASSWORD)
rows++;
- if (flags & G_ASK_PASSWORD_NEED_USERNAME)
+ if (priv->ask_flags & G_ASK_PASSWORD_NEED_USERNAME)
rows++;
- if (flags &G_ASK_PASSWORD_NEED_DOMAIN)
+ if (priv->ask_flags &G_ASK_PASSWORD_NEED_DOMAIN)
rows++;
/* The table that holds the entries */
@@ -593,24 +627,25 @@ gtk_mount_operation_ask_password (GMountOperation *mount_op,
rows = 0;
priv->username_entry = NULL;
- if (flags & G_ASK_PASSWORD_NEED_USERNAME)
+
+ if (priv->ask_flags & G_ASK_PASSWORD_NEED_USERNAME)
priv->username_entry = table_add_entry (table, rows++, _("_Username:"),
default_user, operation);
priv->domain_entry = NULL;
- if (flags & G_ASK_PASSWORD_NEED_DOMAIN)
+ if (priv->ask_flags & G_ASK_PASSWORD_NEED_DOMAIN)
priv->domain_entry = table_add_entry (table, rows++, _("_Domain:"),
default_domain, operation);
priv->password_entry = NULL;
- if (flags & G_ASK_PASSWORD_NEED_PASSWORD)
+ if (priv->ask_flags & G_ASK_PASSWORD_NEED_PASSWORD)
{
priv->password_entry = table_add_entry (table, rows++, _("_Password:"),
NULL, operation);
gtk_entry_set_visibility (GTK_ENTRY (priv->password_entry), FALSE);
}
- if (flags & G_ASK_PASSWORD_SAVING_SUPPORTED)
+ if (priv->ask_flags & G_ASK_PASSWORD_SAVING_SUPPORTED)
{
GtkWidget *choice;
GtkWidget *remember_box;
@@ -621,7 +656,7 @@ gtk_mount_operation_ask_password (GMountOperation *mount_op,
gtk_box_pack_start (GTK_BOX (vbox), remember_box,
FALSE, FALSE, 0);
- password_save = g_mount_operation_get_password_save (mount_op);
+ password_save = g_mount_operation_get_password_save (G_MOUNT_OPERATION (operation));
choice = gtk_radio_button_new_with_mnemonic (NULL, _("Forget password _immediately"));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (choice),
@@ -682,6 +717,89 @@ gtk_mount_operation_ask_password (GMountOperation *mount_op,
}
static void
+call_password_proxy_cb (GObject *source,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ GtkMountOperationHandler *proxy = GTK_MOUNT_OPERATION_HANDLER (source);
+ GMountOperation *op = user_data;
+ GMountOperationResult result;
+ GVariant *result_details;
+ GVariantIter iter;
+ const gchar *key;
+ GVariant *value;
+ GError *error = NULL;
+
+ if (!gtk_mount_operation_handler_call_ask_password_finish (proxy,
+ &result, &result_details, res, &error))
+ {
+ result = G_MOUNT_OPERATION_ABORTED;
+ g_warning ("Shell mount operation error: %s\n", error->message);
+ g_error_free (error);
+ goto out;
+ }
+
+ g_variant_iter_init (&iter, result_details);
+ while (g_variant_iter_loop (&iter, "{&sv}", &key, &value))
+ {
+ if (strcmp (key, "password") == 0)
+ g_mount_operation_set_password (op, g_variant_get_string (value, NULL));
+ else if (strcmp (key, "password_save") == 0)
+ g_mount_operation_set_password_save (op, g_variant_get_uint32 (value));
+ }
+
+ out:
+ gtk_mount_operation_proxy_finish (GTK_MOUNT_OPERATION (op), result);
+}
+
+static void
+gtk_mount_operation_ask_password_do_proxy (GtkMountOperation *operation,
+ const char *message,
+ const char *default_user,
+ const char *default_domain)
+{
+ gchar id[255];
+ g_sprintf(id, "GtkMountOperation%p", operation);
+
+ operation->priv->handler_showing = TRUE;
+ g_object_notify (G_OBJECT (operation), "is-showing");
+
+ /* keep a ref to the operation while the handler is showing */
+ g_object_ref (operation);
+
+ gtk_mount_operation_handler_call_ask_password (operation->priv->handler, id,
+ message, "drive-harddisk",
+ default_user, default_domain,
+ operation->priv->ask_flags, NULL,
+ call_password_proxy_cb, operation);
+}
+
+static void
+gtk_mount_operation_ask_password (GMountOperation *mount_op,
+ const char *message,
+ const char *default_user,
+ const char *default_domain,
+ GAskPasswordFlags flags)
+{
+ GtkMountOperation *operation;
+ GtkMountOperationPrivate *priv;
+ gboolean use_gtk;
+
+ operation = GTK_MOUNT_OPERATION (mount_op);
+ priv = operation->priv;
+ priv->ask_flags = flags;
+
+ use_gtk = (operation->priv->handler == NULL) ||
+ (priv->ask_flags & G_ASK_PASSWORD_NEED_DOMAIN) ||
+ (priv->ask_flags & G_ASK_PASSWORD_NEED_USERNAME);
+
+ if (use_gtk)
+ gtk_mount_operation_ask_password_do_gtk (operation, message, default_user, default_domain);
+ else
+ gtk_mount_operation_ask_password_do_proxy (operation, message, default_user, default_domain);
+}
+
+static void
question_dialog_button_clicked (GtkDialog *dialog,
gint button_number,
GMountOperation *op)
@@ -707,9 +825,9 @@ question_dialog_button_clicked (GtkDialog *dialog,
}
static void
-gtk_mount_operation_ask_question (GMountOperation *op,
- const char *message,
- const char *choices[])
+gtk_mount_operation_ask_question_do_gtk (GtkMountOperation *op,
+ const char *message,
+ const char *choices[])
{
GtkMountOperationPrivate *priv;
GtkWidget *dialog;
@@ -721,7 +839,7 @@ gtk_mount_operation_ask_question (GMountOperation *op,
g_return_if_fail (message != NULL);
g_return_if_fail (choices != NULL);
- priv = GTK_MOUNT_OPERATION (op)->priv;
+ priv = op->priv;
primary = strstr (message, "\n");
if (primary)
@@ -763,6 +881,77 @@ gtk_mount_operation_ask_question (GMountOperation *op,
}
static void
+call_question_proxy_cb (GObject *source,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ GtkMountOperationHandler *proxy = GTK_MOUNT_OPERATION_HANDLER (source);
+ GMountOperation *op = user_data;
+ GMountOperationResult result;
+ GVariant *result_details;
+ GVariantIter iter;
+ const gchar *key;
+ GVariant *value;
+ GError *error = NULL;
+
+ if (!gtk_mount_operation_handler_call_ask_question_finish (proxy, &result,
+ &result_details, res, &error))
+ {
+ result = G_MOUNT_OPERATION_ABORTED;
+ g_warning ("Shell mount operation error: %s\n", error->message);
+ g_error_free (error);
+ goto out;
+ }
+
+ g_variant_iter_init (&iter, result_details);
+ while (g_variant_iter_loop (&iter, "{&sv}", &key, &value))
+ {
+ if (strcmp (key, "choice") == 0)
+ g_mount_operation_set_choice (op, g_variant_get_int32 (value));
+ }
+
+ out:
+ gtk_mount_operation_proxy_finish (GTK_MOUNT_OPERATION (op), result);
+}
+
+static void
+gtk_mount_operation_ask_question_do_proxy (GtkMountOperation *operation,
+ const char *message,
+ const char *choices[])
+{
+ gchar id[255];
+ g_sprintf(id, "GtkMountOperation%p", operation);
+
+ operation->priv->handler_showing = TRUE;
+ g_object_notify (G_OBJECT (operation), "is-showing");
+
+ /* keep a ref to the operation while the handler is showing */
+ g_object_ref (operation);
+
+ gtk_mount_operation_handler_call_ask_question (operation->priv->handler, id,
+ message, "drive-harddisk",
+ choices, NULL,
+ call_question_proxy_cb, operation);
+}
+
+static void
+gtk_mount_operation_ask_question (GMountOperation *op,
+ const char *message,
+ const char *choices[])
+{
+ GtkMountOperation *operation;
+ gboolean use_gtk;
+
+ operation = GTK_MOUNT_OPERATION (op);
+ use_gtk = (operation->priv->handler == NULL);
+
+ if (use_gtk)
+ gtk_mount_operation_ask_question_do_gtk (operation, message, choices);
+ else
+ gtk_mount_operation_ask_question_do_proxy (operation, message, choices);
+}
+
+static void
show_processes_button_clicked (GtkDialog *dialog,
gint button_number,
GMountOperation *op)
@@ -1174,7 +1363,7 @@ on_button_press_event_for_process_tree_view (GtkWidget *widget,
}
static GtkWidget *
-create_show_processes_dialog (GMountOperation *op,
+create_show_processes_dialog (GtkMountOperation *op,
const char *message,
const char *choices[])
{
@@ -1193,7 +1382,7 @@ create_show_processes_dialog (GMountOperation *op,
GtkListStore *list_store;
gchar *s;
- priv = GTK_MOUNT_OPERATION (op)->priv;
+ priv = op->priv;
primary = strstr (message, "\n");
if (primary)
@@ -1306,10 +1495,74 @@ create_show_processes_dialog (GMountOperation *op,
}
static void
-gtk_mount_operation_show_processes (GMountOperation *op,
- const char *message,
- GArray *processes,
- const char *choices[])
+call_processes_proxy_cb (GObject *source,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ GtkMountOperationHandler *proxy = GTK_MOUNT_OPERATION_HANDLER (source);
+ GMountOperation *op = user_data;
+ GMountOperationResult result;
+ GVariant *result_details;
+ GVariantIter iter;
+ const gchar *key;
+ GVariant *value;
+ GError *error = NULL;
+
+ if (!gtk_mount_operation_handler_call_show_processes_finish (proxy,
+ &result, &result_details, res, &error))
+ {
+ result = G_MOUNT_OPERATION_ABORTED;
+ g_warning ("Shell mount operation error: %s\n", error->message);
+ g_error_free (error);
+ goto out;
+ }
+
+ /* If the request was unhandled it means we called the method again;
+ * in this case, just return and wait for the next response.
+ */
+ if (result == G_MOUNT_OPERATION_UNHANDLED)
+ return;
+
+ g_variant_iter_init (&iter, result_details);
+ while (g_variant_iter_loop (&iter, "{&sv}", &key, &value))
+ {
+ if (strcmp (key, "choice") == 0)
+ g_mount_operation_set_choice (op, g_variant_get_int32 (value));
+ }
+
+ out:
+ gtk_mount_operation_proxy_finish (GTK_MOUNT_OPERATION (op), result);
+}
+
+static void
+gtk_mount_operation_show_processes_do_proxy (GtkMountOperation *operation,
+ const char *message,
+ GArray *processes,
+ const char *choices[])
+{
+ gchar id[255];
+ g_sprintf(id, "GtkMountOperation%p", operation);
+
+ operation->priv->handler_showing = TRUE;
+ g_object_notify (G_OBJECT (operation), "is-showing");
+
+ /* keep a ref to the operation while the handler is showing */
+ g_object_ref (operation);
+
+ gtk_mount_operation_handler_call_show_processes (operation->priv->handler, id,
+ message, "drive-harddisk",
+ g_variant_new_fixed_array (G_VARIANT_TYPE_INT32,
+ processes->data, processes->len,
+ sizeof (GPid)),
+ choices, NULL,
+ call_processes_proxy_cb, operation);
+}
+
+static void
+gtk_mount_operation_show_processes_do_gtk (GtkMountOperation *op,
+ const char *message,
+ GArray *processes,
+ const char *choices[])
{
GtkMountOperationPrivate *priv;
GtkWidget *dialog = NULL;
@@ -1319,7 +1572,7 @@ gtk_mount_operation_show_processes (GMountOperation *op,
g_return_if_fail (processes != NULL);
g_return_if_fail (choices != NULL);
- priv = GTK_MOUNT_OPERATION (op)->priv;
+ priv = op->priv;
if (priv->process_list_store == NULL)
{
@@ -1329,7 +1582,7 @@ gtk_mount_operation_show_processes (GMountOperation *op,
/* otherwise, we're showing the dialog, assume messages+choices hasn't changed */
- update_process_list_store (GTK_MOUNT_OPERATION (op),
+ update_process_list_store (op,
priv->process_list_store,
processes);
@@ -1339,6 +1592,26 @@ gtk_mount_operation_show_processes (GMountOperation *op,
}
}
+
+static void
+gtk_mount_operation_show_processes (GMountOperation *op,
+ const char *message,
+ GArray *processes,
+ const char *choices[])
+{
+
+ GtkMountOperation *operation;
+ gboolean use_gtk;
+
+ operation = GTK_MOUNT_OPERATION (op);
+ use_gtk = (operation->priv->handler == NULL);
+
+ if (use_gtk)
+ gtk_mount_operation_show_processes_do_gtk (operation, message, processes, choices);
+ else
+ gtk_mount_operation_show_processes_do_proxy (operation, message, processes, choices);
+}
+
static void
gtk_mount_operation_aborted (GMountOperation *op)
{
@@ -1353,6 +1626,14 @@ gtk_mount_operation_aborted (GMountOperation *op)
g_object_notify (G_OBJECT (op), "is-showing");
g_object_unref (op);
}
+
+ if (priv->handler != NULL)
+ {
+ gtk_mount_operation_handler_call_close (priv->handler, NULL, NULL, NULL);
+
+ priv->handler_showing = FALSE;
+ g_object_notify (G_OBJECT (op), "is-showing");
+ }
}
/**