[recipes] Use the Account portal if available
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [recipes] Use the Account portal if available
- Date: Wed, 7 Dec 2016 21:46:58 +0000 (UTC)
commit 5f6210a5650c29e377856b85ddbb8f67ee3b16d9
Author: Matthias Clasen <mclasen redhat com>
Date: Wed Dec 7 16:45:08 2016 -0500
Use the Account portal if available
src/gr-edit-page.c | 219 ++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 219 insertions(+), 0 deletions(-)
---
diff --git a/src/gr-edit-page.c b/src/gr-edit-page.c
index 2af9ba4..dadd623 100644
--- a/src/gr-edit-page.c
+++ b/src/gr-edit-page.c
@@ -34,6 +34,14 @@
#include "gr-season.h"
#include "gr-images.h"
+#ifdef GDK_WINDOWING_X11
+#include <gdk/gdkx.h>
+#endif
+
+#ifdef GDK_WINDOWING_WAYLAND
+#include <gdk/gdkwayland.h>
+#endif
+
struct _GrEditPage
{
@@ -64,6 +72,8 @@ struct _GrEditPage
GtkWidget *remove_image_button;
GtkWidget *rotate_image_right_button;
GtkWidget *rotate_image_left_button;
+
+ guint account_response_signal_id;
};
G_DEFINE_TYPE (GrEditPage, gr_edit_page, GTK_TYPE_BOX)
@@ -396,6 +406,214 @@ static gboolean validate_ingredients (GrEditPage *page,
const char *ingredients,
GError **error);
+static void
+account_response (GDBusConnection *connection,
+ const char *sender_name,
+ const char *object_path,
+ const char *interface_name,
+ const char *signal_name,
+ GVariant *parameters,
+ gpointer user_data)
+{
+ GrEditPage *page = user_data;
+ guint32 response;
+ GVariant *options;
+ GrRecipeStore *store;
+ g_autoptr(GrChef) chef = NULL;
+ g_autoptr(GError) error = NULL;
+
+ g_variant_get (parameters, "(u@a{sv})", &response, &options);
+
+ if (response == 0) {
+ g_autoptr(GdkPixbuf) pixbuf = NULL;
+ const char *id;
+ const char *name;
+ const char *uri;
+ g_autofree char *path = NULL;
+
+ store = gr_app_get_recipe_store (GR_APP (g_application_get_default ()));
+ chef = gr_recipe_store_get_chef (store, gr_recipe_store_get_user_key (store));
+ if (!chef)
+ chef = gr_chef_new ();
+
+ g_variant_lookup (options, "id", "&s", &id);
+ g_variant_lookup (options, "name", "&s", &name);
+ g_variant_lookup (options, "image", "&s", &uri);
+
+ g_object_set (chef, "name", id, "fullname", name, NULL);
+
+ if (uri && uri[0]) {
+ g_autoptr(GFile) source = NULL;
+ g_autoptr(GFile) dest = NULL;
+ g_autofree char *orig_dest = NULL;
+ g_autofree char *destpath = NULL;
+ int i;
+
+ source = g_file_new_for_uri (uri);
+ orig_dest = g_build_filename (g_get_user_data_dir (), "recipes", id, NULL);
+ destpath = g_strdup (orig_dest);
+ for (i = 1; i < 10; i++) {
+ if (!g_file_test (destpath, G_FILE_TEST_EXISTS))
+ break;
+ g_free (destpath);
+ destpath = g_strdup_printf ("%s%d", orig_dest, i);
+ }
+ dest = g_file_new_for_path (destpath);
+ if (!g_file_copy (source, dest, G_FILE_COPY_NONE, NULL, NULL, NULL, &error))
+ return;
+ g_object_set (chef, "image-path", destpath, NULL);
+ }
+
+ if (!gr_recipe_store_update_user (store, chef, &error)) {
+ g_warning ("Failed to update chef for user: %s", error->message);
+ }
+ }
+
+ if (page->account_response_signal_id != 0) {
+ g_dbus_connection_signal_unsubscribe (connection,
+ page->account_response_signal_id);
+ page->account_response_signal_id = 0;
+ }
+}
+
+typedef void (*GtkWindowHandleExported) (GtkWindow *window,
+ const char *handle,
+ gpointer user_data);
+
+
+#ifdef GDK_WINDOWING_WAYLAND
+typedef struct {
+ GtkWindow *window;
+ GtkWindowHandleExported callback;
+ gpointer user_data;
+} WaylandWindowHandleExportedData;
+
+static void
+wayland_window_handle_exported (GdkWindow *window,
+ const char *wayland_handle_str,
+ gpointer user_data)
+{
+ WaylandWindowHandleExportedData *data = user_data;
+ char *handle_str;
+
+ handle_str = g_strdup_printf ("wayland:%s", wayland_handle_str);
+ data->callback (data->window, handle_str, data->user_data);
+ g_free (handle_str);
+
+ g_free (data);
+}
+#endif
+
+static gboolean
+gtk_window_export_handle (GtkWindow *window,
+ GtkWindowHandleExported callback,
+ gpointer user_data)
+{
+
+#ifdef GDK_WINDOWING_X11
+ if (GDK_IS_X11_DISPLAY (gtk_widget_get_display (GTK_WIDGET (window))))
+ {
+ GdkWindow *gdk_window = gtk_widget_get_window (GTK_WIDGET (window));
+ char *handle_str;
+ guint32 xid = (guint32) gdk_x11_window_get_xid (gdk_window);
+
+ handle_str = g_strdup_printf ("x11:%x", xid);
+ callback (window, handle_str, user_data);
+
+ return TRUE;
+ }
+#endif
+#ifdef GDK_WINDOWING_WAYLAND
+ if (GDK_IS_WAYLAND_DISPLAY (gtk_widget_get_display (GTK_WIDGET (window))))
+ {
+ GdkWindow *gdk_window = gtk_widget_get_window (GTK_WIDGET (window));
+ WaylandWindowHandleExportedData *data;
+
+ data = g_new0 (WaylandWindowHandleExportedData, 1);
+ data->window = window;
+ data->callback = callback;
+ data->user_data = user_data;
+
+ if (!gdk_wayland_window_export_handle (gdk_window,
+ wayland_window_handle_exported,
+ data,
+ g_free))
+ {
+ g_free (data);
+ return FALSE;
+ }
+ else
+ {
+ return TRUE;
+ }
+ }
+#endif
+
+ g_warning ("Couldn't export handle, unsupported windowing system");
+
+ return FALSE;
+}
+
+static void
+window_handle_exported (GtkWindow *window,
+ const char *handle_str,
+ gpointer user_data)
+{
+ GrEditPage *page = user_data;
+ g_autoptr(GError) error = NULL;
+ g_autoptr(GVariant) ret = NULL;
+ const char *handle;
+
+ g_autoptr(GDBusConnection) bus = NULL;
+
+ bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL);
+
+ ret = g_dbus_connection_call_sync (bus,
+ "org.freedesktop.portal.Desktop",
+ "/org/freedesktop/portal/desktop",
+ "org.freedesktop.portal.Account",
+ "GetUserInformation",
+ g_variant_new ("(s)", handle_str),
+ G_VARIANT_TYPE ("(o)"),
+ G_DBUS_CALL_FLAGS_NONE,
+ G_MAXINT,
+ NULL,
+ &error);
+
+ if (!ret) {
+ g_message ("Could not talk to Account portal: %s", error->message);
+ return;
+ }
+
+ g_variant_get (ret, "(&o)", &handle);
+
+ page->account_response_signal_id =
+ g_dbus_connection_signal_subscribe (bus,
+ "org.freedesktop.portal.Desktop",
+ "org.freedesktop.portal.Request",
+ "Response",
+ handle,
+ NULL,
+ G_DBUS_SIGNAL_FLAGS_NO_MATCH_RULE,
+ account_response,
+ page, NULL);
+}
+
+static void
+ensure_user_chef (GrRecipeStore *store,
+ GrEditPage *page)
+{
+ GtkWidget *window;
+ g_autoptr(GrChef) chef = NULL;
+
+ chef = gr_recipe_store_get_chef (store, gr_recipe_store_get_user_key (store));
+ if (chef)
+ return;
+
+ window = gtk_widget_get_ancestor (GTK_WIDGET (page), GTK_TYPE_WINDOW);
+ gtk_window_export_handle (GTK_WINDOW (window), window_handle_exported, page);
+}
+
gboolean
gr_edit_page_save (GrEditPage *page)
{
@@ -466,6 +684,7 @@ gr_edit_page_save (GrEditPage *page)
const char *author;
author = gr_recipe_store_get_user_key (store);
+ ensure_user_chef (store, page);
recipe = g_object_new (GR_TYPE_RECIPE,
"name", name,
"description", description,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]