Blob Blame History Raw
From 72da5fc3a24d531cc4de31238737ff75db06a215 Mon Sep 17 00:00:00 2001
From: Marek Kasik <mkasik@redhat.com>
Date: Fri, 4 Sep 2015 16:25:54 +0200
Subject: [PATCH] Allow scaling of RDP sessions

Add ability to scale RDP sessions using scaling functionality of cairo library.
Session is placed in the center of the window as in other plugins.

https://bugzilla.gnome.org/show_bug.cgi?id=753766
---
 Makefile.am                          |   2 +
 plugins/rdp/vinagre-rdp-connection.c | 118 +++++++++++++++++-
 plugins/rdp/vinagre-rdp-connection.h |   6 +-
 plugins/rdp/vinagre-rdp-plugin.c     |  16 ++-
 plugins/rdp/vinagre-rdp-tab.c        | 224 +++++++++++++++++++++++++++++++++--
 5 files changed, 355 insertions(+), 11 deletions(-)

diff --git a/Makefile.am b/Makefile.am
index 09ff61e..6c1ba2d 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -153,6 +153,8 @@ vinagre_vinagre_SOURCES += \
 	plugins/rdp/vinagre-rdp-plugin.c \
 	plugins/rdp/vinagre-rdp-connection.c \
 	plugins/rdp/vinagre-rdp-tab.c
+
+vinagre_vinagre_LDADD += -lm
 endif
 
 if VINAGRE_ENABLE_SPICE
diff --git a/plugins/rdp/vinagre-rdp-connection.c b/plugins/rdp/vinagre-rdp-connection.c
index 66cf01f..f0ff02b 100644
--- a/plugins/rdp/vinagre-rdp-connection.c
+++ b/plugins/rdp/vinagre-rdp-connection.c
@@ -23,9 +23,17 @@
 #include <vinagre/vinagre-cache-prefs.h>
 #include "vinagre-rdp-connection.h"
 
+#include "vinagre-vala.h"
+
 struct _VinagreRdpConnectionPrivate
 {
-  gint dummy;
+  gboolean scaling;
+};
+
+enum
+{
+  PROP_0,
+  PROP_SCALING,
 };
 
 #define VINAGRE_RDP_CONNECTION_PRIVATE(o)  (G_TYPE_INSTANCE_GET_PRIVATE ((o), VINAGRE_TYPE_RDP_CONNECTION, VinagreRdpConnectionPrivate))
@@ -44,15 +52,76 @@ vinagre_rdp_connection_constructed (GObject *object)
 }
 
 static void
+vinagre_rdp_connection_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
+{
+  VinagreRdpConnection *conn;
+
+  g_return_if_fail (VINAGRE_IS_RDP_CONNECTION (object));
+
+  conn = VINAGRE_RDP_CONNECTION (object);
+
+  switch (prop_id)
+    {
+      case PROP_SCALING:
+        vinagre_rdp_connection_set_scaling (conn, g_value_get_boolean (value));
+        break;
+
+      default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+        break;
+    }
+}
+
+static void
+vinagre_rdp_connection_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
+{
+  VinagreRdpConnection *conn;
+
+  g_return_if_fail (VINAGRE_IS_RDP_CONNECTION (object));
+
+  conn = VINAGRE_RDP_CONNECTION (object);
+
+  switch (prop_id)
+    {
+      case PROP_SCALING:
+        g_value_set_boolean (value, conn->priv->scaling);
+        break;
+
+      default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+        break;
+    }
+}
+
+static void
 rdp_fill_writer (VinagreConnection *conn, xmlTextWriter *writer)
 {
+  VinagreRdpConnection *rdp_conn = VINAGRE_RDP_CONNECTION (conn);
   VINAGRE_CONNECTION_CLASS (vinagre_rdp_connection_parent_class)->impl_fill_writer (conn, writer);
+
+  xmlTextWriterWriteFormatElement (writer, BAD_CAST "scaling", "%d", rdp_conn->priv->scaling);
 }
 
 static void
 rdp_parse_item (VinagreConnection *conn, xmlNode *root)
 {
+  xmlNode *curr;
+  xmlChar *s_value;
+  VinagreRdpConnection *rdp_conn = VINAGRE_RDP_CONNECTION (conn);
+
   VINAGRE_CONNECTION_CLASS (vinagre_rdp_connection_parent_class)->impl_parse_item (conn, root);
+
+  for (curr = root->children; curr; curr = curr->next)
+    {
+      s_value = xmlNodeGetContent (curr);
+
+      if (!xmlStrcmp(curr->name, BAD_CAST "scaling"))
+        {
+          vinagre_rdp_connection_set_scaling (rdp_conn, vinagre_utils_parse_boolean ((const gchar *) s_value));
+        }
+
+      xmlFree (s_value);
+    }
 }
 
 static void
