[gnome-control-center/wip/feborges/new-remote-desktop-dialog: 5/12] sharing: Port Screen Sharing dialog to RDP




commit 40be260b8fe2e43614e26c97b136a90b80aecdff
Author: Felipe Borges <felipeborges gnome org>
Date:   Thu Feb 10 13:03:21 2022 +0100

    sharing: Port Screen Sharing dialog to RDP
    
    Also following the guidelines at
    https://gitlab.gnome.org/Teams/Design/settings-mockups/-/raw/master/remote-desktop/remote-desktop.png
    
    Fixes #1413

 panels/sharing/cc-gnome-remote-desktop.c | 180 ++++++--------
 panels/sharing/cc-gnome-remote-desktop.h |  28 +--
 panels/sharing/cc-sharing-panel.c        | 409 ++++++++++++++++++++-----------
 panels/sharing/cc-sharing-panel.ui       | 259 ++++++++++---------
 4 files changed, 464 insertions(+), 412 deletions(-)
---
diff --git a/panels/sharing/cc-gnome-remote-desktop.c b/panels/sharing/cc-gnome-remote-desktop.c
index c59f3b0eb..ef7bc5303 100644
--- a/panels/sharing/cc-gnome-remote-desktop.c
+++ b/panels/sharing/cc-gnome-remote-desktop.c
@@ -22,141 +22,103 @@
 #include "cc-gnome-remote-desktop.h"
 
 const SecretSchema *
-cc_grd_vnc_password_get_schema (void)
+cc_grd_rdp_credentials_get_schema (void)
 {
-  static const SecretSchema grd_vnc_password_schema = {
-    .name = "org.gnome.RemoteDesktop.VncPassword",
+  static const SecretSchema grd_rdp_credentials_schema = {
+    .name = "org.gnome.RemoteDesktop.RdpCredentials",
     .flags = SECRET_SCHEMA_NONE,
     .attributes = {
-      { "password", SECRET_SCHEMA_ATTRIBUTE_STRING },
+      { "credentials", SECRET_SCHEMA_ATTRIBUTE_STRING },
       { "NULL", 0 },
     },
   };
 
-  return &grd_vnc_password_schema;
+  return &grd_rdp_credentials_schema;
 }
 
-gboolean
-cc_grd_get_is_auth_method_prompt (GValue   *value,
-                                  GVariant *variant,
-                                  gpointer  user_data)
-{
-  const char * auth_method;
-
-  auth_method = g_variant_get_string (variant, NULL);
-
-  if (g_strcmp0 (auth_method, "prompt") == 0)
-    {
-      g_value_set_boolean (value, TRUE);
-    }
-  else if (g_strcmp0 (auth_method, "password") == 0)
-    {
-      g_value_set_boolean (value, FALSE);
-    }
-  else
-    {
-      g_warning ("Unhandled VNC auth method %s", auth_method);
-      g_value_set_boolean (value, FALSE);
-    }
-
-  return TRUE;
-}
-
-GVariant *
-cc_grd_set_is_auth_method_prompt (const GValue       *value,
-                                  const GVariantType *type,
-                                  gpointer            user_data)
+void
+cc_grd_store_rdp_credentials (const gchar  *username,
+                              const gchar  *password,
+                              GCancellable *cancellable)
 {
-  char *auth_method;
-
-  if (g_value_get_boolean (value))
-    auth_method = "prompt";
-  else
-    auth_method = "password";
-
-  return g_variant_new_string (auth_method);
+  GVariantBuilder builder;
+  char *credentials;
+
+  g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}"));
+  g_variant_builder_add (&builder, "{sv}", "username", g_variant_new_string (username));
+  g_variant_builder_add (&builder, "{sv}", "password", g_variant_new_string (password));
+  credentials = g_variant_print (g_variant_builder_end (&builder), TRUE);
+
+  secret_password_store_sync (CC_GRD_RDP_CREDENTIALS_SCHEMA,
+                              SECRET_COLLECTION_DEFAULT,
+                              "GNOME Remote Desktop RDP credentials",
+                              credentials,
+                              NULL, NULL,
+                              NULL);
+
+  g_free (credentials);
 }
 
-gboolean
-cc_grd_get_is_auth_method_password (GValue   *value,
-                                    GVariant *variant,
-                                    gpointer  user_data)
+gchar *
+cc_grd_lookup_rdp_username (GCancellable *cancellable)
 {
-  const char *auth_method;
-
-  auth_method = g_variant_get_string (variant, NULL);
-
-  if (g_strcmp0 (auth_method, "prompt") == 0)
-    {
-      g_value_set_boolean (value, FALSE);
-    }
-  else if (g_strcmp0 (auth_method, "password") == 0)
-    {
-      g_value_set_boolean (value, TRUE);
-    }
-  else
-    {
-      g_warning ("Unhandled VNC auth method %s", auth_method);
-      g_value_set_boolean (value, FALSE);
-    }
-
-  return TRUE;
-}
+  g_autoptr(GError) error = NULL;
+  gchar *username = NULL;
+  g_autofree gchar *secret;
+  GVariant *variant = NULL;
 
-GVariant *
-cc_grd_set_is_auth_method_password (const GValue       *value,
-                                    const GVariantType *type,
-                                    gpointer            user_data)
-{
-  char *auth_method;
+  secret = secret_password_lookup_sync (CC_GRD_RDP_CREDENTIALS_SCHEMA,
+                                          cancellable, &error,
+                                          NULL);
+  if (error) {
+    g_warning ("Failed to get username: %s", error->message);
+    return NULL;
+  }
 
-  if (g_value_get_boolean (value))
-    auth_method = "password";
-  else
-    auth_method = "prompt";
+  if (secret == NULL) {
+      g_debug ("No RDP credentials available");
+      return NULL;
+  }
 
-  return g_variant_new_string (auth_method);
-}
+  variant = g_variant_parse (NULL, secret, NULL, NULL, &error);
+  if (variant == NULL) {
+    g_warning ("Invalid credentials format in the keyring: %s", error->message);
+    return NULL;
+  }
 
