From c4dcb173e7f4df5323086c9b4f92d2f0db8c3da6 Mon Sep 17 00:00:00 2001
From: Antenore Gatta <antenore@simbiosi.org>
Date: Wed, 27 Jan 2021 15:42:41 +0100
Subject: [PATCH 1/8] Adding multi monitor support

---
 plugins/rdp/CMakeLists.txt    |   2 +
 plugins/rdp/rdp_event.c       | 364 +++++++++++++++++-----------------
 plugins/rdp/rdp_plugin.c      | 162 +++++++++++----
 plugins/rdp/rdp_plugin.h      |   5 +
 src/rcw.c                     |  37 +++-
 src/remmina_protocol_widget.c |  10 +
 src/remmina_protocol_widget.h |   1 +
 7 files changed, 357 insertions(+), 224 deletions(-)

diff --git a/plugins/rdp/CMakeLists.txt b/plugins/rdp/CMakeLists.txt
index e39fbfc6d7..0e28b31dd0 100644
--- a/plugins/rdp/CMakeLists.txt
+++ b/plugins/rdp/CMakeLists.txt
@@ -52,6 +52,8 @@ set(REMMINA_PLUGIN_RDP_SRCS
         rdp_graphics.h
         rdp_cliprdr.c
         rdp_cliprdr.h
+        rdp_monitor.c
+        rdp_monitor.h
         rdp_channels.c
         rdp_channels.h
         )
diff --git a/plugins/rdp/rdp_event.c b/plugins/rdp/rdp_event.c
index 66d60534c8..fcd0225d41 100644
--- a/plugins/rdp/rdp_event.c
+++ b/plugins/rdp/rdp_event.c
@@ -37,14 +37,15 @@
  */
 
 #include "rdp_plugin.h"
-#include "rdp_event.h"
 #include "rdp_cliprdr.h"
+#include "rdp_event.h"
+#include "rdp_monitor.h"
 #include "rdp_settings.h"
 #include <gdk/gdkkeysyms.h>
 #include <cairo/cairo-xlib.h>
 #include <freerdp/locale/keyboard.h>
 