@@ -118,6 +187,22 @@ rdp_parse_options_widget (VinagreConnection *conn, GtkWidget *widget)
   vinagre_cache_prefs_set_integer  ("rdp-connection", "height", height);
 
   vinagre_connection_set_height (conn, height);
+
+
+  scaling_button = g_object_get_data (G_OBJECT (widget), "scaling");
+  if (!scaling_button)
+    {
+      g_warning ("Wrong widget passed to rdp_parse_options_widget()");
+      return;
+    }
+
+  scaling = (gboolean) gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (scaling_button));
+
+  vinagre_cache_prefs_set_boolean ("rdp-connection", "scaling", scaling);
+
+  g_object_set (conn,
+                "scaling", scaling,
+                NULL);
 }
 
 static void
@@ -128,11 +213,24 @@ vinagre_rdp_connection_class_init (VinagreRdpConnectionClass *klass)
 
   g_type_class_add_private (klass, sizeof (VinagreRdpConnectionPrivate));
 
+  object_class->set_property = vinagre_rdp_connection_set_property;
+  object_class->get_property = vinagre_rdp_connection_get_property;
   object_class->constructed  = vinagre_rdp_connection_constructed;
 
   parent_class->impl_fill_writer = rdp_fill_writer;
   parent_class->impl_parse_item  = rdp_parse_item;
   parent_class->impl_parse_options_widget = rdp_parse_options_widget;
+
+  g_object_class_install_property (object_class,
+                                   PROP_SCALING,
+                                   g_param_spec_boolean ("scaling",
+                                                         "Use scaling",
+                                                         "Whether to use scaling on this connection",
+                                                         FALSE,
+                                                         G_PARAM_READWRITE |
+                                                         G_PARAM_CONSTRUCT |
+                                                         G_PARAM_STATIC_STRINGS));
+
 }
 
 VinagreConnection *
@@ -141,4 +239,22 @@ vinagre_rdp_connection_new (void)
   return VINAGRE_CONNECTION (g_object_new (VINAGRE_TYPE_RDP_CONNECTION, NULL));
 }
 
+void
+vinagre_rdp_connection_set_scaling (VinagreRdpConnection *conn,
+                                    gboolean              scaling)
+{
+  g_return_if_fail (VINAGRE_IS_RDP_CONNECTION (conn));
+
+  conn->priv->scaling = scaling;
+}
+
+gboolean
+vinagre_rdp_connection_get_scaling (VinagreRdpConnection *conn)
+{
+  g_return_val_if_fail (VINAGRE_IS_RDP_CONNECTION (conn), FALSE);
+
+  return conn->priv->scaling;
+}
+
+
 /* vim: set ts=8: */
diff --git a/plugins/rdp/vinagre-rdp-connection.h b/plugins/rdp/vinagre-rdp-connection.h
index b9e48be..b96fb1b 100644
--- a/plugins/rdp/vinagre-rdp-connection.h
+++ b/plugins/rdp/vinagre-rdp-connection.h
@@ -51,7 +51,11 @@ struct _VinagreRdpConnection
 
 GType vinagre_rdp_connection_get_type (void) G_GNUC_CONST;
 
-VinagreConnection*  vinagre_rdp_connection_new (void);
+VinagreConnection*  vinagre_rdp_connection_new         (void);
+
+gboolean            vinagre_rdp_connection_get_scaling (VinagreRdpConnection *conn);
+void                vinagre_rdp_connection_set_scaling (VinagreRdpConnection *conn,
+                                                        gboolean              scaling);
 
 G_END_DECLS
 
diff --git a/plugins/rdp/vinagre-rdp-plugin.c b/plugins/rdp/vinagre-rdp-plugin.c
index dae9ed3..4751102 100644
--- a/plugins/rdp/vinagre-rdp-plugin.c
+++ b/plugins/rdp/vinagre-rdp-plugin.c
@@ -115,16 +115,28 @@ impl_get_connect_widget (VinagreProtocol *plugin, VinagreConnection *conn)
   gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
   gtk_grid_attach (GTK_GRID (grid), label, 0, 0, 1, 1);
 
