summaryrefslogtreecommitdiff
path: root/gtk/gtkprintoperation-portal.c
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2017-07-01 20:14:15 -0400
committerMatthias Clasen <mclasen@redhat.com>2017-07-07 12:03:55 -0400
commitd9e38198c7774a466203e7229fe241f417306a65 (patch)
tree1be39020368ee4883ff2d94f9a52cc17ebfcec76 /gtk/gtkprintoperation-portal.c
parent388078ba88561c64299fe892720452e679e00be3 (diff)
downloadgtk+-d9e38198c7774a466203e7229fe241f417306a65.tar.gz
Avoid a race in the print portal
Same as the previous commit; use the new predictable request object path to connect to the Response signal early.
Diffstat (limited to 'gtk/gtkprintoperation-portal.c')
-rw-r--r--gtk/gtkprintoperation-portal.c55
1 files changed, 44 insertions, 11 deletions
diff --git a/gtk/gtkprintoperation-portal.c b/gtk/gtkprintoperation-portal.c
index 1272767ce9..faeee259ee 100644
--- a/gtk/gtkprintoperation-portal.c
+++ b/gtk/gtkprintoperation-portal.c
@@ -53,6 +53,7 @@ typedef struct {
GVariant *settings;
GVariant *setup;
GVariant *options;
+ char *prepare_print_handle;
} PortalData;
static void
@@ -70,7 +71,7 @@ portal_data_free (gpointer data)
g_variant_unref (portal->setup);
if (portal->options)
g_variant_unref (portal->options);
-
+ g_free (portal->prepare_print_handle);
g_free (portal);
}
@@ -453,16 +454,23 @@ prepare_print_called (GObject *source,
else
g_variant_get (ret, "(&o)", &handle);
- portal->response_signal_id =
- g_dbus_connection_signal_subscribe (g_dbus_proxy_get_connection (G_DBUS_PROXY (portal->proxy)),
- "org.freedesktop.portal.Desktop",
- "org.freedesktop.portal.Request",
- "Response",
- handle,
- NULL,
- G_DBUS_SIGNAL_FLAGS_NO_MATCH_RULE,
- prepare_print_response,
- portal, NULL);
+ if (strcmp (portal->prepare_print_handle, handle) != 0)
+ {
+ g_free (portal->prepare_print_handle);
+ portal->prepare_print_handle = g_strdup (handle);
+ g_dbus_connection_signal_unsubscribe (g_dbus_proxy_get_connection (G_DBUS_PROXY (portal->proxy)),
+ portal->response_signal_id);
+ portal->response_signal_id =
+ g_dbus_connection_signal_subscribe (g_dbus_proxy_get_connection (G_DBUS_PROXY (portal->proxy)),
+ "org.freedesktop.portal.Desktop",
+ "org.freedesktop.portal.Request",
+ "Response",
+ handle,
+ NULL,
+ G_DBUS_SIGNAL_FLAGS_NO_MATCH_RULE,
+ prepare_print_response,
+ portal, NULL);
+ }
g_variant_unref (ret);
}
@@ -547,8 +555,33 @@ call_prepare_print (GtkPrintOperation *op,
{
GtkPrintOperationPrivate *priv = op->priv;
GVariantBuilder opt_builder;
+ char *token;
+ char *sender;
+ int i;
+
+ token = g_strdup_printf ("gtk%d", g_random_int_range (0, G_MAXINT));
+ sender = g_strdup (g_dbus_connection_get_unique_name (g_dbus_proxy_get_connection (portal->proxy)) + 1);
+ for (i = 0; sender[i]; i++)
+ if (sender[i] == '.')
+ sender[i] = '_';
+
+ portal->prepare_print_handle = g_strdup_printf ("/org/fredesktop/portal/desktop/request/%s/%s", sender, token);
+ g_free (sender);
+
+ portal->response_signal_id =
+ g_dbus_connection_signal_subscribe (g_dbus_proxy_get_connection (G_DBUS_PROXY (portal->proxy)),
+ "org.freedesktop.portal.Desktop",
+ "org.freedesktop.portal.Request",
+ "Response",
+ portal->prepare_print_handle,
+ NULL,
+ G_DBUS_SIGNAL_FLAGS_NO_MATCH_RULE,
+ prepare_print_response,
+ portal, NULL);
g_variant_builder_init (&opt_builder, G_VARIANT_TYPE_VARDICT);
+ g_variant_builder_add (&opt_builder, "{sv}", "handle_token", g_variant_new_string (token));
+ g_free (token);
portal->options = g_variant_builder_end (&opt_builder);
if (priv->print_settings)