-static gboolean remmina_rdp_event_on_map (GtkWindow *window, GdkEvent  *event, RemminaProtocolWidget* gp)
+static gboolean remmina_rdp_event_on_map(GtkWindow *window, GdkEvent *event, RemminaProtocolWidget *gp)
 {
 	TRACE_CALL(__func__);
 	rfContext* rfi = GET_PLUGIN_DATA(gp);
@@ -61,7 +62,7 @@ static gboolean remmina_rdp_event_on_map (GtkWindow *window, GdkEvent  *event, R
 	return FALSE;
 }
 
-static gboolean remmina_rdp_event_on_unmap (GtkWindow *window, GdkEvent  *event, RemminaProtocolWidget* gp)
+static gboolean remmina_rdp_event_on_unmap(GtkWindow *window, GdkEvent *event, RemminaProtocolWidget *gp)
 {
 	TRACE_CALL(__func__);
 	rfContext* rfi = GET_PLUGIN_DATA(gp);
@@ -78,11 +79,11 @@ static gboolean remmina_rdp_event_on_unmap (GtkWindow *window, GdkEvent  *event,
 	return FALSE;
 }
 
-static gboolean remmina_rdp_event_on_focus_in(GtkWidget* widget, GdkEventKey* event, RemminaProtocolWidget* gp)
+static gboolean remmina_rdp_event_on_focus_in(GtkWidget *widget, GdkEventKey *event, RemminaProtocolWidget *gp)
 {
 	TRACE_CALL(__func__);
-	rfContext* rfi = GET_PLUGIN_DATA(gp);
-	rdpInput* input;
+	rfContext *rfi = GET_PLUGIN_DATA(gp);
+	rdpInput *input;
 	GdkModifierType state;
 
 #if GTK_CHECK_VERSION(3, 20, 0)
@@ -107,15 +108,12 @@ static gboolean remmina_rdp_event_on_focus_in(GtkWidget* widget, GdkEventKey* ev
 #endif
 	gdk_window_get_device_position(gdk_get_default_root_window(), keyboard, NULL, NULL, &state);
 
-	if (state & GDK_LOCK_MASK) {
+	if (state & GDK_LOCK_MASK)
 		toggle_keys_state |= KBD_SYNC_CAPS_LOCK;
-	}
-	if (state & GDK_MOD2_MASK) {
+	if (state & GDK_MOD2_MASK)
 		toggle_keys_state |= KBD_SYNC_NUM_LOCK;
-	}
-	if (state & GDK_MOD5_MASK) {
+	if (state & GDK_MOD5_MASK)
 		toggle_keys_state |= KBD_SYNC_SCROLL_LOCK;
-	}
 
 	input->SynchronizeEvent(input, toggle_keys_state);
 	input->KeyboardEvent(input, KBD_FLAGS_RELEASE, 0x0F);
@@ -123,11 +121,11 @@ static gboolean remmina_rdp_event_on_focus_in(GtkWidget* widget, GdkEventKey* ev
 	return FALSE;
 }
 
-void remmina_rdp_event_event_push(RemminaProtocolWidget* gp, const RemminaPluginRdpEvent* e)
+void remmina_rdp_event_event_push(RemminaProtocolWidget *gp, const RemminaPluginRdpEvent *e)
 {
 	TRACE_CALL(__func__);
-	rfContext* rfi = GET_PLUGIN_DATA(gp);
-	RemminaPluginRdpEvent* event;
+	rfContext *rfi = GET_PLUGIN_DATA(gp);
+	RemminaPluginRdpEvent *event;
 
 	/* Called by the main GTK thread to send an event to the libfreerdp thread */
 
@@ -143,10 +141,10 @@ void remmina_rdp_event_event_push(RemminaProtocolWidget* gp, const RemminaPlugin
 	}
 }
 
-static void remmina_rdp_event_release_all_keys(RemminaProtocolWidget* gp)
+static void remmina_rdp_event_release_all_keys(RemminaProtocolWidget *gp)
 {
 	TRACE_CALL(__func__);
-	rfContext* rfi = GET_PLUGIN_DATA(gp);
+	rfContext *rfi = GET_PLUGIN_DATA(gp);
 	RemminaPluginRdpEvent rdp_event = { 0 };
 	int i;
 
@@ -164,18 +162,18 @@ static void remmina_rdp_event_release_all_keys(RemminaProtocolWidget* gp)
 	g_array_set_size(rfi->pressed_keys, 0);
 }
 
-static void remmina_rdp_event_release_key(RemminaProtocolWidget* gp, RemminaPluginRdpEvent rdp_event)
+static void remmina_rdp_event_release_key(RemminaProtocolWidget *gp, RemminaPluginRdpEvent rdp_event)
 {
 	TRACE_CALL(__func__);
 	gint i;
-	rfContext* rfi = GET_PLUGIN_DATA(gp);
+	rfContext *rfi = GET_PLUGIN_DATA(gp);
 	RemminaPluginRdpEvent rdp_event_2 = { 0 };
 
 	rdp_event_2.type = REMMINA_RDP_EVENT_TYPE_SCANCODE;
 
 	if ((rdp_event.type == REMMINA_RDP_EVENT_TYPE_SCANCODE ||
 	     rdp_event.type == REMMINA_RDP_EVENT_TYPE_SCANCODE_UNICODE) &&
-	    rdp_event.key_event.up ) {
+	    rdp_event.key_event.up) {
 		/* Unregister the keycode only */
 		for (i = 0; i < rfi->pressed_keys->len; i++) {
 			rdp_event_2 = g_array_index(rfi->pressed_keys, RemminaPluginRdpEvent, i);
@@ -193,25 +191,24 @@ static void remmina_rdp_event_release_key(RemminaProtocolWidget* gp, RemminaPlug
 static void keypress_list_add(RemminaProtocolWidget *gp, RemminaPluginRdpEvent rdp_event)
 {
 	TRACE_CALL(__func__);
-	rfContext* rfi = GET_PLUGIN_DATA(gp);
+	rfContext *rfi = GET_PLUGIN_DATA(gp);
 	if (!rdp_event.key_event.key_code)
 		return;
 
-	if (rdp_event.key_event.up) {
+	if (rdp_event.key_event.up)
 		remmina_rdp_event_release_key(gp, rdp_event);
-	} else {
+	else
 		g_array_append_val(rfi->pressed_keys, rdp_event);
-	}
 
 }
 
 
-static void remmina_rdp_event_scale_area(RemminaProtocolWidget* gp, gint* x, gint* y, gint* w, gint* h)
+static void remmina_rdp_event_scale_area(RemminaProtocolWidget *gp, gint *x, gint *y, gint *w, gint *h)
 {
 	TRACE_CALL(__func__);
 	gint width, height;
 	gint sx, sy, sw, sh;
-	rfContext* rfi = GET_PLUGIN_DATA(gp);
+	rfContext *rfi = GET_PLUGIN_DATA(gp);
 
 	if (!rfi || !rfi->connected || rfi->is_reconnecting || !rfi->surface)
 		return;
@@ -234,16 +231,16 @@ static void remmina_rdp_event_scale_area(RemminaProtocolWidget* gp, gint* x, gin
 	/* We have to extend the scaled region one scaled pixel, to avoid gaps */
 
 	sx = MIN(MAX(0, (*x) * rfi->scale_width / width
-			- rfi->scale_width / width - 2), rfi->scale_width - 1);
+		     - rfi->scale_width / width - 2), rfi->scale_width - 1);
 
 	sy = MIN(MAX(0, (*y) * rfi->scale_height / height
-			- rfi->scale_height / height - 2), rfi->scale_height - 1);
+		     - rfi->scale_height / height - 2), rfi->scale_height - 1);
 
 	sw = MIN(rfi->scale_width - sx, (*w) * rfi->scale_width / width
-		+ rfi->scale_width / width + 4);
+		 + rfi->scale_width / width + 4);
 
 	sh = MIN(rfi->scale_height - sy, (*h) * rfi->scale_height / height
-		+ rfi->scale_height / height + 4);
+		 + rfi->scale_height / height + 4);
 
 	*x = sx;
 	*y = sy;
@@ -251,13 +248,13 @@ static void remmina_rdp_event_scale_area(RemminaProtocolWidget* gp, gint* x, gin
 	*h = sh;
 }
 
-void remmina_rdp_event_update_regions(RemminaProtocolWidget* gp, RemminaPluginRdpUiObject* ui)
+void remmina_rdp_event_update_regions(RemminaProtocolWidget *gp, RemminaPluginRdpUiObject *ui)
 {
 	TRACE_CALL(__func__);
-	rfContext* rfi = GET_PLUGIN_DATA(gp);
+	rfContext *rfi = GET_PLUGIN_DATA(gp);
 	gint x, y, w, h, i;
 
-	for(i = 0; i < ui->reg.ninvalid; i++) {
+	for (i = 0; i < ui->reg.ninvalid; i++) {
 		x = ui->reg.ureg[i].x;
 		y = ui->reg.ureg[i].y;
 		w = ui->reg.ureg[i].w;
@@ -271,10 +268,10 @@ void remmina_rdp_event_update_regions(RemminaProtocolWidget* gp, RemminaPluginRd
 	g_free(ui->reg.ureg);
 }
 
-void remmina_rdp_event_update_rect(RemminaProtocolWidget* gp, gint x, gint y, gint w, gint h)
+void remmina_rdp_event_update_rect(RemminaProtocolWidget *gp, gint x, gint y, gint w, gint h)
 {
 	TRACE_CALL(__func__);
-	rfContext* rfi = GET_PLUGIN_DATA(gp);
+	rfContext *rfi = GET_PLUGIN_DATA(gp);
 
 	if (rfi->scale == REMMINA_PROTOCOL_WIDGET_SCALE_MODE_SCALED)
 		remmina_rdp_event_scale_area(gp, &x, &y, &w, &h);
@@ -282,13 +279,13 @@ void remmina_rdp_event_update_rect(RemminaProtocolWidget* gp, gint x, gint y, gi
 	gtk_widget_queue_draw_area(rfi->drawing_area, x, y, w, h);
 }
 
-static void remmina_rdp_event_update_scale_factor(RemminaProtocolWidget* gp)
+static void remmina_rdp_event_update_scale_factor(RemminaProtocolWidget *gp)
 {
 	TRACE_CALL(__func__);
 	GtkAllocation a;
 	gint rdwidth, rdheight;
 	gint gpwidth, gpheight;
-	rfContext* rfi = GET_PLUGIN_DATA(gp);
+	rfContext *rfi = GET_PLUGIN_DATA(gp);
 
 	gtk_widget_get_allocation(GTK_WIDGET(gp), &a);
 	gpwidth = a.width;
@@ -305,19 +302,18 @@ static void remmina_rdp_event_update_scale_factor(RemminaProtocolWidget* gp)
 			rfi->scale_x = (gdouble)rfi->scale_width / (gdouble)rdwidth;
 			rfi->scale_y = (gdouble)rfi->scale_height / (gdouble)rdheight;
 		}
-	}else  {
+	} else {
 		rfi->scale_width = 0;
 		rfi->scale_height = 0;
 		rfi->scale_x = 0;
 		rfi->scale_y = 0;
 	}
-
 }
 
-static gboolean remmina_rdp_event_on_draw(GtkWidget* widget, cairo_t* context, RemminaProtocolWidget* gp)
+static gboolean remmina_rdp_event_on_draw(GtkWidget *widget, cairo_t *context, RemminaProtocolWidget *gp)
 {
 	TRACE_CALL(__func__);
-	rfContext* rfi = GET_PLUGIN_DATA(gp);
+	rfContext *rfi = GET_PLUGIN_DATA(gp);
 	guint width, height;
 	gchar *msg;
 	cairo_text_extents_t extents;
@@ -334,7 +330,7 @@ static gboolean remmina_rdp_event_on_draw(GtkWidget* widget, cairo_t* context, R
 
 		/* Draw text */
 		msg = g_strdup_printf(_("Reconnection attempt %d of %d…"),
-			rfi->reconnect_nattempt, rfi->reconnect_maxattempts);
+				      rfi->reconnect_nattempt, rfi->reconnect_maxattempts);
 
 		cairo_select_font_face(context, "Sans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
 		cairo_set_font_size(context, 24);
@@ -343,8 +339,7 @@ static gboolean remmina_rdp_event_on_draw(GtkWidget* widget, cairo_t* context, R
 		cairo_move_to(context, (width - (extents.width + extents.x_bearing)) / 2, (height - (extents.height + extents.y_bearing)) / 2);
 		cairo_show_text(context, msg);
 		g_free(msg);
-
-	}else  {
+	} else {
 		/* Standard drawing: We copy the surface from RDP */
 
 		if (!rfi->surface)
@@ -362,10 +357,10 @@ static gboolean remmina_rdp_event_on_draw(GtkWidget* widget, cairo_t* context, R
 	return TRUE;
 }
 
-static gboolean remmina_rdp_event_delayed_monitor_layout(RemminaProtocolWidget* gp)
+static gboolean remmina_rdp_event_delayed_monitor_layout(RemminaProtocolWidget *gp)
 {
 	TRACE_CALL(__func__);
-	rfContext* rfi = GET_PLUGIN_DATA(gp);
+	rfContext *rfi = GET_PLUGIN_DATA(gp);
 
 	RemminaPluginRdpEvent rdp_event = { 0 };
 	GtkAllocation a;
@@ -380,6 +375,12 @@ static gboolean remmina_rdp_event_delayed_monitor_layout(RemminaProtocolWidget*
 	rfi->delayed_monitor_layout_handler = 0;
 	gint gpwidth, gpheight, prevwidth, prevheight;
 
+	gchar *monitorids = NULL;
+	guint32 maxwidth = 0;
+	guint32 maxheight = 0;
+	remmina_rdp_monitor_get(rfi, &monitorids, &maxwidth, &maxheight);
+
+	REMMINA_PLUGIN_DEBUG("Sending preconfigured monitor layout");
 	if (rfi->dispcontext && rfi->dispcontext->SendMonitorLayout) {
 		remmina_rdp_settings_get_orientation_scale_prefs(&desktopOrientation, &desktopScaleFactor, &deviceScaleFactor);
 		gtk_widget_get_allocation(GTK_WIDGET(gp), &a);
@@ -388,10 +389,7 @@ static gboolean remmina_rdp_event_delayed_monitor_layout(RemminaProtocolWidget*
 		prevwidth = remmina_plugin_service->protocol_plugin_get_width(gp);
 		prevheight = remmina_plugin_service->protocol_plugin_get_height(gp);
 
-		if ((gpwidth != prevwidth || gpheight != prevheight) &&
-		    gpwidth >= 200 && gpwidth < 8192 &&
-		    gpheight >= 200 && gpheight < 8192
-		    ) {
+		if ((gpwidth != prevwidth || gpheight != prevheight) && gpwidth >= 200 && gpheight >= 200) {
 			if (rfi->rdpgfxchan) {
 				/* Workaround for FreeRDP issue #5417 */
 				if (gpwidth < AVC_MIN_DESKTOP_WIDTH)
@@ -400,40 +398,59 @@ static gboolean remmina_rdp_event_delayed_monitor_layout(RemminaProtocolWidget*
 					gpheight = AVC_MIN_DESKTOP_HEIGHT;
 			}
 			rdp_event.type = REMMINA_RDP_EVENT_TYPE_SEND_MONITOR_LAYOUT;
-			rdp_event.monitor_layout.width = gpwidth;
-			rdp_event.monitor_layout.height = gpheight;
-			rdp_event.monitor_layout.desktopOrientation = desktopOrientation;
-			rdp_event.monitor_layout.desktopScaleFactor = desktopScaleFactor;
-			rdp_event.monitor_layout.deviceScaleFactor = deviceScaleFactor;
-			remmina_rdp_event_event_push(gp, &rdp_event);
+			for (gint i = 0; i < rfi->settings->MonitorCount; ++i) {
+				REMMINA_PLUGIN_DEBUG("Sending diplay layout n° %d", i);
+				rdp_event.monitor_layout.Flags = rfi->settings->MonitorDefArray[i].is_primary;
+				REMMINA_PLUGIN_DEBUG("EVNT MON LAYOUT - Flags: %i", rdp_event.monitor_layout.Flags);
+				rdp_event.monitor_layout.Left = rfi->settings->MonitorDefArray[i].x;
+				REMMINA_PLUGIN_DEBUG("EVNT MON LAYOUT - Left: %i", rdp_event.monitor_layout.Left);
+				rdp_event.monitor_layout.Top = rfi->settings->MonitorDefArray[i].y;
+				//rdp_event.monitor_layout.Top = rfi->settings->MonitorDefArray[0].y;
+				REMMINA_PLUGIN_DEBUG("EVNT MON LAYOUT - Top: %i", rdp_event.monitor_layout.Top);
+				rdp_event.monitor_layout.width = rfi->settings->MonitorDefArray[i].width;
+				REMMINA_PLUGIN_DEBUG("EVNT MON LAYOUT - width: %i", rdp_event.monitor_layout.width);
+				rdp_event.monitor_layout.height = rfi->settings->MonitorDefArray[i].height;
+				REMMINA_PLUGIN_DEBUG("EVNT MON LAYOUT - height: %i", rdp_event.monitor_layout.height);
+				rdp_event.monitor_layout.physicalWidth = rfi->settings->MonitorDefArray[i].attributes.physicalWidth;
+				REMMINA_PLUGIN_DEBUG("EVNT MON LAYOUT - physicalWidth: %i", rdp_event.monitor_layout.physicalWidth);
+				rdp_event.monitor_layout.physicalHeight = rfi->settings->MonitorDefArray[i].attributes.physicalHeight;
+				REMMINA_PLUGIN_DEBUG("EVNT MON LAYOUT - PhysicalHeight: %i", rdp_event.monitor_layout.physicalHeight);
+				rdp_event.monitor_layout.desktopOrientation = rdp_event.monitor_layout.desktopOrientation;
+				REMMINA_PLUGIN_DEBUG("EVNT MON LAYOUT - desktopOrientation: %i", rdp_event.monitor_layout.desktopOrientation);
+				rdp_event.monitor_layout.desktopScaleFactor = rdp_event.monitor_layout.desktopScaleFactor;
+				REMMINA_PLUGIN_DEBUG("EVNT MON LAYOUT - ScaleFactorflag: %i", rdp_event.monitor_layout.desktopScaleFactor);
+				rdp_event.monitor_layout.deviceScaleFactor = rdp_event.monitor_layout.deviceScaleFactor;
+				remmina_rdp_event_event_push(gp, &rdp_event);
+			}
 		}
 	}
 
+	g_free(monitorids);
+
 	return FALSE;
 }
 
-void remmina_rdp_event_send_delayed_monitor_layout(RemminaProtocolWidget* gp)
+void remmina_rdp_event_send_delayed_monitor_layout(RemminaProtocolWidget *gp)
 {
 	TRACE_CALL(__func__);
-	rfContext* rfi = GET_PLUGIN_DATA(gp);
+	rfContext *rfi = GET_PLUGIN_DATA(gp);
 	if (!rfi || !rfi->connected || rfi->is_reconnecting)
 		return;
 	if (rfi->delayed_monitor_layout_handler) {
 		g_source_remove(rfi->delayed_monitor_layout_handler);
 		rfi->delayed_monitor_layout_handler = 0;
 	}
-	if (rfi->scale == REMMINA_PROTOCOL_WIDGET_SCALE_MODE_DYNRES) {
+	if (rfi->scale == REMMINA_PROTOCOL_WIDGET_SCALE_MODE_DYNRES)
 		rfi->delayed_monitor_layout_handler = g_timeout_add(500, (GSourceFunc)remmina_rdp_event_delayed_monitor_layout, gp);
-	}
 
 }
 
-static gboolean remmina_rdp_event_on_configure(GtkWidget* widget, GdkEventConfigure* event, RemminaProtocolWidget* gp)
+static gboolean remmina_rdp_event_on_configure(GtkWidget *widget, GdkEventConfigure *event, RemminaProtocolWidget *gp)
 {
 	TRACE_CALL(__func__);
 	/* Called when gp changes its size or position */
 
-	rfContext* rfi = GET_PLUGIN_DATA(gp);
+	rfContext *rfi = GET_PLUGIN_DATA(gp);
 	if (!rfi || !rfi->connected || rfi->is_reconnecting)
 		return FALSE;
 
@@ -446,10 +463,10 @@ static gboolean remmina_rdp_event_on_configure(GtkWidget* widget, GdkEventConfig
 	return FALSE;
 }
 
-static void remmina_rdp_event_translate_pos(RemminaProtocolWidget* gp, int ix, int iy, UINT16* ox, UINT16* oy)
+static void remmina_rdp_event_translate_pos(RemminaProtocolWidget *gp, int ix, int iy, UINT16 *ox, UINT16 *oy)
 {
 	TRACE_CALL(__func__);
-	rfContext* rfi = GET_PLUGIN_DATA(gp);
+	rfContext *rfi = GET_PLUGIN_DATA(gp);
 
 	/*
 	 * Translate a position from local window coordinates (ix,iy) to
@@ -462,16 +479,16 @@ static void remmina_rdp_event_translate_pos(RemminaProtocolWidget* gp, int ix, i
 	if ((rfi->scale == REMMINA_PROTOCOL_WIDGET_SCALE_MODE_SCALED) && (rfi->scale_width >= 1) && (rfi->scale_height >= 1)) {
 		*ox = (UINT16)(ix * remmina_plugin_service->protocol_plugin_get_width(gp) / rfi->scale_width);
 		*oy = (UINT16)(iy * remmina_plugin_service->protocol_plugin_get_height(gp) / rfi->scale_height);
-	}else  {
+	} else {
 		*ox = (UINT16)ix;
 		*oy = (UINT16)iy;
 	}
 }
 
-static void remmina_rdp_event_reverse_translate_pos_reverse(RemminaProtocolWidget* gp, int ix, int iy, int* ox, int* oy)
+static void remmina_rdp_event_reverse_translate_pos_reverse(RemminaProtocolWidget *gp, int ix, int iy, int *ox, int *oy)
 {
 	TRACE_CALL(__func__);
-	rfContext* rfi = GET_PLUGIN_DATA(gp);
+	rfContext *rfi = GET_PLUGIN_DATA(gp);
 
 	/*
 	 * Translate a position from RDP coordinates (ix,iy) to
@@ -484,13 +501,13 @@ static void remmina_rdp_event_reverse_translate_pos_reverse(RemminaProtocolWidge
 	if ((rfi->scale == REMMINA_PROTOCOL_WIDGET_SCALE_MODE_SCALED) && (rfi->scale_width >= 1) && (rfi->scale_height >= 1)) {
 		*ox = (ix * rfi->scale_width) / remmina_plugin_service->protocol_plugin_get_width(gp);
 		*oy = (iy * rfi->scale_height) / remmina_plugin_service->protocol_plugin_get_height(gp);
-	}else  {
+	} else {
 		*ox = ix;
 		*oy = iy;
 	}
 }
 
-static gboolean remmina_rdp_event_on_motion(GtkWidget* widget, GdkEventMotion* event, RemminaProtocolWidget* gp)
+static gboolean remmina_rdp_event_on_motion(GtkWidget *widget, GdkEventMotion *event, RemminaProtocolWidget *gp)
 {
 	TRACE_CALL(__func__);
 	RemminaPluginRdpEvent rdp_event = { 0 };
@@ -505,7 +522,7 @@ static gboolean remmina_rdp_event_on_motion(GtkWidget* widget, GdkEventMotion* e
 	return TRUE;
 }
 
-static gboolean remmina_rdp_event_on_button(GtkWidget* widget, GdkEventButton* event, RemminaProtocolWidget* gp)
+static gboolean remmina_rdp_event_on_button(GtkWidget *widget, GdkEventButton *event, RemminaProtocolWidget *gp)
 {
 	TRACE_CALL(__func__);
 	gint flag;
@@ -561,7 +578,7 @@ static gboolean remmina_rdp_event_on_button(GtkWidget* widget, GdkEventButton* e
 	return TRUE;
 }
 
-static gboolean remmina_rdp_event_on_scroll(GtkWidget* widget, GdkEventScroll* event, RemminaProtocolWidget* gp)
+static gboolean remmina_rdp_event_on_scroll(GtkWidget *widget, GdkEventScroll *event, RemminaProtocolWidget *gp)
 {
 	TRACE_CALL(__func__);
 	gint flag;
@@ -574,7 +591,6 @@ static gboolean remmina_rdp_event_on_scroll(GtkWidget* widget, GdkEventScroll* e
 	/* See [MS-RDPBCGR] TS_POINTER_EVENT and WM_MOUSEWHEEL message */
 
 	switch (event->direction) {
-
 	case GDK_SCROLL_UP:
 		flag = PTR_FLAGS_WHEEL | 0x0078;  // 120 is one scroll unit defined in WM_MOUSEWHEEL
 		break;
@@ -619,7 +635,7 @@ static gboolean remmina_rdp_event_on_scroll(GtkWidget* widget, GdkEventScroll* e
 	return TRUE;
 }
 
-static void remmina_rdp_event_init_keymap(rfContext* rfi, const gchar* strmap)
+static void remmina_rdp_event_init_keymap(rfContext *rfi, const gchar *strmap)
 {
 	long int v1, v2;
 	const char *s;
@@ -632,7 +648,7 @@ static void remmina_rdp_event_init_keymap(rfContext* rfi, const gchar* strmap)
 	}
 	s = strmap;
 	rfi->keymap = g_array_new(FALSE, TRUE, sizeof(RemminaPluginRdpKeymapEntry));
-	while(1) {
+	while (1) {
 		v1 = strtol(s, &endptr, 10);
 		if (endptr == s) break;
 		s = endptr;
@@ -651,17 +667,16 @@ static void remmina_rdp_event_init_keymap(rfContext* rfi, const gchar* strmap)
 		g_array_unref(rfi->keymap);
 		rfi->keymap = NULL;
 	}
-
 }
 
-static gboolean remmina_rdp_event_on_key(GtkWidget* widget, GdkEventKey* event, RemminaProtocolWidget* gp)
+static gboolean remmina_rdp_event_on_key(GtkWidget *widget, GdkEventKey *event, RemminaProtocolWidget *gp)
 {
 	TRACE_CALL(__func__);
 	guint32 unicode_keyval;
 	guint16 hardware_keycode;
-	rfContext* rfi = GET_PLUGIN_DATA(gp);
+	rfContext *rfi = GET_PLUGIN_DATA(gp);
 	RemminaPluginRdpEvent rdp_event;
-	RemminaPluginRdpKeymapEntry* kep;
+	RemminaPluginRdpKeymapEntry *kep;
 	DWORD scancode = 0;
 	int ik;
 
@@ -671,9 +686,9 @@ static gboolean remmina_rdp_event_on_key(GtkWidget* widget, GdkEventKey* event,
 #ifdef ENABLE_GTK_INSPECTOR_KEY
 	/* GTK inspector key is propagated up. Disabled by default.
 	 * enable it by defining ENABLE_GTK_INSPECTOR_KEY */
-	if ( ( event->state & GDK_CONTROL_MASK ) != 0 && ( event->keyval == GDK_KEY_I || event->keyval == GDK_KEY_D ) ) {
+	if ((event->state & GDK_CONTROL_MASK) != 0 && (event->keyval == GDK_KEY_I || event->keyval == GDK_KEY_D))
 		return FALSE;
-	}
+
 #endif
 
 	rdp_event.type = REMMINA_RDP_EVENT_TYPE_SCANCODE;
@@ -705,7 +720,7 @@ static gboolean remmina_rdp_event_on_key(GtkWidget* widget, GdkEventKey* event,
 		if (!rfi->use_client_keymap) {
 			hardware_keycode = event->hardware_keycode;
 			if (rfi->keymap) {
-				for(ik = 0; ik < rfi->keymap->len; ik++) {
+				for (ik = 0; ik < rfi->keymap->len; ik++) {
 					kep = &g_array_index(rfi->keymap, RemminaPluginRdpKeymapEntry, ik);
 					if (hardware_keycode == kep->orig_keycode) {
 						hardware_keycode = kep->translated_keycode;
@@ -731,7 +746,7 @@ static gboolean remmina_rdp_event_on_key(GtkWidget* widget, GdkEventKey* event,
 			 * - The rest as Unicode char
 			 */
 			if (event->keyval >= 0xfe00 ||                                                  // Arrows, Shift, Alt, Fn, num keypad…
-				event->hardware_keycode == 0x41 ||											// Spacebar
+			    event->hardware_keycode == 0x41 ||                                          // Spacebar
 			    unicode_keyval == 0 ||                                                      // Impossible to translate
 			    (event->state & (GDK_MOD1_MASK | GDK_CONTROL_MASK | GDK_SUPER_MASK)) != 0   // A modifier not recognized by gdk_keyval_to_unicode()
 			    ) {
@@ -761,7 +776,7 @@ gboolean remmina_rdp_event_on_clipboard(GtkClipboard *gtkClipboard, GdkEvent *ev
 	/* Signal handler for GTK clipboard owner-change */
 	TRACE_CALL(__func__);
 	RemminaPluginRdpEvent rdp_event = { 0 };
-	CLIPRDR_FORMAT_LIST* pFormatList;
+	CLIPRDR_FORMAT_LIST *pFormatList;
 
 	/* Usually "owner-change" is fired when a user pres "COPY" on the client
 	 * OR when this plugin calls gtk_clipboard_set_with_owner()
@@ -774,11 +789,11 @@ gboolean remmina_rdp_event_on_clipboard(GtkClipboard *gtkClipboard, GdkEvent *ev
 	if (rfi)
 		remmina_rdp_clipboard_abort_transfer(rfi);
 
-	if (gtk_clipboard_get_owner(gtkClipboard) != (GObject*)gp) {
+	if (gtk_clipboard_get_owner(gtkClipboard) != (GObject *)gp) {
 		/* To do: avoid this when the new owner is another remmina protocol widget of
 		 * the same remmina application */
 		REMMINA_PLUGIN_DEBUG("     new owner is different than me: new=%p me=%p. Sending local clipboard format list to server.",
-				gtk_clipboard_get_owner(gtkClipboard), (GObject*)gp);
+				     gtk_clipboard_get_owner(gtkClipboard), (GObject *)gp);
 
 		pFormatList = remmina_rdp_cliprdr_get_client_format_list(gp);
 		rdp_event.type = REMMINA_RDP_EVENT_TYPE_CLIPBOARD_SEND_CLIENT_FORMAT_LIST;
@@ -790,14 +805,14 @@ gboolean remmina_rdp_event_on_clipboard(GtkClipboard *gtkClipboard, GdkEvent *ev
 	return TRUE;
 }
 
-void remmina_rdp_event_init(RemminaProtocolWidget* gp)
+void remmina_rdp_event_init(RemminaProtocolWidget *gp)
 {
 	TRACE_CALL(__func__);
-	gchar* s;
+	gchar *s;
 	gint flags;
-	rfContext* rfi = GET_PLUGIN_DATA(gp);
-	GtkClipboard* clipboard;
-	RemminaFile* remminafile;
+	rfContext *rfi = GET_PLUGIN_DATA(gp);
+	GtkClipboard *clipboard;
+	RemminaFile *remminafile;
 
 	if (!rfi) return;
 	remminafile = remmina_plugin_service->protocol_plugin_get_file(gp);
@@ -807,12 +822,12 @@ void remmina_rdp_event_init(RemminaProtocolWidget* gp)
 	gtk_container_add(GTK_CONTAINER(gp), rfi->drawing_area);
 
 	gtk_widget_add_events(rfi->drawing_area, GDK_POINTER_MOTION_MASK
-		| GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
-		| GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK
-#if GTK_CHECK_VERSION(3,4,0)
-		| GDK_SMOOTH_SCROLL_MASK
+			      | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+			      | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK
+#if GTK_CHECK_VERSION(3, 4, 0)
+			      | GDK_SMOOTH_SCROLL_MASK
 #endif
-		| GDK_SCROLL_MASK | GDK_FOCUS_CHANGE_MASK);
+			      | GDK_SCROLL_MASK | GDK_FOCUS_CHANGE_MASK);
 	gtk_widget_set_can_focus(rfi->drawing_area, TRUE);
 
 	remmina_plugin_service->protocol_plugin_register_hostkey(gp, rfi->drawing_area);
@@ -824,32 +839,31 @@ void remmina_rdp_event_init(RemminaProtocolWidget* gp)
 	/* Read special keymap from profile file, if exists */
 	remmina_rdp_event_init_keymap(rfi, remmina_plugin_service->pref_get_value("rdp_map_keycode"));
 
-	if (rfi->use_client_keymap && rfi->keymap) {
+	if (rfi->use_client_keymap && rfi->keymap)
 		fprintf(stderr, "RDP profile error: you cannot define both rdp_map_hardware_keycode and have 'Use client keuboard mapping' enabled\n");
-	}
 
 	g_signal_connect(G_OBJECT(rfi->drawing_area), "draw",
-		G_CALLBACK(remmina_rdp_event_on_draw), gp);
+			 G_CALLBACK(remmina_rdp_event_on_draw), gp);
 	g_signal_connect(G_OBJECT(rfi->drawing_area), "configure-event",
-		G_CALLBACK(remmina_rdp_event_on_configure), gp);
+			 G_CALLBACK(remmina_rdp_event_on_configure), gp);
 	g_signal_connect(G_OBJECT(rfi->drawing_area), "motion-notify-event",
-		G_CALLBACK(remmina_rdp_event_on_motion), gp);
+			 G_CALLBACK(remmina_rdp_event_on_motion), gp);
 	g_signal_connect(G_OBJECT(rfi->drawing_area), "button-press-event",
-		G_CALLBACK(remmina_rdp_event_on_button), gp);
+			 G_CALLBACK(remmina_rdp_event_on_button), gp);
 	g_signal_connect(G_OBJECT(rfi->drawing_area), "button-release-event",
-		G_CALLBACK(remmina_rdp_event_on_button), gp);
+			 G_CALLBACK(remmina_rdp_event_on_button), gp);
 	g_signal_connect(G_OBJECT(rfi->drawing_area), "scroll-event",
-		G_CALLBACK(remmina_rdp_event_on_scroll), gp);
+			 G_CALLBACK(remmina_rdp_event_on_scroll), gp);
 	g_signal_connect(G_OBJECT(rfi->drawing_area), "key-press-event",
-		G_CALLBACK(remmina_rdp_event_on_key), gp);
+			 G_CALLBACK(remmina_rdp_event_on_key), gp);
 	g_signal_connect(G_OBJECT(rfi->drawing_area), "key-release-event",
-		G_CALLBACK(remmina_rdp_event_on_key), gp);
+			 G_CALLBACK(remmina_rdp_event_on_key), gp);
 	g_signal_connect(G_OBJECT(rfi->drawing_area), "focus-in-event",
-		G_CALLBACK(remmina_rdp_event_on_focus_in), gp);
+			 G_CALLBACK(remmina_rdp_event_on_focus_in), gp);
 	g_signal_connect(G_OBJECT(gtk_widget_get_toplevel(rfi->drawing_area)), "map-event",
-		G_CALLBACK(remmina_rdp_event_on_map), gp);
+			 G_CALLBACK(remmina_rdp_event_on_map), gp);
 	g_signal_connect(G_OBJECT(gtk_widget_get_toplevel(rfi->drawing_area)), "unmap-event",
-		G_CALLBACK(remmina_rdp_event_on_unmap), gp);
+			 G_CALLBACK(remmina_rdp_event_on_unmap), gp);
 
 	if (!remmina_plugin_service->file_get_int(remminafile, "disableclipboard", FALSE)) {
 		clipboard = gtk_widget_get_clipboard(rfi->drawing_area, GDK_SELECTION_CLIPBOARD);
@@ -866,13 +880,12 @@ void remmina_rdp_event_init(RemminaProtocolWidget* gp)
 		rfi->event_pipe[0] = -1;
 		rfi->event_pipe[1] = -1;
 		rfi->event_handle = NULL;
-	}else  {
+	} else {
 		flags = fcntl(rfi->event_pipe[0], F_GETFL, 0);
 		fcntl(rfi->event_pipe[0], F_SETFL, flags | O_NONBLOCK);
 		rfi->event_handle = CreateFileDescriptorEvent(NULL, FALSE, FALSE, rfi->event_pipe[0], WINPR_FD_READ);
-		if (!rfi->event_handle) {
+		if (!rfi->event_handle)
 			g_print("CreateFileDescriptorEvent() failed\n");
-		}
 	}
 
 	rfi->object_table = g_hash_table_new_full(NULL, NULL, NULL, g_free);
@@ -881,14 +894,14 @@ void remmina_rdp_event_init(RemminaProtocolWidget* gp)
 
 #if GTK_CHECK_VERSION(3, 22, 0)
 	GdkVisual *visual = gdk_screen_get_system_visual(
-			gdk_display_get_default_screen(rfi->display));
-	rfi->bpp = gdk_visual_get_depth (visual);
+		gdk_display_get_default_screen(rfi->display));
+	rfi->bpp = gdk_visual_get_depth(visual);
 #else
 	rfi->bpp = gdk_visual_get_best_depth();
 #endif
 }
 
-void remmina_rdp_event_free_event(RemminaProtocolWidget* gp, RemminaPluginRdpUiObject* obj)
+void remmina_rdp_event_free_event(RemminaProtocolWidget *gp, RemminaPluginRdpUiObject *obj)
 {
 	TRACE_CALL(__func__);
 
@@ -904,11 +917,11 @@ void remmina_rdp_event_free_event(RemminaProtocolWidget* gp, RemminaPluginRdpUiO
 	g_free(obj);
 }
 
-void remmina_rdp_event_uninit(RemminaProtocolWidget* gp)
+void remmina_rdp_event_uninit(RemminaProtocolWidget *gp)
 {
 	TRACE_CALL(__func__);
-	rfContext* rfi = GET_PLUGIN_DATA(gp);
-	RemminaPluginRdpUiObject* ui;
+	rfContext *rfi = GET_PLUGIN_DATA(gp);
+	RemminaPluginRdpUiObject *ui;
 
 	if (!rfi) return;
 
@@ -925,9 +938,8 @@ void remmina_rdp_event_uninit(RemminaProtocolWidget* gp)
 		g_source_remove(rfi->ui_handler);
 		rfi->ui_handler = 0;
 	}
-	while ((ui = (RemminaPluginRdpUiObject*)g_async_queue_try_pop(rfi->ui_queue)) != NULL) {
+	while ((ui = (RemminaPluginRdpUiObject *)g_async_queue_try_pop(rfi->ui_queue)) != NULL)
 		remmina_rdp_event_free_event(gp, ui);
-	}
 	if (rfi->surface) {
 		cairo_surface_destroy(rfi->surface);
 		rfi->surface = NULL;
@@ -955,10 +967,10 @@ void remmina_rdp_event_uninit(RemminaProtocolWidget* gp)
 	close(rfi->event_pipe[1]);
 }
 
-static void remmina_rdp_event_create_cairo_surface(rfContext* rfi)
+static void remmina_rdp_event_create_cairo_surface(rfContext *rfi)
 {
 	int stride;
-	rdpGdi* gdi;
+	rdpGdi *gdi;
 
 	if (!rfi)
 		return;
@@ -973,33 +985,33 @@ static void remmina_rdp_event_create_cairo_surface(rfContext* rfi)
 		rfi->surface = NULL;
 	}
 	stride = cairo_format_stride_for_width(rfi->cairo_format, gdi->width);
-	rfi->surface = cairo_image_surface_create_for_data((unsigned char*)gdi->primary_buffer, rfi->cairo_format, gdi->width, gdi->height, stride);
+	rfi->surface = cairo_image_surface_create_for_data((unsigned char *)gdi->primary_buffer, rfi->cairo_format, gdi->width, gdi->height, stride);
 }
 
-void remmina_rdp_event_update_scale(RemminaProtocolWidget* gp)
+void remmina_rdp_event_update_scale(RemminaProtocolWidget *gp)
 {
 	TRACE_CALL(__func__);
 	gint width, height;
-	rdpGdi* gdi;
-	rfContext* rfi = GET_PLUGIN_DATA(gp);
+	rdpGdi *gdi;
+	rfContext *rfi = GET_PLUGIN_DATA(gp);
 
 	width = remmina_plugin_service->protocol_plugin_get_width(gp);
 	height = remmina_plugin_service->protocol_plugin_get_height(gp);
 
-	gdi = ((rdpContext*)rfi)->gdi;
+	gdi = ((rdpContext *)rfi)->gdi;
 
 	rfi->scale = remmina_plugin_service->remmina_protocol_widget_get_current_scale_mode(gp);
 
 	/* See if we also must rellocate rfi->surface with different width and height,
 	 * this usually happens after a DesktopResize RDP event*/
 
-	if ( rfi->surface && (cairo_image_surface_get_width(rfi->surface) != gdi->width ||
-		cairo_image_surface_get_height(rfi->surface) != gdi->height) ) {
+	if (rfi->surface && (cairo_image_surface_get_width(rfi->surface) != gdi->width ||
+			     cairo_image_surface_get_height(rfi->surface) != gdi->height)) {
 		/* Destroys and recreate rfi->surface with new width and height */
 		cairo_surface_destroy(rfi->surface);
 		rfi->surface = NULL;
 		remmina_rdp_event_create_cairo_surface(rfi);
-	} else if ( rfi->surface == NULL ) {
+	} else if (rfi->surface == NULL) {
 		remmina_rdp_event_create_cairo_surface(rfi);
 	}
 
@@ -1012,21 +1024,20 @@ void remmina_rdp_event_update_scale(RemminaProtocolWidget* gp)
 
 	remmina_rdp_event_update_scale_factor(gp);
 
-	if (rfi->scale == REMMINA_PROTOCOL_WIDGET_SCALE_MODE_SCALED || rfi->scale == REMMINA_PROTOCOL_WIDGET_SCALE_MODE_DYNRES) {
+	if (rfi->scale == REMMINA_PROTOCOL_WIDGET_SCALE_MODE_SCALED || rfi->scale == REMMINA_PROTOCOL_WIDGET_SCALE_MODE_DYNRES)
 		/* In scaled mode and autores mode, drawing_area will get its dimensions from its parent */
-		gtk_widget_set_size_request(rfi->drawing_area, -1, -1 );
-	}else  {
+		gtk_widget_set_size_request(rfi->drawing_area, -1, -1);
+	else
 		/* In non scaled mode, the plugins forces dimensions of drawing area */
 		gtk_widget_set_size_request(rfi->drawing_area, width, height);
-	}
 	remmina_plugin_service->protocol_plugin_update_align(gp);
 }
 
-static void remmina_rdp_event_connected(RemminaProtocolWidget* gp, RemminaPluginRdpUiObject* ui)
+static void remmina_rdp_event_connected(RemminaProtocolWidget *gp, RemminaPluginRdpUiObject *ui)
 {
 	TRACE_CALL(__func__);
-	rfContext* rfi = GET_PLUGIN_DATA(gp);
-	rdpGdi* gdi;
+	rfContext *rfi = GET_PLUGIN_DATA(gp);
+	rdpGdi *gdi;
 
 	gdi = ((rdpContext *)rfi)->gdi;
 
@@ -1037,27 +1048,27 @@ static void remmina_rdp_event_connected(RemminaProtocolWidget* gp, RemminaPlugin
 
 	remmina_rdp_event_update_scale(gp);
 
-    remmina_plugin_service->protocol_plugin_signal_connection_opened(gp);
+	remmina_plugin_service->protocol_plugin_signal_connection_opened(gp);
 }
 
-static void remmina_rdp_event_reconnect_progress(RemminaProtocolWidget* gp, RemminaPluginRdpUiObject* ui)
+static void remmina_rdp_event_reconnect_progress(RemminaProtocolWidget *gp, RemminaPluginRdpUiObject *ui)
 {
 	TRACE_CALL(__func__);
-	rfContext* rfi = GET_PLUGIN_DATA(gp);
+	rfContext *rfi = GET_PLUGIN_DATA(gp);
 	gdk_window_invalidate_rect(gtk_widget_get_window(rfi->drawing_area), NULL, TRUE);
 }
 
-static BOOL remmina_rdp_event_create_cursor(RemminaProtocolWidget* gp, RemminaPluginRdpUiObject* ui)
+static BOOL remmina_rdp_event_create_cursor(RemminaProtocolWidget *gp, RemminaPluginRdpUiObject *ui)
 {
 	TRACE_CALL(__func__);
-	GdkPixbuf* pixbuf;
-	rfContext* rfi = GET_PLUGIN_DATA(gp);
-	rdpPointer* pointer = (rdpPointer*)ui->cursor.pointer;
-	cairo_surface_t* surface;
-	UINT8* data = malloc(pointer->width * pointer->height * 4);
+	GdkPixbuf *pixbuf;
+	rfContext *rfi = GET_PLUGIN_DATA(gp);
+	rdpPointer *pointer = (rdpPointer *)ui->cursor.pointer;
+	cairo_surface_t *surface;
+	UINT8 *data = malloc(pointer->width * pointer->height * 4);
 
 	if (!freerdp_image_copy_from_pointer_data(
-		    (BYTE*)data, PIXEL_FORMAT_BGRA32,
+		    (BYTE *)data, PIXEL_FORMAT_BGRA32,
 		    pointer->width * 4, 0, 0, pointer->width, pointer->height,
 		    pointer->xorMaskData, pointer->lengthXorMask,
 		    pointer->andMaskData, pointer->lengthAndMask,
@@ -1070,13 +1081,13 @@ static BOOL remmina_rdp_event_create_cursor(RemminaProtocolWidget* gp, RemminaPl
 	pixbuf = gdk_pixbuf_get_from_surface(surface, 0, 0, pointer->width, pointer->height);
 	cairo_surface_destroy(surface);
 	free(data);
-	((rfPointer*)ui->cursor.pointer)->cursor = gdk_cursor_new_from_pixbuf(rfi->display, pixbuf, pointer->xPos, pointer->yPos);
+	((rfPointer *)ui->cursor.pointer)->cursor = gdk_cursor_new_from_pixbuf(rfi->display, pixbuf, pointer->xPos, pointer->yPos);
 	g_object_unref(pixbuf);
 
 	return TRUE;
 }
 
-static void remmina_rdp_event_free_cursor(RemminaProtocolWidget* gp, RemminaPluginRdpUiObject* ui)
+static void remmina_rdp_event_free_cursor(RemminaProtocolWidget *gp, RemminaPluginRdpUiObject *ui)
 {
 	TRACE_CALL(__func__);
 	g_object_unref(ui->cursor.pointer->cursor);
@@ -1094,7 +1105,7 @@ static BOOL remmina_rdp_event_set_pointer_position(RemminaProtocolWidget *gp, gi
 	GdkDeviceManager *manager;
 #endif
 	GdkDevice *dev;
-	rfContext* rfi = GET_PLUGIN_DATA(gp);
+	rfContext *rfi = GET_PLUGIN_DATA(gp);
 
 	if (rfi == NULL)
 		return FALSE;
@@ -1120,10 +1131,10 @@ static BOOL remmina_rdp_event_set_pointer_position(RemminaProtocolWidget *gp, gi
 	return TRUE;
 }
 
-static void remmina_rdp_event_cursor(RemminaProtocolWidget* gp, RemminaPluginRdpUiObject* ui)
+static void remmina_rdp_event_cursor(RemminaProtocolWidget *gp, RemminaPluginRdpUiObject *ui)
 {
 	TRACE_CALL(__func__);
-	rfContext* rfi = GET_PLUGIN_DATA(gp);
+	rfContext *rfi = GET_PLUGIN_DATA(gp);
 
 	switch (ui->cursor.type) {
 	case REMMINA_RDP_POINTER_NEW:
@@ -1145,8 +1156,8 @@ static void remmina_rdp_event_cursor(RemminaProtocolWidget* gp, RemminaPluginRdp
 
 	case REMMINA_RDP_POINTER_NULL:
 		gdk_window_set_cursor(gtk_widget_get_window(rfi->drawing_area),
-			gdk_cursor_new_for_display(gdk_display_get_default(),
-				GDK_BLANK_CURSOR));
+				      gdk_cursor_new_for_display(gdk_display_get_default(),
+								 GDK_BLANK_CURSOR));
 		ui->retval = 1;
 		break;
 
@@ -1157,31 +1168,31 @@ static void remmina_rdp_event_cursor(RemminaProtocolWidget* gp, RemminaPluginRdp
 	}
 }
 
-static void remmina_rdp_ui_event_update_scale(RemminaProtocolWidget* gp, RemminaPluginRdpUiObject* ui)
+static void remmina_rdp_ui_event_update_scale(RemminaProtocolWidget *gp, RemminaPluginRdpUiObject *ui)
 {
 	TRACE_CALL(__func__);
 	remmina_rdp_event_update_scale(gp);
 }
 
-void remmina_rdp_event_unfocus(RemminaProtocolWidget* gp)
+void remmina_rdp_event_unfocus(RemminaProtocolWidget *gp)
 {
 	TRACE_CALL(__func__);
-	rfContext* rfi = GET_PLUGIN_DATA(gp);
+	rfContext *rfi = GET_PLUGIN_DATA(gp);
 
 	if (!rfi || !rfi->connected || rfi->is_reconnecting)
 		return;
 	remmina_rdp_event_release_all_keys(gp);
 }
 
-static void remmina_rdp_ui_event_destroy_cairo_surface(RemminaProtocolWidget* gp, RemminaPluginRdpUiObject* ui)
+static void remmina_rdp_ui_event_destroy_cairo_surface(RemminaProtocolWidget *gp, RemminaPluginRdpUiObject *ui)
 {
 	TRACE_CALL(__func__);
-	rfContext* rfi = GET_PLUGIN_DATA(gp);
+	rfContext *rfi = GET_PLUGIN_DATA(gp);
 	cairo_surface_destroy(rfi->surface);
 	rfi->surface = NULL;
 }
 
-static void remmina_rdp_event_process_event(RemminaProtocolWidget* gp, RemminaPluginRdpUiObject* ui)
+static void remmina_rdp_event_process_event(RemminaProtocolWidget *gp, RemminaPluginRdpUiObject *ui)
 {
 	TRACE_CALL(__func__);
 	switch (ui->event.type) {
@@ -1194,7 +1205,7 @@ static void remmina_rdp_event_process_event(RemminaProtocolWidget* gp, RemminaPl
 	}
 }
 
-static void remmina_rdp_event_process_ui_event(RemminaProtocolWidget* gp, RemminaPluginRdpUiObject* ui)
+static void remmina_rdp_event_process_ui_event(RemminaProtocolWidget *gp, RemminaPluginRdpUiObject *ui)
 {
 	TRACE_CALL(__func__);
 	switch (ui->type) {
@@ -1227,49 +1238,46 @@ static void remmina_rdp_event_process_ui_event(RemminaProtocolWidget* gp, Remmin
 	}
 }
 
-static gboolean remmina_rdp_event_process_ui_queue(RemminaProtocolWidget* gp)
+static gboolean remmina_rdp_event_process_ui_queue(RemminaProtocolWidget *gp)
 {
 	TRACE_CALL(__func__);
 
-	rfContext* rfi = GET_PLUGIN_DATA(gp);
-	RemminaPluginRdpUiObject* ui;
+	rfContext *rfi = GET_PLUGIN_DATA(gp);
+	RemminaPluginRdpUiObject *ui;
 
 	pthread_mutex_lock(&rfi->ui_queue_mutex);
-	ui = (RemminaPluginRdpUiObject*)g_async_queue_try_pop(rfi->ui_queue);
+	ui = (RemminaPluginRdpUiObject *)g_async_queue_try_pop(rfi->ui_queue);
 	if (ui) {
 		pthread_mutex_lock(&ui->sync_wait_mutex);
-		if (!rfi->thread_cancelled) {
+		if (!rfi->thread_cancelled)
 			remmina_rdp_event_process_ui_event(gp, ui);
-		}
 		// Should we signal the caller thread to unlock ?
 		if (ui->sync) {
 			ui->complete = TRUE;
 			pthread_cond_signal(&ui->sync_wait_cond);
 			pthread_mutex_unlock(&ui->sync_wait_mutex);
-
 		} else {
 			remmina_rdp_event_free_event(gp, ui);
 		}
 
 		pthread_mutex_unlock(&rfi->ui_queue_mutex);
 		return TRUE;
-	}else  {
+	} else {
 		rfi->ui_handler = 0;
 		pthread_mutex_unlock(&rfi->ui_queue_mutex);
 		return FALSE;
 	}
 }
 
-static void remmina_rdp_event_queue_ui(RemminaProtocolWidget* gp, RemminaPluginRdpUiObject* ui)
+static void remmina_rdp_event_queue_ui(RemminaProtocolWidget *gp, RemminaPluginRdpUiObject *ui)
 {
 	TRACE_CALL(__func__);
-	rfContext* rfi = GET_PLUGIN_DATA(gp);
+	rfContext *rfi = GET_PLUGIN_DATA(gp);
 	gboolean ui_sync_save;
 	int oldcanceltype;
 
-	if (rfi->thread_cancelled) {
+	if (rfi->thread_cancelled)
 		return;
-	}
 
 	if (remmina_plugin_service->is_main_thread()) {
 		remmina_rdp_event_process_ui_event(gp, ui);
@@ -1292,17 +1300,15 @@ static void remmina_rdp_event_queue_ui(RemminaProtocolWidget* gp, RemminaPluginR
 
 	g_async_queue_push(rfi->ui_queue, ui);
 
-	if (!rfi->ui_handler) {
+	if (!rfi->ui_handler)
 		rfi->ui_handler = IDLE_ADD((GSourceFunc)remmina_rdp_event_process_ui_queue, gp);
-	}
 
 	if (ui_sync_save) {
 		/* Wait for main thread function completion before returning */
 		pthread_mutex_lock(&ui->sync_wait_mutex);
 		pthread_mutex_unlock(&rfi->ui_queue_mutex);
-		while (!ui->complete) {
+		while (!ui->complete)
 			pthread_cond_wait(&ui->sync_wait_cond, &ui->sync_wait_mutex);
-		}
 		pthread_cond_destroy(&ui->sync_wait_cond);
 		pthread_mutex_destroy(&ui->sync_wait_mutex);
 	} else {
@@ -1311,13 +1317,13 @@ static void remmina_rdp_event_queue_ui(RemminaProtocolWidget* gp, RemminaPluginR
 	pthread_setcanceltype(oldcanceltype, NULL);
 }
 
-void remmina_rdp_event_queue_ui_async(RemminaProtocolWidget* gp, RemminaPluginRdpUiObject* ui)
+void remmina_rdp_event_queue_ui_async(RemminaProtocolWidget *gp, RemminaPluginRdpUiObject *ui)
 {
 	ui->sync = FALSE;
 	remmina_rdp_event_queue_ui(gp, ui);
 }
 
-int remmina_rdp_event_queue_ui_sync_retint(RemminaProtocolWidget* gp, RemminaPluginRdpUiObject* ui)
+int remmina_rdp_event_queue_ui_sync_retint(RemminaProtocolWidget *gp, RemminaPluginRdpUiObject *ui)
 {
 	TRACE_CALL(__func__);
 	int retval;
@@ -1328,7 +1334,7 @@ int remmina_rdp_event_queue_ui_sync_retint(RemminaProtocolWidget* gp, RemminaPlu
 	return retval;
 }
 
-void *remmina_rdp_event_queue_ui_sync_retptr(RemminaProtocolWidget* gp, RemminaPluginRdpUiObject* ui)
+void *remmina_rdp_event_queue_ui_sync_retptr(RemminaProtocolWidget *gp, RemminaPluginRdpUiObject *ui)
 {
 	TRACE_CALL(__func__);
 	void *rp;
diff --git a/plugins/rdp/rdp_plugin.c b/plugins/rdp/rdp_plugin.c
index ca937adfcf..507ab68e1e 100644
--- a/plugins/rdp/rdp_plugin.c
+++ b/plugins/rdp/rdp_plugin.c
@@ -43,6 +43,7 @@
 #include "rdp_file.h"
 #include "rdp_settings.h"
 #include "rdp_cliprdr.h"
+#include "rdp_monitor.h"
 #include "rdp_channels.h"
 
 #include <errno.h>
@@ -84,7 +85,7 @@
 #define REMMINA_RDP_FEATURE_TOOL_SENDCTRLALTDEL  4
 #define REMMINA_RDP_FEATURE_DYNRESUPDATE         5
 
-#define REMMINA_CONNECTION_TYPE_NONE		 0
+#define REMMINA_CONNECTION_TYPE_NONE             0
 
 /* Some string settings of FreeRDP are preallocated buffers of N bytes */
 #define FREERDP_CLIENTHOSTNAME_LEN      32
@@ -241,17 +242,32 @@ static BOOL rf_process_event_queue(RemminaProtocolWidget *gp)
 			break;
 
 		case REMMINA_RDP_EVENT_TYPE_SEND_MONITOR_LAYOUT:
-			dcml = g_malloc0(sizeof(DISPLAY_CONTROL_MONITOR_LAYOUT));
-			if (dcml) {
-				dcml->Flags = DISPLAY_CONTROL_MONITOR_PRIMARY;
-				dcml->Width = event->monitor_layout.width;
-				dcml->Height = event->monitor_layout.height;
-				dcml->Orientation = event->monitor_layout.desktopOrientation;
-				dcml->DesktopScaleFactor = event->monitor_layout.desktopScaleFactor;
-				dcml->DeviceScaleFactor = event->monitor_layout.deviceScaleFactor;
-				rfi->dispcontext->SendMonitorLayout(rfi->dispcontext, 1, dcml);
-				g_free(dcml);
+			dcml = calloc(rfi->settings->MonitorCount, sizeof(DISPLAY_CONTROL_MONITOR_LAYOUT));
+			REMMINA_PLUGIN_DEBUG("REMMINA_RDP_EVENT_TYPE_SEND_MONITOR_LAYOUT:");
+			if (!dcml)
+				break;
+			for (gint i = 0; i < rfi->settings->MonitorCount; ++i) {
+				REMMINA_PLUGIN_DEBUG("Sending diplay layout for monitor n° %d", i);
+				dcml[i].Flags = (rfi->settings->MonitorDefArray[i].is_primary ? DISPLAY_CONTROL_MONITOR_PRIMARY : 0);
+				REMMINA_PLUGIN_DEBUG("Monitor %d is primary: %d", i, dcml[i].Flags);
+				dcml[i].Left = rfi->settings->MonitorDefArray[i].x;
+				REMMINA_PLUGIN_DEBUG("Monitor %d x: %d", i, dcml[i].Left);
+				dcml[i].Top = rfi->settings->MonitorDefArray[i].y;
+				REMMINA_PLUGIN_DEBUG("Monitor %d y: %d", i, dcml[i].Top);
+				dcml[i].Width = rfi->settings->MonitorDefArray[i].width;
+				REMMINA_PLUGIN_DEBUG("Monitor %d width: %d", i, dcml[i].Width);
+				dcml[i].Height = rfi->settings->MonitorDefArray[i].height;
+				REMMINA_PLUGIN_DEBUG("Monitor %d height: %d", i, dcml[i].Height);
+				dcml[i].PhysicalWidth = rfi->settings->MonitorDefArray[i].attributes.physicalWidth;
+				REMMINA_PLUGIN_DEBUG("Monitor %d physical width: %d", i, dcml[i].PhysicalWidth);
+				dcml[i].PhysicalHeight = rfi->settings->MonitorDefArray[i].attributes.physicalHeight;
+				REMMINA_PLUGIN_DEBUG("Monitor %d physical height: %d", i, dcml[i].PhysicalHeight);
+				dcml[i].Orientation = event->monitor_layout.desktopOrientation;
+				dcml[i].DesktopScaleFactor = event->monitor_layout.desktopScaleFactor;
+				dcml[i].DeviceScaleFactor = event->monitor_layout.deviceScaleFactor;
 			}
+			rfi->dispcontext->SendMonitorLayout(rfi->dispcontext, rfi->settings->MonitorCount, dcml);
+			g_free(dcml);
 			break;
 		case REMMINA_RDP_EVENT_DISCONNECT:
 			/* Disconnect requested via GUI (i.e: tab destroy/close) */
@@ -725,20 +741,20 @@ static BOOL remmina_rdp_gw_authenticate(freerdp *instance, char **username, char
 
 	if (basecredforgw) {
 		ret = remmina_plugin_service->protocol_plugin_init_auth(gp,
-								(disablepasswordstoring ? 0 : REMMINA_MESSAGE_PANEL_FLAG_SAVEPASSWORD) | REMMINA_MESSAGE_PANEL_FLAG_USERNAME | REMMINA_MESSAGE_PANEL_FLAG_DOMAIN,
-								_("Enter RDP authentication credentials"),
-								remmina_plugin_service->file_get_string(remminafile, "username"),
-								remmina_plugin_service->file_get_string(remminafile, "password"),
-								remmina_plugin_service->file_get_string(remminafile, "domain"),
-								NULL);
+									(disablepasswordstoring ? 0 : REMMINA_MESSAGE_PANEL_FLAG_SAVEPASSWORD) | REMMINA_MESSAGE_PANEL_FLAG_USERNAME | REMMINA_MESSAGE_PANEL_FLAG_DOMAIN,
+									_("Enter RDP authentication credentials"),
+									remmina_plugin_service->file_get_string(remminafile, "username"),
+									remmina_plugin_service->file_get_string(remminafile, "password"),
+									remmina_plugin_service->file_get_string(remminafile, "domain"),
+									NULL);
 	} else {
 		ret = remmina_plugin_service->protocol_plugin_init_auth(gp,
-								(disablepasswordstoring ? 0 : REMMINA_MESSAGE_PANEL_FLAG_SAVEPASSWORD) | REMMINA_MESSAGE_PANEL_FLAG_USERNAME | REMMINA_MESSAGE_PANEL_FLAG_DOMAIN,
-								_("Enter RDP gateway authentication credentials"),
-								remmina_plugin_service->file_get_string(remminafile, "gateway_username"),
-								remmina_plugin_service->file_get_string(remminafile, "gateway_password"),
-								remmina_plugin_service->file_get_string(remminafile, "gateway_domain"),
-								NULL);
+									(disablepasswordstoring ? 0 : REMMINA_MESSAGE_PANEL_FLAG_SAVEPASSWORD) | REMMINA_MESSAGE_PANEL_FLAG_USERNAME | REMMINA_MESSAGE_PANEL_FLAG_DOMAIN,
+									_("Enter RDP gateway authentication credentials"),
+									remmina_plugin_service->file_get_string(remminafile, "gateway_username"),
+									remmina_plugin_service->file_get_string(remminafile, "gateway_password"),
+									remmina_plugin_service->file_get_string(remminafile, "gateway_domain"),
+									NULL);
 	}
 
 
@@ -1167,8 +1183,9 @@ static gboolean remmina_rdp_set_connection_type(rdpSettings *settings, guint32 t
 		settings->SupportGraphicsPipeline = TRUE;
 	} else if (type == REMMINA_CONNECTION_TYPE_NONE) {
 		return FALSE;
-	} else
+	} else {
 		return FALSE;
+	}
 
 	return TRUE;
 }
@@ -1326,7 +1343,7 @@ static gboolean remmina_rdp_main(RemminaProtocolWidget *gp)
 			rfi->settings->ProxyPort = proxy_port;
 	}
 
-	if (remmina_plugin_service->file_get_int(remminafile, "base-cred-for-gw", FALSE)){
+	if (remmina_plugin_service->file_get_int(remminafile, "base-cred-for-gw", FALSE)) {
 		// Reset gateway credentials
 		remmina_plugin_service->file_set_string(remminafile, "gateway_username", NULL);
 		remmina_plugin_service->file_set_string(remminafile, "gateway_domain", NULL);
@@ -1546,6 +1563,14 @@ static gboolean remmina_rdp_main(RemminaProtocolWidget *gp)
 	 * dynamically resize remote desktop. This will automatically open
 	 * the "disp" dynamic channel, if available */
 	rfi->settings->SupportDisplayControl = TRUE;
+	if (rfi->settings->SupportDisplayControl) {
+		char *d[1];
+		int dcount;
+
+		dcount = 1;
+		d[0] = "disp";
+		freerdp_client_add_dynamic_channel(rfi->settings, dcount, d);
+	}
 
 	/* Sound settings */
 
@@ -1617,19 +1642,20 @@ static gboolean remmina_rdp_main(RemminaProtocolWidget *gp)
 
 
 	cs = remmina_plugin_service->file_get_string(remminafile, "freerdp_log_level");
-	if (cs != NULL && cs[0] != '\0') {
-		REMMINA_PLUGIN_DEBUG ("Log level set to to %s", cs);
-	} else
-		cs = g_strdup ("INFO");
+	if (cs != NULL && cs[0] != '\0')
+		REMMINA_PLUGIN_DEBUG("Log level set to to %s", cs);
+	else
+		cs = g_strdup("INFO");
 	wLog *root = WLog_GetRoot();
 	WLog_SetStringLogLevel(root, cs);
 
 	cs = remmina_plugin_service->file_get_string(remminafile, "freerdp_log_filters");
 	if (cs != NULL && cs[0] != '\0') {
-		REMMINA_PLUGIN_DEBUG ("Log filters set to to %s", cs);
+		REMMINA_PLUGIN_DEBUG("Log filters set to to %s", cs);
 		WLog_AddStringLogFilters(cs);
-	} else
+	} else {
 		WLog_AddStringLogFilters(NULL);
+	}
 
 
 	cs = remmina_plugin_service->file_get_string(remminafile, "usb");
@@ -1717,6 +1743,53 @@ static gboolean remmina_rdp_main(RemminaProtocolWidget *gp)
 #endif /* HAVE_CUPS */
 	}
 
+	if (remmina_plugin_service->file_get_int(remminafile, "span", FALSE)) {
+		rfi->settings->SpanMonitors = TRUE;
+		rfi->settings->UseMultimon = TRUE;
+		rfi->settings->Fullscreen = TRUE;
+		remmina_plugin_service->file_set_int(remminafile, "multimon", 1);
+	}
+
+	if (remmina_plugin_service->file_get_int(remminafile, "multimon", FALSE)) {
+		guint32 maxwidth = 0;
+		guint32 maxheight = 0;
+		rfi->settings->UseMultimon = TRUE;
+		/* TODO Add an option for this */
+		rfi->settings->ForceMultimon = TRUE;
+		rfi->settings->Fullscreen = TRUE;
+		//if (!rfi->settings->NumMonitorIds)
+			//rfi->settings->NumMonitorIds = 0;
+
+		gchar *monitorids = g_strdup(remmina_plugin_service->file_get_string(remminafile, "monitorids"));
+		/* Otherwise we get all the attached monitors */
+		//if (monitorids != NULL && monitorids[0] != '\0')
+		//gchar *monitorids = NULL;
+		remmina_rdp_monitor_get(rfi, &monitorids, &maxwidth, &maxheight);
+		if (monitorids != NULL && monitorids[0] != '\0') {
+			gchar **items;
+			guint32 i;
+			items = g_strsplit(monitorids, ",", -1);
+			rfi->settings->NumMonitorIds = g_strv_length(items);
+			REMMINA_PLUGIN_DEBUG("NumMonitorIds: %d", rfi->settings->NumMonitorIds);
+			for (i = 0; i < g_strv_length(items); i++) {
+				rfi->settings->MonitorIds[i] = (guint32)atoi(items[i]);
+				REMMINA_PLUGIN_DEBUG("Added monitor with ID %d", rfi->settings->MonitorIds[i]);
+			}
+			g_free(monitorids);
+			g_strfreev(items);
+		}
+		if (maxwidth && maxheight) {
+			REMMINA_PLUGIN_DEBUG("Setting DesktopWidth and DesktopHeight to: %dx%d", maxwidth, maxheight);
+			rfi->settings->DesktopWidth = maxwidth;
+			rfi->settings->DesktopHeight = maxheight;
+			REMMINA_PLUGIN_DEBUG("DesktopWidth and DesktopHeight set to: %dx%d", rfi->settings->DesktopWidth, rfi->settings->DesktopHeight);
+		} else {
+			REMMINA_PLUGIN_DEBUG("Cannot set Desktop Size, we are using the previously set values: %dx%d", rfi->settings->DesktopWidth, rfi->settings->DesktopHeight);
+		}
+		remmina_plugin_service->protocol_plugin_set_width(gp, rfi->settings->DesktopWidth);
+		remmina_plugin_service->protocol_plugin_set_height(gp, rfi->settings->DesktopHeight);
+	}
+
 	if (remmina_plugin_service->file_get_int(remminafile, "sharesmartcard", FALSE)) {
 		RDPDR_SMARTCARD *smartcard;
 		smartcard = (RDPDR_SMARTCARD *)calloc(1, sizeof(RDPDR_SMARTCARD));
@@ -2399,15 +2472,18 @@ static gchar network_tooltip[] =
  */
 static const RemminaProtocolSetting remmina_rdp_basic_settings[] =
 {
-	{ REMMINA_PROTOCOL_SETTING_TYPE_SERVER,	    "server",	   NULL,			  FALSE, NULL,		  NULL		  },
-	{ REMMINA_PROTOCOL_SETTING_TYPE_TEXT,	    "username",	   N_("Username"),		  FALSE, NULL,		  NULL		  },
-	{ REMMINA_PROTOCOL_SETTING_TYPE_PASSWORD,   "password",	   N_("Password"),		  FALSE, NULL,		  NULL		  },
-	{ REMMINA_PROTOCOL_SETTING_TYPE_TEXT,	    "domain",	   N_("Domain"),		  FALSE, NULL,		  NULL		  },
-	{ REMMINA_PROTOCOL_SETTING_TYPE_RESOLUTION, "resolution",  NULL,			  FALSE, NULL,		  NULL		  },
-	{ REMMINA_PROTOCOL_SETTING_TYPE_SELECT,	    "colordepth",  N_("Colour depth"),		  FALSE, colordepth_list, NULL		  },
-	{ REMMINA_PROTOCOL_SETTING_TYPE_SELECT,	    "network",	   N_("Network connection type"), FALSE, network_list,	  network_tooltip },
-	{ REMMINA_PROTOCOL_SETTING_TYPE_FOLDER,	    "sharefolder", N_("Share folder"),		  FALSE, NULL,		  NULL		  },
-	{ REMMINA_PROTOCOL_SETTING_TYPE_END,	    NULL,	   NULL,			  FALSE, NULL,		  NULL		  }
+	{ REMMINA_PROTOCOL_SETTING_TYPE_SERVER,	    "server",	   NULL,			  FALSE, NULL,		  NULL						      },
+	{ REMMINA_PROTOCOL_SETTING_TYPE_TEXT,	    "username",	   N_("Username"),		  FALSE, NULL,		  NULL						      },
+	{ REMMINA_PROTOCOL_SETTING_TYPE_PASSWORD,   "password",	   N_("Password"),		  FALSE, NULL,		  NULL						      },
+	{ REMMINA_PROTOCOL_SETTING_TYPE_TEXT,	    "domain",	   N_("Domain"),		  FALSE, NULL,		  NULL						      },
+	{ REMMINA_PROTOCOL_SETTING_TYPE_CHECK,	    "multimon",	   N_("Enable multi monitor"),	  TRUE, NULL,		  NULL						      },
+	{ REMMINA_PROTOCOL_SETTING_TYPE_CHECK,	    "span",	   N_("Span screen over multiple monitors"),	  TRUE, NULL,		  NULL						      },
+	{ REMMINA_PROTOCOL_SETTING_TYPE_TEXT,	    "monitorids",  N_("Monitor ID list"),	  FALSE, NULL,		  N_("Comma separated list of monitor IDs (0,1,2,4)") },
+	{ REMMINA_PROTOCOL_SETTING_TYPE_RESOLUTION, "resolution",  NULL,			  FALSE, NULL,		  NULL						      },
+	{ REMMINA_PROTOCOL_SETTING_TYPE_SELECT,	    "colordepth",  N_("Colour depth"),		  FALSE, colordepth_list, NULL						      },
+	{ REMMINA_PROTOCOL_SETTING_TYPE_SELECT,	    "network",	   N_("Network connection type"), FALSE, network_list,	  network_tooltip				      },
+	{ REMMINA_PROTOCOL_SETTING_TYPE_FOLDER,	    "sharefolder", N_("Share folder"),		  FALSE, NULL,		  NULL						      },
+	{ REMMINA_PROTOCOL_SETTING_TYPE_END,	    NULL,	   NULL,			  FALSE, NULL,		  NULL						      }
 };
 
 /* Array of RemminaProtocolSetting for advanced settings.
@@ -2427,7 +2503,7 @@ static const RemminaProtocolSetting remmina_rdp_advanced_settings[] =
 	{ REMMINA_PROTOCOL_SETTING_TYPE_SELECT,	  "freerdp_log_level",	    N_("FreeRDP log level"),				 FALSE, log_level,	  NULL														 },
 	{ REMMINA_PROTOCOL_SETTING_TYPE_TEXT,	  "freerdp_log_filters",    N_("FreeRDP log filters"),				 FALSE, NULL,		  N_("tag:level[,tag:level[,…]]")										 },
 	{ REMMINA_PROTOCOL_SETTING_TYPE_SELECT,	  "sound",		    N_("Sound"),					 FALSE, sound_list,	  NULL														 },
-	{ REMMINA_PROTOCOL_SETTING_TYPE_TEXT,	  "audio-output",	    N_("Redirect local audio output"),			 TRUE,	NULL,		  audio_tooltip												 },
+	{ REMMINA_PROTOCOL_SETTING_TYPE_TEXT,	  "audio-output",	    N_("Redirect local audio output"),			 TRUE,	NULL,		  audio_tooltip													 },
 	{ REMMINA_PROTOCOL_SETTING_TYPE_TEXT,	  "microphone",		    N_("Redirect local microphone"),			 TRUE,	NULL,		  microphone_tooltip												 },
 	{ REMMINA_PROTOCOL_SETTING_TYPE_TEXT,	  "timeout",		    N_("Connection timeout in ms"),			 TRUE,	NULL,		  timeout_tooltip												 },
 	{ REMMINA_PROTOCOL_SETTING_TYPE_TEXT,	  "gateway_server",	    N_("Remote Desktop Gateway server"),		 FALSE, NULL,		  NULL														 },
@@ -2437,7 +2513,7 @@ static const RemminaProtocolSetting remmina_rdp_advanced_settings[] =
 	{ REMMINA_PROTOCOL_SETTING_TYPE_TEXT,	  "clientname",		    N_("Client name"),					 FALSE, NULL,		  NULL														 },
 	{ REMMINA_PROTOCOL_SETTING_TYPE_COMBO,	  "clientbuild",	    N_("Client build"),					 FALSE, clientbuild_list, clientbuild_tooltip												 },
 	{ REMMINA_PROTOCOL_SETTING_TYPE_TEXT,	  "exec",		    N_("Start-up program"),				 FALSE, NULL,		  NULL														 },
-	{ REMMINA_PROTOCOL_SETTING_TYPE_TEXT,	  "execpath",		    N_("Start-up path"),					 FALSE, NULL,		  NULL														 },
+	{ REMMINA_PROTOCOL_SETTING_TYPE_TEXT,	  "execpath",		    N_("Start-up path"),				 FALSE, NULL,		  NULL														 },
 	{ REMMINA_PROTOCOL_SETTING_TYPE_TEXT,	  "loadbalanceinfo",	    N_("Load balance info"),				 FALSE, NULL,		  NULL														 },
 	{ REMMINA_PROTOCOL_SETTING_TYPE_TEXT,	  "printer_overrides",	    N_("Override printer drivers"),			 FALSE, NULL,		  N_("\"Samsung_CLX-3300_Series\":\"Samsung CLX-3300 Series PS\";\"Canon MF410\":\"Canon MF410 Series UFR II\"") },
 	{ REMMINA_PROTOCOL_SETTING_TYPE_TEXT,	  "usb",		    N_("USB device redirection"),			 TRUE,	NULL,		  usb_tooltip													 },
@@ -2469,7 +2545,7 @@ static const RemminaProtocolSetting remmina_rdp_advanced_settings[] =
 	{ REMMINA_PROTOCOL_SETTING_TYPE_CHECK,	  "relax-order-checks",	    N_("Relax order checks"),				 TRUE,	NULL,		  NULL														 },
 	{ REMMINA_PROTOCOL_SETTING_TYPE_CHECK,	  "glyph-cache",	    N_("Glyph cache"),					 TRUE,	NULL,		  NULL														 },
 	{ REMMINA_PROTOCOL_SETTING_TYPE_CHECK,	  "multitransport",	    N_("Enable multitransport protocol (UDP)"),		 TRUE,	NULL,		  N_("Using the UDP protocol may improve performance")								 },
-	{ REMMINA_PROTOCOL_SETTING_TYPE_CHECK,	  "base-cred-for-gw",	    N_("Use base credentials for gateway too"),					 TRUE,	NULL,		  NULL														 },
+	{ REMMINA_PROTOCOL_SETTING_TYPE_CHECK,	  "base-cred-for-gw",	    N_("Use base credentials for gateway too"),		 TRUE,	NULL,		  NULL														 },
 	{ REMMINA_PROTOCOL_SETTING_TYPE_END,	  NULL,			    NULL,						 FALSE, NULL,		  NULL														 }
 };
 
diff --git a/plugins/rdp/rdp_plugin.h b/plugins/rdp/rdp_plugin.h
index 9eb982a505..d736c12f0a 100644
--- a/plugins/rdp/rdp_plugin.h
+++ b/plugins/rdp/rdp_plugin.h
@@ -173,11 +173,16 @@ struct remmina_plugin_rdp_event {
 			CLIPRDR_FORMAT_DATA_REQUEST *pFormatDataRequest;
 		} clipboard_formatdatarequest;
 		struct {
+			gint    Flags;
+			gint    Left;
+			gint    Top;
 			gint	width;
 			gint	height;
 			gint	desktopOrientation;
 			gint	desktopScaleFactor;
 			gint	deviceScaleFactor;
+			gint    physicalWidth;
+			gint    physicalHeight;
 		} monitor_layout;
 	};
 };
diff --git a/src/rcw.c b/src/rcw.c
index 80276eb8bf..58a15105a6 100644
--- a/src/rcw.c
+++ b/src/rcw.c
@@ -1311,6 +1311,14 @@ static void rcw_toolbar_fullscreen(GtkToolItem *toggle, RemminaConnectionWindow
 
 	if (!(cnnobj = rcw_get_visible_cnnobj(cnnwin))) return;
 
+	RemminaProtocolWidget *gp = REMMINA_PROTOCOL_WIDGET(cnnobj->proto);
+
+	if (remmina_protocol_widget_get_multimon (gp) >= 1) {
+		REMMINA_DEBUG("Fullscreen on all monitor");
+		gdk_window_set_fullscreen_mode (gtk_widget_get_window(GTK_WIDGET(toggle)), GDK_FULLSCREEN_ON_ALL_MONITORS);
+	} else
+		REMMINA_DEBUG("Fullscreen on one monitor");
+
 	if (gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(toggle)))
 		rcw_switch_viewmode(cnnwin, cnnwin->priv->fss_view_mode);
 	else
@@ -2943,12 +2951,37 @@ static gboolean rcw_state_event(GtkWidget *widget, GdkEventWindowState *event, g
 
 static gboolean rcw_map_event_fullscreen(GtkWidget *widget, GdkEvent *event, gpointer data)
 {
+	TRACE_CALL(__func__);
+	RemminaConnectionObject *cnnobj;
 	gint target_monitor;
 
-	TRACE_CALL(__func__);
+	REMMINA_DEBUG ("Mapping Remmina connection window");
 
-	if (!REMMINA_IS_CONNECTION_WINDOW(widget))
+	if (!REMMINA_IS_CONNECTION_WINDOW(widget)) {
+		REMMINA_DEBUG ("Remmina Connection Window undefined, cannot go fullscreen");
+		return FALSE;
+	}
+
+	//RemminaConnectionWindow *cnnwin = (RemminaConnectionWindow *)data;
+	cnnobj = rcw_get_visible_cnnobj((RemminaConnectionWindow*)widget);
+	//cnnobj = g_object_get_data(G_OBJECT(widget), "cnnobj");
+	if (!cnnobj) {
+		REMMINA_DEBUG ("Remmina Connection Object undefined, cannot go fullscreen");
 		return FALSE;
+	}
+
+	RemminaProtocolWidget *gp = REMMINA_PROTOCOL_WIDGET(cnnobj->proto);
+	if (!gp) {
+		REMMINA_DEBUG ("Remmina Protocol Widget undefined, cannot go fullscreen");
+	}
+
+	if (remmina_protocol_widget_get_multimon (gp) >= 1) {
+		REMMINA_DEBUG("Fullscreen on all monitor");
+		gdk_window_set_fullscreen_mode (gtk_widget_get_window(widget), GDK_FULLSCREEN_ON_ALL_MONITORS);
+		gdk_window_fullscreen(gtk_widget_get_window(widget));
+		return TRUE;
+	} else
+		REMMINA_DEBUG("Fullscreen on one monitor");
 
 	target_monitor = GPOINTER_TO_INT(data);
 
diff --git a/src/remmina_protocol_widget.c b/src/remmina_protocol_widget.c
index 3397a691c1..1a42da1b28 100644
--- a/src/remmina_protocol_widget.c
+++ b/src/remmina_protocol_widget.c
@@ -84,6 +84,7 @@ struct _RemminaProtocolWidgetPriv {
 
 	gint			profile_remote_width;
 	gint			profile_remote_height;
+	gint			multimon;
 
 	RemminaMessagePanel *	connect_message_panel;
 	RemminaMessagePanel *	listen_message_panel;
@@ -1129,6 +1130,15 @@ gint remmina_protocol_widget_get_profile_remote_width(RemminaProtocolWidget *gp)
 	return gp->priv->profile_remote_width;
 }
 
+gint remmina_protocol_widget_get_multimon(RemminaProtocolWidget *gp)
+{
+	TRACE_CALL(__func__);
+	/* Returns ehenever multi monitor is enabled (1) */
+	gp->priv->multimon = remmina_file_get_int(gp->priv->remmina_file, "multimon", -1);
+	REMMINA_DEBUG ("Multi monitor is set to %d", gp->priv->multimon);
+	return gp->priv->multimon;
+}
+
 gint remmina_protocol_widget_get_profile_remote_height(RemminaProtocolWidget *gp)
 {
 	TRACE_CALL(__func__);
diff --git a/src/remmina_protocol_widget.h b/src/remmina_protocol_widget.h
index 98d71cdf1d..abb971159c 100644
--- a/src/remmina_protocol_widget.h
+++ b/src/remmina_protocol_widget.h
@@ -88,6 +88,7 @@ gint remmina_protocol_widget_get_height(RemminaProtocolWidget *gp);
 void remmina_protocol_widget_set_height(RemminaProtocolWidget *gp, gint height);
 gint remmina_protocol_widget_get_profile_remote_width(RemminaProtocolWidget *gp);
 gint remmina_protocol_widget_get_profile_remote_height(RemminaProtocolWidget *gp);
+gint remmina_protocol_widget_get_multimon(RemminaProtocolWidget *gp);
 
 RemminaScaleMode remmina_protocol_widget_get_current_scale_mode(RemminaProtocolWidget *gp);
 void remmina_protocol_widget_set_current_scale_mode(RemminaProtocolWidget *gp, RemminaScaleMode scalemode);
-- 
GitLab


From d429c38dabcf6fb7fa5d213553229325d3704384 Mon Sep 17 00:00:00 2001
From: Antenore Gatta <antenore@simbiosi.org>
Date: Wed, 27 Jan 2021 15:46:05 +0100
Subject: [PATCH 2/8] Adding multi monitor support: monitor detection

---
 plugins/rdp/rdp_monitor.c | 226 ++++++++++++++++++++++++++++++++++++++
 plugins/rdp/rdp_monitor.h |  45 ++++++++
 2 files changed, 271 insertions(+)
 create mode 100644 plugins/rdp/rdp_monitor.c
 create mode 100644 plugins/rdp/rdp_monitor.h

diff --git a/plugins/rdp/rdp_monitor.c b/plugins/rdp/rdp_monitor.c
new file mode 100644
index 0000000000..a590f791d0
--- /dev/null
+++ b/plugins/rdp/rdp_monitor.c
@@ -0,0 +1,226 @@
+/*
+ * Remmina - The GTK+ Remote Desktop Client
+ * Copyright (C) 2016-2020 Antenore Gatta, Giovanni Panozzo
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA  02110-1301, USA.
+ *
+ *  In addition, as a special exception, the copyright holders give
+ *  permission to link the code of portions of this program with the
+ *  OpenSSL library under certain conditions as described in each
+ *  individual source file, and distribute linked combinations
+ *  including the two.
+ *  You must obey the GNU General Public License in all respects
+ *  for all of the code used other than OpenSSL. *  If you modify
+ *  file(s) with this exception, you may extend this exception to your
+ *  version of the file(s), but you are not obligated to do so. *  If you
+ *  do not wish to do so, delete this exception statement from your
+ *  version. *  If you delete this exception statement from all source
+ *  files in the program, then also delete it here.
+ *
+ */
+
+#include "rdp_plugin.h"
+#include "rdp_monitor.h"
+
+/** @ToDo Utility functions should be moved somewhere else */
+gint remmina_rdp_utils_strpos(const gchar *haystack, const gchar *needle)
+{
+	TRACE_CALL(__func__);
+	const gchar *sub;
+
+	if (!*needle)
+		return -1;
+
+	sub = strstr(haystack, needle);
+	if (!sub)
+		return -1;
+
+	return sub - haystack;
+}
+
+/* https://github.com/adlocode/xfwm4/blob/1d21be9ffc0fa1cea91905a07d1446c5227745f4/common/xfwm-common.c */
+
+
+/**
+ * Set the MonitorIDs, the maxwidth and maxheight
+ *
+ * - number of monitors
+ * - Geometry of each
+ * - Choosen by the user
+ * - Primary monitor
+ *   - Otherwise use current monitor as the origin
+ *
+ *   The origin must be 0,0
+ */
+void remmina_rdp_monitor_get (rfContext *rfi, gchar **monitorids, guint32 *maxwidth, guint32 *maxheight)
+{
+	TRACE_CALL(__func__);
+
+	GdkDisplay *display;
+	GdkMonitor *current_monitor, *monitor;
+	gboolean has_custom_monitors = FALSE;
+
+	gboolean primary_found = FALSE;
+
+	gint n_monitors;
+	gint scale;
+	gint index = 0;
+	gint count = 0;
+
+	static gchar buffer[256];
+
+	GdkRectangle geometry = { 0, 0, 0, 0 };
+	GdkRectangle tempgeom = { 0, 0, 0, 0 };
+	GdkRectangle destgeom = { 0, 0, 0, 0 };
+	rdpSettings* settings;
+	if (!rfi || !rfi->settings)
+		return;
+
+	settings = rfi->settings;
+
+	*maxwidth = settings->DesktopWidth;
+	*maxheight = settings->DesktopHeight;
+
+	display = gdk_display_get_default ();
+	n_monitors = gdk_display_get_n_monitors(display);
+
+	/* Get monitor at windows curently in use */
+	//w = gtk_widget_get_window(rfi->drawing_area);
+
+	//current_monitor = gdk_display_get_monitor_at_window (display, w);
+
+	/* we got monitorids as options */
+	if (*monitorids)
+		has_custom_monitors = TRUE;
+
+	buffer[0] = '\0';
+
+	for (gint i = 0; i < n_monitors; ++i) {
+		if (has_custom_monitors) {
+			REMMINA_PLUGIN_DEBUG("We have custom monitors");
+			gchar itoc[10];
+			sprintf(itoc, "%d", i);;
+			if (remmina_rdp_utils_strpos(*monitorids, itoc) < 0 ) {
+				REMMINA_PLUGIN_DEBUG("Monitor n %d it's out of the provided list", i);
+				index += 1;
+				continue;
+			}
+		}
+
+		monitor = gdk_display_get_monitor(display, i);
+		if (monitor == NULL) {
+			REMMINA_PLUGIN_DEBUG("Monitor n %d does not exist or is not active", i);
+			index +=1;
+			continue;
+		}
+
+		monitor = gdk_display_get_monitor(display, index);
+		REMMINA_PLUGIN_DEBUG("Monitor n %d", index);
+		/* If the desktop env in use doesn't have the working area concept
+		 * gdk_monitor_get_workarea will return the monitor geometry*/
+		//gdk_monitor_get_workarea (monitor, &geometry);
+		gdk_monitor_get_geometry (monitor, &geometry);
+		settings->MonitorDefArray[index].x = geometry.x;
+		REMMINA_PLUGIN_DEBUG("Monitor n %d x: %d", index, geometry.x);
+		settings->MonitorDefArray[index].y = geometry.y;
+		REMMINA_PLUGIN_DEBUG("Monitor n %d y: %d", index, geometry.y);
+		/* geometry contain the application geometry, to obtain the real one
+		 * we must multiply by the scale factor */
+		scale = gdk_monitor_get_scale_factor (monitor);
+		REMMINA_PLUGIN_DEBUG("Monitor n %d scale: %d", index, scale);
+		geometry.width *= scale;
+		geometry.height *= scale;
+		REMMINA_PLUGIN_DEBUG("Monitor n %d width: %d", index, geometry.width);
+		REMMINA_PLUGIN_DEBUG("Monitor n %d height: %d", index, geometry.height);
+		settings->MonitorDefArray[index].width = geometry.width;
+		settings->MonitorDefArray[index].height = geometry.height;
+		settings->MonitorDefArray[index].attributes.physicalHeight = gdk_monitor_get_height_mm (monitor);
+		REMMINA_PLUGIN_DEBUG("Monitor n %d physical  height: %d", i, settings->MonitorDefArray[index].attributes.physicalHeight);
+		settings->MonitorDefArray[index].attributes.physicalWidth = gdk_monitor_get_width_mm (monitor);
+		REMMINA_PLUGIN_DEBUG("Monitor n %d physical  width: %d", i, settings->MonitorDefArray[index].attributes.physicalWidth);
+		settings->MonitorDefArray[index].orig_screen = index;
+		if (!primary_found) {
+			settings->MonitorLocalShiftX = settings->MonitorDefArray[index].x;
+			settings->MonitorLocalShiftY = settings->MonitorDefArray[index].y;
+		}
+		if (gdk_monitor_is_primary(monitor)) {
+			REMMINA_PLUGIN_DEBUG ("Primary monitor found with id: %d", index);
+			settings->MonitorDefArray[index].is_primary = TRUE;
+			primary_found = TRUE;
+			if (settings->MonitorDefArray[index].x != 0 || settings->MonitorDefArray[index].y != 0)
+			{
+				REMMINA_PLUGIN_DEBUG ("Primary monitor not at 0,0 coordinates: %d", index);
+				settings->MonitorLocalShiftX = settings->MonitorDefArray[index].x;
+				settings->MonitorLocalShiftY = settings->MonitorDefArray[index].y;
+			}
+		} else {
+			if (!primary_found && settings->MonitorDefArray[index].x == 0 &&
+					settings->MonitorDefArray[index].y == 0)
+			{
+				REMMINA_PLUGIN_DEBUG ("Monitor %d has 0,0 coordiantes", index);
+				settings->MonitorDefArray[index].is_primary = TRUE;
+				settings->MonitorLocalShiftX = settings->MonitorDefArray[index].x;
+				settings->MonitorLocalShiftY = settings->MonitorDefArray[index].y;
+				primary_found = TRUE;
+				REMMINA_PLUGIN_DEBUG ("Primary monitor set to id: %d", index);
+			}
+		}
+		REMMINA_PLUGIN_DEBUG ("Local X Shift: %d", settings->MonitorLocalShiftX);
+		REMMINA_PLUGIN_DEBUG ("Local Y Shift: %d", settings->MonitorLocalShiftY);
+		//settings->MonitorDefArray[index].x =
+			//settings->MonitorDefArray[index].x - settings->MonitorLocalShiftX;
+		//REMMINA_PLUGIN_DEBUG("Monitor n %d calculated x: %d", index, settings->MonitorDefArray[index].x);
+		//settings->MonitorDefArray[index].y =
+			//settings->MonitorDefArray[index].y - settings->MonitorLocalShiftY;
+		//REMMINA_PLUGIN_DEBUG("Monitor n %d calculated y: %d", index, settings->MonitorDefArray[index].y);
+
+		if (buffer[0] == '\0')
+			g_sprintf (buffer, "%d", i);
+		else
+			g_sprintf(buffer, "%s,%d", buffer, i);
+		REMMINA_PLUGIN_DEBUG("Monitor IDs buffer: %s", buffer);
+		gdk_rectangle_union(&tempgeom, &geometry, &destgeom);
+		memcpy(&tempgeom, &destgeom, sizeof tempgeom);
+		count++;
+		index++;
+
+	}
+	settings->MonitorCount = index;
+	/* Subtract monitor shift from monitor variables for server-side use.
+	 * We maintain monitor shift value as Window requires the primary monitor to have a
+	 * coordinate of 0,0 In some X configurations, no monitor may have a coordinate of 0,0. This
+	 * can also be happen if the user requests specific monitors from the command-line as well.
+	 * So, we make sure to translate our primary monitor's upper-left corner to 0,0 on the
+	 * server.
+	 */
+	for (gint i = 0; i < settings->MonitorCount; i++)
+	{
+		settings->MonitorDefArray[i].x =
+			settings->MonitorDefArray[i].x - settings->MonitorLocalShiftX;
+		REMMINA_PLUGIN_DEBUG("Monitor n %d calculated x: %d", index, settings->MonitorDefArray[index].x);
+		settings->MonitorDefArray[i].y =
+			settings->MonitorDefArray[i].y - settings->MonitorLocalShiftY;
+		REMMINA_PLUGIN_DEBUG("Monitor n %d calculated y: %d", index, settings->MonitorDefArray[index].y);
+	}
+
+	REMMINA_PLUGIN_DEBUG("%d monitors on %d have been configured", rfi->settings->MonitorCount, count);
+	*maxwidth = destgeom.width;
+	*maxheight = destgeom.height;
+	REMMINA_PLUGIN_DEBUG("maxw and maxh: %ux%u", *maxwidth, *maxheight);
+	if (n_monitors > 1)
+		rfi->settings->SupportMonitorLayoutPdu = TRUE;
+	*monitorids = g_strdup(buffer);
+}
diff --git a/plugins/rdp/rdp_monitor.h b/plugins/rdp/rdp_monitor.h
new file mode 100644
index 0000000000..1c8f08dbb7
--- /dev/null
+++ b/plugins/rdp/rdp_monitor.h
@@ -0,0 +1,45 @@
+/*
+ * Remmina - The GTK+ Remote Desktop Client
+ * Copyright (C) 2016-2020 Antenore Gatta, Giovanni Panozzo
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA  02110-1301, USA.
+ *
+ *  In addition, as a special exception, the copyright holders give
+ *  permission to link the code of portions of this program with the
+ *  OpenSSL library under certain conditions as described in each
+ *  individual source file, and distribute linked combinations
+ *  including the two.
+ *  You must obey the GNU General Public License in all respects
+ *  for all of the code used other than OpenSSL. *  If you modify
+ *  file(s) with this exception, you may extend this exception to your
+ *  version of the file(s), but you are not obligated to do so. *  If you
+ *  do not wish to do so, delete this exception statement from your
+ *  version. *  If you delete this exception statement from all source
+ *  files in the program, then also delete it here.
+ *
+ */
+
+#pragma once
+
+
+#include <freerdp/freerdp.h>
+#include "rdp_plugin.h"
+
+G_BEGIN_DECLS
+
+void remmina_rdp_monitor_get (rfContext *rfi, gchar **monitorids, guint32 *maxwidth, guint32 *maxheight);
+
+G_END_DECLS
-- 
GitLab


From 5dfc287d896ae5c5958472a3b157c6a65dc19505 Mon Sep 17 00:00:00 2001
From: Antenore Gatta <antenore@simbiosi.org>
Date: Wed, 27 Jan 2021 16:30:07 +0100
Subject: [PATCH 3/8] Sending multiple layouts only if multimon is active

---
 plugins/rdp/rdp_event.c  | 57 ++++++++++++++++++++-------------
 plugins/rdp/rdp_plugin.c | 68 +++++++++++++++++++++++++---------------
 2 files changed, 78 insertions(+), 47 deletions(-)

diff --git a/plugins/rdp/rdp_event.c b/plugins/rdp/rdp_event.c
index fcd0225d41..d3609f9aee 100644
--- a/plugins/rdp/rdp_event.c
+++ b/plugins/rdp/rdp_event.c
@@ -366,9 +366,13 @@ static gboolean remmina_rdp_event_delayed_monitor_layout(RemminaProtocolWidget *
 	GtkAllocation a;
 	gint desktopOrientation, desktopScaleFactor, deviceScaleFactor;
 
+	RemminaFile *remminafile;
+
 	if (!rfi || !rfi->connected || rfi->is_reconnecting)
 		return FALSE;
 
+	remminafile = remmina_plugin_service->protocol_plugin_get_file(gp);
+
 	if (rfi->scale != REMMINA_PROTOCOL_WIDGET_SCALE_MODE_DYNRES)
 		return FALSE;
 
@@ -398,28 +402,37 @@ static gboolean remmina_rdp_event_delayed_monitor_layout(RemminaProtocolWidget *
 					gpheight = AVC_MIN_DESKTOP_HEIGHT;
 			}
 			rdp_event.type = REMMINA_RDP_EVENT_TYPE_SEND_MONITOR_LAYOUT;
-			for (gint i = 0; i < rfi->settings->MonitorCount; ++i) {
-				REMMINA_PLUGIN_DEBUG("Sending diplay layout n° %d", i);
-				rdp_event.monitor_layout.Flags = rfi->settings->MonitorDefArray[i].is_primary;
-				REMMINA_PLUGIN_DEBUG("EVNT MON LAYOUT - Flags: %i", rdp_event.monitor_layout.Flags);
-				rdp_event.monitor_layout.Left = rfi->settings->MonitorDefArray[i].x;
-				REMMINA_PLUGIN_DEBUG("EVNT MON LAYOUT - Left: %i", rdp_event.monitor_layout.Left);
-				rdp_event.monitor_layout.Top = rfi->settings->MonitorDefArray[i].y;
-				//rdp_event.monitor_layout.Top = rfi->settings->MonitorDefArray[0].y;
-				REMMINA_PLUGIN_DEBUG("EVNT MON LAYOUT - Top: %i", rdp_event.monitor_layout.Top);
-				rdp_event.monitor_layout.width = rfi->settings->MonitorDefArray[i].width;
-				REMMINA_PLUGIN_DEBUG("EVNT MON LAYOUT - width: %i", rdp_event.monitor_layout.width);
-				rdp_event.monitor_layout.height = rfi->settings->MonitorDefArray[i].height;
-				REMMINA_PLUGIN_DEBUG("EVNT MON LAYOUT - height: %i", rdp_event.monitor_layout.height);
-				rdp_event.monitor_layout.physicalWidth = rfi->settings->MonitorDefArray[i].attributes.physicalWidth;
-				REMMINA_PLUGIN_DEBUG("EVNT MON LAYOUT - physicalWidth: %i", rdp_event.monitor_layout.physicalWidth);
-				rdp_event.monitor_layout.physicalHeight = rfi->settings->MonitorDefArray[i].attributes.physicalHeight;
-				REMMINA_PLUGIN_DEBUG("EVNT MON LAYOUT - PhysicalHeight: %i", rdp_event.monitor_layout.physicalHeight);
-				rdp_event.monitor_layout.desktopOrientation = rdp_event.monitor_layout.desktopOrientation;
-				REMMINA_PLUGIN_DEBUG("EVNT MON LAYOUT - desktopOrientation: %i", rdp_event.monitor_layout.desktopOrientation);
-				rdp_event.monitor_layout.desktopScaleFactor = rdp_event.monitor_layout.desktopScaleFactor;
-				REMMINA_PLUGIN_DEBUG("EVNT MON LAYOUT - ScaleFactorflag: %i", rdp_event.monitor_layout.desktopScaleFactor);
-				rdp_event.monitor_layout.deviceScaleFactor = rdp_event.monitor_layout.deviceScaleFactor;
+			if (remmina_plugin_service->file_get_int(remminafile, "multimon", FALSE)) {
+				for (gint i = 0; i < rfi->settings->MonitorCount; ++i) {
+					REMMINA_PLUGIN_DEBUG("Sending diplay layout n° %d", i);
+					rdp_event.monitor_layout.Flags = rfi->settings->MonitorDefArray[i].is_primary;
+					REMMINA_PLUGIN_DEBUG("EVNT MON LAYOUT - Flags: %i", rdp_event.monitor_layout.Flags);
+					rdp_event.monitor_layout.Left = rfi->settings->MonitorDefArray[i].x;
+					REMMINA_PLUGIN_DEBUG("EVNT MON LAYOUT - Left: %i", rdp_event.monitor_layout.Left);
+					rdp_event.monitor_layout.Top = rfi->settings->MonitorDefArray[i].y;
+					REMMINA_PLUGIN_DEBUG("EVNT MON LAYOUT - Top: %i", rdp_event.monitor_layout.Top);
+					rdp_event.monitor_layout.width = rfi->settings->MonitorDefArray[i].width;
+					REMMINA_PLUGIN_DEBUG("EVNT MON LAYOUT - width: %i", rdp_event.monitor_layout.width);
+					rdp_event.monitor_layout.height = rfi->settings->MonitorDefArray[i].height;
+					REMMINA_PLUGIN_DEBUG("EVNT MON LAYOUT - height: %i", rdp_event.monitor_layout.height);
+					rdp_event.monitor_layout.physicalWidth = rfi->settings->MonitorDefArray[i].attributes.physicalWidth;
+					REMMINA_PLUGIN_DEBUG("EVNT MON LAYOUT - physicalWidth: %i", rdp_event.monitor_layout.physicalWidth);
+					rdp_event.monitor_layout.physicalHeight = rfi->settings->MonitorDefArray[i].attributes.physicalHeight;
+					REMMINA_PLUGIN_DEBUG("EVNT MON LAYOUT - PhysicalHeight: %i", rdp_event.monitor_layout.physicalHeight);
+					rdp_event.monitor_layout.desktopOrientation = rdp_event.monitor_layout.desktopOrientation;
+					REMMINA_PLUGIN_DEBUG("EVNT MON LAYOUT - desktopOrientation: %i", rdp_event.monitor_layout.desktopOrientation);
+					rdp_event.monitor_layout.desktopScaleFactor = rdp_event.monitor_layout.desktopScaleFactor;
+					REMMINA_PLUGIN_DEBUG("EVNT MON LAYOUT - ScaleFactorflag: %i", rdp_event.monitor_layout.desktopScaleFactor);
+					rdp_event.monitor_layout.deviceScaleFactor = rdp_event.monitor_layout.deviceScaleFactor;
+				}
+				remmina_rdp_event_event_push(gp, &rdp_event);
+			} else {
+
+				rdp_event.monitor_layout.width = gpwidth;
+				rdp_event.monitor_layout.height = gpheight;
+				rdp_event.monitor_layout.desktopOrientation = desktopOrientation;
+				rdp_event.monitor_layout.desktopScaleFactor = desktopScaleFactor;
+				rdp_event.monitor_layout.deviceScaleFactor = deviceScaleFactor;
 				remmina_rdp_event_event_push(gp, &rdp_event);
 			}
 		}
diff --git a/plugins/rdp/rdp_plugin.c b/plugins/rdp/rdp_plugin.c
index 507ab68e1e..cb114a6582 100644
--- a/plugins/rdp/rdp_plugin.c
+++ b/plugins/rdp/rdp_plugin.c
@@ -193,12 +193,15 @@ static BOOL rf_process_event_queue(RemminaProtocolWidget *gp)
 	RemminaPluginRdpEvent *event;
 	DISPLAY_CONTROL_MONITOR_LAYOUT *dcml;
 	CLIPRDR_FORMAT_DATA_RESPONSE response = { 0 };
+	RemminaFile *remminafile;
 
 	if (rfi->event_queue == NULL)
 		return True;
 
 	input = rfi->instance->input;
 
+	remminafile = remmina_plugin_service->protocol_plugin_get_file(gp);
+
 	while ((event = (RemminaPluginRdpEvent *)g_async_queue_try_pop(rfi->event_queue)) != NULL) {
 		switch (event->type) {
 		case REMMINA_RDP_EVENT_TYPE_SCANCODE:
@@ -242,32 +245,47 @@ static BOOL rf_process_event_queue(RemminaProtocolWidget *gp)
 			break;
 
 		case REMMINA_RDP_EVENT_TYPE_SEND_MONITOR_LAYOUT:
-			dcml = calloc(rfi->settings->MonitorCount, sizeof(DISPLAY_CONTROL_MONITOR_LAYOUT));
-			REMMINA_PLUGIN_DEBUG("REMMINA_RDP_EVENT_TYPE_SEND_MONITOR_LAYOUT:");
-			if (!dcml)
-				break;
-			for (gint i = 0; i < rfi->settings->MonitorCount; ++i) {
-				REMMINA_PLUGIN_DEBUG("Sending diplay layout for monitor n° %d", i);
-				dcml[i].Flags = (rfi->settings->MonitorDefArray[i].is_primary ? DISPLAY_CONTROL_MONITOR_PRIMARY : 0);
-				REMMINA_PLUGIN_DEBUG("Monitor %d is primary: %d", i, dcml[i].Flags);
-				dcml[i].Left = rfi->settings->MonitorDefArray[i].x;
-				REMMINA_PLUGIN_DEBUG("Monitor %d x: %d", i, dcml[i].Left);
-				dcml[i].Top = rfi->settings->MonitorDefArray[i].y;
-				REMMINA_PLUGIN_DEBUG("Monitor %d y: %d", i, dcml[i].Top);
-				dcml[i].Width = rfi->settings->MonitorDefArray[i].width;
-				REMMINA_PLUGIN_DEBUG("Monitor %d width: %d", i, dcml[i].Width);
-				dcml[i].Height = rfi->settings->MonitorDefArray[i].height;
-				REMMINA_PLUGIN_DEBUG("Monitor %d height: %d", i, dcml[i].Height);
-				dcml[i].PhysicalWidth = rfi->settings->MonitorDefArray[i].attributes.physicalWidth;
-				REMMINA_PLUGIN_DEBUG("Monitor %d physical width: %d", i, dcml[i].PhysicalWidth);
-				dcml[i].PhysicalHeight = rfi->settings->MonitorDefArray[i].attributes.physicalHeight;
-				REMMINA_PLUGIN_DEBUG("Monitor %d physical height: %d", i, dcml[i].PhysicalHeight);
-				dcml[i].Orientation = event->monitor_layout.desktopOrientation;
-				dcml[i].DesktopScaleFactor = event->monitor_layout.desktopScaleFactor;
-				dcml[i].DeviceScaleFactor = event->monitor_layout.deviceScaleFactor;
+			if (remmina_plugin_service->file_get_int(remminafile, "multimon", FALSE)) {
+				/* got some crashes with g_malloc0, to be investigated */
+				dcml = calloc(rfi->settings->MonitorCount, sizeof(DISPLAY_CONTROL_MONITOR_LAYOUT));
+				REMMINA_PLUGIN_DEBUG("REMMINA_RDP_EVENT_TYPE_SEND_MONITOR_LAYOUT:");
+				if (!dcml)
+					break;
+				for (gint i = 0; i < rfi->settings->MonitorCount; ++i) {
+					REMMINA_PLUGIN_DEBUG("Sending diplay layout for monitor n° %d", i);
+					dcml[i].Flags = (rfi->settings->MonitorDefArray[i].is_primary ? DISPLAY_CONTROL_MONITOR_PRIMARY : 0);
+					REMMINA_PLUGIN_DEBUG("Monitor %d is primary: %d", i, dcml[i].Flags);
+					dcml[i].Left = rfi->settings->MonitorDefArray[i].x;
+					REMMINA_PLUGIN_DEBUG("Monitor %d x: %d", i, dcml[i].Left);
+					dcml[i].Top = rfi->settings->MonitorDefArray[i].y;
+					REMMINA_PLUGIN_DEBUG("Monitor %d y: %d", i, dcml[i].Top);
+					dcml[i].Width = rfi->settings->MonitorDefArray[i].width;
+					REMMINA_PLUGIN_DEBUG("Monitor %d width: %d", i, dcml[i].Width);
+					dcml[i].Height = rfi->settings->MonitorDefArray[i].height;
+					REMMINA_PLUGIN_DEBUG("Monitor %d height: %d", i, dcml[i].Height);
+					dcml[i].PhysicalWidth = rfi->settings->MonitorDefArray[i].attributes.physicalWidth;
+					REMMINA_PLUGIN_DEBUG("Monitor %d physical width: %d", i, dcml[i].PhysicalWidth);
+					dcml[i].PhysicalHeight = rfi->settings->MonitorDefArray[i].attributes.physicalHeight;
+					REMMINA_PLUGIN_DEBUG("Monitor %d physical height: %d", i, dcml[i].PhysicalHeight);
+					dcml[i].Orientation = event->monitor_layout.desktopOrientation;
+					dcml[i].DesktopScaleFactor = event->monitor_layout.desktopScaleFactor;
+					dcml[i].DeviceScaleFactor = event->monitor_layout.deviceScaleFactor;
+				}
+				rfi->dispcontext->SendMonitorLayout(rfi->dispcontext, rfi->settings->MonitorCount, dcml);
+				g_free(dcml);
+			} else {
+				dcml = g_malloc0(sizeof(DISPLAY_CONTROL_MONITOR_LAYOUT));
+				if (dcml) {
+					dcml->Flags = DISPLAY_CONTROL_MONITOR_PRIMARY;
+					dcml->Width = event->monitor_layout.width;
+					dcml->Height = event->monitor_layout.height;
+					dcml->Orientation = event->monitor_layout.desktopOrientation;
+					dcml->DesktopScaleFactor = event->monitor_layout.desktopScaleFactor;
+					dcml->DeviceScaleFactor = event->monitor_layout.deviceScaleFactor;
+					rfi->dispcontext->SendMonitorLayout(rfi->dispcontext, 1, dcml);
+					g_free(dcml);\
+				}
 			}
-			rfi->dispcontext->SendMonitorLayout(rfi->dispcontext, rfi->settings->MonitorCount, dcml);
-			g_free(dcml);
 			break;
 		case REMMINA_RDP_EVENT_DISCONNECT:
 			/* Disconnect requested via GUI (i.e: tab destroy/close) */
-- 
GitLab


From 634010c7da0f445f48140dce2c18d78bb5924741 Mon Sep 17 00:00:00 2001
From: Antenore Gatta <antenore@simbiosi.org>
Date: Wed, 27 Jan 2021 15:42:41 +0100
Subject: [PATCH 4/8] Adding multi monitor support

---
 plugins/rdp/rdp_plugin.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/plugins/rdp/rdp_plugin.c b/plugins/rdp/rdp_plugin.c
index cb114a6582..8c2d6a8012 100644
--- a/plugins/rdp/rdp_plugin.c
+++ b/plugins/rdp/rdp_plugin.c
@@ -286,6 +286,8 @@ static BOOL rf_process_event_queue(RemminaProtocolWidget *gp)
 					g_free(dcml);\
 				}
 			}
+			rfi->dispcontext->SendMonitorLayout(rfi->dispcontext, rfi->settings->MonitorCount, dcml);
+			g_free(dcml);
 			break;
 		case REMMINA_RDP_EVENT_DISCONNECT:
 			/* Disconnect requested via GUI (i.e: tab destroy/close) */
-- 
GitLab


From de382ef139cda19c30958e1068ed03d907a104e1 Mon Sep 17 00:00:00 2001
From: Antenore Gatta <antenore@simbiosi.org>
Date: Wed, 27 Jan 2021 16:30:07 +0100
Subject: [PATCH 5/8] Sending multiple layouts only if multimon is active

---
 plugins/rdp/rdp_plugin.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/plugins/rdp/rdp_plugin.c b/plugins/rdp/rdp_plugin.c
index 8c2d6a8012..cb114a6582 100644
--- a/plugins/rdp/rdp_plugin.c
+++ b/plugins/rdp/rdp_plugin.c
@@ -286,8 +286,6 @@ static BOOL rf_process_event_queue(RemminaProtocolWidget *gp)
 					g_free(dcml);\
 				}
 			}
-			rfi->dispcontext->SendMonitorLayout(rfi->dispcontext, rfi->settings->MonitorCount, dcml);
-			g_free(dcml);
 			break;
 		case REMMINA_RDP_EVENT_DISCONNECT:
 			/* Disconnect requested via GUI (i.e: tab destroy/close) */
-- 
GitLab


From 6b95aed88b3711efd04cc23e258a88090913a175 Mon Sep 17 00:00:00 2001
From: Antenore Gatta <antenore@simbiosi.org>
Date: Fri, 29 Jan 2021 17:10:57 +0100
Subject: [PATCH 6/8] Adding multi monitor toolbar button

---
 data/icons/CMakeLists.txt                     |   1 +
 .../remmina-multi-monitor-symbolic.svg        |  69 ++++
 data/ui/remmina_main.glade                    |   2 +-
 data/ui/remmina_preferences.glade             | 294 ++++++++++--------
 plugins/rdp/rdp_monitor.c                     |   6 +-
 plugins/rdp/rdp_plugin.c                      |  36 ++-
 plugins/rdp/rdp_settings.c                    |   2 -
 src/include/remmina/types.h                   |   1 +
 src/rcw.c                                     |  43 ++-
 src/remmina_main.c                            |   1 +
 src/remmina_pref.c                            |   6 +
 src/remmina_pref.h                            |   2 +
 src/remmina_pref_dialog.c                     |  29 ++
 src/remmina_pref_dialog.h                     |   3 +
 14 files changed, 344 insertions(+), 151 deletions(-)
 create mode 100644 data/icons/scalable/actions/remmina-multi-monitor-symbolic.svg

diff --git a/data/icons/CMakeLists.txt b/data/icons/CMakeLists.txt
index fd246807d4..645c09ef69 100644
--- a/data/icons/CMakeLists.txt
+++ b/data/icons/CMakeLists.txt
@@ -45,6 +45,7 @@ set(APPICONSCALE_ACTIONS_DATA
     scalable/actions/remmina-dynres-symbolic.svg
     scalable/actions/remmina-fit-window-symbolic.svg
     scalable/actions/remmina-fullscreen-symbolic.svg
+    scalable/actions/remmina-multi-monitor-symbolic.svg
     scalable/actions/remmina-go-bottom-symbolic.svg
     scalable/actions/remmina-keyboard-symbolic.svg
     scalable/actions/remmina-pan-down-symbolic.svg
diff --git a/data/icons/scalable/actions/remmina-multi-monitor-symbolic.svg b/data/icons/scalable/actions/remmina-multi-monitor-symbolic.svg
new file mode 100644
index 0000000000..2555478986
--- /dev/null
+++ b/data/icons/scalable/actions/remmina-multi-monitor-symbolic.svg
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="22.983299mm"
+   height="19.69982mm"
+   viewBox="0 0 22.983299 19.69982"
+   version="1.1"
+   id="svg723"
+   inkscape:version="1.0.1 (3bc2e813f5, 2020-09-07)"
+   sodipodi:docname="remmina-multi-monitor-symbolic.svg">
+  <defs
+     id="defs717" />
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="11.313708"
+     inkscape:cx="46.830344"
+     inkscape:cy="55.482858"
+     inkscape:document-units="mm"
+     inkscape:current-layer="layer1"
+     inkscape:document-rotation="0"
+     showgrid="false"
+     fit-margin-top="0"
+     fit-margin-left="0"
+     fit-margin-right="0"
+     fit-margin-bottom="0"
+     inkscape:window-width="3840"
+     inkscape:window-height="2102"
+     inkscape:window-x="1920"
+     inkscape:window-y="30"
+     inkscape:window-maximized="1" />
+  <metadata
+     id="metadata720">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(-64.859519,-115.63819)">
+    <path
+       d="m 66.507946,115.65733 c -1.648427,0 -1.648427,1.23946 -1.648427,1.23946 v 4.95762 h 3.296746 v -3.71817 h 4.944872 v -2.47891 z m 13.186281,0 v 2.47891 h 4.944872 v 3.71817 h 3.296443 v -4.95762 c 0,-1.23946 -1.648321,-1.23946 -1.648321,-1.23946 z m -14.834708,8.67577 v 4.95763 c 0,1.23925 1.648427,1.23925 1.648427,1.23925 h 6.593191 v -2.4787 h -4.944872 v -3.71818 z m 19.77958,0 v 3.71818 h -4.944872 v 2.4787 h 6.592994 c 0,0 1.648321,0 1.648321,-1.23925 v -4.95763 z"
+       id="path19-6"
+       inkscape:connector-curvature="0"
+       style="isolation:isolate;fill:#171717;stroke-width:0.230354" />
+    <path
+       id="path1753"
+       style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-variant-east-asian:normal;font-feature-settings:normal;font-variation-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;shape-margin:0;inline-size:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#171717;fill-opacity:1;fill-rule:nonzero;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate;stop-color:#000000;stop-opacity:1;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none"
+       d="m 76.396755,128.05397 -1.229899,5.2e-4 -0.532267,5.379 -3.91294,0.39325 -0.0021,1.51309 5.678206,-0.001 z m 0.001,7.28483 5.677689,0.001 -0.0021,-1.51309 -3.912939,-0.39325 -0.532267,-5.379 -1.2299,-5.2e-4 z" />
+  </g>
+</svg>
diff --git a/data/ui/remmina_main.glade b/data/ui/remmina_main.glade
index 53f557c965..369462dd07 100644
--- a/data/ui/remmina_main.glade
+++ b/data/ui/remmina_main.glade
@@ -45,7 +45,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
     <property name="visible">True</property>
     <property name="can_focus">False</property>
     <property name="tooltip_text" translatable="yes">Show the Remmina changelog.</property>
-    <property name="stock">gtk-info</property>
+    <property name="icon_name">dialog-information</property>
   </object>
   <object class="GtkImage" id="view_toggle_icon">
     <property name="visible">True</property>
diff --git a/data/ui/remmina_preferences.glade b/data/ui/remmina_preferences.glade
index d9927dd140..401ff77afc 100644
--- a/data/ui/remmina_preferences.glade
+++ b/data/ui/remmina_preferences.glade
@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<!-- Generated with glade 3.36.0
+<!-- Generated with glade 3.36.0 
 
-Remmina Preferences Dialog -
-Copyright © 2014-2021 Antenore Gatta, Giovanni Panozzo
+Remmina Preferences Dialog - 
+Copyright (C) Antenore Gatta, Giovanni Panozzo 2014-2020
 
 This program is free software; you can redistribute it and/or
 modify it under the terms of the GNU General Public License
@@ -27,19 +27,10 @@ Author: Antenore Gatta
   <!-- interface-name Remmina Preferences Dialog -->
   <!-- interface-copyright Antenore Gatta, Giovanni Panozzo 2014-2020 -->
   <!-- interface-authors Antenore Gatta -->
-  <object class="GtkActionGroup" id="actiongroup_preferences">
-    <child>
-      <object class="GtkAction" id="action_preferences_close">
-        <property name="label" translatable="yes">Close</property>
-        <property name="short_label" translatable="yes">Close</property>
-        <signal name="activate" handler="remmina_pref_dialog_on_close_clicked" swapped="no"/>
-      </object>
-    </child>
-  </object>
   <object class="GtkDialog" id="RemminaPrefDialog">
     <property name="can_focus">False</property>
     <property name="title" translatable="yes">Remmina Preferences</property>
-    <property name="modal">True</property>
+    <property name="window_position">center-on-parent</property>
     <property name="type_hint">dialog</property>
     <signal name="close" handler="remmina_pref_dialog_on_close_clicked" swapped="no"/>
     <signal name="destroy" handler="remmina_pref_on_dialog_destroy" swapped="no"/>
@@ -55,11 +46,10 @@ Author: Antenore Gatta
             <child>
               <object class="GtkButton" id="button_close">
                 <property name="label" translatable="yes">Close</property>
-                <property name="use_action_appearance">True</property>
-                <property name="related_action">action_preferences_close</property>
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
                 <property name="receives_default">True</property>
+                <property name="action_name">pref.close</property>
                 <property name="use_underline">True</property>
               </object>
               <packing>
@@ -80,6 +70,9 @@ Author: Antenore Gatta
           <object class="GtkNotebook" id="notebook_preferences">
             <property name="visible">True</property>
             <property name="can_focus">True</property>
+            <property name="tab_pos">left</property>
+            <property name="scrollable">True</property>
+            <property name="enable_popup">True</property>
             <child>
               <object class="GtkGrid" id="grid_options">
                 <property name="visible">True</property>
@@ -91,7 +84,7 @@ Author: Antenore Gatta
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
                     <property name="halign">start</property>
-                    <property name="margin_left">18</property>
+                    <property name="margin_start">18</property>
                     <property name="hexpand">False</property>
                     <property name="label" translatable="yes">Double-click action</property>
                     <property name="justify">right</property>
@@ -105,7 +98,7 @@ Author: Antenore Gatta
                   <object class="GtkComboBoxText" id="comboboxtext_options_double_click">
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
-                    <property name="margin_right">18</property>
+                    <property name="margin_end">18</property>
                     <items>
                       <item translatable="yes">Open connection</item>
                       <item translatable="yes">Edit settings</item>
@@ -122,7 +115,7 @@ Author: Antenore Gatta
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
                     <property name="halign">start</property>
-                    <property name="margin_left">18</property>
+                    <property name="margin_start">18</property>
                     <property name="hexpand">False</property>
                     <property name="label" translatable="yes">Scaling quality</property>
                     <property name="justify">right</property>
@@ -136,7 +129,7 @@ Author: Antenore Gatta
                   <object class="GtkComboBoxText" id="comboboxtext_options_scale_quality">
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
-                    <property name="margin_right">18</property>
+                    <property name="margin_end">18</property>
                     <items>
                       <item translatable="yes">Nearest</item>
                       <item translatable="yes">Tiles</item>
@@ -155,7 +148,7 @@ Author: Antenore Gatta
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
                     <property name="halign">start</property>
-                    <property name="margin_left">18</property>
+                    <property name="margin_start">18</property>
                     <property name="hexpand">False</property>
                     <property name="label" translatable="yes">Step size for auto-scroll</property>
                     <property name="justify">right</property>
@@ -169,7 +162,7 @@ Author: Antenore Gatta
                   <object class="GtkEntry" id="entry_options_scroll">
                     <property name="visible">True</property>
                     <property name="can_focus">True</property>
-                    <property name="margin_right">18</property>
+                    <property name="margin_end">18</property>
                     <property name="max_length">3</property>
                   </object>
                   <packing>
@@ -183,7 +176,7 @@ Author: Antenore Gatta
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
                     <property name="halign">start</property>
-                    <property name="margin_left">18</property>
+                    <property name="margin_start">18</property>
                     <property name="hexpand">False</property>
                     <property name="label" translatable="yes">Maximal amount of recent items</property>
                     <property name="justify">right</property>
@@ -213,7 +206,7 @@ Author: Antenore Gatta
                     <property name="can_focus">True</property>
                     <property name="receives_default">True</property>
                     <property name="halign">start</property>
-                    <property name="margin_right">18</property>
+                    <property name="margin_end">18</property>
                     <signal name="clicked" handler="remmina_pref_dialog_clear_recent" swapped="no"/>
                   </object>
                   <packing>
@@ -226,7 +219,7 @@ Author: Antenore Gatta
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
                     <property name="halign">start</property>
-                    <property name="margin_left">18</property>
+                    <property name="margin_start">18</property>
                     <property name="hexpand">False</property>
                     <property name="label" translatable="yes">Screen resolutions</property>
                     <property name="justify">right</property>
@@ -241,7 +234,7 @@ Author: Antenore Gatta
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
                     <property name="halign">start</property>
-                    <property name="margin_left">18</property>
+                    <property name="margin_start">18</property>
                     <property name="hexpand">False</property>
                     <property name="label" translatable="yes">Keystrokes</property>
                     <property name="justify">right</property>
@@ -257,8 +250,8 @@ Author: Antenore Gatta
                     <property name="visible">True</property>
                     <property name="can_focus">True</property>
                     <property name="receives_default">True</property>
-                    <property name="halign">start</property>
-                    <property name="margin_right">18</property>
+                    <property name="halign">end</property>
+                    <property name="margin_end">18</property>
                     <signal name="clicked" handler="remmina_pref_on_button_keystrokes_clicked" swapped="no"/>
                   </object>
                   <packing>
@@ -272,7 +265,7 @@ Author: Antenore Gatta
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
                     <property name="halign">start</property>
-                    <property name="margin_left">18</property>
+                    <property name="margin_start">18</property>
                     <property name="hexpand">False</property>
                     <property name="label" translatable="yes">Folder for screenshots</property>
                     <property name="justify">right</property>
@@ -287,7 +280,7 @@ Author: Antenore Gatta
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
                     <property name="tooltip_text" translatable="yes">Choose a folder to save screenshots from Remmina in.</property>
-                    <property name="margin_right">18</property>
+                    <property name="margin_end">18</property>
                     <property name="action">select-folder</property>
                     <property name="title" translatable="yes">Select a folder</property>
                   </object>
@@ -303,8 +296,8 @@ Author: Antenore Gatta
                     <property name="visible">True</property>
                     <property name="can_focus">True</property>
                     <property name="receives_default">True</property>
-                    <property name="halign">start</property>
-                    <property name="margin_right">18</property>
+                    <property name="halign">end</property>
+                    <property name="margin_end">18</property>
                     <signal name="clicked" handler="remmina_pref_on_button_resolutions_clicked" swapped="no"/>
                   </object>
                   <packing>
@@ -318,7 +311,7 @@ Author: Antenore Gatta
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
                     <property name="halign">start</property>
-                    <property name="margin_left">18</property>
+                    <property name="margin_start">18</property>
                     <property name="hexpand">False</property>
                     <property name="label" translatable="yes">Screenshot filenames</property>
                     <property name="justify">right</property>
@@ -336,7 +329,7 @@ Author: Antenore Gatta
 %h Server name/IP
 %Y Year, %m Month, %d Day, %H Hour, %M Minute, %S Seconds (UTC time)
 </property>
-                    <property name="margin_right">18</property>
+                    <property name="margin_end">18</property>
                     <property name="width_chars">35</property>
                     <property name="placeholder_text">remmina_%p_%h_%Y%m%d-%H%M%S</property>
                   </object>
@@ -352,7 +345,7 @@ Author: Antenore Gatta
                     <property name="can_focus">False</property>
                     <property name="tooltip_text" translatable="yes">The folder connection profiles are saved in, it defaults to the XDG_USER_DATA</property>
                     <property name="halign">start</property>
-                    <property name="margin_left">18</property>
+                    <property name="margin_start">18</property>
                     <property name="margin_top">18</property>
                     <property name="hexpand">False</property>
                     <property name="label" translatable="yes" comments="The folder where profiles are saved">Remmina data folder</property>
@@ -367,7 +360,7 @@ Author: Antenore Gatta
                   <object class="GtkFileChooserButton" id="filechooserbutton_options_datadir_path">
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
-                    <property name="margin_right">18</property>
+                    <property name="margin_end">18</property>
                     <property name="margin_top">18</property>
                     <property name="action">select-folder</property>
                     <property name="title" translatable="yes"/>
@@ -384,7 +377,7 @@ Author: Antenore Gatta
                     <property name="can_focus">False</property>
                     <property name="tooltip_text" translatable="yes">Remember last view for each connection</property>
                     <property name="halign">start</property>
-                    <property name="margin_left">18</property>
+                    <property name="margin_start">18</property>
                     <property name="hexpand">False</property>
                     <property name="label" translatable="yes" comments="The star (*) is a reference to privacy consent">Remember last view mode</property>
                     <property name="justify">right</property>
@@ -398,9 +391,9 @@ Author: Antenore Gatta
                   <object class="GtkSwitch" id="switch_options_remember_last_view_mode">
                     <property name="visible">True</property>
                     <property name="can_focus">True</property>
-                    <property name="halign">start</property>
+                    <property name="halign">end</property>
                     <property name="valign">center</property>
-                    <property name="margin_right">18</property>
+                    <property name="margin_end">18</property>
                   </object>
                   <packing>
                     <property name="left_attach">1</property>
@@ -412,9 +405,9 @@ Author: Antenore Gatta
                   <object class="GtkSwitch" id="switch_permit_send_stats">
                     <property name="visible">True</property>
                     <property name="can_focus">True</property>
-                    <property name="halign">start</property>
+                    <property name="halign">end</property>
                     <property name="valign">center</property>
-                    <property name="margin_right">18</property>
+                    <property name="margin_end">18</property>
                   </object>
                   <packing>
                     <property name="left_attach">1</property>
@@ -428,7 +421,7 @@ Author: Antenore Gatta
                     <property name="can_focus">False</property>
                     <property name="tooltip_text" translatable="yes">Set a custom filename for your Remmina connection profiles, using a formatting string.</property>
                     <property name="halign">start</property>
-                    <property name="margin_left">18</property>
+                    <property name="margin_start">18</property>
                     <property name="hexpand">False</property>
                     <property name="label" translatable="yes">Template for profile filenames</property>
                     <property name="justify">right</property>
@@ -449,7 +442,7 @@ Author: Antenore Gatta
 
 
 </property>
-                    <property name="margin_right">18</property>
+                    <property name="margin_end">18</property>
                     <property name="width_chars">25</property>
                     <property name="placeholder_text">%G_%P_%N_%h</property>
                   </object>
@@ -465,7 +458,7 @@ Author: Antenore Gatta
                     <property name="can_focus">False</property>
                     <property name="tooltip_text" translatable="yes">Only save generated screenshots, don't copy them to clipboard.</property>
                     <property name="halign">start</property>
-                    <property name="margin_left">18</property>
+                    <property name="margin_start">18</property>
                     <property name="margin_bottom">18</property>
                     <property name="hexpand">False</property>
                     <property name="label" translatable="yes">Prevent screenshots from entering clipboard</property>
@@ -480,9 +473,9 @@ Author: Antenore Gatta
                   <object class="GtkSwitch" id="switch_options_deny_screenshot_clipboard">
                     <property name="visible">True</property>
                     <property name="can_focus">True</property>
-                    <property name="halign">start</property>
+                    <property name="halign">end</property>
                     <property name="valign">center</property>
-                    <property name="margin_right">18</property>
+                    <property name="margin_end">18</property>
                     <property name="margin_bottom">18</property>
                   </object>
                   <packing>
@@ -495,9 +488,9 @@ Author: Antenore Gatta
                   <object class="GtkSwitch" id="switch_permit_news">
                     <property name="visible">True</property>
                     <property name="can_focus">True</property>
-                    <property name="halign">start</property>
+                    <property name="halign">end</property>
                     <property name="valign">center</property>
-                    <property name="margin_right">18</property>
+                    <property name="margin_end">18</property>
                   </object>
                   <packing>
                     <property name="left_attach">1</property>
@@ -509,6 +502,9 @@ Author: Antenore Gatta
                   <object class="GtkLabel" id="privacy_disclaimer_label">
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
+                    <property name="halign">start</property>
+                    <property name="margin_start">18</property>
+                    <property name="margin_end">18</property>
                     <property name="label" translatable="yes">* By enabling statistics and/or news you consent to send and fetch data to/from remmina.org</property>
                     <property name="justify">fill</property>
                     <property name="wrap">True</property>
@@ -525,7 +521,7 @@ Author: Antenore Gatta
                     <property name="visible">True</property>
                     <property name="can_focus">True</property>
                     <property name="halign">start</property>
-                    <property name="margin_left">18</property>
+                    <property name="margin_start">18</property>
                     <property name="hexpand">False</property>
                     <property name="label" translatable="yes" comments="The star (*) is a reference to privacy consent">Send &lt;b&gt;&lt;a href="https://remmina.gitlab.io/remminadoc.gitlab.io/remmina__stats_8c.html#details" title="Remmina usage statistics"&gt;anonymous&lt;/a&gt;&lt;/b&gt; statistics. (*)</property>
                     <property name="use_markup">True</property>
@@ -540,7 +536,7 @@ Author: Antenore Gatta
                     <property name="visible">True</property>
                     <property name="can_focus">True</property>
                     <property name="halign">start</property>
-                    <property name="margin_left">18</property>
+                    <property name="margin_start">18</property>
                     <property name="hexpand">False</property>
                     <property name="label" translatable="yes" comments="The star (*) is a reference to privacy consent">Fetch news from &lt;a href="https://remmina.org" title="Remmina news site"&gt;remmina.org&lt;/a&gt; (*)</property>
                     <property name="use_markup">True</property>
@@ -556,6 +552,8 @@ Author: Antenore Gatta
               <object class="GtkLabel" id="label_tab_options">
                 <property name="visible">True</property>
                 <property name="can_focus">False</property>
+                <property name="halign">end</property>
+                <property name="margin_end">18</property>
                 <property name="label" translatable="yes">Options</property>
               </object>
               <packing>
@@ -576,7 +574,7 @@ Author: Antenore Gatta
                     <property name="can_focus">True</property>
                     <property name="receives_default">False</property>
                     <property name="halign">start</property>
-                    <property name="margin_left">18</property>
+                    <property name="margin_start">18</property>
                     <property name="hexpand">True</property>
                     <property name="draw_indicator">True</property>
                   </object>
@@ -593,7 +591,7 @@ Author: Antenore Gatta
                     <property name="can_focus">True</property>
                     <property name="receives_default">False</property>
                     <property name="halign">start</property>
-                    <property name="margin_left">18</property>
+                    <property name="margin_start">18</property>
                     <property name="hexpand">True</property>
                     <property name="draw_indicator">True</property>
                   </object>
@@ -608,7 +606,7 @@ Author: Antenore Gatta
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
                     <property name="halign">start</property>
-                    <property name="margin_left">18</property>
+                    <property name="margin_start">18</property>
                     <property name="label" translatable="yes">Default view</property>
                   </object>
                   <packing>
@@ -620,7 +618,7 @@ Author: Antenore Gatta
                   <object class="GtkComboBoxText" id="comboboxtext_appearance_view_mode">
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
-                    <property name="margin_right">18</property>
+                    <property name="margin_end">18</property>
                     <property name="hexpand">True</property>
                     <items>
                       <item translatable="yes">Automatic</item>
@@ -640,7 +638,7 @@ Author: Antenore Gatta
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
                     <property name="halign">start</property>
-                    <property name="margin_left">18</property>
+                    <property name="margin_start">18</property>
                     <property name="margin_bottom">18</property>
                     <property name="label" translatable="yes">Tabs</property>
                   </object>
@@ -653,7 +651,7 @@ Author: Antenore Gatta
                   <object class="GtkComboBoxText" id="comboboxtext_appearance_tab_interface">
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
-                    <property name="margin_right">18</property>
+                    <property name="margin_end">18</property>
                     <property name="margin_bottom">18</property>
                     <property name="hexpand">True</property>
                     <items>
@@ -676,7 +674,7 @@ Author: Antenore Gatta
                     <property name="can_focus">True</property>
                     <property name="receives_default">False</property>
                     <property name="halign">start</property>
-                    <property name="margin_left">18</property>
+                    <property name="margin_start">18</property>
                     <property name="margin_top">18</property>
                     <property name="hexpand">True</property>
                     <property name="active">True</property>
@@ -692,7 +690,7 @@ Author: Antenore Gatta
                   <object class="GtkComboBoxText" id="comboboxtext_appearance_fullscreen_toolbar_visibility">
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
-                    <property name="margin_right">18</property>
+                    <property name="margin_end">18</property>
                     <property name="active_id">0</property>
                     <items>
                       <item id="0" translatable="yes">Peeking</item>
@@ -711,7 +709,7 @@ Author: Antenore Gatta
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
                     <property name="halign">start</property>
-                    <property name="margin_left">18</property>
+                    <property name="margin_start">18</property>
                     <property name="label" translatable="yes">Fullscreen toolbar visibility</property>
                     <property name="selectable">True</property>
                   </object>
@@ -727,7 +725,7 @@ Author: Antenore Gatta
                     <property name="can_focus">True</property>
                     <property name="receives_default">False</property>
                     <property name="halign">start</property>
-                    <property name="margin_left">18</property>
+                    <property name="margin_start">18</property>
                     <property name="hexpand">True</property>
                     <property name="draw_indicator">True</property>
                   </object>
@@ -746,6 +744,8 @@ Author: Antenore Gatta
               <object class="GtkLabel" id="label_tab_appearance">
                 <property name="visible">True</property>
                 <property name="can_focus">False</property>
+                <property name="halign">end</property>
+                <property name="margin_end">18</property>
                 <property name="label" translatable="yes">Appearance</property>
               </object>
               <packing>
@@ -767,7 +767,7 @@ Author: Antenore Gatta
                     <property name="can_focus">True</property>
                     <property name="receives_default">False</property>
                     <property name="halign">start</property>
-                    <property name="margin_left">18</property>
+                    <property name="margin_start">18</property>
                     <property name="margin_top">18</property>
                     <property name="hexpand">True</property>
                     <property name="draw_indicator">True</property>
@@ -785,7 +785,7 @@ Author: Antenore Gatta
                     <property name="can_focus">True</property>
                     <property name="receives_default">False</property>
                     <property name="halign">start</property>
-                    <property name="margin_left">18</property>
+                    <property name="margin_start">18</property>
                     <property name="hexpand">True</property>
                     <property name="draw_indicator">True</property>
                   </object>
@@ -802,7 +802,7 @@ Author: Antenore Gatta
                     <property name="can_focus">True</property>
                     <property name="receives_default">False</property>
                     <property name="halign">start</property>
-                    <property name="margin_left">18</property>
+                    <property name="margin_start">18</property>
                     <property name="hexpand">True</property>
                     <property name="draw_indicator">True</property>
                     <signal name="toggled" handler="remmina_pref_dialog_disable_tray_icon_on_toggled" swapped="no"/>
@@ -820,7 +820,7 @@ Author: Antenore Gatta
                     <property name="can_focus">True</property>
                     <property name="receives_default">False</property>
                     <property name="halign">start</property>
-                    <property name="margin_left">18</property>
+                    <property name="margin_start">18</property>
                     <property name="margin_bottom">18</property>
                     <property name="hexpand">True</property>
                     <property name="draw_indicator">True</property>
@@ -839,7 +839,7 @@ Author: Antenore Gatta
                     <property name="receives_default">False</property>
                     <property name="tooltip_text" translatable="yes">Improves contrast if you have a light panel.</property>
                     <property name="halign">start</property>
-                    <property name="margin_left">18</property>
+                    <property name="margin_start">18</property>
                     <property name="hexpand">True</property>
                     <property name="draw_indicator">True</property>
                   </object>
@@ -858,6 +858,8 @@ Author: Antenore Gatta
               <object class="GtkLabel" id="label_tab_applet">
                 <property name="visible">True</property>
                 <property name="can_focus">False</property>
+                <property name="halign">end</property>
+                <property name="margin_end">18</property>
                 <property name="label" translatable="yes">Applet</property>
               </object>
               <packing>
@@ -877,7 +879,7 @@ Author: Antenore Gatta
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
                     <property name="halign">start</property>
-                    <property name="margin_left">18</property>
+                    <property name="margin_start">18</property>
                     <property name="margin_top">18</property>
                     <property name="hexpand">True</property>
                     <property name="label" translatable="yes">Host key</property>
@@ -894,7 +896,7 @@ Author: Antenore Gatta
                     <property name="visible">True</property>
                     <property name="can_focus">True</property>
                     <property name="receives_default">True</property>
-                    <property name="margin_right">18</property>
+                    <property name="margin_end">18</property>
                     <property name="margin_top">18</property>
                     <signal name="clicked" handler="remmina_pref_dialog_on_key_chooser" swapped="no"/>
                   </object>
@@ -909,7 +911,7 @@ Author: Antenore Gatta
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
                     <property name="halign">start</property>
-                    <property name="margin_left">18</property>
+                    <property name="margin_start">18</property>
                     <property name="hexpand">True</property>
                     <property name="label" translatable="yes">Show/hide fullscreen</property>
                   </object>
@@ -925,7 +927,7 @@ Author: Antenore Gatta
                     <property name="visible">True</property>
                     <property name="can_focus">True</property>
                     <property name="receives_default">True</property>
-                    <property name="margin_right">18</property>
+                    <property name="margin_end">18</property>
                     <signal name="clicked" handler="remmina_pref_dialog_on_key_chooser" swapped="no"/>
                   </object>
                   <packing>
@@ -939,7 +941,7 @@ Author: Antenore Gatta
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
                     <property name="halign">start</property>
-                    <property name="margin_left">18</property>
+                    <property name="margin_start">18</property>
                     <property name="hexpand">True</property>
                     <property name="label" translatable="yes">Auto-fit window</property>
                   </object>
@@ -955,7 +957,7 @@ Author: Antenore Gatta
                     <property name="visible">True</property>
                     <property name="can_focus">True</property>
                     <property name="receives_default">True</property>
-                    <property name="margin_right">18</property>
+                    <property name="margin_end">18</property>
                     <signal name="clicked" handler="remmina_pref_dialog_on_key_chooser" swapped="no"/>
                   </object>
                   <packing>
@@ -969,7 +971,7 @@ Author: Antenore Gatta
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
                     <property name="halign">start</property>
-                    <property name="margin_left">18</property>
+                    <property name="margin_start">18</property>
                     <property name="hexpand">True</property>
                     <property name="label" translatable="yes">Switch tab pages</property>
                   </object>
@@ -999,7 +1001,7 @@ Author: Antenore Gatta
                     <property name="visible">True</property>
                     <property name="can_focus">True</property>
                     <property name="receives_default">True</property>
-                    <property name="margin_right">18</property>
+                    <property name="margin_end">18</property>
                     <signal name="clicked" handler="remmina_pref_dialog_on_key_chooser" swapped="no"/>
                   </object>
                   <packing>
@@ -1012,7 +1014,7 @@ Author: Antenore Gatta
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
                     <property name="halign">start</property>
-                    <property name="margin_left">18</property>
+                    <property name="margin_start">18</property>
                     <property name="hexpand">True</property>
                     <property name="label" translatable="yes">Apply/remove scaling</property>
                   </object>
@@ -1028,7 +1030,7 @@ Author: Antenore Gatta
                     <property name="visible">True</property>
                     <property name="can_focus">True</property>
                     <property name="receives_default">True</property>
-                    <property name="margin_right">18</property>
+                    <property name="margin_end">18</property>
                     <signal name="clicked" handler="remmina_pref_dialog_on_key_chooser" swapped="no"/>
                   </object>
                   <packing>
@@ -1042,7 +1044,7 @@ Author: Antenore Gatta
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
                     <property name="halign">start</property>
-                    <property name="margin_left">18</property>
+                    <property name="margin_start">18</property>
                     <property name="hexpand">True</property>
                     <property name="label" translatable="yes">Grab keyboard</property>
                   </object>
@@ -1058,7 +1060,7 @@ Author: Antenore Gatta
                     <property name="visible">True</property>
                     <property name="can_focus">True</property>
                     <property name="receives_default">True</property>
-                    <property name="margin_right">18</property>
+                    <property name="margin_end">18</property>
                     <signal name="clicked" handler="remmina_pref_dialog_on_key_chooser" swapped="no"/>
                   </object>
                   <packing>
@@ -1072,7 +1074,7 @@ Author: Antenore Gatta
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
                     <property name="halign">start</property>
-                    <property name="margin_left">18</property>
+                    <property name="margin_start">18</property>
                     <property name="hexpand">True</property>
                     <property name="label" translatable="yes">Minimize window</property>
                   </object>
@@ -1088,8 +1090,7 @@ Author: Antenore Gatta
                     <property name="visible">True</property>
                     <property name="can_focus">True</property>
                     <property name="receives_default">True</property>
-                    <property name="valign">start</property>
-                    <property name="margin_right">18</property>
+                    <property name="margin_end">18</property>
                     <signal name="clicked" handler="remmina_pref_dialog_on_key_chooser" swapped="no"/>
                   </object>
                   <packing>
@@ -1103,7 +1104,7 @@ Author: Antenore Gatta
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
                     <property name="halign">start</property>
-                    <property name="margin_left">18</property>
+                    <property name="margin_start">18</property>
                     <property name="hexpand">True</property>
                     <property name="label" translatable="yes">Disconnect</property>
                   </object>
@@ -1119,7 +1120,7 @@ Author: Antenore Gatta
                     <property name="visible">True</property>
                     <property name="can_focus">True</property>
                     <property name="receives_default">True</property>
-                    <property name="margin_right">18</property>
+                    <property name="margin_end">18</property>
                     <signal name="clicked" handler="remmina_pref_dialog_on_key_chooser" swapped="no"/>
                   </object>
                   <packing>
@@ -1133,7 +1134,7 @@ Author: Antenore Gatta
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
                     <property name="halign">start</property>
-                    <property name="margin_left">18</property>
+                    <property name="margin_start">18</property>
                     <property name="hexpand">True</property>
                     <property name="label" translatable="yes">Show/hide toolbar</property>
                   </object>
@@ -1149,7 +1150,7 @@ Author: Antenore Gatta
                     <property name="visible">True</property>
                     <property name="can_focus">True</property>
                     <property name="receives_default">True</property>
-                    <property name="margin_right">18</property>
+                    <property name="margin_end">18</property>
                     <signal name="clicked" handler="remmina_pref_dialog_on_key_chooser" swapped="no"/>
                   </object>
                   <packing>
@@ -1163,7 +1164,7 @@ Author: Antenore Gatta
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
                     <property name="halign">start</property>
-                    <property name="margin_left">18</property>
+                    <property name="margin_start">18</property>
                     <property name="hexpand">True</property>
                     <property name="label" translatable="yes">Screenshot</property>
                     <property name="ellipsize">start</property>
@@ -1180,7 +1181,7 @@ Author: Antenore Gatta
                     <property name="visible">True</property>
                     <property name="can_focus">True</property>
                     <property name="receives_default">True</property>
-                    <property name="margin_right">18</property>
+                    <property name="margin_end">18</property>
                     <signal name="clicked" handler="remmina_pref_dialog_on_key_chooser" swapped="no"/>
                   </object>
                   <packing>
@@ -1194,8 +1195,7 @@ Author: Antenore Gatta
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
                     <property name="halign">start</property>
-                    <property name="margin_left">18</property>
-                    <property name="margin_bottom">18</property>
+                    <property name="margin_start">18</property>
                     <property name="hexpand">True</property>
                     <property name="label" translatable="yes">View-only mode</property>
                     <property name="ellipsize">start</property>
@@ -1212,8 +1212,7 @@ Author: Antenore Gatta
                     <property name="visible">True</property>
                     <property name="can_focus">True</property>
                     <property name="receives_default">True</property>
-                    <property name="margin_right">18</property>
-                    <property name="margin_bottom">18</property>
+                    <property name="margin_end">18</property>
                     <signal name="clicked" handler="remmina_pref_dialog_on_key_chooser" swapped="no"/>
                   </object>
                   <packing>
@@ -1222,6 +1221,39 @@ Author: Antenore Gatta
                     <property name="width">2</property>
                   </packing>
                 </child>
+                <child>
+                  <object class="GtkLabel" id="label_keyboard_multimon">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="halign">start</property>
+                    <property name="margin_start">18</property>
+                    <property name="margin_bottom">18</property>
+                    <property name="hexpand">True</property>
+                    <property name="label" translatable="yes">Multi monitor</property>
+                    <property name="ellipsize">start</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">0</property>
+                    <property name="top_attach">11</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkButton" id="button_keyboard_multimon">
+                    <property name="label" translatable="yes">Multi monitor</property>
+                    <property name="width_request">100</property>
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="receives_default">True</property>
+                    <property name="margin_end">18</property>
+                    <property name="margin_bottom">18</property>
+                    <signal name="clicked" handler="remmina_pref_dialog_on_key_chooser" swapped="no"/>
+                  </object>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="top_attach">11</property>
+                    <property name="width">2</property>
+                  </packing>
+                </child>
               </object>
               <packing>
                 <property name="position">3</property>
@@ -1231,6 +1263,8 @@ Author: Antenore Gatta
               <object class="GtkLabel" id="label_tab_keyboard">
                 <property name="visible">True</property>
                 <property name="can_focus">False</property>
+                <property name="halign">end</property>
+                <property name="margin_end">18</property>
                 <property name="label" translatable="yes">Keyboard</property>
               </object>
               <packing>
@@ -1250,7 +1284,7 @@ Author: Antenore Gatta
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
                     <property name="halign">start</property>
-                    <property name="margin_left">18</property>
+                    <property name="margin_start">18</property>
                     <property name="label" translatable="yes">Local SSH port</property>
                   </object>
                   <packing>
@@ -1262,7 +1296,7 @@ Author: Antenore Gatta
                   <object class="GtkEntry" id="entry_options_ssh_port">
                     <property name="visible">True</property>
                     <property name="can_focus">True</property>
-                    <property name="margin_right">18</property>
+                    <property name="margin_end">18</property>
                     <property name="hexpand">True</property>
                     <property name="max_length">5</property>
                     <property name="input_purpose">number</property>
@@ -1280,7 +1314,7 @@ Author: Antenore Gatta
                     <property name="can_focus">True</property>
                     <property name="receives_default">False</property>
                     <property name="halign">start</property>
-                    <property name="margin_left">18</property>
+                    <property name="margin_start">18</property>
                     <property name="margin_bottom">18</property>
                     <property name="hexpand">True</property>
                     <property name="draw_indicator">True</property>
@@ -1295,7 +1329,7 @@ Author: Antenore Gatta
                   <object class="GtkComboBoxText" id="comboboxtext_options_ssh_loglevel">
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
-                    <property name="margin_right">18</property>
+                    <property name="margin_end">18</property>
                     <property name="margin_top">18</property>
                     <property name="hexpand">True</property>
                     <items>
@@ -1317,7 +1351,7 @@ Author: Antenore Gatta
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
                     <property name="halign">start</property>
-                    <property name="margin_left">18</property>
+                    <property name="margin_start">18</property>
                     <property name="margin_top">18</property>
                     <property name="label" translatable="yes">SSH log level</property>
                   </object>
@@ -1331,7 +1365,7 @@ Author: Antenore Gatta
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
                     <property name="halign">start</property>
-                    <property name="margin_left">18</property>
+                    <property name="margin_start">18</property>
                     <property name="label">TCP_keepidle</property>
                     <property name="selectable">True</property>
                   </object>
@@ -1345,7 +1379,7 @@ Author: Antenore Gatta
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
                     <property name="halign">start</property>
-                    <property name="margin_left">18</property>
+                    <property name="margin_start">18</property>
                     <property name="label">TCP_keepintvl</property>
                     <property name="selectable">True</property>
                   </object>
@@ -1359,7 +1393,7 @@ Author: Antenore Gatta
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
                     <property name="halign">start</property>
-                    <property name="margin_left">18</property>
+                    <property name="margin_start">18</property>
                     <property name="label">TCP_keepcnt</property>
                     <property name="selectable">True</property>
                   </object>
@@ -1373,7 +1407,7 @@ Author: Antenore Gatta
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
                     <property name="halign">start</property>
-                    <property name="margin_left">18</property>
+                    <property name="margin_start">18</property>
                     <property name="label">TCP_user_timeout</property>
                     <property name="selectable">True</property>
                   </object>
@@ -1387,7 +1421,7 @@ Author: Antenore Gatta
                     <property name="visible">True</property>
                     <property name="can_focus">True</property>
                     <property name="tooltip_text" translatable="yes" comments="http://man7.org/linux/man-pages/man7/tcp.7.html">Seconds of connection idleness before TCP keepalive probes are sent.</property>
-                    <property name="margin_right">18</property>
+                    <property name="margin_end">18</property>
                     <property name="hexpand">True</property>
                     <property name="max_length">5</property>
                     <property name="input_purpose">number</property>
@@ -1403,7 +1437,7 @@ Author: Antenore Gatta
                     <property name="visible">True</property>
                     <property name="can_focus">True</property>
                     <property name="tooltip_text" translatable="yes" comments="http://man7.org/linux/man-pages/man7/tcp.7.html">Seconds between each keepalive probe.</property>
-                    <property name="margin_right">18</property>
+                    <property name="margin_end">18</property>
                     <property name="hexpand">True</property>
                     <property name="max_length">5</property>
                     <property name="input_purpose">number</property>
@@ -1419,7 +1453,7 @@ Author: Antenore Gatta
                     <property name="visible">True</property>
                     <property name="can_focus">True</property>
                     <property name="tooltip_text" translatable="yes" comments="http://man7.org/linux/man-pages/man7/tcp.7.html">Number of keepalive probes sent via TCP connection before it is dropped.</property>
-                    <property name="margin_right">18</property>
+                    <property name="margin_end">18</property>
                     <property name="hexpand">True</property>
                     <property name="max_length">5</property>
                     <property name="input_purpose">number</property>
@@ -1435,7 +1469,7 @@ Author: Antenore Gatta
                     <property name="visible">True</property>
                     <property name="can_focus">True</property>
                     <property name="tooltip_text" translatable="yes" comments="http://man7.org/linux/man-pages/man7/tcp.7.html">Amount of milliseconds to attempt acknowledging data before closing the corresponding TCP connection forcibly.</property>
-                    <property name="margin_right">18</property>
+                    <property name="margin_end">18</property>
                     <property name="hexpand">True</property>
                     <property name="max_length">5</property>
                     <property name="input_purpose">number</property>
@@ -1455,6 +1489,8 @@ Author: Antenore Gatta
               <object class="GtkLabel" id="label_tab_ssh">
                 <property name="visible">True</property>
                 <property name="can_focus">False</property>
+                <property name="halign">end</property>
+                <property name="margin_end">18</property>
                 <property name="label" translatable="yes">SSH options</property>
               </object>
               <packing>
@@ -1486,7 +1522,7 @@ Author: Antenore Gatta
                   <packing>
                     <property name="left_attach">0</property>
                     <property name="top_attach">0</property>
-                    <property name="width">3</property>
+                    <property name="width">2</property>
                   </packing>
                 </child>
                 <child>
@@ -1503,7 +1539,6 @@ Author: Antenore Gatta
                   <packing>
                     <property name="left_attach">1</property>
                     <property name="top_attach">1</property>
-                    <property name="width">2</property>
                   </packing>
                 </child>
                 <child>
@@ -1512,7 +1547,6 @@ Author: Antenore Gatta
                     <property name="can_focus">False</property>
                     <property name="tooltip_text" translatable="yes">Use secret key authentication for some widgets</property>
                     <property name="halign">start</property>
-                    <property name="margin_left">36</property>
                     <property name="margin_start">36</property>
                     <property name="margin_top">9</property>
                     <property name="margin_bottom">9</property>
@@ -1542,7 +1576,6 @@ Author: Antenore Gatta
                     <property name="visible">True</property>
                     <property name="can_focus">True</property>
                     <property name="tooltip_text" translatable="yes">Master password validity in seconds</property>
-                    <property name="halign">start</property>
                     <property name="margin_end">18</property>
                     <property name="hexpand">True</property>
                     <property name="width_chars">24</property>
@@ -1552,7 +1585,6 @@ Author: Antenore Gatta
                   <packing>
                     <property name="left_attach">1</property>
                     <property name="top_attach">2</property>
-                    <property name="width">2</property>
                   </packing>
                 </child>
                 <child>
@@ -1571,7 +1603,7 @@ Author: Antenore Gatta
                   <packing>
                     <property name="left_attach">0</property>
                     <property name="top_attach">7</property>
-                    <property name="width">3</property>
+                    <property name="width">2</property>
                   </packing>
                 </child>
                 <child>
@@ -1579,7 +1611,6 @@ Author: Antenore Gatta
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
                     <property name="halign">start</property>
-                    <property name="margin_left">36</property>
                     <property name="margin_start">36</property>
                     <property name="label" translatable="yes">Password</property>
                   </object>
@@ -1593,7 +1624,6 @@ Author: Antenore Gatta
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
                     <property name="halign">start</property>
-                    <property name="margin_left">36</property>
                     <property name="margin_start">36</property>
                     <property name="label" translatable="yes">Repeat the password</property>
                   </object>
@@ -1606,7 +1636,6 @@ Author: Antenore Gatta
                   <object class="GtkEntry" id="unlock_password">
                     <property name="visible">True</property>
                     <property name="can_focus">True</property>
-                    <property name="halign">start</property>
                     <property name="margin_end">18</property>
                     <property name="hexpand">True</property>
                     <property name="visibility">False</property>
@@ -1617,14 +1646,12 @@ Author: Antenore Gatta
                   <packing>
                     <property name="left_attach">1</property>
                     <property name="top_attach">3</property>
-                    <property name="width">2</property>
                   </packing>
                 </child>
                 <child>
                   <object class="GtkEntry" id="unlock_repassword">
                     <property name="visible">True</property>
                     <property name="can_focus">True</property>
-                    <property name="halign">start</property>
                     <property name="margin_end">18</property>
                     <property name="hexpand">True</property>
                     <property name="visibility">False</property>
@@ -1639,7 +1666,6 @@ Author: Antenore Gatta
                   <packing>
                     <property name="left_attach">1</property>
                     <property name="top_attach">4</property>
-                    <property name="width">2</property>
                   </packing>
                 </child>
                 <child>
@@ -1658,7 +1684,7 @@ Author: Antenore Gatta
                   <packing>
                     <property name="left_attach">0</property>
                     <property name="top_attach">5</property>
-                    <property name="width">3</property>
+                    <property name="width">2</property>
                   </packing>
                 </child>
                 <child>
@@ -1692,7 +1718,6 @@ Author: Antenore Gatta
                   <packing>
                     <property name="left_attach">1</property>
                     <property name="top_attach">6</property>
-                    <property name="width">2</property>
                   </packing>
                 </child>
               </object>
@@ -1704,6 +1729,8 @@ Author: Antenore Gatta
               <object class="GtkLabel">
                 <property name="visible">True</property>
                 <property name="can_focus">False</property>
+                <property name="halign">end</property>
+                <property name="margin_end">18</property>
                 <property name="label" translatable="yes">Security</property>
               </object>
               <packing>
@@ -1724,7 +1751,7 @@ Author: Antenore Gatta
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
                     <property name="halign">start</property>
-                    <property name="margin_left">18</property>
+                    <property name="margin_start">18</property>
                     <property name="margin_top">18</property>
                     <property name="label" translatable="yes">Terminal font</property>
                   </object>
@@ -1738,7 +1765,7 @@ Author: Antenore Gatta
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
                     <property name="halign">start</property>
-                    <property name="margin_left">18</property>
+                    <property name="margin_start">18</property>
                     <property name="label" translatable="yes">Scrollback lines</property>
                   </object>
                   <packing>
@@ -1805,7 +1832,7 @@ Author: Antenore Gatta
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
                     <property name="halign">start</property>
-                    <property name="margin_left">18</property>
+                    <property name="margin_start">18</property>
                     <property name="label" translatable="yes">Shortcut for copying to clipboard</property>
                   </object>
                   <packing>
@@ -1818,7 +1845,7 @@ Author: Antenore Gatta
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
                     <property name="halign">start</property>
-                    <property name="margin_left">18</property>
+                    <property name="margin_start">18</property>
                     <property name="label" translatable="yes">Shortcut for pasting from clipboard</property>
                   </object>
                   <packing>
@@ -1831,7 +1858,7 @@ Author: Antenore Gatta
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
                     <property name="halign">start</property>
-                    <property name="margin_left">18</property>
+                    <property name="margin_start">18</property>
                     <property name="label" translatable="yes">Select all shortcuts</property>
                   </object>
                   <packing>
@@ -1898,7 +1925,7 @@ Author: Antenore Gatta
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
                     <property name="halign">start</property>
-                    <property name="margin_left">18</property>
+                    <property name="margin_start">18</property>
                     <property name="label" translatable="yes">Use default system font</property>
                   </object>
                   <packing>
@@ -1937,7 +1964,7 @@ Author: Antenore Gatta
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
                     <property name="halign">start</property>
-                    <property name="margin_left">18</property>
+                    <property name="margin_start">18</property>
                     <property name="label" translatable="yes">Allow using bright colours with bold text</property>
                   </object>
                   <packing>
@@ -1950,7 +1977,7 @@ Author: Antenore Gatta
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
                     <property name="halign">start</property>
-                    <property name="margin_left">18</property>
+                    <property name="margin_start">18</property>
                     <property name="margin_bottom">18</property>
                     <property name="label" translatable="yes">Colour theme</property>
                   </object>
@@ -1980,7 +2007,7 @@ Author: Antenore Gatta
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
                     <property name="halign">start</property>
-                    <property name="margin_left">18</property>
+                    <property name="margin_start">18</property>
                     <property name="label" translatable="yes">Bright colours</property>
                   </object>
                   <packing>
@@ -2187,7 +2214,7 @@ Author: Antenore Gatta
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
                     <property name="halign">start</property>
-                    <property name="margin_left">18</property>
+                    <property name="margin_start">18</property>
                     <property name="label" translatable="yes">Normal colours</property>
                   </object>
                   <packing>
@@ -2200,7 +2227,7 @@ Author: Antenore Gatta
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
                     <property name="halign">start</property>
-                    <property name="margin_left">18</property>
+                    <property name="margin_start">18</property>
                     <property name="label" translatable="yes">Cursor colour</property>
                   </object>
                   <packing>
@@ -2228,7 +2255,7 @@ Author: Antenore Gatta
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
                     <property name="halign">start</property>
-                    <property name="margin_left">18</property>
+                    <property name="margin_start">18</property>
                     <property name="label" translatable="yes">Background colour</property>
                   </object>
                   <packing>
@@ -2271,7 +2298,7 @@ Author: Antenore Gatta
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
                     <property name="halign">start</property>
-                    <property name="margin_left">18</property>
+                    <property name="margin_start">18</property>
                     <property name="label" translatable="yes">Foreground colour</property>
                   </object>
                   <packing>
@@ -2284,7 +2311,7 @@ Author: Antenore Gatta
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
                     <property name="halign">start</property>
-                    <property name="margin_left">18</property>
+                    <property name="margin_start">18</property>
                     <property name="label" translatable="yes">Increase font size</property>
                   </object>
                   <packing>
@@ -2297,7 +2324,7 @@ Author: Antenore Gatta
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
                     <property name="halign">start</property>
-                    <property name="margin_left">18</property>
+                    <property name="margin_start">18</property>
                     <property name="label" translatable="yes">Decrease font size</property>
                   </object>
                   <packing>
@@ -2346,7 +2373,7 @@ Author: Antenore Gatta
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
                     <property name="halign">start</property>
-                    <property name="margin_left">18</property>
+                    <property name="margin_start">18</property>
                     <property name="label" translatable="yes">Search text</property>
                   </object>
                   <packing>
@@ -2376,6 +2403,7 @@ Author: Antenore Gatta
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
                     <property name="halign">start</property>
+                    <property name="margin_start">18</property>
                     <property name="label" translatable="yes">Bold colour</property>
                   </object>
                   <packing>
@@ -2407,6 +2435,8 @@ Author: Antenore Gatta
               <object class="GtkLabel" id="label_tab_terminal">
                 <property name="visible">True</property>
                 <property name="can_focus">False</property>
+                <property name="halign">end</property>
+                <property name="margin_end">18</property>
                 <property name="label" translatable="yes">Terminal</property>
               </object>
               <packing>
diff --git a/plugins/rdp/rdp_monitor.c b/plugins/rdp/rdp_monitor.c
index a590f791d0..01c024025d 100644
--- a/plugins/rdp/rdp_monitor.c
+++ b/plugins/rdp/rdp_monitor.c
@@ -70,7 +70,7 @@ void remmina_rdp_monitor_get (rfContext *rfi, gchar **monitorids, guint32 *maxwi
 	TRACE_CALL(__func__);
 
 	GdkDisplay *display;
-	GdkMonitor *current_monitor, *monitor;
+	GdkMonitor *monitor;
 	gboolean has_custom_monitors = FALSE;
 
 	gboolean primary_found = FALSE;
@@ -210,10 +210,10 @@ void remmina_rdp_monitor_get (rfContext *rfi, gchar **monitorids, guint32 *maxwi
 	{
 		settings->MonitorDefArray[i].x =
 			settings->MonitorDefArray[i].x - settings->MonitorLocalShiftX;
-		REMMINA_PLUGIN_DEBUG("Monitor n %d calculated x: %d", index, settings->MonitorDefArray[index].x);
+		REMMINA_PLUGIN_DEBUG("Monitor n %d calculated x: %d", i, settings->MonitorDefArray[i].x);
 		settings->MonitorDefArray[i].y =
 			settings->MonitorDefArray[i].y - settings->MonitorLocalShiftY;
-		REMMINA_PLUGIN_DEBUG("Monitor n %d calculated y: %d", index, settings->MonitorDefArray[index].y);
+		REMMINA_PLUGIN_DEBUG("Monitor n %d calculated y: %d", i, settings->MonitorDefArray[i].y);
 	}
 
 	REMMINA_PLUGIN_DEBUG("%d monitors on %d have been configured", rfi->settings->MonitorCount, count);
diff --git a/plugins/rdp/rdp_plugin.c b/plugins/rdp/rdp_plugin.c
index cb114a6582..15bfcbb51b 100644
--- a/plugins/rdp/rdp_plugin.c
+++ b/plugins/rdp/rdp_plugin.c
@@ -84,6 +84,7 @@
 #define REMMINA_RDP_FEATURE_UNFOCUS              3
 #define REMMINA_RDP_FEATURE_TOOL_SENDCTRLALTDEL  4
 #define REMMINA_RDP_FEATURE_DYNRESUPDATE         5
+#define REMMINA_RDP_FEATURE_MULTIMON             6
 
 #define REMMINA_CONNECTION_TYPE_NONE             0
 
@@ -1775,13 +1776,9 @@ static gboolean remmina_rdp_main(RemminaProtocolWidget *gp)
 		/* TODO Add an option for this */
 		rfi->settings->ForceMultimon = TRUE;
 		rfi->settings->Fullscreen = TRUE;
-		//if (!rfi->settings->NumMonitorIds)
-			//rfi->settings->NumMonitorIds = 0;
 
 		gchar *monitorids = g_strdup(remmina_plugin_service->file_get_string(remminafile, "monitorids"));
 		/* Otherwise we get all the attached monitors */
-		//if (monitorids != NULL && monitorids[0] != '\0')
-		//gchar *monitorids = NULL;
 		remmina_rdp_monitor_get(rfi, &monitorids, &maxwidth, &maxheight);
 		if (monitorids != NULL && monitorids[0] != '\0') {
 			gchar **items;
@@ -2269,22 +2266,36 @@ static void remmina_rdp_call_feature(RemminaProtocolWidget *gp, const RemminaPro
 		if (rfi) {
 			rfi->scale = remmina_plugin_service->remmina_protocol_widget_get_current_scale_mode(gp);
 			remmina_rdp_event_update_scale(gp);
-		} else {
-			printf("Remmina RDP plugin warning: Null value for rfi in %s REMMINA_RDP_FEATURE_SCALE\n", __func__);
+		} else
+			REMMINA_PLUGIN_DEBUG("Remmina RDP plugin warning: Null value for rfi by REMMINA_RDP_FEATURE_SCALE");
+		break;
+
+	case REMMINA_RDP_FEATURE_MULTIMON:
+		if (rfi) {
+			RemminaFile *remminafile = remmina_plugin_service->protocol_plugin_get_file(gp);
+			if (remmina_plugin_service->file_get_int(remminafile, "multimon", FALSE)) {
+				rfi->settings->UseMultimon = TRUE;
+				/* TODO Add an option for this */
+				rfi->settings->ForceMultimon = TRUE;
+				rfi->settings->Fullscreen = TRUE;
+				remmina_rdp_event_send_delayed_monitor_layout(gp);
+			}
+
 		}
+		else
+			REMMINA_PLUGIN_DEBUG("Remmina RDP plugin warning: Null value for rfi by REMMINA_RDP_FEATURE_MULTIMON");
 		break;
 
 	case REMMINA_RDP_FEATURE_DYNRESUPDATE:
 		break;
 
 	case REMMINA_RDP_FEATURE_TOOL_REFRESH:
-		if (rfi) {
+		if (rfi)
 			gtk_widget_queue_draw_area(rfi->drawing_area, 0, 0,
-						   remmina_plugin_service->protocol_plugin_get_width(gp),
-						   remmina_plugin_service->protocol_plugin_get_height(gp));
-		} else {
-			printf("Remmina RDP plugin warning: Null value for rfi in %s REMMINA_RDP_FEATURE_TOOL_REFRESH\n", __func__);
-		}
+					remmina_plugin_service->protocol_plugin_get_width(gp),
+					remmina_plugin_service->protocol_plugin_get_height(gp));
+		else
+			REMMINA_PLUGIN_DEBUG("Remmina RDP plugin warning: Null value for rfi by REMMINA_RDP_FEATURE_TOOL_REFRESH");
 		break;
 
 	case REMMINA_RDP_FEATURE_TOOL_SENDCTRLALTDEL:
@@ -2574,6 +2585,7 @@ static const RemminaProtocolFeature remmina_rdp_features[] =
 	{ REMMINA_PROTOCOL_FEATURE_TYPE_TOOL,	      REMMINA_RDP_FEATURE_TOOL_REFRESH,	       N_("Refresh"),		   NULL, NULL },
 	{ REMMINA_PROTOCOL_FEATURE_TYPE_SCALE,	      REMMINA_RDP_FEATURE_SCALE,	       NULL,			   NULL, NULL },
 	{ REMMINA_PROTOCOL_FEATURE_TYPE_DYNRESUPDATE, REMMINA_RDP_FEATURE_DYNRESUPDATE,	       NULL,			   NULL, NULL },
+	{ REMMINA_PROTOCOL_FEATURE_TYPE_MULTIMON,     REMMINA_RDP_FEATURE_MULTIMON,	       NULL,			   NULL, NULL },
 	{ REMMINA_PROTOCOL_FEATURE_TYPE_TOOL,	      REMMINA_RDP_FEATURE_TOOL_SENDCTRLALTDEL, N_("Send Ctrl+Alt+Delete"), NULL, NULL },
 	{ REMMINA_PROTOCOL_FEATURE_TYPE_UNFOCUS,      REMMINA_RDP_FEATURE_UNFOCUS,	       NULL,			   NULL, NULL },
 	{ REMMINA_PROTOCOL_FEATURE_TYPE_END,	      0,				       NULL,			   NULL, NULL }
diff --git a/plugins/rdp/rdp_settings.c b/plugins/rdp/rdp_settings.c
index 9ec68ae589..fd04effdad 100644
--- a/plugins/rdp/rdp_settings.c
+++ b/plugins/rdp/rdp_settings.c
@@ -223,7 +223,6 @@ static void remmina_rdp_settings_grid_load_layout(RemminaPluginRdpsetGrid* grid)
 	free(layouts);
 }
 
-
 static void remmina_rdp_settings_grid_load_devicescalefactor_combo(RemminaPluginRdpsetGrid* grid)
 {
 	TRACE_CALL(__func__);
@@ -256,7 +255,6 @@ static void remmina_rdp_settings_grid_load_desktoporientation_combo(RemminaPlugi
 
 }
 
-
 static void remmina_rdp_settings_grid_load_quality(RemminaPluginRdpsetGrid* grid)
 {
 	TRACE_CALL(__func__);
diff --git a/src/include/remmina/types.h b/src/include/remmina/types.h
index 19488bf14a..b8d448e6e4 100644
--- a/src/include/remmina/types.h
+++ b/src/include/remmina/types.h
@@ -49,6 +49,7 @@ typedef enum {
 	REMMINA_PROTOCOL_FEATURE_TYPE_UNFOCUS,
 	REMMINA_PROTOCOL_FEATURE_TYPE_SCALE,
 	REMMINA_PROTOCOL_FEATURE_TYPE_DYNRESUPDATE,
+	REMMINA_PROTOCOL_FEATURE_TYPE_MULTIMON,
 	REMMINA_PROTOCOL_FEATURE_TYPE_GTKSOCKET
 } RemminaProtocolFeatureType;
 
diff --git a/src/rcw.c b/src/rcw.c
index 58a15105a6..2b898aee99 100644
--- a/src/rcw.c
+++ b/src/rcw.c
@@ -111,6 +111,7 @@ struct _RemminaConnectionWindowPriv {
 	GtkToolItem *					toolitem_dynres;
 	GtkToolItem *					toolitem_scale;
 	GtkToolItem *					toolitem_grab;
+	GtkToolItem *					toolitem_multimon;
 	GtkToolItem *					toolitem_preferences;
 	GtkToolItem *					toolitem_tools;
 	GtkToolItem *					toolitem_duplicate;
@@ -1656,6 +1657,28 @@ static void rcw_toolbar_scaled_mode(GtkToolItem *toggle, RemminaConnectionWindow
 	rco_change_scalemode(cnnobj, bdyn, bscale);
 }
 
+static void rcw_toolbar_multi_monitor_mode(GtkToolItem *toggle, RemminaConnectionWindow *cnnwin)
+{
+	TRACE_CALL(__func__);
+	RemminaConnectionObject *cnnobj;
+
+	if (cnnwin->priv->toolbar_is_reconfiguring)
+		return;
+
+	if (!(cnnobj = rcw_get_visible_cnnobj(cnnwin))) return;
+
+	if (gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(toggle))) {
+		remmina_file_set_int(cnnobj->remmina_file, "multimon", 1);
+		remmina_protocol_widget_call_feature_by_type(REMMINA_PROTOCOL_WIDGET(cnnobj->proto),
+				REMMINA_PROTOCOL_FEATURE_TYPE_MULTIMON, 0);
+		// Here we need a new rcw->toolbar->fullscreen_toggle. passing this toggle is a mistake
+		rcw_toolbar_fullscreen(cnnwin->priv->toolitem_fullscreen, cnnwin);
+	} else {
+		remmina_file_set_int(cnnobj->remmina_file, "multimon", 0);
+		rcw_toolbar_fullscreen(NULL, cnnwin);
+	}
+}
+
 static void rcw_toolbar_preferences_popdown(GtkToolItem *toggle, RemminaConnectionWindow *cnnwin)
 {
 	TRACE_CALL(__func__);
@@ -2139,6 +2162,12 @@ rcw_create_toolbar(RemminaConnectionWindow *cnnwin, gint mode)
 	GtkWidget *widget;
 	GtkWidget *arrow;
 
+	GdkDisplay *display;
+	gint n_monitors;
+
+	display = gdk_display_get_default ();
+	n_monitors = gdk_display_get_n_monitors(display);
+
 	cnnobj = rcw_get_visible_cnnobj(cnnwin);
 
 	priv->toolbar_is_reconfiguring = TRUE;
@@ -2264,6 +2293,19 @@ rcw_create_toolbar(RemminaConnectionWindow *cnnwin, gint mode)
 	g_signal_connect(G_OBJECT(widget), "toggled", G_CALLBACK(rcw_toolbar_scaler_option), cnnwin);
 	priv->scaler_option_button = widget;
 
+	/* Multi monitor */
+
+	if (n_monitors > 1) {
+		toolitem = gtk_toggle_tool_button_new();
+		gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(toolitem), "remmina-multi-monitor-symbolic");
+		rcw_set_tooltip(GTK_WIDGET(toolitem), _("Multi monitor"),
+				remmina_pref.shortcutkey_multimon, 0);
+		gtk_toolbar_insert(GTK_TOOLBAR(toolbar), toolitem, -1);
+		gtk_widget_show(GTK_WIDGET(toolitem));
+		g_signal_connect(G_OBJECT(toolitem), "toggled", G_CALLBACK(rcw_toolbar_multi_monitor_mode), cnnwin);
+		priv->toolitem_multimon = toolitem;
+	}
+
 	/* Grab keyboard button */
 	toolitem = gtk_toggle_tool_button_new();
 	gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(toolitem), "remmina-keyboard-symbolic");
@@ -2381,7 +2423,6 @@ static void rco_update_toolbar(RemminaConnectionObject *cnnobj)
 
 	rco_update_toolbar_autofit_button(cnnobj);
 
-
 	toolitem = priv->toolitem_switch_page;
 	if (kioskmode)
 		bval = FALSE;
diff --git a/src/remmina_main.c b/src/remmina_main.c
index aaec2fb5f7..1edc329fb7 100644
--- a/src/remmina_main.c
+++ b/src/remmina_main.c
@@ -1409,6 +1409,7 @@ GtkWidget *remmina_main_new(void)
 	gtk_window_add_accel_group(remminamain->window, accel_group);
 	gtk_accel_group_connect(accel_group, GDK_KEY_Q, GDK_CONTROL_MASK, 0,
 				g_cclosure_new_swap(G_CALLBACK(remmina_main_on_action_application_quit), NULL, NULL));
+	// TODO: This crash remmina because the function doesn't receive the parameter we expect
 	gtk_accel_group_connect(accel_group, GDK_KEY_P, GDK_CONTROL_MASK, 0,
 				g_cclosure_new_swap(G_CALLBACK(remmina_main_on_accel_application_preferences), NULL, NULL));
 	gtk_accel_group_connect(accel_group, GDK_KEY_F, GDK_CONTROL_MASK, 0,
diff --git a/src/remmina_pref.c b/src/remmina_pref.c
index 4b6a9eaf62..0d46f79104 100644
--- a/src/remmina_pref.c
+++ b/src/remmina_pref.c
@@ -563,6 +563,11 @@ void remmina_pref_init(void)
 	else
 		remmina_pref.shortcutkey_viewonly = GDK_KEY_m;
 
+	if (g_key_file_has_key(gkeyfile, "remmina_pref", "shortcutkey_multimon", NULL))
+		remmina_pref.shortcutkey_multimon = g_key_file_get_integer(gkeyfile, "remmina_pref", "shortcutkey_multimon", NULL);
+	else
+		remmina_pref.shortcutkey_multimon = GDK_KEY_Page_Up;
+
 	if (g_key_file_has_key(gkeyfile, "remmina_pref", "shortcutkey_grab", NULL))
 		remmina_pref.shortcutkey_grab = g_key_file_get_integer(gkeyfile, "remmina_pref", "shortcutkey_grab", NULL);
 	else
@@ -809,6 +814,7 @@ gboolean remmina_pref_save(void)
 	g_key_file_set_integer(gkeyfile, "remmina_pref", "shortcutkey_prevtab", remmina_pref.shortcutkey_prevtab);
 	g_key_file_set_integer(gkeyfile, "remmina_pref", "shortcutkey_scale", remmina_pref.shortcutkey_scale);
 	g_key_file_set_integer(gkeyfile, "remmina_pref", "shortcutkey_grab", remmina_pref.shortcutkey_grab);
+	g_key_file_set_integer(gkeyfile, "remmina_pref", "shortcutkey_multimon", remmina_pref.shortcutkey_multimon);
 	g_key_file_set_integer(gkeyfile, "remmina_pref", "shortcutkey_viewonly", remmina_pref.shortcutkey_viewonly);
 	g_key_file_set_integer(gkeyfile, "remmina_pref", "shortcutkey_screenshot", remmina_pref.shortcutkey_screenshot);
 	g_key_file_set_integer(gkeyfile, "remmina_pref", "shortcutkey_minimize", remmina_pref.shortcutkey_minimize);
diff --git a/src/remmina_pref.h b/src/remmina_pref.h
index a7964a2f53..1b7b507d00 100644
--- a/src/remmina_pref.h
+++ b/src/remmina_pref.h
@@ -35,6 +35,7 @@
  */
 
 #pragma once
+#include <gtk/gtk.h>
 
 /*
  * Remmina Preference Loader
@@ -152,6 +153,7 @@ typedef struct _RemminaPref {
 	guint			shortcutkey_nexttab;
 	guint			shortcutkey_dynres;
 	guint			shortcutkey_scale;
+	guint			shortcutkey_multimon;
 	guint			shortcutkey_grab;
 	guint			shortcutkey_viewonly;
 	guint			shortcutkey_screenshot;
diff --git a/src/remmina_pref_dialog.c b/src/remmina_pref_dialog.c
index 6f228753b6..ca1972e7f7 100644
--- a/src/remmina_pref_dialog.c
+++ b/src/remmina_pref_dialog.c
@@ -56,6 +56,12 @@ static RemminaPrefDialog *remmina_pref_dialog;
 
 #define GET_OBJECT(object_name) gtk_builder_get_object(remmina_pref_dialog->builder, object_name)
 
+static GActionEntry pref_actions[] = {
+	{ "close",	 remmina_pref_dialog_on_action_close,	   NULL, NULL, NULL },
+
+};
+
+
 /* Show a key chooser dialog */
 void remmina_pref_dialog_on_key_chooser(GtkWidget *widget, gpointer user_data)
 {
@@ -188,6 +194,11 @@ void remmina_prefdiag_unlock_repwd_on_changed(GtkEditable* editable, RemminaPref
 
 }
 
+void remmina_pref_dialog_on_action_close(GSimpleAction *action, GVariant *param, gpointer data)
+{
+	TRACE_CALL(__func__);
+	gtk_widget_destroy(GTK_WIDGET(remmina_pref_dialog->dialog));
+}
 void remmina_pref_dialog_on_close_clicked(GtkWidget *widget, RemminaPrefDialog *dialog)
 {
 	TRACE_CALL(__func__);
@@ -296,6 +307,7 @@ void remmina_pref_on_dialog_destroy(GtkWidget *widget, gpointer user_data)
 	remmina_pref.shortcutkey_prevtab = remmina_key_chooser_get_keyval(gtk_button_get_label(remmina_pref_dialog->button_keyboard_switch_tab_left));
 	remmina_pref.shortcutkey_nexttab = remmina_key_chooser_get_keyval(gtk_button_get_label(remmina_pref_dialog->button_keyboard_switch_tab_right));
 	remmina_pref.shortcutkey_scale = remmina_key_chooser_get_keyval(gtk_button_get_label(remmina_pref_dialog->button_keyboard_scaled));
+	remmina_pref.shortcutkey_multimon = remmina_key_chooser_get_keyval(gtk_button_get_label(remmina_pref_dialog->button_keyboard_multimon));
 	remmina_pref.shortcutkey_grab = remmina_key_chooser_get_keyval(gtk_button_get_label(remmina_pref_dialog->button_keyboard_grab_keyboard));
 	remmina_pref.shortcutkey_screenshot = remmina_key_chooser_get_keyval(gtk_button_get_label(remmina_pref_dialog->button_keyboard_screenshot));
 	remmina_pref.shortcutkey_viewonly = remmina_key_chooser_get_keyval(gtk_button_get_label(remmina_pref_dialog->button_keyboard_viewonly));
@@ -374,6 +386,8 @@ static gboolean remmina_pref_dialog_add_pref_plugin(gchar *name, RemminaPlugin *
 	pref_plugin = (RemminaPrefPlugin*)plugin;
 
 	widget = gtk_label_new(pref_plugin->pref_label);
+	gtk_widget_set_halign(widget, GTK_ALIGN_END);
+	gtk_widget_set_margin_end(widget, 18);
 	gtk_widget_show(widget);
 
 	vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
@@ -495,6 +509,7 @@ static void remmina_pref_dialog_init(void)
 	remmina_pref_dialog_set_button_label(remmina_pref_dialog->button_keyboard_switch_tab_left, remmina_pref.shortcutkey_prevtab);
 	remmina_pref_dialog_set_button_label(remmina_pref_dialog->button_keyboard_switch_tab_right, remmina_pref.shortcutkey_nexttab);
 	remmina_pref_dialog_set_button_label(remmina_pref_dialog->button_keyboard_scaled, remmina_pref.shortcutkey_scale);
+	remmina_pref_dialog_set_button_label(remmina_pref_dialog->button_keyboard_multimon, remmina_pref.shortcutkey_multimon);
 	remmina_pref_dialog_set_button_label(remmina_pref_dialog->button_keyboard_grab_keyboard, remmina_pref.shortcutkey_grab);
 	remmina_pref_dialog_set_button_label(remmina_pref_dialog->button_keyboard_screenshot, remmina_pref.shortcutkey_screenshot);
 	remmina_pref_dialog_set_button_label(remmina_pref_dialog->button_keyboard_viewonly, remmina_pref.shortcutkey_viewonly);
@@ -633,6 +648,8 @@ static void remmina_pref_dialog_init(void)
 GtkDialog* remmina_pref_dialog_new(gint default_tab, GtkWindow *parent)
 {
 	TRACE_CALL(__func__);
+	GSimpleActionGroup *actions;
+	GtkAccelGroup *accel_group = NULL;
 
 	remmina_pref_dialog = g_new0(RemminaPrefDialog, 1);
 	remmina_pref_dialog->priv = g_new0(RemminaPrefDialogPriv, 1);
@@ -692,6 +709,7 @@ GtkDialog* remmina_pref_dialog_new(gint default_tab, GtkWindow *parent)
 	remmina_pref_dialog->button_keyboard_switch_tab_right = GTK_BUTTON(GET_OBJECT("button_keyboard_switch_tabright"));
 	remmina_pref_dialog->button_keyboard_scaled = GTK_BUTTON(GET_OBJECT("button_keyboard_scaled"));
 	remmina_pref_dialog->button_keyboard_grab_keyboard = GTK_BUTTON(GET_OBJECT("button_keyboard_grab_keyboard"));
+	remmina_pref_dialog->button_keyboard_multimon = GTK_BUTTON(GET_OBJECT("button_keyboard_multimon"));
 	remmina_pref_dialog->button_keyboard_screenshot = GTK_BUTTON(GET_OBJECT("button_keyboard_screenshot"));
 	remmina_pref_dialog->button_keyboard_viewonly = GTK_BUTTON(GET_OBJECT("button_keyboard_viewonly"));
 	remmina_pref_dialog->button_keyboard_minimize = GTK_BUTTON(GET_OBJECT("button_keyboard_minimize"));
@@ -752,6 +770,17 @@ GtkDialog* remmina_pref_dialog_new(gint default_tab, GtkWindow *parent)
 	g_free(destpath);
 #endif
 #endif
+	/* Non widget objects */
+	actions = g_simple_action_group_new();
+	g_action_map_add_action_entries(G_ACTION_MAP(actions), pref_actions, G_N_ELEMENTS(pref_actions), remmina_pref_dialog->dialog);
+	gtk_widget_insert_action_group(GTK_WIDGET(remmina_pref_dialog->dialog), "pref", G_ACTION_GROUP(actions));
+	g_action_map_add_action_entries(G_ACTION_MAP(actions), pref_actions, G_N_ELEMENTS(pref_actions), remmina_pref_dialog->dialog);
+	g_object_unref(actions);
+	/* Accelerators */
+	accel_group = gtk_accel_group_new();
+	gtk_window_add_accel_group(GTK_WINDOW(remmina_pref_dialog->dialog), accel_group);
+	gtk_accel_group_connect(accel_group, GDK_KEY_Q, GDK_CONTROL_MASK, 0,
+				g_cclosure_new_swap(G_CALLBACK(remmina_pref_dialog_on_action_close), NULL, NULL));
 
 	/* Connect signals */
 	gtk_builder_connect_signals(remmina_pref_dialog->builder, NULL);
diff --git a/src/remmina_pref_dialog.h b/src/remmina_pref_dialog.h
index 18319c6296..87bb481731 100644
--- a/src/remmina_pref_dialog.h
+++ b/src/remmina_pref_dialog.h
@@ -34,6 +34,7 @@
  */
 
 #pragma once
+#include <gtk/gtk.h>
 
 /*
  * Remmina Preferences Dialog
@@ -95,6 +96,7 @@ typedef struct _RemminaPrefDialog {
 	GtkButton *		button_keyboard_switch_tab_left;
 	GtkButton *		button_keyboard_switch_tab_right;
 	GtkButton *		button_keyboard_scaled;
+	GtkButton *		button_keyboard_multimon;
 	GtkButton *		button_keyboard_grab_keyboard;
 	GtkButton *		button_keyboard_screenshot;
 	GtkButton *		button_keyboard_viewonly;
@@ -156,5 +158,6 @@ GtkDialog *remmina_pref_dialog_new(gint default_tab, GtkWindow *parent);
 /* Get the current PrefDialog or NULL if not initialized */
 GtkDialog *remmina_pref_dialog_get_dialog(void);
 void remmina_prefdiag_unlock_repwd_on_changed(GtkEditable *editable, RemminaPrefDialog *dialog);
+void remmina_pref_dialog_on_action_close(GSimpleAction *action, GVariant *param, gpointer data);
 
 G_END_DECLS
-- 
GitLab


From fbeab11e3aefbbd4931eec6ee2cc3c1bb5b5695c Mon Sep 17 00:00:00 2001
From: Antenore Gatta <antenore@simbiosi.org>
Date: Mon, 1 Feb 2021 10:02:52 +0100
Subject: [PATCH 7/8] Setting toolbar status updates for multi monitor

---
 src/rcw.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/src/rcw.c b/src/rcw.c
index 2b898aee99..a57fded6b6 100644
--- a/src/rcw.c
+++ b/src/rcw.c
@@ -1671,8 +1671,8 @@ static void rcw_toolbar_multi_monitor_mode(GtkToolItem *toggle, RemminaConnectio
 		remmina_file_set_int(cnnobj->remmina_file, "multimon", 1);
 		remmina_protocol_widget_call_feature_by_type(REMMINA_PROTOCOL_WIDGET(cnnobj->proto),
 				REMMINA_PROTOCOL_FEATURE_TYPE_MULTIMON, 0);
-		// Here we need a new rcw->toolbar->fullscreen_toggle. passing this toggle is a mistake
-		rcw_toolbar_fullscreen(cnnwin->priv->toolitem_fullscreen, cnnwin);
+		if (!gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(cnnwin->priv->toolitem_fullscreen)))
+			gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(cnnwin->priv->toolitem_fullscreen), TRUE);
 	} else {
 		remmina_file_set_int(cnnobj->remmina_file, "multimon", 0);
 		rcw_toolbar_fullscreen(NULL, cnnwin);
@@ -2457,6 +2457,11 @@ static void rco_update_toolbar(RemminaConnectionObject *cnnobj)
 		break;
 	}
 
+	toolitem = priv->toolitem_multimon;
+	gtk_widget_set_sensitive(GTK_WIDGET(toolitem), cnnobj->connected);
+	gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(toolitem),
+					  remmina_file_get_int(cnnobj->remmina_file, "multimon", FALSE));
+
 	toolitem = priv->toolitem_grab;
 	gtk_widget_set_sensitive(GTK_WIDGET(toolitem), cnnobj->connected);
 	gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(toolitem),
-- 
GitLab


From bdf5f37e10c4a8d3278d9531841941b984999d14 Mon Sep 17 00:00:00 2001
From: Antenore Gatta <antenore@simbiosi.org>
Date: Tue, 2 Feb 2021 11:52:40 +0100
Subject: [PATCH 8/8] Moving the multi monitor icon up close to fullscreen

---
 src/rcw.c | 25 ++++++++++++-------------
 1 file changed, 12 insertions(+), 13 deletions(-)

diff --git a/src/rcw.c b/src/rcw.c
index a57fded6b6..9cb882adb7 100644
--- a/src/rcw.c
+++ b/src/rcw.c
@@ -2234,6 +2234,18 @@ rcw_create_toolbar(RemminaConnectionWindow *cnnwin, gint mode)
 	if (mode == SCROLLED_WINDOW_MODE)
 		gtk_widget_set_sensitive(GTK_WIDGET(widget), FALSE);
 
+	/* Multi monitor */
+	if (n_monitors > 1) {
+		toolitem = gtk_toggle_tool_button_new();
+		gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(toolitem), "remmina-multi-monitor-symbolic");
+		rcw_set_tooltip(GTK_WIDGET(toolitem), _("Multi monitor"),
+				remmina_pref.shortcutkey_multimon, 0);
+		gtk_toolbar_insert(GTK_TOOLBAR(toolbar), toolitem, -1);
+		gtk_widget_show(GTK_WIDGET(toolitem));
+		g_signal_connect(G_OBJECT(toolitem), "toggled", G_CALLBACK(rcw_toolbar_multi_monitor_mode), cnnwin);
+		priv->toolitem_multimon = toolitem;
+	}
+
 	/* Switch tabs */
 	toolitem = gtk_toggle_tool_button_new();
 	gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(toolitem), "remmina-switch-page-symbolic");
@@ -2293,19 +2305,6 @@ rcw_create_toolbar(RemminaConnectionWindow *cnnwin, gint mode)
 	g_signal_connect(G_OBJECT(widget), "toggled", G_CALLBACK(rcw_toolbar_scaler_option), cnnwin);
 	priv->scaler_option_button = widget;
 
-	/* Multi monitor */
-
-	if (n_monitors > 1) {
-		toolitem = gtk_toggle_tool_button_new();
-		gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(toolitem), "remmina-multi-monitor-symbolic");
-		rcw_set_tooltip(GTK_WIDGET(toolitem), _("Multi monitor"),
-				remmina_pref.shortcutkey_multimon, 0);
-		gtk_toolbar_insert(GTK_TOOLBAR(toolbar), toolitem, -1);
-		gtk_widget_show(GTK_WIDGET(toolitem));
-		g_signal_connect(G_OBJECT(toolitem), "toggled", G_CALLBACK(rcw_toolbar_multi_monitor_mode), cnnwin);
-		priv->toolitem_multimon = toolitem;
-	}
-
 	/* Grab keyboard button */
 	toolitem = gtk_toggle_tool_button_new();
 	gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(toolitem), "remmina-keyboard-symbolic");
-- 
GitLab