+
+  /* Scaling check button */
+  check = gtk_check_button_new_with_mnemonic (_("_Scaling"));
+  g_object_set_data (G_OBJECT (grid), "scaling", check);
+  gtk_widget_set_margin_left (check, 12);
+  gtk_grid_attach (GTK_GRID (grid), check, 0, 1, 1, 1);
+  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check),
+                                VINAGRE_IS_CONNECTION (conn) ?
+                                vinagre_rdp_connection_get_scaling (VINAGRE_RDP_CONNECTION (conn)) :
+                                vinagre_cache_prefs_get_boolean ("rdp-connection", "scaling", FALSE));
+
+
   label = gtk_label_new_with_mnemonic (_("_Username:"));
   gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
-  gtk_grid_attach (GTK_GRID (grid), label, 0, 1, 1, 1);
+  gtk_grid_attach (GTK_GRID (grid), label, 0, 2, 1, 1);
   gtk_widget_set_margin_left (label, 12);
 
   u_entry = gtk_entry_new ();
   /* Translators: This is the tooltip for the username field in a RDP connection */
   gtk_widget_set_tooltip_text (u_entry, _("Optional. If blank, your username will be used. Also, it can be supplied in the Host field above, in the form username@hostname."));
   g_object_set_data (G_OBJECT (grid), "username_entry", u_entry);
-  gtk_grid_attach (GTK_GRID (grid), u_entry, 1, 1, 1, 1);
+  gtk_grid_attach (GTK_GRID (grid), u_entry, 1, 2, 1, 1);
   gtk_label_set_mnemonic_widget (GTK_LABEL (label), u_entry);
   str = g_strdup (VINAGRE_IS_CONNECTION (conn) ?
 		  vinagre_connection_get_username (conn) :
diff --git a/plugins/rdp/vinagre-rdp-tab.c b/plugins/rdp/vinagre-rdp-tab.c
index 90eea1c..e9a4623 100644
--- a/plugins/rdp/vinagre-rdp-tab.c
+++ b/plugins/rdp/vinagre-rdp-tab.c
@@ -24,6 +24,7 @@
 #include <errno.h>
 #include <glib/gi18n.h>
 #include <gdk/gdkkeysyms.h>
+#include <math.h>
 #include <freerdp/api.h>
 #include <freerdp/types.h>
 #include <freerdp/freerdp.h>
@@ -65,6 +66,9 @@ struct _VinagreRdpTabPrivate
 
   GSList          *connected_actions;
   double           scale;
+  gboolean         scaling;
+  GtkWidget       *scaling_button;
+  GtkAction       *scaling_action;
   double           offset_x, offset_y;
 
   guint            authentication_attempts;
@@ -74,6 +78,11 @@ struct _VinagreRdpTabPrivate
 G_DEFINE_TYPE (VinagreRdpTab, vinagre_rdp_tab, VINAGRE_TYPE_TAB)
 
 static void open_freerdp (VinagreRdpTab *rdp_tab);
+static void setup_toolbar (VinagreRdpTab *rdp_tab);
+static void vinagre_rdp_tab_set_scaling (VinagreRdpTab *tab,
+                                         gboolean       scaling);
+static void scaling_button_clicked (GtkToggleToolButton *button,
+                                    VinagreRdpTab       *rdp_tab);
 
 struct frdp_context
 {
@@ -135,12 +144,42 @@ free_frdpEvent (gpointer event,
 }
 
 static void
+view_scaling_cb (GtkAction     *action,
+                 VinagreRdpTab *rdp_tab)
+{
+  VinagreRdpTabPrivate *priv = rdp_tab->priv;
+  gboolean              scaling;
+
+  scaling = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
+
+  vinagre_rdp_tab_set_scaling (rdp_tab, scaling);
+
+  g_signal_handlers_block_by_func (priv->scaling_button, scaling_button_clicked, rdp_tab);
+  gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (priv->scaling_button), scaling);
+  g_signal_handlers_unblock_by_func (priv->scaling_button, scaling_button_clicked, rdp_tab);
+}
+
+const static GSList *
+rdp_get_connected_actions (VinagreTab *tab)
+{
+  VinagreRdpTab *rdp_tab = VINAGRE_RDP_TAB (tab);
+
+  return rdp_tab->priv->connected_actions;
+}
+
+static void
 vinagre_rdp_tab_dispose (GObject *object)
 {
   VinagreRdpTab        *rdp_tab = VINAGRE_RDP_TAB (object);
   VinagreRdpTabPrivate *priv = rdp_tab->priv;
   GtkWindow            *window = GTK_WINDOW (vinagre_tab_get_window (VINAGRE_TAB (rdp_tab)));
 
+  if (priv->connected_actions)
+    {
+      vinagre_tab_free_actions (priv->connected_actions);
+      priv->connected_actions = NULL;
+    }
+
   if (priv->freerdp_session)
     {
       gdi_free (priv->freerdp_session);
@@ -202,6 +241,7 @@ vinagre_rdp_tab_constructed (GObject *object)
   if (G_OBJECT_CLASS (vinagre_rdp_tab_parent_class)->constructed)
     G_OBJECT_CLASS (vinagre_rdp_tab_parent_class)->constructed (object);
 
+  setup_toolbar (rdp_tab);
   open_freerdp (rdp_tab);
 }
 
@@ -215,6 +255,7 @@ vinagre_rdp_tab_class_init (VinagreRdpTabClass *klass)
   object_class->dispose = vinagre_rdp_tab_dispose;
 
   tab_class->impl_get_tooltip = rdp_tab_get_tooltip;
+  tab_class->impl_get_connected_actions = rdp_get_connected_actions;
 
   g_type_class_add_private (object_class, sizeof (VinagreRdpTabPrivate));
 }
@@ -227,12 +268,110 @@ idle_close (VinagreTab *tab)
   return FALSE;
 }
 
