remote-desktop/session: Forward MetaSelection::owner-changed

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1552>
This commit is contained in:
Jonas Ådahl 2020-11-04 10:27:40 +01:00 committed by Marge Bot
parent ac1a5366b1
commit 6398d5a109

View File

@ -33,6 +33,7 @@
#include "backends/meta-remote-access-controller-private.h"
#include "backends/x11/meta-backend-x11.h"
#include "cogl/cogl.h"
#include "core/display-private.h"
#include "meta/meta-backend.h"
#include "meta-dbus-remote-desktop.h"
@ -52,6 +53,7 @@ struct _MetaRemoteDesktopSession
{
MetaDBusRemoteDesktopSessionSkeleton parent;
GDBusConnection *connection;
char *peer_name;
char *session_id;
@ -68,6 +70,8 @@ struct _MetaRemoteDesktopSession
MetaRemoteDesktopSessionHandle *handle;
gboolean is_clipboard_enabled;
gulong owner_changed_handler_id;
unsigned int transfer_serial;
};
static void
@ -231,16 +235,15 @@ meta_remote_desktop_session_new (MetaRemoteDesktop *remote_desktop,
{
GDBusInterfaceSkeleton *interface_skeleton;
MetaRemoteDesktopSession *session;
GDBusConnection *connection;
session = g_object_new (META_TYPE_REMOTE_DESKTOP_SESSION, NULL);
session->peer_name = g_strdup (peer_name);
interface_skeleton = G_DBUS_INTERFACE_SKELETON (session);
connection = meta_remote_desktop_get_connection (remote_desktop);
session->connection = meta_remote_desktop_get_connection (remote_desktop);
if (!g_dbus_interface_skeleton_export (interface_skeleton,
connection,
session->connection,
session->object_path,
error))
{
@ -793,12 +796,103 @@ handle_notify_touch_up (MetaDBusRemoteDesktopSession *skeleton,
return TRUE;
}
static const char *
mime_types_to_string (char **formats,
char *buf,
int buf_len)
{
g_autofree char *mime_types_string = NULL;
int len;
if (!formats)
return "N\\A";
mime_types_string = g_strjoinv (",", formats);
len = strlen (mime_types_string);
strncpy (buf, mime_types_string, buf_len - 1);
if (len >= buf_len - 1)
buf[buf_len - 2] = '*';
buf[buf_len - 1] = '\0';
return buf;
}
static GVariant *
generate_owner_changed_variant (char **mime_types_array)
{
GVariantBuilder builder;
g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}"));
if (mime_types_array)
{
g_variant_builder_add (&builder, "{sv}", "mime-types",
g_variant_new ("(^as)", mime_types_array));
}
return g_variant_builder_end (&builder);
}
static void
on_selection_owner_changed (MetaSelection *selection,
MetaSelectionType selection_type,
MetaSelectionSource *owner,
MetaRemoteDesktopSession *session)
{
char log_buf[255];
g_autofree char **mime_types_array = NULL;
GList *l;
int i;
GVariant *options_variant;
const char *object_path;
if (selection_type != META_SELECTION_CLIPBOARD)
return;
if (owner)
{
GList *mime_types;
mime_types = meta_selection_source_get_mimetypes (owner);
mime_types_array = g_new0 (char *, g_list_length (mime_types) + 1);
for (l = meta_selection_source_get_mimetypes (owner), i = 0;
l;
l = l->next, i++)
mime_types_array[i] = l->data;
}
meta_topic (META_DEBUG_REMOTE_DESKTOP,
"Clipboard owner changed, owner: %p (%s), mime types: [%s], "
"notifying %s",
owner,
owner ? g_type_name_from_instance ((GTypeInstance *) owner)
: "NULL",
mime_types_to_string (mime_types_array, log_buf,
G_N_ELEMENTS (log_buf)),
session->peer_name);
options_variant = generate_owner_changed_variant (mime_types_array);
object_path = g_dbus_interface_skeleton_get_object_path (
G_DBUS_INTERFACE_SKELETON (session));
g_dbus_connection_emit_signal (session->connection,
NULL,
object_path,
"org.gnome.Mutter.RemoteDesktop.Session",
"SelectionOwnerChanged",
g_variant_new ("(@a{sv})", options_variant),
NULL);
session->transfer_serial++;
}
static gboolean
handle_enable_clipboard (MetaDBusRemoteDesktopSession *skeleton,
GDBusMethodInvocation *invocation,
GVariant *arg_options)
{
MetaRemoteDesktopSession *session = META_REMOTE_DESKTOP_SESSION (skeleton);
MetaDisplay *display = meta_get_display ();
MetaSelection *selection = meta_display_get_selection (display);
meta_topic (META_DEBUG_REMOTE_DESKTOP,
"Enable clipboard for %s",
@ -813,6 +907,10 @@ handle_enable_clipboard (MetaDBusRemoteDesktopSession *skeleton,
}
session->is_clipboard_enabled = TRUE;
session->owner_changed_handler_id =
g_signal_connect (selection, "owner-changed",
G_CALLBACK (on_selection_owner_changed),
session);
meta_dbus_remote_desktop_session_complete_enable_clipboard (skeleton,
invocation);
@ -825,6 +923,8 @@ handle_disable_clipboard (MetaDBusRemoteDesktopSession *skeleton,
GDBusMethodInvocation *invocation)
{
MetaRemoteDesktopSession *session = META_REMOTE_DESKTOP_SESSION (skeleton);
MetaDisplay *display = meta_get_display ();
MetaSelection *selection = meta_display_get_selection (display);
meta_topic (META_DEBUG_REMOTE_DESKTOP,
"Disable clipboard for %s",
@ -838,6 +938,8 @@ handle_disable_clipboard (MetaDBusRemoteDesktopSession *skeleton,
return TRUE;
}
g_clear_signal_handler (&session->owner_changed_handler_id, selection);
meta_dbus_remote_desktop_session_complete_disable_clipboard (skeleton,
invocation);
@ -889,6 +991,18 @@ handle_selection_write (MetaDBusRemoteDesktopSession *skeleton,
return TRUE;
}
if (session->transfer_serial != serial)
{
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
G_DBUS_ERROR_FAILED,
"Provided transfer serial %u "
"doesn't match current current "
"transfer serial %u",
serial,
session->transfer_serial);
return TRUE;
}
meta_dbus_remote_desktop_session_complete_selection_write (skeleton,
invocation,
NULL,
@ -990,9 +1104,13 @@ static void
meta_remote_desktop_session_finalize (GObject *object)
{
MetaRemoteDesktopSession *session = META_REMOTE_DESKTOP_SESSION (object);
MetaDisplay *display = meta_get_display ();
MetaSelection *selection = meta_display_get_selection (display);
g_assert (!meta_remote_desktop_session_is_running (session));
g_clear_signal_handler (&session->owner_changed_handler_id, selection);
g_clear_object (&session->handle);
g_free (session->peer_name);
g_free (session->session_id);