-static void
-on_password_stored (GObject      *source,
-                    GAsyncResult *result,
-                    gpointer      user_data)
-{
-  GError *error = NULL;
-
-  if (!secret_password_store_finish (result, &error))
-    {
-      if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
-        {
-          g_warning ("Failed to store VNC password: %s", error->message);
-        }
-      g_error_free (error);
-    }
-}
+  g_variant_lookup (variant, "username", "&s", &username);
 
-void
-cc_grd_store_vnc_password (const gchar *password, GCancellable *cancellable)
-{
-  secret_password_store (CC_GRD_VNC_PASSWORD_SCHEMA,
-                         SECRET_COLLECTION_DEFAULT,
-                         "GNOME Remote Desktop VNC password",
-                         password,
-                         cancellable, on_password_stored, NULL,
-                         NULL);
+  return username;
 }
 
 gchar *
-cc_grd_lookup_vnc_password (GCancellable *cancellable)
+cc_grd_lookup_rdp_password (GCancellable *cancellable)
 {
   g_autoptr(GError) error = NULL;
-  g_autofree gchar *password = NULL;
+  g_autofree gchar *secret;
+  gchar *password = NULL;
+  GVariant *variant = NULL;
 
-  password = secret_password_lookup_sync (CC_GRD_VNC_PASSWORD_SCHEMA,
+  secret = secret_password_lookup_sync (CC_GRD_RDP_CREDENTIALS_SCHEMA,
                                           cancellable, &error,
                                           NULL);
-  if (error)
+  if (error) {
     g_warning ("Failed to get password: %s", error->message);
+    return NULL;
+  }
+
+  if (secret == NULL) {
+      g_debug ("No RDP credentials available");
+      return NULL;
+  }
+
+  variant = g_variant_parse (NULL, secret, NULL, NULL, &error);
+  if (variant == NULL) {
+    g_warning ("Invalid credentials format in the keyring: %s", error->message);
+    return NULL;
+  }
+
+  g_variant_lookup (variant, "password", "&s", &password);
 
-  return g_steal_pointer (&password);
+  return password;
 }
diff --git a/panels/sharing/cc-gnome-remote-desktop.h b/panels/sharing/cc-gnome-remote-desktop.h
index a3a99aed4..592da3497 100644
--- a/panels/sharing/cc-gnome-remote-desktop.h
+++ b/panels/sharing/cc-gnome-remote-desktop.h
@@ -23,28 +23,14 @@
 
 G_BEGIN_DECLS
 
-const SecretSchema * cc_grd_vnc_password_get_schema (void);
-#define CC_GRD_VNC_PASSWORD_SCHEMA cc_grd_vnc_password_get_schema ()
+const SecretSchema * cc_grd_rdp_credentials_get_schema (void);
+#define CC_GRD_RDP_CREDENTIALS_SCHEMA cc_grd_rdp_credentials_get_schema ()
 
-gboolean cc_grd_get_is_auth_method_prompt (GValue   *value,
-                                           GVariant *variant,
-                                           gpointer  user_data);
+void cc_grd_store_rdp_credentials (const gchar  *username,
+                                   const gchar  *password,
+                                   GCancellable *cancellable);
 
-GVariant * cc_grd_set_is_auth_method_prompt (const GValue       *value,
-                                             const GVariantType *type,
-                                             gpointer            user_data);
-
-gboolean cc_grd_get_is_auth_method_password (GValue   *value,
-                                             GVariant *variant,
-                                             gpointer  user_data);
-
-GVariant * cc_grd_set_is_auth_method_password (const GValue       *value,
-                                               const GVariantType *type,
-                                               gpointer            user_data);
-
-void cc_grd_store_vnc_password (const gchar  *password,
-                                GCancellable *cancellable);
-
-gchar * cc_grd_lookup_vnc_password (GCancellable *cancellable);
+gchar * cc_grd_lookup_rdp_username (GCancellable *cancellable);
+gchar * cc_grd_lookup_rdp_password (GCancellable *cancellable);
 
 G_END_DECLS
diff --git a/panels/sharing/cc-sharing-panel.c b/panels/sharing/cc-sharing-panel.c
index fb48c8b29..a4f84f411 100644
--- a/panels/sharing/cc-sharing-panel.c
+++ b/panels/sharing/cc-sharing-panel.c
@@ -43,19 +43,16 @@ static GtkWidget *cc_sharing_panel_new_media_sharing_row (const char     *uri_or
 
 #define FILE_SHARING_SCHEMA_ID "org.gnome.desktop.file-sharing"
 #define GNOME_REMOTE_DESKTOP_SCHEMA_ID "org.gnome.desktop.remote-desktop"
-#define GNOME_REMOTE_DESKTOP_VNC_SCHEMA_ID "org.gnome.desktop.remote-desktop.vnc"
+#define GNOME_REMOTE_DESKTOP_RDP_SCHEMA_ID "org.gnome.desktop.remote-desktop.rdp"
 
-typedef enum
-{
-  GRD_VNC_AUTH_METHOD_PROMPT,
-  GRD_VNC_AUTH_METHOD_PASSWORD
-} GrdVncAuthMethod;
+#define REMOTE_DESKTOP_STORE_CREDENTIALS_TIMEOUT_S 1
+
+#define REMOTE_DESKTOP_SERVICE_NAME "gnome-remote-desktop"
 
 struct _CcSharingPanel
 {
   CcPanel parent_instance;
 
-  GtkWidget *approve_connections_radiobutton;
   GtkWidget *hostname_entry;
   GtkWidget *main_list_box;
   GtkWidget *master_switch;
@@ -72,34 +69,36 @@ struct _CcSharingPanel
   GtkWidget *personal_file_sharing_require_password_switch;
   GtkWidget *personal_file_sharing_row;
   GtkWidget *personal_file_sharing_switch;
-  GtkWidget *password_grid;
-  GtkWidget *remote_control_box;
-  GtkWidget *remote_control_checkbutton;
-  GtkWidget *remote_control_password_entry;
   GtkWidget *remote_login_dialog;
   GtkWidget *remote_login_label;
   GtkWidget *remote_login_row;
   GtkWidget *remote_login_switch;
-  GtkWidget *require_password_radiobutton;
-  GtkWidget *screen_sharing_dialog;
-  GtkWidget *screen_sharing_grid;
-  GtkWidget *screen_sharing_headerbar;
-  GtkWidget *screen_sharing_label;
-  GtkWidget *screen_sharing_row;
-  GtkWidget *screen_sharing_switch;
+
+  GtkWidget *remote_control_checkbutton;
+  GtkWidget *remote_desktop_password_entry;
+  GtkWidget *remote_desktop_username_entry;
+  GtkWidget *remote_desktop_dialog;
+  GtkWidget *remote_desktop_device_name_label;
+  GtkWidget *remote_desktop_address_label;
+  GtkWidget *remote_desktop_row;
+  GtkWidget *remote_desktop_switch;
+  GtkWidget *remote_desktop_fingerprint_dialog;
+
   GtkWidget *shared_folders_grid;
   GtkWidget *shared_folders_listbox;
-  GtkWidget *show_password_checkbutton;
 
   GDBusProxy *sharing_proxy;
 
   guint remote_desktop_name_watch;
+  guint remote_desktop_store_credentials_id;
 };
 
 CC_PANEL_REGISTER (CcSharingPanel, cc_sharing_panel)
 
 #define OFF_IF_VISIBLE(x, y) { if (gtk_widget_is_visible(x) && (y) != NULL && gtk_widget_is_sensitive(y)) 
gtk_switch_set_active (GTK_SWITCH(y), FALSE); }
 
+static gboolean store_remote_desktop_credentials_timeout (gpointer user_data);
+
 static void
 cc_sharing_panel_master_switch_notify (CcSharingPanel *self)
 {
@@ -112,7 +111,7 @@ cc_sharing_panel_master_switch_notify (CcSharingPanel *self)
       /* disable all services if the master switch is not active */
       OFF_IF_VISIBLE(self->media_sharing_row, self->media_sharing_switch);
       OFF_IF_VISIBLE(self->personal_file_sharing_row, self->personal_file_sharing_switch);
-      OFF_IF_VISIBLE(self->screen_sharing_row, self->screen_sharing_switch);
+      OFF_IF_VISIBLE(self->remote_desktop_row, self->remote_desktop_switch);
 
       gtk_switch_set_active (GTK_SWITCH (self->remote_login_switch), FALSE);
     }
@@ -147,14 +146,21 @@ cc_sharing_panel_dispose (GObject *object)
       self->remote_login_dialog = NULL;
     }
 