+static GSList *
+create_connected_actions (VinagreRdpTab *tab)
+{
+  GSList *list = NULL;
+  VinagreTabUiAction *action;
+
+  /* View->Scaling */
+  action = g_slice_new (VinagreTabUiAction);
+  action->paths = g_new (gchar *, 3);
+  action->paths[0] = g_strdup ("/MenuBar/ViewMenu");
+  action->paths[1] = g_strdup ("/ToolBar");
+  action->paths[2] = NULL;
+  action->action = GTK_ACTION (gtk_toggle_action_new ("RDPViewScaling",
+                                                 _("S_caling"),
+                                                 _("Fit the remote screen into the current window size"),
+                                                 "zoom-fit-best"));
+  gtk_action_set_icon_name (action->action, "zoom-fit-best");
+  g_signal_connect (action->action, "activate", G_CALLBACK (view_scaling_cb), tab);
+  list = g_slist_append (list, action);
+  tab->priv->scaling_action = action->action;
+
+  return list;
+}
+
+static void
+scaling_button_clicked (GtkToggleToolButton *button,
+                        VinagreRdpTab       *rdp_tab)
+{
+  vinagre_rdp_tab_set_scaling (rdp_tab,
+                               gtk_toggle_tool_button_get_active (button));
+}
+
+static void
+vinagre_rdp_tab_set_scaling (VinagreRdpTab *tab,
+                             gboolean       scaling)
+{
+  VinagreRdpTabPrivate *priv = tab->priv;
+  VinagreConnection    *conn = vinagre_tab_get_conn (VINAGRE_TAB (tab));
+  GtkWidget            *scrolled;
+  gint                  window_width, window_height;
+
+  priv->scaling = scaling;
+
+  gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (priv->scaling_action),
+                                priv->scaling);
+
+  if (scaling)
+    {
+      scrolled = gtk_widget_get_ancestor (priv->display, GTK_TYPE_SCROLLED_WINDOW);
+      window_width = gtk_widget_get_allocated_width (scrolled);
+      window_height = gtk_widget_get_allocated_height (scrolled);
+
+      gtk_widget_set_size_request (priv->display,
+                                   window_width,
+                                   window_height);
+
+      gtk_widget_set_halign (priv->display, GTK_ALIGN_FILL);
+      gtk_widget_set_valign (priv->display, GTK_ALIGN_FILL);
+    }
+  else
+    {
+      gtk_widget_set_size_request (priv->display,
+                                   vinagre_connection_get_width (VINAGRE_CONNECTION (conn)),
+                                   vinagre_connection_get_height (VINAGRE_CONNECTION (conn)));
+      gtk_widget_set_halign (priv->display, GTK_ALIGN_CENTER);
+      gtk_widget_set_valign (priv->display, GTK_ALIGN_CENTER);
+    }
+
+  gtk_widget_queue_draw_area (priv->display, 0, 0,
+                              gtk_widget_get_allocated_width (priv->display),
+                              gtk_widget_get_allocated_height (priv->display));
+}
+
+static void
+setup_toolbar (VinagreRdpTab *rdp_tab)
+{
+  GtkWidget *toolbar = vinagre_tab_get_toolbar (VINAGRE_TAB (rdp_tab));
+  GtkWidget *button;
+
+  /* Space */
+  button = GTK_WIDGET (gtk_separator_tool_item_new ());
+  gtk_tool_item_set_expand (GTK_TOOL_ITEM (button), TRUE);
+  gtk_widget_show (GTK_WIDGET (button));
+  gtk_toolbar_insert (GTK_TOOLBAR (toolbar), GTK_TOOL_ITEM (button), -1);
+
+  /* Scaling */
+  button = GTK_WIDGET (gtk_toggle_tool_button_new ());
+  gtk_tool_button_set_label (GTK_TOOL_BUTTON (button), _("Scaling"));
+  gtk_tool_item_set_tooltip_text (GTK_TOOL_ITEM (button), _("Scaling"));
+  gtk_tool_button_set_icon_name (GTK_TOOL_BUTTON (button), "zoom-fit-best");
+  gtk_widget_show (GTK_WIDGET (button));
+  gtk_toolbar_insert (GTK_TOOLBAR (toolbar), GTK_TOOL_ITEM (button), -1);
+  g_signal_connect (button, "toggled", G_CALLBACK (scaling_button_clicked), rdp_tab);
+  rdp_tab->priv->scaling_button = button;
+}
 
 static void
 frdp_process_events (freerdp *instance,
                      GQueue  *events)
 {
-  frdpEvent *event;
+  VinagreRdpTab        *rdp_tab = ((frdpContext *) instance->context)->rdp_tab;
+  VinagreRdpTabPrivate *priv = rdp_tab->priv;
+  frdpEvent            *event;
+  gint                  x, y;
 
   while (!g_queue_is_empty (events))
     {
@@ -247,10 +386,27 @@ frdp_process_events (freerdp *instance,
                                                 ((frdpEventKey *) event)->code);
                 break;
               case FRDP_EVENT_TYPE_BUTTON:
+                if (priv->scaling)
+                  {
+                    x = (((frdpEventButton *) event)->x - priv->offset_x) / priv->scale;
+                    y = (((frdpEventButton *) event)->y - priv->offset_y) / priv->scale;
+                  }
+                else
+                  {
+                    x = ((frdpEventButton *) event)->x;
+                    y = ((frdpEventButton *) event)->y;
+                  }
+
+                if (x < 0)
+                  x = 0;
+
+                if (y < 0)
+                  y = 0;
+
                 instance->input->MouseEvent (instance->input,
                                              ((frdpEventButton *) event)->flags,
-                                             ((frdpEventButton *) event)->x,
-                                             ((frdpEventButton *) event)->y);
+                                             x,
+                                             y);
                 break;
               default:
                 break;
@@ -268,10 +424,44 @@ frdp_drawing_area_draw (GtkWidget *area,
 {
   VinagreRdpTab        *rdp_tab = (VinagreRdpTab *) user_data;
   VinagreRdpTabPrivate *priv = rdp_tab->priv;
+  VinagreRdpConnection *conn = VINAGRE_RDP_CONNECTION (vinagre_tab_get_conn (VINAGRE_TAB (rdp_tab)));
+  GtkWidget            *scrolled;
+  double                scale_x, scale_y;
+  gint                  window_width, window_height;
 
   if (priv->surface == NULL)
     return FALSE;
 
+  if (priv->scaling)
+    {
+      scrolled = gtk_widget_get_ancestor (area, GTK_TYPE_SCROLLED_WINDOW);
+      window_width = gtk_widget_get_allocated_width (scrolled);
+      window_height = gtk_widget_get_allocated_height (scrolled);
+
+      scale_x = (double) window_width / vinagre_connection_get_width (VINAGRE_CONNECTION (conn));
+      scale_y = (double) window_height / vinagre_connection_get_height (VINAGRE_CONNECTION (conn));
+
+      priv->scale = scale_x < scale_y ? scale_x : scale_y;
+
+      priv->offset_x = (window_width - vinagre_connection_get_width (VINAGRE_CONNECTION (conn)) * priv->scale) / 2.0;
+      priv->offset_y = (window_height - vinagre_connection_get_height (VINAGRE_CONNECTION (conn)) * priv->scale) / 2.0;
+
+      if (priv->offset_x < 0)
+        priv->offset_x = 0;
+
+      if (priv->offset_y < 0)
+        priv->offset_y = 0;
+
+      cairo_translate (cr, priv->offset_x, priv->offset_y);
+      cairo_scale (cr, priv->scale, priv->scale);
+
+      if (window_width != gtk_widget_get_allocated_width (area) ||
+          window_height != gtk_widget_get_allocated_height (area))
+        gtk_widget_set_size_request (area,
+                                     window_width,
+                                     window_height);
+    }
+
   cairo_set_source_surface (cr, priv->surface, 0, 0);
   cairo_paint (cr);
 
@@ -293,6 +483,7 @@ frdp_end_paint (rdpContext *context)
   VinagreRdpTab        *rdp_tab = ((frdpContext *) context)->rdp_tab;
   VinagreRdpTabPrivate *priv = rdp_tab->priv;
   rdpGdi               *gdi = context->gdi;
+  double                pos_x, pos_y;
   gint                  x, y, w, h;
 
   if (gdi->primary->hdc->hwnd->invalid->null)
@@ -303,7 +494,21 @@ frdp_end_paint (rdpContext *context)
   w = gdi->primary->hdc->hwnd->invalid->w;
   h = gdi->primary->hdc->hwnd->invalid->h;
 
-  gtk_widget_queue_draw_area (priv->display, x, y, w, h);
+  if (priv->scaling)
+    {
+      pos_x = priv->offset_x + x * priv->scale;
+      pos_y = priv->offset_y + y * priv->scale;
+
+      gtk_widget_queue_draw_area (priv->display,
+                                  floor (pos_x),
+                                  floor (pos_y),
+                                  ceil (pos_x + w * priv->scale) - floor (pos_x),
+                                  ceil (pos_y + h * priv->scale) - floor (pos_y));
+    }
+  else
+    {
+      gtk_widget_queue_draw_area (priv->display, x, y, w, h);
+    }
 }
 
 static BOOL
@@ -817,12 +1022,14 @@ init_freerdp (VinagreRdpTab *rdp_tab)
   gchar                *hostname;
   gint                  width, height;
   gint                  port;
+  gboolean              scaling;
 
   g_object_get (conn,
                 "port", &port,
                 "host", &hostname,
                 "width", &width,
                 "height", &height,
+                "scaling", &scaling,
                 NULL);
 
   /* Setup FreeRDP session */
@@ -899,21 +1106,20 @@ init_display (VinagreRdpTab *rdp_tab)
   VinagreTab           *tab = VINAGRE_TAB (rdp_tab);
   VinagreConnection    *conn = vinagre_tab_get_conn (tab);
   GtkWindow            *window = GTK_WINDOW (vinagre_tab_get_window (tab));
-  gboolean              fullscreen;
+  gboolean              fullscreen, scaling;
   gint                  width, height;
 
   g_object_get (conn,
                 "width", &width,
                 "height", &height,
                 "fullscreen", &fullscreen,
+                "scaling", &scaling,
                 NULL);
 
   /* Setup display for FreeRDP session */
   priv->display = gtk_drawing_area_new ();
   if (priv->display)
     {
-      gtk_widget_set_size_request (priv->display, width, height);
-
       g_signal_connect (priv->display, "draw",
                         G_CALLBACK (frdp_drawing_area_draw), rdp_tab);
 
@@ -946,6 +1152,8 @@ init_display (VinagreRdpTab *rdp_tab)
 
       if (fullscreen)
         gtk_window_fullscreen (window);
+
+      vinagre_rdp_tab_set_scaling (rdp_tab, scaling);
     }
 
   priv->key_press_handler_id = g_signal_connect (window, "key-press-event",
@@ -1007,6 +1215,8 @@ static void
 vinagre_rdp_tab_init (VinagreRdpTab *rdp_tab)
 {
   rdp_tab->priv = VINAGRE_RDP_TAB_GET_PRIVATE (rdp_tab);
+
+  rdp_tab->priv->connected_actions = create_connected_actions (rdp_tab);
 }
 
 GtkWidget *
-- 
2.5.5