-  if (self->screen_sharing_dialog)
+  if (self->remote_desktop_dialog)
     {
-      gtk_window_destroy (GTK_WINDOW (self->screen_sharing_dialog));
-      self->screen_sharing_dialog = NULL;
+      gtk_window_destroy (GTK_WINDOW (self->remote_desktop_dialog));
+      self->remote_desktop_dialog = NULL;
     }
 
   g_clear_object (&self->sharing_proxy);
 
+  if (self->remote_desktop_store_credentials_id)
+    {
+      g_clear_handle_id (&self->remote_desktop_store_credentials_id,
+                         g_source_remove);
+      store_remote_desktop_credentials_timeout (self);
+    }
+
   G_OBJECT_CLASS (cc_sharing_panel_parent_class)->dispose (object);
 }
 
@@ -164,6 +170,20 @@ cc_sharing_panel_get_help_uri (CcPanel *panel)
   return "help:gnome-help/prefs-sharing";
 }
 
+static void
+remote_desktop_show_encryption_fingerprint (CcSharingPanel *self)
+{
+  gtk_window_set_transient_for (GTK_WINDOW (self->remote_desktop_fingerprint_dialog),
+                                GTK_WINDOW (self->remote_desktop_dialog));
+  gtk_window_present (GTK_WINDOW (self->remote_desktop_fingerprint_dialog));
+}
+
+static void
+remote_desktop_hide_encryption_fingerprint (CcSharingPanel *self)
+{
+  gtk_widget_hide (self->remote_desktop_fingerprint_dialog);
+}
+
 static void
 cc_sharing_panel_class_init (CcSharingPanelClass *klass)
 {
@@ -177,9 +197,7 @@ cc_sharing_panel_class_init (CcSharingPanelClass *klass)
 
   gtk_widget_class_set_template_from_resource (widget_class, 
"/org/gnome/control-center/sharing/cc-sharing-panel.ui");
 
-  gtk_widget_class_bind_template_child (widget_class, CcSharingPanel, approve_connections_radiobutton);
   gtk_widget_class_bind_template_child (widget_class, CcSharingPanel, hostname_entry);
-  gtk_widget_class_bind_template_child (widget_class, CcSharingPanel, screen_sharing_grid);
   gtk_widget_class_bind_template_child (widget_class, CcSharingPanel, shared_folders_grid);
   gtk_widget_class_bind_template_child (widget_class, CcSharingPanel, master_switch);
   gtk_widget_class_bind_template_child (widget_class, CcSharingPanel, main_list_box);
@@ -194,21 +212,23 @@ cc_sharing_panel_class_init (CcSharingPanelClass *klass)
   gtk_widget_class_bind_template_child (widget_class, CcSharingPanel, personal_file_sharing_password_label);
   gtk_widget_class_bind_template_child (widget_class, CcSharingPanel, 
personal_file_sharing_require_password_switch);
   gtk_widget_class_bind_template_child (widget_class, CcSharingPanel, personal_file_sharing_row);
-  gtk_widget_class_bind_template_child (widget_class, CcSharingPanel, password_grid);
-  gtk_widget_class_bind_template_child (widget_class, CcSharingPanel, remote_control_box);
-  gtk_widget_class_bind_template_child (widget_class, CcSharingPanel, remote_control_checkbutton);
-  gtk_widget_class_bind_template_child (widget_class, CcSharingPanel, remote_control_password_entry);
   gtk_widget_class_bind_template_child (widget_class, CcSharingPanel, remote_login_dialog);
   gtk_widget_class_bind_template_child (widget_class, CcSharingPanel, remote_login_label);
   gtk_widget_class_bind_template_child (widget_class, CcSharingPanel, remote_login_row);
   gtk_widget_class_bind_template_child (widget_class, CcSharingPanel, remote_login_switch);
-  gtk_widget_class_bind_template_child (widget_class, CcSharingPanel, require_password_radiobutton);
-  gtk_widget_class_bind_template_child (widget_class, CcSharingPanel, screen_sharing_dialog);
-  gtk_widget_class_bind_template_child (widget_class, CcSharingPanel, screen_sharing_headerbar);
-  gtk_widget_class_bind_template_child (widget_class, CcSharingPanel, screen_sharing_label);
-  gtk_widget_class_bind_template_child (widget_class, CcSharingPanel, screen_sharing_row);
+  gtk_widget_class_bind_template_child (widget_class, CcSharingPanel, remote_desktop_dialog);
+  gtk_widget_class_bind_template_child (widget_class, CcSharingPanel, remote_desktop_switch);
+  gtk_widget_class_bind_template_child (widget_class, CcSharingPanel, remote_control_checkbutton);
+  gtk_widget_class_bind_template_child (widget_class, CcSharingPanel, remote_desktop_username_entry);
+  gtk_widget_class_bind_template_child (widget_class, CcSharingPanel, remote_desktop_password_entry);
+  gtk_widget_class_bind_template_child (widget_class, CcSharingPanel, remote_desktop_device_name_label);
+  gtk_widget_class_bind_template_child (widget_class, CcSharingPanel, remote_desktop_address_label);
+  gtk_widget_class_bind_template_child (widget_class, CcSharingPanel, remote_desktop_fingerprint_dialog);
+  gtk_widget_class_bind_template_child (widget_class, CcSharingPanel, remote_desktop_row);
   gtk_widget_class_bind_template_child (widget_class, CcSharingPanel, shared_folders_listbox);
-  gtk_widget_class_bind_template_child (widget_class, CcSharingPanel, show_password_checkbutton);
+
+  gtk_widget_class_bind_template_callback (widget_class, remote_desktop_show_encryption_fingerprint);
+  gtk_widget_class_bind_template_callback (widget_class, remote_desktop_hide_encryption_fingerprint);
 
   g_type_ensure (CC_TYPE_LIST_ROW);
   g_type_ensure (CC_TYPE_HOSTNAME_ENTRY);
@@ -222,7 +242,7 @@ cc_sharing_panel_run_dialog (CcSharingPanel *self,
 
   /* ensure labels with the hostname are updated if the hostname has changed */
   cc_sharing_panel_setup_label_with_hostname (self,
-                                              self->screen_sharing_label);
+                                              self->remote_desktop_address_label);
   cc_sharing_panel_setup_label_with_hostname (self, self->remote_login_label);
   cc_sharing_panel_setup_label_with_hostname (self,
                                               self->personal_file_sharing_label);
@@ -246,8 +266,8 @@ cc_sharing_panel_main_list_box_row_activated (CcSharingPanel *self,
     dialog = self->personal_file_sharing_dialog;
   else if (row == GTK_LIST_BOX_ROW (self->remote_login_row))
     dialog = self->remote_login_dialog;
-  else if (row == GTK_LIST_BOX_ROW (self->screen_sharing_row))
-    dialog = self->screen_sharing_dialog;
+  else if (row == GTK_LIST_BOX_ROW (self->remote_desktop_row))
+    dialog = self->remote_desktop_dialog;
   else
     return;
 
@@ -662,11 +682,9 @@ cc_sharing_panel_setup_label (CcSharingPanel *self,
       /* TRANSLATORS: %s is replaced with a link to a "ssh <hostname>" command to run */
       text = g_strdup_printf (_("When remote login is enabled, remote users can connect using the Secure 
Shell command:\n%s"), command);
     }
-  else if (label == self->screen_sharing_label)
+  else if (label == self->remote_desktop_address_label)
     {
-      g_autofree gchar *url = g_strdup_printf ("<a href=\"vnc://%s\">vnc://%s</a>", hostname, hostname);
-      /* TRANSLATORS: %s is replaced with a link to a vnc://<hostname> URL */
-      text = g_strdup_printf (_("Screen sharing allows remote users to view or control your screen by 
connecting to %s"), url);
+      text = g_strdup_printf ("ms-rd://%s", hostname);
     }
   else
     g_assert_not_reached ();
@@ -890,151 +908,248 @@ cc_sharing_panel_check_schema_available (CcSharingPanel *self,
   return TRUE;
 }
 
-static void
-screen_sharing_show_cb (CcSharingPanel *self)
-{
-  gtk_check_button_set_active (GTK_CHECK_BUTTON (self->show_password_checkbutton),
-                               FALSE);
-}
-
-static void
-screen_sharing_hide_cb (CcSharingPanel *self)
-{
-  GtkCheckButton *ac_radio;
-  GtkEntry    *pw_entry;
-  const gchar *password;
-
-  ac_radio = GTK_CHECK_BUTTON (self->approve_connections_radiobutton);
-  pw_entry = GTK_ENTRY (self->remote_control_password_entry);
-  password = gtk_editable_get_text (GTK_EDITABLE (pw_entry));
-
-  if (password == NULL || *password == '\0')
-    gtk_check_button_set_active (ac_radio, TRUE);
-}
-
 #define MAX_PASSWORD_SIZE 8
 static void
-screen_sharing_password_insert_text_cb (CcSharingPanel *self,
+remote_desktop_password_insert_text_cb (CcSharingPanel *self,
                                         gchar          *new_text,
                                         gint            new_text_length,
                                         gpointer        position)
 {
   int l, available_size;
 
-  l = gtk_entry_buffer_get_bytes (gtk_entry_get_buffer (GTK_ENTRY (self->remote_control_password_entry)));
+  l = gtk_entry_buffer_get_bytes (gtk_entry_get_buffer (GTK_ENTRY (self->remote_desktop_password_entry)));
 
   if (l + new_text_length <= MAX_PASSWORD_SIZE)
     return;
 
-  g_signal_stop_emission_by_name (self->remote_control_password_entry, "insert-text");
-  gtk_widget_error_bell (GTK_WIDGET (self->remote_control_password_entry));
+  g_signal_stop_emission_by_name (self->remote_desktop_password_entry, "insert-text");
+  gtk_widget_error_bell (GTK_WIDGET (self->remote_desktop_password_entry));
 
   available_size = g_utf8_strlen (new_text, MAX_PASSWORD_SIZE - l);
   if (available_size == 0)
     return;
 
-  g_signal_handlers_block_by_func (self->remote_control_password_entry,
-                                   (gpointer) screen_sharing_password_insert_text_cb,
+  g_signal_handlers_block_by_func (self->remote_desktop_password_entry,
+                                   (gpointer) remote_desktop_password_insert_text_cb,
                                    self);
-  gtk_editable_insert_text (GTK_EDITABLE (self->remote_control_password_entry), new_text, available_size, 
position);
-  g_signal_handlers_unblock_by_func (self->remote_control_password_entry,
-                                     (gpointer) screen_sharing_password_insert_text_cb,
+  gtk_editable_insert_text (GTK_EDITABLE (self->remote_desktop_password_entry), new_text, available_size, 
position);
+  g_signal_handlers_unblock_by_func (self->remote_desktop_password_entry,
+                                     (gpointer) remote_desktop_password_insert_text_cb,
                                      self);
 }
 #undef MAX_PASSWORD_SIZE
 
+static gboolean
+store_remote_desktop_credentials_timeout (gpointer user_data)
+{
+  CcSharingPanel *self = CC_SHARING_PANEL (user_data);
+  const char *username, *password;
+
+  username = gtk_editable_get_text (GTK_EDITABLE (self->remote_desktop_username_entry));
+  password = gtk_editable_get_text (GTK_EDITABLE (self->remote_desktop_password_entry));
+
+  if (username && password)
+    {
+      cc_grd_store_rdp_credentials (username, password,
+                                    cc_panel_get_cancellable (CC_PANEL (self)));
+    }
+
+  self->remote_desktop_store_credentials_id = 0;
+
+  return G_SOURCE_REMOVE;
+}
+
 static void
-on_vnc_password_entry_notify_text (CcSharingPanel *self)
+remote_desktop_credentials_changed (CcSharingPanel *self)
 {
-  const char *password = gtk_editable_get_text (GTK_EDITABLE (self->remote_control_password_entry));
-  cc_grd_store_vnc_password (password, cc_panel_get_cancellable (CC_PANEL (self)));
+  g_clear_handle_id (&self->remote_desktop_store_credentials_id,
+                     g_source_remove);
+
+  self->remote_desktop_store_credentials_id =
+    g_timeout_add_seconds (REMOTE_DESKTOP_STORE_CREDENTIALS_TIMEOUT_S,
+                           store_remote_desktop_credentials_timeout,
+                           self);
+}
+
+static gboolean
+is_remote_desktop_enabled (CcSharingPanel *self)
+{
+  g_autoptr(GVariant) networks = NULL;
+  g_autoptr(GError) error = NULL;
+  GVariantIter iter;
+  const char *current_network;
+  char *uuid = NULL;
+
+  if (!gsd_sharing_call_list_networks_sync (GSD_SHARING (self->sharing_proxy),
+                                            REMOTE_DESKTOP_SERVICE_NAME,
+                                            &networks, NULL, &error))
+    {
+      g_warning ("Failed to retrieve network list: %s", error->message);
+      return FALSE;
+    }
+
+  if (g_variant_n_children (networks) == 0)
+    return FALSE;
+
+  current_network =
+    gsd_sharing_get_current_network (GSD_SHARING (self->sharing_proxy));
+  if (!current_network)
+    return FALSE;
+
+  g_variant_iter_init (&iter, networks);
+  while (g_variant_iter_next (&iter, "(sss)", &uuid, NULL, NULL))
+    {
+      if (g_strcmp0 (uuid, current_network) == 0)
+        {
+          g_free (uuid);
+          return TRUE;
+        }
+      g_free (uuid);
+    }
+  return FALSE;
 }
 
 static void
-cc_sharing_panel_setup_screen_sharing_dialog_gnome_remote_desktop (CcSharingPanel *self)
+enable_gnome_remote_desktop_service (CcSharingPanel *self)
 {
-  g_autofree gchar *password = NULL;
-  g_autoptr(GSettings) vnc_settings = NULL;
-  GtkWidget *networks, *w;
+  g_autoptr(GError) error = NULL;
 
-  cc_sharing_panel_bind_switch_to_widgets (self->require_password_radiobutton, self->password_grid, NULL);
+  if (is_remote_desktop_enabled (self))
+    return;
 
-  cc_sharing_panel_setup_label_with_hostname (self, self->screen_sharing_label);
+  if (!gsd_sharing_call_enable_service_sync (GSD_SHARING (self->sharing_proxy),
+                                             REMOTE_DESKTOP_SERVICE_NAME,
+                                             NULL,
+                                             &error))
+    g_warning ("Failed to enable remote desktop service: %s", error->message);
+}
 
-  g_object_bind_property (self->show_password_checkbutton,
-                          "active",
-                          self->remote_control_password_entry,
-                          "visibility",
-                          G_BINDING_SYNC_CREATE);
+static void
+disable_gnome_remote_desktop_service (CcSharingPanel *self)
+{
+  g_autoptr(GError) error = NULL;
+  const char *current_network;
+  GCancellable *cancellable;
 
-  /* make sure the password entry is hidden by default */
-  g_signal_connect_object (self->screen_sharing_dialog,
-                           "show",
-                           G_CALLBACK (screen_sharing_show_cb),
-                           self,
-                           G_CONNECT_SWAPPED);
+  if (!is_remote_desktop_enabled (self))
+    return;
 
-  g_signal_connect_object (self->screen_sharing_dialog,
-                           "hide",
-                           G_CALLBACK (screen_sharing_hide_cb),
-                           self,
-                           G_CONNECT_SWAPPED);
+  cancellable = cc_panel_get_cancellable (CC_PANEL (self));
+  g_cancellable_cancel (cancellable);
+  g_cancellable_reset (cancellable);
+
+  current_network =
+    gsd_sharing_get_current_network (GSD_SHARING (self->sharing_proxy));
+  if (!gsd_sharing_call_disable_service_sync (GSD_SHARING (self->sharing_proxy),
+                                              REMOTE_DESKTOP_SERVICE_NAME,
+                                              current_network,
+                                              NULL,
+                                              &error))
+    g_warning ("Failed to disable remote desktop service: %s", error->message);
+}
 
-  password = cc_grd_lookup_vnc_password (cc_panel_get_cancellable (CC_PANEL (self)));
-  if (password != NULL)
-    gtk_editable_set_text (GTK_EDITABLE (self->remote_control_password_entry), password);
+static void
+on_remote_desktop_state_changed (GtkWidget      *widget,
+                                 GParamSpec     *pspec,
+                                 CcSharingPanel *self)
+{
+  if (gtk_switch_get_active (GTK_SWITCH (widget)))
+    enable_gnome_remote_desktop_service (self);
+  else
+    disable_gnome_remote_desktop_service (self);
+}
 
-  /* accept at most 8 bytes in password entry */
-  g_signal_connect_object (self->remote_control_password_entry,
-                           "insert-text",
-                           G_CALLBACK (screen_sharing_password_insert_text_cb),
-                           self,
-                           G_CONNECT_SWAPPED);
+static char *
+get_hostname (void)
+{
+  g_autoptr(GDBusConnection) bus = NULL;
+  g_autoptr(GVariant) res = NULL;
+  g_autoptr(GVariant) inner = NULL;
+  g_autoptr(GError) error = NULL;
+
+  bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error);
+  if (bus == NULL)
+    {
+      g_warning ("Failed to get system bus connection: %s", error->message);
+      return NULL;
+    }
+  res = g_dbus_connection_call_sync (bus,
+                                     "org.freedesktop.hostname1",
+                                     "/org/freedesktop/hostname1",
+                                     "org.freedesktop.DBus.Properties",
+                                     "Get",
+                                     g_variant_new ("(ss)",
+                                                    "org.freedesktop.hostname1",
+                                                    "PrettyHostname"),
+                                     (GVariantType*)"(v)",
+                                     G_DBUS_CALL_FLAGS_NONE,
+                                     -1,
+                                     NULL,
+                                     &error);
+
+  if (res == NULL)
+    {
+      g_warning ("Getting pretty hostname failed: %s", error->message);
+      return NULL;
+    }
+
+  g_variant_get (res, "(v)", &inner);
+  return g_variant_dup_string (inner, NULL);
+}
+
+static void
+cc_sharing_panel_setup_remote_desktop_dialog (CcSharingPanel *self)
+{
+  const gchar *username = NULL;
+  const gchar *password = NULL;
+  g_autoptr(GSettings) rdp_settings = NULL;
+  g_autofree char *hostname = NULL;
+
+  cc_sharing_panel_bind_switch_to_label (self, self->remote_desktop_switch,
+                                         self->remote_desktop_row);
+
+  cc_sharing_panel_setup_label_with_hostname (self, self->remote_desktop_address_label);
 
-  /* Bind settings to widgets */
-  vnc_settings = g_settings_new (GNOME_REMOTE_DESKTOP_VNC_SCHEMA_ID);
+  rdp_settings = g_settings_new (GNOME_REMOTE_DESKTOP_RDP_SCHEMA_ID);
 
-  g_settings_bind (vnc_settings,
+  g_settings_bind (rdp_settings,
                    "view-only",
                    self->remote_control_checkbutton,
                    "active",
                    G_SETTINGS_BIND_DEFAULT | G_SETTINGS_BIND_INVERT_BOOLEAN);
+  g_object_bind_property (self->remote_desktop_switch, "state",
+                          self->remote_control_checkbutton, "sensitive",
+                          G_BINDING_SYNC_CREATE);
 
-  g_settings_bind_with_mapping (vnc_settings,
-                                "auth-method",
-                                self->approve_connections_radiobutton,
-                                "active",
-                                G_SETTINGS_BIND_DEFAULT,
-                                cc_grd_get_is_auth_method_prompt,
-                                cc_grd_set_is_auth_method_prompt,
-                                NULL,
-                                NULL);
-
-  g_settings_bind_with_mapping (vnc_settings,
-                                "auth-method",
-                                self->require_password_radiobutton,
-                                "active",
-                                G_SETTINGS_BIND_DEFAULT,
-                                cc_grd_get_is_auth_method_password,
-                                cc_grd_set_is_auth_method_password,
-                                NULL,
-                                NULL);
-
-  g_signal_connect_object (self->remote_control_password_entry,
-                           "notify::text",
-                           G_CALLBACK (on_vnc_password_entry_notify_text),
-                           self,
-                           G_CONNECT_SWAPPED);
+  hostname = get_hostname ();
+  gtk_label_set_label (GTK_LABEL (self->remote_desktop_device_name_label),
+                       hostname);
 
-  networks = cc_sharing_networks_new (self->sharing_proxy, "gnome-remote-desktop");
-  gtk_box_append (GTK_BOX (self->remote_control_box), networks);
+  username = cc_grd_lookup_rdp_username (cc_panel_get_cancellable (CC_PANEL (self)));
+  if (username != NULL)
+    gtk_editable_set_text (GTK_EDITABLE (self->remote_desktop_username_entry), username);
 
-  w = create_switch_with_bindings (GTK_SWITCH (g_object_get_data (G_OBJECT (networks), "switch")));
-  gtk_header_bar_pack_start (GTK_HEADER_BAR (self->screen_sharing_headerbar), w);
-  self->screen_sharing_switch = w;
+  password = cc_grd_lookup_rdp_password (cc_panel_get_cancellable (CC_PANEL (self)));
+  if (password != NULL)
+    gtk_editable_set_text (GTK_EDITABLE (self->remote_desktop_password_entry), password);
 
-  cc_sharing_panel_bind_networks_to_label (self, networks,
-                                           self->screen_sharing_row);
+  g_signal_connect_swapped (self->remote_desktop_username_entry,
+                            "notify::text",
+                            G_CALLBACK (remote_desktop_credentials_changed),
+                            self);
+  g_signal_connect_swapped (self->remote_desktop_password_entry,
+                            "notify::text",
+                            G_CALLBACK (remote_desktop_credentials_changed),
+                            self);
+
+  g_signal_connect (self->remote_desktop_switch, "notify::state",
+                    G_CALLBACK (on_remote_desktop_state_changed), self);
+
+  if (is_remote_desktop_enabled (self))
+    {
+      gtk_switch_set_active (GTK_SWITCH (self->remote_desktop_switch),
+                             TRUE);
+    }
 }
 
 static void
@@ -1048,8 +1163,8 @@ remote_desktop_name_appeared (GDBusConnection *connection,
   g_bus_unwatch_name (self->remote_desktop_name_watch);
   self->remote_desktop_name_watch = 0;
 
-  cc_sharing_panel_setup_screen_sharing_dialog_gnome_remote_desktop (self);
-  gtk_widget_show (self->screen_sharing_row);
+  cc_sharing_panel_setup_remote_desktop_dialog (self);
+  gtk_widget_show (self->remote_desktop_row);
 }
 
 static void
@@ -1058,7 +1173,7 @@ check_remote_desktop_available (CcSharingPanel *self)
   if (!cc_sharing_panel_check_schema_available (self, GNOME_REMOTE_DESKTOP_SCHEMA_ID))
     return;
 
-  if (!cc_sharing_panel_check_schema_available (self, GNOME_REMOTE_DESKTOP_VNC_SCHEMA_ID))
+  if (!cc_sharing_panel_check_schema_available (self, GNOME_REMOTE_DESKTOP_RDP_SCHEMA_ID))
     return;
 
   self->remote_desktop_name_watch = g_bus_watch_name (G_BUS_TYPE_SESSION,
@@ -1103,7 +1218,7 @@ sharing_proxy_ready (GObject      *source,
 
   /* screen sharing */
   check_remote_desktop_available (self);
-  gtk_widget_hide (self->screen_sharing_row);
+  gtk_widget_hide (self->remote_desktop_row);
 }
 
 static void
@@ -1122,7 +1237,7 @@ cc_sharing_panel_init (CcSharingPanel *self)
                     G_CALLBACK (gtk_widget_hide), NULL);
   g_signal_connect (self->remote_login_dialog, "response",
                     G_CALLBACK (gtk_widget_hide), NULL);
-  g_signal_connect (self->screen_sharing_dialog, "response",
+  g_signal_connect (self->remote_desktop_dialog, "response",
                     G_CALLBACK (gtk_widget_hide), NULL);
 
   gtk_list_box_set_activate_on_single_click (GTK_LIST_BOX (self->main_list_box),
diff --git a/panels/sharing/cc-sharing-panel.ui b/panels/sharing/cc-sharing-panel.ui
index 57bac425f..04fcc6b5d 100644
--- a/panels/sharing/cc-sharing-panel.ui
+++ b/panels/sharing/cc-sharing-panel.ui
@@ -59,10 +59,10 @@
                       </object>
                     </child>
                     <child>
-                      <object class="CcListRow" id="screen_sharing_row">
+                      <object class="CcListRow" id="remote_desktop_row">
                         <property name="show-arrow">True</property>
                         <property name="use-underline">True</property>
-                        <property name="title" translatable="yes">_Screen Sharing</property>
+                        <property name="title" translatable="yes">Remote _Desktop</property>
                       </object>
                     </child>
                     <child>
@@ -246,156 +246,145 @@
     </child>
 
   </object>
-  <object class="GtkDialog" id="screen_sharing_dialog">
-    <property name="title" translatable="yes">Screen Sharing</property>
-    <property name="resizable">False</property>
-    <property name="use_header_bar">1</property>
+  <object class="GtkDialog" id="remote_desktop_dialog">
+    <property name="title" translatable="yes">Remote Desktop</property>
     <property name="modal">True</property>
+    <property name="default-width">640</property>
+    <child type="titlebar">
+      <object class="GtkHeaderBar">
+        <property name="show_title_buttons">True</property>
+      </object>
+    </child>
+
     <child>
-      <object class="GtkBox">
-        <property name="margin-top">12</property>
-        <property name="margin-bottom">12</property>
-        <property name="margin-start">12</property>
-        <property name="margin-end">12</property>
-        <property name="orientation">vertical</property>
+      <object class="AdwPreferencesPage">
         <child>
-          <object class="GtkBox" id="box8">
-            <property name="orientation">vertical</property>
+          <object class="AdwPreferencesGroup">
+            <property name="description" translatable="yes">Remote desktop allows viewing and controlling 
your desktop from another computer.</property>
+
             <child>
-              <object class="GtkGrid" id="screen_sharing_grid">
-                <property name="margin_start">12</property>
-                <property name="margin_end">6</property>
-                <property name="margin_bottom">12</property>
-                <property name="row_spacing">12</property>
-                <property name="column_spacing">6</property>
-                <child>
-                  <object class="GtkLabel" id="screen_sharing_label">
-                    <property name="xalign">0</property>
-                    <property name="label">Screen sharing allows remote users to view or control your screen 
by connecting to: &lt;a href="vnc://%s"&gt;vnc://%s&lt;/a&gt;</property>
-                    <property name="use_markup">True</property>
-                    <property name="wrap">True</property>
-                    <property name="max-width-chars">36</property>
-                    <property name="margin_bottom">6</property>
-                    <layout>
-                      <property name="column">0</property>
-                      <property name="row">0</property>
-                      <property name="column-span">2</property>
-                    </layout>
+              <object class="AdwActionRow">
+                <property name="title" translatable="yes">Remote Desktop</property>
+                <property name="subtitle" translatable="yes">Enable or disable remote desktop connections to 
this computer.</property>
+                <child type="suffix">
+                  <object class="GtkSwitch" id="remote_desktop_switch">
+                    <property name="state">False</property>
+                    <property name="valign">center</property>
                   </object>
                 </child>
-                <child>
-                  <object class="GtkBox" id="remote_control_box">
-                    <property name="orientation">vertical</property>
-                    <property name="spacing">12</property>
-                    <layout>
-                      <property name="column">0</property>
-                      <property name="row">2</property>
-                      <property name="column-span">2</property>
-                    </layout>
-                    <child>
-                      <object class="GtkCheckButton" id="remote_control_checkbutton">
-                        <property name="use_underline">True</property>
-                        <property name="label" translatable="yes">_Allow connections to control the 
screen</property>
-                      </object>
-                    </child>
-                    <child>
-                      <object class="GtkGrid" id="remote_control_grid">
-                        <property name="row_spacing">6</property>
-                        <child>
-                          <object class="GtkGrid" id="password_grid">
-                            <property name="row_spacing">6</property>
-                            <property name="column_spacing">6</property>
-                            <layout>
-                              <property name="column">0</property>
-                              <property name="row">3</property>
-                            </layout>
-                            <child>
-                              <object class="GtkLabel" id="remote_control_password_label">
-                                <property name="halign">start</property>
-                                <property name="margin_start">12</property>
-                                <property name="label" translatable="yes">_Password:</property>
-                                <property name="use_underline">True</property>
-                                <property name="mnemonic_widget">remote_control_password_entry</property>
-                                <layout>
-                                  <property name="column">0</property>
-                                  <property name="row">0</property>
-                                </layout>
-                              </object>
-                            </child>
-                            <child>
-                              <object class="GtkEntry" id="remote_control_password_entry">
-                                <property name="hexpand">True</property>
-                                <property name="visibility">False</property>
-                                <property name="invisible_char">●</property>
-                                <property name="input_purpose">password</property>
-                                <layout>
-                                  <property name="column">1</property>
-                                  <property name="row">0</property>
-                                </layout>
-                              </object>
-                            </child>
-                            <child>
-                              <object class="GtkCheckButton" id="show_password_checkbutton">
-                                <property name="label" translatable="yes">_Show Password</property>
-                                <property name="use_underline">True</property>
-                                <layout>
-                                  <property name="column">1</property>
-                                  <property name="row">1</property>
-                                </layout>
-                              </object>
-                            </child>
-                          </object>
-                        </child>
-                        <child>
-                          <object class="GtkLabel" id="label2">
-                            <property name="xalign">0</property>
-                            <property name="label" translatable="yes">Access Options</property>
-                            <layout>
-                              <property name="column">0</property>
-                              <property name="row">0</property>
-                            </layout>
-                            <attributes>
-                              <attribute name="weight" value="bold"/>
-                            </attributes>
-                          </object>
-                        </child>
-                        <child>
-                          <object class="GtkCheckButton" id="approve_connections_radiobutton">
-                            <property name="label" translatable="yes">_New connections must ask for 
access</property>
-                            <property name="group">require_password_radiobutton</property>
-                            <property name="use_underline">True</property>
-                            <layout>
-                              <property name="column">0</property>
-                              <property name="row">1</property>
-                            </layout>
-                          </object>
-                        </child>
-                        <child>
-                          <object class="GtkCheckButton" id="require_password_radiobutton">
-                            <property name="label" translatable="yes">_Require a password</property>
-                            <property name="use_underline">True</property>
-                            <layout>
-                              <property name="column">0</property>
-                              <property name="row">2</property>
-                            </layout>
-                          </object>
-                        </child>
-                      </object>
-                    </child>
+              </object>
+            </child>
+
+            <child>
+              <object class="AdwActionRow">
+                <property name="title" translatable="yes">Remote Control</property>
+                <property name="subtitle" translatable="yes">Allows remote connections to control the 
screen.</property>
+                <child type="suffix">
+                  <object class="GtkSwitch" id="remote_control_checkbutton">
+                    <property name="valign">center</property>
+                  </object>
+                </child>
+              </object>
+            </child>
+          </object>
+        </child>
+
+        <child>
+          <object class="AdwPreferencesGroup">
+            <property name="title" translatable="yes">How to Connect</property>
+            <property name="description" translatable="yes">Connect to this computer using the device name 
or remote desktop address.</property>
+
+            <child>
+              <object class="AdwActionRow">
+                <property name="title" translatable="yes">Device Name</property>
+                <child type="suffix">
+                  <object class="GtkLabel" id="remote_desktop_device_name_label"/>
+                </child>
+              </object>
+            </child>
+            <child>
+              <object class="AdwActionRow">
+                <property name="title" translatable="yes">Remote Desktop Address</property>
+                <child type="suffix">
+                  <object class="GtkLabel" id="remote_desktop_address_label"/>
+                </child>
+              </object>
+            </child>
+          </object>
+        </child>
+
+        <child>
+          <object class="AdwPreferencesGroup">
+            <property name="title" translatable="yes">Authentication</property>
+            <property name="description" translatable="yes">The user name and password are required to 
connect to this computer.</property>
+
+            <child>
+              <object class="AdwActionRow">
+                <property name="title" translatable="yes">User Name</property>
+                <child type="suffix">
+                  <object class="GtkEntry" id="remote_desktop_username_entry">
+                    <property name="hexpand">True</property>
+                    <property name="valign">center</property>
+                  </object>
+                </child>
+              </object>
+            </child>
+
+            <child>
+              <object class="AdwActionRow">
+                <property name="title" translatable="yes">Password</property>
+                <child type="suffix">
+                  <object class="GtkPasswordEntry" id="remote_desktop_password_entry">
+                    <property name="hexpand">True</property>
+                    <property name="show-peek-icon">True</property>
+                    <property name="valign">center</property>
                   </object>
                 </child>
               </object>
             </child>
+
+            <child>
+              <object class="GtkButton" id="remote_desktop_verify_encryption">
+                <property name="sensitive">False</property>
+                <property name="halign">end</property>
+                <property name="margin-top">12</property>
+                <property name="label" translatable="yes">Verify Encryption</property>
+                <signal name="clicked" handler="remote_desktop_show_encryption_fingerprint" swapped="yes"/>
+              </object>
+            </child>
           </object>
         </child>
       </object>
     </child>
-    <child type="titlebar">
-      <object class="GtkHeaderBar" id="screen_sharing_headerbar">
-        <property name="show_title_buttons">True</property>
+  </object>
+
+  <object class="AdwWindow" id="remote_desktop_fingerprint_dialog">
+    <property name="default-width">360</property>
+    <property name="default-height">360</property>
+    <property name="modal">True</property>
+    <child>
+      <object class="GtkBox">
+        <property name="orientation">vertical</property>
+        <child>
+          <object class="GtkButton">
+            <property name="halign">end</property>
+            <property name="icon-name">window-close-symbolic</property>
+            <signal name="clicked" handler="remote_desktop_hide_encryption_fingerprint" swapped="yes"/>
+            <style>
+              <class name="flat"/>
+            </style>
+          </object>
+        </child>
+        <child>
+          <object class="AdwStatusPage">
+            <property name="title" translatable="yes">Encryption Fingerprint</property>
+            <property name="description" translatable="yes">The encryption fingerprint can be seen in 
connecting clients and should be identical</property>
+          </object>
+        </child>
       </object>
     </child>
   </object>
+
   <object class="GtkDialog" id="media_sharing_dialog">
     <property name="title" translatable="yes">Media Sharing</property>
     <property name="resizable">False</property>


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