Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/Remmina/Remmina.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAntenore Gatta <antenore@simbiosi.org>2016-03-18 01:43:04 +0300
committerAntenore Gatta <antenore@simbiosi.org>2016-03-18 01:43:04 +0300
commit860af6bf9b16e831f2cd09e098329d3f5605efe2 (patch)
tree2e14945dc2c2a1643ac2bfbf602711808606ff17
parentac2a205d2ffeb8979c9b0c558eadd4c28943463e (diff)
parent395bfe8f645e6b4392e66024cf5558161d1ca9b5 (diff)
Merge pull request #802 from FreeRDP/remmina_screenshot1.2.0.rcgit.11
Remote machine screenshot [feature request] closes #644 and closes #801
-rw-r--r--AUTHORS2
-rw-r--r--CMakeLists.txt2
-rw-r--r--remmina-plugins-gnome/src/glibsecret_plugin.c10
-rw-r--r--remmina-plugins/nx/nx_plugin.c3
-rw-r--r--remmina-plugins/rdp/rdp_event.c3
-rw-r--r--remmina-plugins/rdp/rdp_plugin.c37
-rw-r--r--remmina-plugins/vnc/vnc_plugin.c3
-rw-r--r--remmina-plugins/xdmcp/xdmcp_plugin.c7
-rw-r--r--remmina/include/remmina/plugin.h1
-rw-r--r--remmina/include/remmina/types.h13
-rw-r--r--remmina/src/remmina_connection_window.c828
-rw-r--r--remmina/src/remmina_file_editor.c19
-rw-r--r--remmina/src/remmina_pref.c16
-rw-r--r--remmina/src/remmina_pref.h9
-rw-r--r--remmina/src/remmina_pref_dialog.c11
-rw-r--r--remmina/src/remmina_pref_dialog.h2
-rw-r--r--remmina/src/remmina_protocol_widget.c12
-rw-r--r--remmina/src/remmina_protocol_widget.h2
-rw-r--r--remmina/src/remmina_public.c57
-rw-r--r--remmina/src/remmina_public.h7
-rw-r--r--remmina/ui/remmina_about.glade2
-rw-r--r--remmina/ui/remmina_preferences.glade331
22 files changed, 862 insertions, 515 deletions
diff --git a/AUTHORS b/AUTHORS
index 39e24aec9..b10184059 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -13,6 +13,7 @@ Authors of Remmina Project
Ben Kohler <bkohler@gmail.com>
Christopher Rawlings <chris.rawlings+git@gmail.com>
Daniel M. Weeks <dan@danweeks.net>
+ Daniele Tieghi <notdisclosed>
Dmitry Kubatkin <maelnor@gmail.com>
dupondje <jean-louis@dupondje.be>
Emmanuel Grognet <emmanuel@grognet.fr>
@@ -30,6 +31,7 @@ Authors of Remmina Project
Kyle Sanderson <kyle.leet@gmail.com>
Luca Falavigna <dktrkranz@debian.org>
Marc-André Moreau <marcandre.moreau@gmail.com>
+ Michele Sartori <mik.thrasher@aol.com>
Mike Dalessio <mike@csa.net>
Mike Gilbert <floppym@gentoo.org>
Muflone <muflone@vbsimple.net>
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 78a8317c2..b7b6c69f5 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -110,7 +110,7 @@ set(WITH_LIBRARY_VERSIONING "ON")
set(REMMINA_VERSION_MAJOR "1")
set(REMMINA_VERSION_MINOR "2")
set(REMMINA_VERSION_REVISION "0")
-set(REMMINA_VERSION_SUFFIX "rcgit.10")
+set(REMMINA_VERSION_SUFFIX "rcgit.11")
set(REMMINA_VERSION "${REMMINA_VERSION_MAJOR}.${REMMINA_VERSION_MINOR}.${REMMINA_VERSION_REVISION}-${REMMINA_VERSION_SUFFIX}")
include(GetGitRevisionDescription)
diff --git a/remmina-plugins-gnome/src/glibsecret_plugin.c b/remmina-plugins-gnome/src/glibsecret_plugin.c
index 380eea914..35ca27522 100644
--- a/remmina-plugins-gnome/src/glibsecret_plugin.c
+++ b/remmina-plugins-gnome/src/glibsecret_plugin.c
@@ -62,9 +62,8 @@ static void remmina_plugin_glibsecret_unlock_secret_service()
#ifdef LIBSECRET_VERSION_0_18
GError *error = NULL;
- GList *l, *ul;
+ GList *objects, *ul;
gchar* lbl;
- gint nu;
if (secretservice && defaultcollection)
{
@@ -72,10 +71,9 @@ static void remmina_plugin_glibsecret_unlock_secret_service()
{
lbl = secret_collection_get_label(defaultcollection);
remmina_plugin_service->log_printf("[glibsecret] requesting unlock of the default '%s' collection\n", lbl);
- l = NULL;
- g_list_append(l, defaultcollection);
- nu = secret_service_unlock_sync(secretservice, l, NULL, &ul, &error);
- g_list_free(l);
+ objects = g_list_append(NULL, defaultcollection);
+ secret_service_unlock_sync(secretservice, objects, NULL, &ul, &error);
+ g_list_free(objects);
g_list_free(ul);
}
}
diff --git a/remmina-plugins/nx/nx_plugin.c b/remmina-plugins/nx/nx_plugin.c
index 62eb391ea..0406d96af 100644
--- a/remmina-plugins/nx/nx_plugin.c
+++ b/remmina-plugins/nx/nx_plugin.c
@@ -799,7 +799,8 @@ static RemminaProtocolPlugin remmina_plugin_nx =
remmina_plugin_nx_close_connection, // Plugin close connection
remmina_plugin_nx_query_feature, // Query for available features
remmina_plugin_nx_call_feature, // Call a feature
- NULL // Send a keystroke
+ NULL, // Send a keystroke
+ NULL // Screenshot
};
G_MODULE_EXPORT gboolean
diff --git a/remmina-plugins/rdp/rdp_event.c b/remmina-plugins/rdp/rdp_event.c
index 90ab78d6b..39b62e335 100644
--- a/remmina-plugins/rdp/rdp_event.c
+++ b/remmina-plugins/rdp/rdp_event.c
@@ -1077,6 +1077,3 @@ int remmina_rdp_event_queue_ui(RemminaProtocolWidget* gp, RemminaPluginRdpUiObje
pthread_setcanceltype(oldcanceltype, NULL);
return rc;
}
-
-
-
diff --git a/remmina-plugins/rdp/rdp_plugin.c b/remmina-plugins/rdp/rdp_plugin.c
index 848fd4835..82ef9435b 100644
--- a/remmina-plugins/rdp/rdp_plugin.c
+++ b/remmina-plugins/rdp/rdp_plugin.c
@@ -1230,6 +1230,40 @@ static void remmina_rdp_keystroke(RemminaProtocolWidget *gp, const guint keystro
return;
}
+static gboolean remmina_rdp_get_screenshot(RemminaProtocolWidget *gp, RemminaPluginScreenshotData *rpsd)
+{
+ rfContext* rfi = GET_PLUGIN_DATA(gp);
+ rdpGdi* gdi;
+ size_t szmem;
+
+ if (!rfi)
+ return FALSE;
+
+ /* ToDo: we should lock freerdp subthread to update rfi->primary_buffer, rfi->gdi and w/h,
+ * from here to memcpy, but... how ? */
+
+ gdi = ((rdpContext *)rfi)->gdi;
+
+ szmem = gdi->width * gdi->height * rfi->hdc->bytesPerPixel;
+ remmina_plugin_service->log_printf("[RDP] allocating %zu bytes for a full screenshot\n", szmem);
+ rpsd->buffer = malloc(szmem);
+ if (!rpsd->buffer)
+ {
+ remmina_plugin_service->log_printf("[RDP] unable to allocate %zu bytes for a full screenshot\n", szmem);
+ return FALSE;
+ }
+ rpsd->width = gdi->width;
+ rpsd->height = gdi->height;
+ rpsd->bitsPerPixel = rfi->hdc->bitsPerPixel;
+ rpsd->bytesPerPixel = rfi->hdc->bytesPerPixel;
+
+ memcpy(rpsd->buffer, rfi->primary_buffer, szmem);
+
+ /* Returning TRUE instruct also the caller to deallocate rpsd->buffer */
+ return TRUE;
+
+}
+
/* Array of key/value pairs for color depths */
static gpointer colordepth_list[] =
{
@@ -1355,7 +1389,8 @@ static RemminaProtocolPlugin remmina_rdp =
remmina_rdp_close_connection, // Plugin close connection
remmina_rdp_query_feature, // Query for available features
remmina_rdp_call_feature, // Call a feature
- remmina_rdp_keystroke // Send a keystroke
+ remmina_rdp_keystroke, // Send a keystroke
+ remmina_rdp_get_screenshot // Screenshot
};
/* File plugin definition and features */
diff --git a/remmina-plugins/vnc/vnc_plugin.c b/remmina-plugins/vnc/vnc_plugin.c
index 2001285b1..c6a903d7d 100644
--- a/remmina-plugins/vnc/vnc_plugin.c
+++ b/remmina-plugins/vnc/vnc_plugin.c
@@ -2088,7 +2088,8 @@ static RemminaProtocolPlugin remmina_plugin_vnci =
remmina_plugin_vnc_close_connection, // Plugin close connection
remmina_plugin_vnc_query_feature, // Query for available features
remmina_plugin_vnc_call_feature, // Call a feature
- remmina_plugin_vnc_keystroke // Send a keystroke
+ remmina_plugin_vnc_keystroke, // Send a keystroke
+ NULL // No screenshot support available
};
G_MODULE_EXPORT gboolean
diff --git a/remmina-plugins/xdmcp/xdmcp_plugin.c b/remmina-plugins/xdmcp/xdmcp_plugin.c
index 3cb7a77a7..58c824894 100644
--- a/remmina-plugins/xdmcp/xdmcp_plugin.c
+++ b/remmina-plugins/xdmcp/xdmcp_plugin.c
@@ -1,6 +1,6 @@
/*
* Remmina - The GTK+ Remote Desktop Client
- * Copyright (C) 2010 Vic Lee
+ * Copyright (C) 2010 Vic Lee
* Copyright (C) 2014-2015 Antenore Gatta, Fabio Castelli, Giovanni Panozzo
*
* This program is free software; you can redistribute it and/or modify
@@ -15,7 +15,7 @@
*
* 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,
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*
* In addition, as a special exception, the copyright holders give
@@ -422,7 +422,8 @@ static RemminaProtocolPlugin remmina_plugin_xdmcp =
remmina_plugin_xdmcp_close_connection, // Plugin close connection
remmina_plugin_xdmcp_query_feature, // Query for available features
remmina_plugin_xdmcp_call_feature, // Call a feature
- NULL // Send a keystroke
+ NULL, // Send a keystroke
+ NULL // Screenshot
};
G_MODULE_EXPORT gboolean
diff --git a/remmina/include/remmina/plugin.h b/remmina/include/remmina/plugin.h
index 27a056eef..4afe35415 100644
--- a/remmina/include/remmina/plugin.h
+++ b/remmina/include/remmina/plugin.h
@@ -81,6 +81,7 @@ typedef struct _RemminaProtocolPlugin
gboolean (* query_feature) (RemminaProtocolWidget *gp, const RemminaProtocolFeature *feature);
void (* call_feature) (RemminaProtocolWidget *gp, const RemminaProtocolFeature *feature);
void (* send_keystrokes) (RemminaProtocolWidget *gp, const guint keystrokes[], const gint keylen);
+ gboolean (* get_plugin_screenshot)(RemminaProtocolWidget *gp, RemminaPluginScreenshotData *rpsd);
} RemminaProtocolPlugin;
typedef struct _RemminaEntryPlugin
diff --git a/remmina/include/remmina/types.h b/remmina/include/remmina/types.h
index cf5541ca2..13bc09624 100644
--- a/remmina/include/remmina/types.h
+++ b/remmina/include/remmina/types.h
@@ -1,6 +1,6 @@
/*
* Remmina - The GTK+ Remote Desktop Client
- * Copyright (C) 2010 Vic Lee
+ * Copyright (C) 2010 Vic Lee
* Copyright (C) 2014-2015 Antenore Gatta, Fabio Castelli, Giovanni Panozzo
*
* This program is free software; you can redistribute it and/or modify
@@ -15,7 +15,7 @@
*
* 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,
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*
* In addition, as a special exception, the copyright holders give
@@ -61,6 +61,15 @@ typedef struct _RemminaProtocolFeature
gpointer opt3;
} RemminaProtocolFeature;
+typedef struct _RemminaPluginScreenshotData {
+ unsigned char* buffer;
+ int bitsPerPixel;
+ int bytesPerPixel;
+ int width;
+ int height;
+} RemminaPluginScreenshotData;
+
+
typedef struct _RemminaProtocolWidgetClass RemminaProtocolWidgetClass;
typedef struct _RemminaProtocolWidget RemminaProtocolWidget;
typedef gpointer RemminaTunnelInitFunc;
diff --git a/remmina/src/remmina_connection_window.c b/remmina/src/remmina_connection_window.c
index d5aa70501..9d9e9cd65 100644
--- a/remmina/src/remmina_connection_window.c
+++ b/remmina/src/remmina_connection_window.c
@@ -35,11 +35,14 @@
#include "config.h"
-#include <gtk/gtk.h>
-#include <gdk/gdkkeysyms.h>
-#include <glib/gi18n.h>
#include <stdlib.h>
+#include <cairo/cairo-xlib.h>
+#include <glib/gi18n.h>
+#include <gdk/gdk.h>
+#include <gdk/gdkkeysyms.h>
+#include <gtk/gtk.h>
+
#include "remmina_connection_window.h"
#include "remmina_file.h"
#include "remmina_file_manager.h"
@@ -51,6 +54,7 @@
#include "remmina_public.h"
#include "remmina_scrolled_viewport.h"
#include "remmina_widget_pool.h"
+#include "remmina_log.h"
#include "remmina/remmina_trace_calls.h"
G_DEFINE_TYPE( RemminaConnectionWindow, remmina_connection_window, GTK_TYPE_WINDOW)
@@ -59,9 +63,9 @@ G_DEFINE_TYPE( RemminaConnectionWindow, remmina_connection_window, GTK_TYPE_WIND
#define FLOATING_TOOLBAR_WIDGET (GTK_CHECK_VERSION(3, 10, 0))
-typedef struct _RemminaConnectionHolder RemminaConnectionHolder;
+ typedef struct _RemminaConnectionHolder RemminaConnectionHolder;
-struct _RemminaConnectionWindowPriv
+ struct _RemminaConnectionWindowPriv
{
RemminaConnectionHolder* cnnhld;
@@ -99,6 +103,7 @@ struct _RemminaConnectionWindowPriv
GtkToolItem* toolitem_grab;
GtkToolItem* toolitem_preferences;
GtkToolItem* toolitem_tools;
+ GtkToolItem* toolitem_screenshot;
GtkWidget* fullscreen_option_button;
GtkWidget* fullscreen_scaler_button;
GtkWidget* scaler_option_button;
@@ -154,22 +159,22 @@ static guint remmina_connection_window_signals[LAST_SIGNAL] =
{ 0 };
#define DECLARE_CNNOBJ \
- if (!cnnhld || !cnnhld->cnnwin || gtk_notebook_get_current_page (GTK_NOTEBOOK (cnnhld->cnnwin->priv->notebook)) < 0) return; \
- RemminaConnectionObject* cnnobj = (RemminaConnectionObject*) g_object_get_data ( \
- G_OBJECT(gtk_notebook_get_nth_page (GTK_NOTEBOOK (cnnhld->cnnwin->priv->notebook), \
- gtk_notebook_get_current_page (GTK_NOTEBOOK (cnnhld->cnnwin->priv->notebook)))), "cnnobj");
+ if (!cnnhld || !cnnhld->cnnwin || gtk_notebook_get_current_page (GTK_NOTEBOOK (cnnhld->cnnwin->priv->notebook)) < 0) return; \
+RemminaConnectionObject* cnnobj = (RemminaConnectionObject*) g_object_get_data ( \
+ G_OBJECT(gtk_notebook_get_nth_page (GTK_NOTEBOOK (cnnhld->cnnwin->priv->notebook), \
+ gtk_notebook_get_current_page (GTK_NOTEBOOK (cnnhld->cnnwin->priv->notebook)))), "cnnobj");
#define DECLARE_CNNOBJ_WITH_RETURN(r) \
- if (!cnnhld || !cnnhld->cnnwin || gtk_notebook_get_current_page (GTK_NOTEBOOK (cnnhld->cnnwin->priv->notebook)) < 0) return r; \
- RemminaConnectionObject* cnnobj = (RemminaConnectionObject*) g_object_get_data ( \
- G_OBJECT(gtk_notebook_get_nth_page (GTK_NOTEBOOK (cnnhld->cnnwin->priv->notebook), \
- gtk_notebook_get_current_page (GTK_NOTEBOOK (cnnhld->cnnwin->priv->notebook)))), "cnnobj");
+ if (!cnnhld || !cnnhld->cnnwin || gtk_notebook_get_current_page (GTK_NOTEBOOK (cnnhld->cnnwin->priv->notebook)) < 0) return r; \
+RemminaConnectionObject* cnnobj = (RemminaConnectionObject*) g_object_get_data ( \
+ G_OBJECT(gtk_notebook_get_nth_page (GTK_NOTEBOOK (cnnhld->cnnwin->priv->notebook), \
+ gtk_notebook_get_current_page (GTK_NOTEBOOK (cnnhld->cnnwin->priv->notebook)))), "cnnobj");
static void remmina_connection_holder_create_scrolled(RemminaConnectionHolder* cnnhld, RemminaConnectionObject* cnnobj);
static void remmina_connection_holder_create_fullscreen(RemminaConnectionHolder* cnnhld, RemminaConnectionObject* cnnobj,
- gint view_mode);
+ gint view_mode);
static gboolean remmina_connection_window_hostkey_func(RemminaProtocolWidget* gp, guint keyval, gboolean release,
- RemminaConnectionHolder* cnnhld);
+ RemminaConnectionHolder* cnnhld);
static void remmina_connection_holder_grab_focus(GtkNotebook *notebook);
static GtkWidget* remmina_connection_holder_create_toolbar(RemminaConnectionHolder* cnnhld, gint mode);
@@ -209,70 +214,70 @@ static void remmina_connection_window_class_init(RemminaConnectionWindowClass* k
* we will never know its internal area size, because GtkViweport::viewport_get_view_allocation,
* which returns the internal size of the GtkViewport, is private and we cannot access it */
gtk_css_provider_load_from_data (provider,
- "GtkViewport, GtkAspectFrame {\n"
- " padding:0;\n"
- " border:0;\n"
- " background-color: black;\n"
- "}\n"
- "GtkDrawingArea {\n"
- " background-color: black;\n"
- "}\n"
- "GtkToolbar {\n"
- " -GtkWidget-window-dragging: 0;\n"
- "}\n"
- "#remmina-connection-window-fullscreen {\n"
- " background-color: black;\n"
- "}\n"
- "#remmina-small-button {\n"
- " -GtkWidget-focus-padding: 0;\n"
- " -GtkWidget-focus-line-width: 0;\n"
- " padding: 0;\n"
- " border: 0;\n"
- "}\n"
- "#remmina-pin-button {\n"
- " -GtkWidget-focus-padding: 0;\n"
- " -GtkWidget-focus-line-width: 0;\n"
- " padding: 2px;\n"
- " border: 0;\n"
- "}\n"
- "#remmina-scrolled-container {\n"
- " background-color: black;\n"
- "}\n"
- "#remmina-scrolled-container.undershoot {\n"
- " background: none\n"
- "}\n"
- "#ftbbox-upper {\n"
- " border-style: none solid solid solid;\n"
- " border-width: 1px;\n"
- " border-radius: 4px;\n"
- " border-color: #808080;\n"
- " padding: 0px;\n"
- " background-color: #f0f0f0;\n"
- "}\n"
- "#ftbbox-lower {\n"
- " border-style: solid solid none solid;\n"
- " border-width: 1px;\n"
- " border-radius: 4px;\n"
- " border-color: #808080;\n"
- " padding: 0px;\n"
- " background-color: #f0f0f0;\n"
- "}\n"
- "#ftb-handle {\n"
- " background-color: #f0f0f0;\n"
- "}\n"
-
- ,-1, NULL);
+ "GtkViewport, GtkAspectFrame {\n"
+ " padding:0;\n"
+ " border:0;\n"
+ " background-color: black;\n"
+ "}\n"
+ "GtkDrawingArea {\n"
+ " background-color: black;\n"
+ "}\n"
+ "GtkToolbar {\n"
+ " -GtkWidget-window-dragging: 0;\n"
+ "}\n"
+ "#remmina-connection-window-fullscreen {\n"
+ " background-color: black;\n"
+ "}\n"
+ "#remmina-small-button {\n"
+ " -GtkWidget-focus-padding: 0;\n"
+ " -GtkWidget-focus-line-width: 0;\n"
+ " padding: 0;\n"
+ " border: 0;\n"
+ "}\n"
+ "#remmina-pin-button {\n"
+ " -GtkWidget-focus-padding: 0;\n"
+ " -GtkWidget-focus-line-width: 0;\n"
+ " padding: 2px;\n"
+ " border: 0;\n"
+ "}\n"
+ "#remmina-scrolled-container {\n"
+ " background-color: black;\n"
+ "}\n"
+ "#remmina-scrolled-container.undershoot {\n"
+ " background: none\n"
+ "}\n"
+ "#ftbbox-upper {\n"
+ " border-style: none solid solid solid;\n"
+ " border-width: 1px;\n"
+ " border-radius: 4px;\n"
+ " border-color: #808080;\n"
+ " padding: 0px;\n"
+ " background-color: #f0f0f0;\n"
+ "}\n"
+ "#ftbbox-lower {\n"
+ " border-style: solid solid none solid;\n"
+ " border-width: 1px;\n"
+ " border-radius: 4px;\n"
+ " border-color: #808080;\n"
+ " padding: 0px;\n"
+ " background-color: #f0f0f0;\n"
+ "}\n"
+ "#ftb-handle {\n"
+ " background-color: #f0f0f0;\n"
+ "}\n"
+
+ ,-1, NULL);
gtk_style_context_add_provider_for_screen (gdk_screen_get_default(),
- GTK_STYLE_PROVIDER (provider),
- GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
+ GTK_STYLE_PROVIDER (provider),
+ GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
g_object_unref(provider);
/* Define a signal used to notify all remmina_connection_windows of toolbar move */
remmina_connection_window_signals[TOOLBARPLACE_SIGNAL] = g_signal_new("toolbar-place", G_TYPE_FROM_CLASS(klass),
- G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, G_STRUCT_OFFSET(RemminaConnectionWindowClass, toolbar_place), NULL, NULL,
- g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, G_STRUCT_OFFSET(RemminaConnectionWindowClass, toolbar_place), NULL, NULL,
+ g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
}
@@ -355,8 +360,8 @@ void remmina_connection_window_delete(RemminaConnectionWindow* cnnwin)
if (n > 1)
{
dialog = gtk_message_dialog_new(GTK_WINDOW(cnnwin), GTK_DIALOG_MODAL, GTK_MESSAGE_QUESTION,
- GTK_BUTTONS_YES_NO,
- _("There are %i active connections in the current window. Are you sure to close?"), n);
+ GTK_BUTTONS_YES_NO,
+ _("There are %i active connections in the current window. Are you sure to close?"), n);
i = gtk_dialog_run(GTK_DIALOG(dialog));
gtk_widget_destroy(dialog);
if (i != GTK_RESPONSE_YES)
@@ -439,7 +444,7 @@ gboolean remmina_connection_window_notify_widget_toolbar_placement(GtkWidget *wi
}
static gboolean remmina_connection_window_tb_drag_failed(GtkWidget *widget, GdkDragContext *context,
- GtkDragResult result, gpointer user_data)
+ GtkDragResult result, gpointer user_data)
{
TRACE_CALL("remmina_connection_window_tb_drag_failed");
RemminaConnectionHolder* cnnhld;
@@ -455,7 +460,7 @@ static gboolean remmina_connection_window_tb_drag_failed(GtkWidget *widget, GdkD
}
static gboolean remmina_connection_window_tb_drag_drop(GtkWidget *widget, GdkDragContext *context,
- gint x, gint y, guint time, gpointer user_data)
+ gint x, gint y, guint time, gpointer user_data)
{
TRACE_CALL("remmina_connection_window_tb_drag_drop");
GtkAllocation wa;
@@ -539,8 +544,8 @@ static void remmina_connection_holder_update_toolbar_opacity(RemminaConnectionHo
RemminaConnectionWindowPriv* priv = cnnhld->cnnwin->priv;
priv->floating_toolbar_opacity = (1.0 - TOOLBAR_OPACITY_MIN) / ((gdouble) TOOLBAR_OPACITY_LEVEL)
- * ((gdouble)(TOOLBAR_OPACITY_LEVEL - remmina_file_get_int(cnnobj->remmina_file, "toolbar_opacity", 0)))
- + TOOLBAR_OPACITY_MIN;
+ * ((gdouble)(TOOLBAR_OPACITY_LEVEL - remmina_file_get_int(cnnobj->remmina_file, "toolbar_opacity", 0)))
+ + TOOLBAR_OPACITY_MIN;
#if FLOATING_TOOLBAR_WIDGET
if (priv->floating_toolbar_widget)
{
@@ -598,10 +603,10 @@ static gboolean remmina_connection_holder_floating_toolbar_motion(RemminaConnect
{
#if GTK_CHECK_VERSION(3, 8, 0)
gtk_widget_set_opacity(GTK_WIDGET(priv->floating_toolbar_window),
- (gdouble)(y - t) / (gdouble)(-t) * priv->floating_toolbar_opacity);
+ (gdouble)(y - t) / (gdouble)(-t) * priv->floating_toolbar_opacity);
#else
gtk_window_set_opacity(GTK_WINDOW(priv->floating_toolbar_window),
- (gdouble)(y - t) / (gdouble)(-t) * priv->floating_toolbar_opacity);
+ (gdouble)(y - t) / (gdouble)(-t) * priv->floating_toolbar_opacity);
#endif
}
if ((priv->floating_toolbar_motion_show && y >= 0) || (!priv->floating_toolbar_motion_show && y <= t))
@@ -629,14 +634,14 @@ static void remmina_connection_holder_floating_toolbar_update(RemminaConnectionH
if (priv->floating_toolbar_motion_handler)
g_source_remove(priv->floating_toolbar_motion_handler);
priv->floating_toolbar_motion_handler = g_idle_add(
- (GSourceFunc) remmina_connection_holder_floating_toolbar_motion, cnnhld);
+ (GSourceFunc) remmina_connection_holder_floating_toolbar_motion, cnnhld);
}
else
{
if (priv->floating_toolbar_motion_handler == 0)
{
priv->floating_toolbar_motion_handler = g_timeout_add(MOTION_TIME,
- (GSourceFunc) remmina_connection_holder_floating_toolbar_motion, cnnhld);
+ (GSourceFunc) remmina_connection_holder_floating_toolbar_motion, cnnhld);
}
}
}
@@ -728,7 +733,7 @@ static void remmina_connection_object_set_scrolled_policy(RemminaConnectionObjec
gboolean scale;
scale = remmina_protocol_widget_get_scale(REMMINA_PROTOCOL_WIDGET(cnnobj->proto));
gtk_scrolled_window_set_policy(scrolled_window, scale ? GTK_POLICY_NEVER : GTK_POLICY_AUTOMATIC,
- scale ? GTK_POLICY_NEVER : GTK_POLICY_AUTOMATIC);
+ scale ? GTK_POLICY_NEVER : GTK_POLICY_AUTOMATIC);
}
static gboolean remmina_connection_holder_toolbar_autofit_restore(RemminaConnectionHolder* cnnhld)
@@ -746,15 +751,15 @@ static gboolean remmina_connection_holder_toolbar_autofit_restore(RemminaConnect
gtk_widget_get_allocation(cnnobj->scrolled_container, &ca);
gtk_widget_get_allocation(priv->toolbar, &ta);
if (remmina_pref.toolbar_placement == TOOLBAR_PLACEMENT_LEFT ||
- remmina_pref.toolbar_placement == TOOLBAR_PLACEMENT_RIGHT)
+ remmina_pref.toolbar_placement == TOOLBAR_PLACEMENT_RIGHT)
{
gtk_window_resize(GTK_WINDOW(cnnhld->cnnwin), MAX(1, dwidth + ta.width + nba.width - ca.width),
- MAX(1, dheight + nba.height - ca.height));
+ MAX(1, dheight + nba.height - ca.height));
}
else
{
gtk_window_resize(GTK_WINDOW(cnnhld->cnnwin), MAX(1, dwidth + nba.width - ca.width),
- MAX(1, dheight + ta.height + nba.height - ca.height));
+ MAX(1, dheight + ta.height + nba.height - ca.height));
}
gtk_container_check_resize(GTK_CONTAINER(cnnhld->cnnwin));
}
@@ -770,21 +775,21 @@ static void remmina_connection_holder_toolbar_autofit(GtkWidget* widget, Remmina
TRACE_CALL("remmina_connection_holder_toolbar_autofit");
DECLARE_CNNOBJ
- if (GTK_IS_SCROLLED_WINDOW(cnnobj->scrolled_container))
- {
- if ((gdk_window_get_state(gtk_widget_get_window(GTK_WIDGET(cnnhld->cnnwin))) & GDK_WINDOW_STATE_MAXIMIZED) != 0)
+ if (GTK_IS_SCROLLED_WINDOW(cnnobj->scrolled_container))
{
- gtk_window_unmaximize(GTK_WINDOW(cnnhld->cnnwin));
- }
+ if ((gdk_window_get_state(gtk_widget_get_window(GTK_WIDGET(cnnhld->cnnwin))) & GDK_WINDOW_STATE_MAXIMIZED) != 0)
+ {
+ gtk_window_unmaximize(GTK_WINDOW(cnnhld->cnnwin));
+ }
- /* It's tricky to make the toolbars disappear automatically, while keeping scrollable.
- Please tell me if you know a better way to do this */
- gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(cnnobj->scrolled_container), GTK_POLICY_NEVER,
- GTK_POLICY_NEVER);
+ /* It's tricky to make the toolbars disappear automatically, while keeping scrollable.
+ Please tell me if you know a better way to do this */
+ gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(cnnobj->scrolled_container), GTK_POLICY_NEVER,
+ GTK_POLICY_NEVER);
- /* ToDo: save returned source id in priv->something and then delete when main object is destroyed */
- g_timeout_add(200, (GSourceFunc) remmina_connection_holder_toolbar_autofit_restore, cnnhld);
- }
+ /* ToDo: save returned source id in priv->something and then delete when main object is destroyed */
+ g_timeout_add(200, (GSourceFunc) remmina_connection_holder_toolbar_autofit_restore, cnnhld);
+ }
}
@@ -813,60 +818,60 @@ static void remmina_connection_holder_check_resize(RemminaConnectionHolder* cnnh
screen_height = screen_size.height;
if (!remmina_protocol_widget_get_expand(REMMINA_PROTOCOL_WIDGET(cnnobj->proto))
- && (server_width <= 0 || server_height <= 0 || screen_width < server_width
- || screen_height < server_height))
+ && (server_width <= 0 || server_height <= 0 || screen_width < server_width
+ || screen_height < server_height))
{
scroll_required = TRUE;
}
switch (cnnhld->cnnwin->priv->view_mode)
{
- case SCROLLED_FULLSCREEN_MODE:
- gtk_window_resize(GTK_WINDOW(cnnhld->cnnwin), screen_width, screen_height);
- gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(cnnobj->scrolled_container),
- (scroll_required ? GTK_POLICY_AUTOMATIC : GTK_POLICY_NEVER),
- (scroll_required ? GTK_POLICY_AUTOMATIC : GTK_POLICY_NEVER));
- break;
-
- case VIEWPORT_FULLSCREEN_MODE:
- bordersz = scroll_required ? 1 : 0;
- gtk_window_resize (GTK_WINDOW(cnnhld->cnnwin), screen_width , screen_height);
- if (REMMINA_IS_SCROLLED_VIEWPORT(cnnobj->scrolled_container))
- {
- /* Put a border around Notebook content (RemminaScrolledViewpord), so we can
- * move the mouse over the border to scroll */
- gtk_container_set_border_width (GTK_CONTAINER (cnnobj->scrolled_container), bordersz);
- }
-
- break;
+ case SCROLLED_FULLSCREEN_MODE:
+ gtk_window_resize(GTK_WINDOW(cnnhld->cnnwin), screen_width, screen_height);
+ gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(cnnobj->scrolled_container),
+ (scroll_required ? GTK_POLICY_AUTOMATIC : GTK_POLICY_NEVER),
+ (scroll_required ? GTK_POLICY_AUTOMATIC : GTK_POLICY_NEVER));
+ break;
- case SCROLLED_WINDOW_MODE:
- if (remmina_file_get_int (cnnobj->remmina_file, "viewmode", AUTO_MODE) == AUTO_MODE)
- {
- gtk_window_set_default_size (GTK_WINDOW(cnnhld->cnnwin),
- MIN (server_width, screen_width), MIN (server_height, screen_height));
- if (server_width >= screen_width || server_height >= screen_height)
+ case VIEWPORT_FULLSCREEN_MODE:
+ bordersz = scroll_required ? 1 : 0;
+ gtk_window_resize (GTK_WINDOW(cnnhld->cnnwin), screen_width , screen_height);
+ if (REMMINA_IS_SCROLLED_VIEWPORT(cnnobj->scrolled_container))
{
- gtk_window_maximize (GTK_WINDOW(cnnhld->cnnwin));
- remmina_file_set_int (cnnobj->remmina_file, "window_maximize", TRUE);
+ /* Put a border around Notebook content (RemminaScrolledViewpord), so we can
+ * move the mouse over the border to scroll */
+ gtk_container_set_border_width (GTK_CONTAINER (cnnobj->scrolled_container), bordersz);
}
- else
+
+ break;
+
+ case SCROLLED_WINDOW_MODE:
+ if (remmina_file_get_int (cnnobj->remmina_file, "viewmode", AUTO_MODE) == AUTO_MODE)
{
- remmina_connection_holder_toolbar_autofit (NULL, cnnhld);
- remmina_file_set_int (cnnobj->remmina_file, "window_maximize", FALSE);
+ gtk_window_set_default_size (GTK_WINDOW(cnnhld->cnnwin),
+ MIN (server_width, screen_width), MIN (server_height, screen_height));
+ if (server_width >= screen_width || server_height >= screen_height)
+ {
+ gtk_window_maximize (GTK_WINDOW(cnnhld->cnnwin));
+ remmina_file_set_int (cnnobj->remmina_file, "window_maximize", TRUE);
+ }
+ else
+ {
+ remmina_connection_holder_toolbar_autofit (NULL, cnnhld);
+ remmina_file_set_int (cnnobj->remmina_file, "window_maximize", FALSE);
+ }
}
- }
- else
- {
- if (remmina_file_get_int (cnnobj->remmina_file, "window_maximize", FALSE))
+ else
{
- gtk_window_maximize (GTK_WINDOW(cnnhld->cnnwin));
+ if (remmina_file_get_int (cnnobj->remmina_file, "window_maximize", FALSE))
+ {
+ gtk_window_maximize (GTK_WINDOW(cnnhld->cnnwin));
+ }
}
- }
- break;
+ break;
- default:
- break;
+ default:
+ break;
}
}
@@ -881,7 +886,7 @@ static void remmina_connection_holder_set_tooltip(GtkWidget* item, const gchar*
if (key2)
{
s1 = g_strdup_printf(" (%s + %s,%s)", gdk_keyval_name(remmina_pref.hostkey),
- gdk_keyval_name(gdk_keyval_to_upper(key1)), gdk_keyval_name(gdk_keyval_to_upper(key2)));
+ gdk_keyval_name(gdk_keyval_to_upper(key1)), gdk_keyval_name(gdk_keyval_to_upper(key2)));
}
else if (key1 == remmina_pref.hostkey)
{
@@ -890,7 +895,7 @@ static void remmina_connection_holder_set_tooltip(GtkWidget* item, const gchar*
else
{
s1 = g_strdup_printf(" (%s + %s)", gdk_keyval_name(remmina_pref.hostkey),
- gdk_keyval_name(gdk_keyval_to_upper(key1)));
+ gdk_keyval_name(gdk_keyval_to_upper(key1)));
}
}
else
@@ -1068,7 +1073,7 @@ static void remmina_connection_holder_toolbar_fullscreen_option(GtkWidget* widge
g_signal_connect(G_OBJECT(menu), "deactivate", G_CALLBACK(remmina_connection_holder_fullscreen_option_popdown), cnnhld);
gtk_menu_popup(GTK_MENU(menu), NULL, NULL, remmina_public_popup_position, priv->toolitem_fullscreen, 0,
- gtk_get_current_event_time());
+ gtk_get_current_event_time());
}
@@ -1143,7 +1148,7 @@ static void remmina_connection_holder_toolbar_scaler_option(GtkWidget* widget, R
g_signal_connect(G_OBJECT(menu), "deactivate", G_CALLBACK(remmina_connection_holder_scaler_option_popdown), cnnhld);
gtk_menu_popup(GTK_MENU(menu), NULL, NULL, remmina_public_popup_position, priv->toolitem_fullscreen, 0,
- gtk_get_current_event_time());
+ gtk_get_current_event_time());
}
static void remmina_connection_holder_switch_page_activate(GtkMenuItem* menuitem, RemminaConnectionHolder* cnnhld)
@@ -1202,7 +1207,7 @@ static void remmina_connection_holder_toolbar_switch_page(GtkWidget* widget, Rem
g_object_set_data(G_OBJECT(menuitem), "new-page-num", GINT_TO_POINTER(i));
g_signal_connect(G_OBJECT(menuitem), "activate", G_CALLBACK(remmina_connection_holder_switch_page_activate),
- cnnhld);
+ cnnhld);
if (i == gtk_notebook_get_current_page(GTK_NOTEBOOK(priv->notebook)))
{
gtk_widget_set_sensitive(menuitem, FALSE);
@@ -1210,7 +1215,7 @@ static void remmina_connection_holder_toolbar_switch_page(GtkWidget* widget, Rem
}
g_signal_connect(G_OBJECT(menu), "deactivate", G_CALLBACK(remmina_connection_holder_toolbar_switch_page_popdown),
- cnnhld);
+ cnnhld);
gtk_menu_popup(GTK_MENU(menu), NULL, NULL, remmina_public_popup_position, widget, 0, gtk_get_current_event_time());
}
@@ -1252,7 +1257,7 @@ static void remmina_connection_holder_toolbar_scaled_mode(GtkWidget* widget, Rem
gtk_widget_set_sensitive(GTK_WIDGET(priv->scaler_option_button), scale);
remmina_protocol_widget_call_feature_by_type(REMMINA_PROTOCOL_WIDGET(cnnobj->proto),
- REMMINA_PROTOCOL_FEATURE_TYPE_SCALE, 0);
+ REMMINA_PROTOCOL_FEATURE_TYPE_SCALE, 0);
if (cnnhld->cnnwin->priv->view_mode != SCROLLED_WINDOW_MODE)
{
remmina_connection_holder_check_resize(cnnhld);
@@ -1334,7 +1339,7 @@ static void remmina_connection_holder_call_protocol_feature_activate(GtkMenuItem
}
static void remmina_connection_holder_toolbar_preferences_radio(RemminaConnectionHolder* cnnhld, RemminaFile* remminafile,
- GtkWidget* menu, const RemminaProtocolFeature* feature, const gchar* domain, gboolean enabled)
+ GtkWidget* menu, const RemminaProtocolFeature* feature, const gchar* domain, gboolean enabled)
{
TRACE_CALL("remmina_connection_holder_toolbar_preferences_radio");
GtkWidget* menuitem;
@@ -1364,7 +1369,7 @@ static void remmina_connection_holder_toolbar_preferences_radio(RemminaConnectio
}
g_signal_connect(G_OBJECT(menuitem), "toggled",
- G_CALLBACK(remmina_connection_holder_call_protocol_feature_radio), cnnhld);
+ G_CALLBACK(remmina_connection_holder_call_protocol_feature_radio), cnnhld);
}
else
{
@@ -1374,7 +1379,7 @@ static void remmina_connection_holder_toolbar_preferences_radio(RemminaConnectio
}
static void remmina_connection_holder_toolbar_preferences_check(RemminaConnectionHolder* cnnhld, RemminaFile* remminafile,
- GtkWidget* menu, const RemminaProtocolFeature* feature, const gchar* domain, gboolean enabled)
+ GtkWidget* menu, const RemminaProtocolFeature* feature, const gchar* domain, gboolean enabled)
{
TRACE_CALL("remmina_connection_holder_toolbar_preferences_check");
GtkWidget* menuitem;
@@ -1388,10 +1393,10 @@ static void remmina_connection_holder_toolbar_preferences_check(RemminaConnectio
g_object_set_data(G_OBJECT(menuitem), "feature-type", (gpointer) feature);
gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menuitem),
- remmina_file_get_int(remminafile, (const gchar*) feature->opt2, FALSE));
+ remmina_file_get_int(remminafile, (const gchar*) feature->opt2, FALSE));
g_signal_connect(G_OBJECT(menuitem), "toggled",
- G_CALLBACK(remmina_connection_holder_call_protocol_feature_check), cnnhld);
+ G_CALLBACK(remmina_connection_holder_call_protocol_feature_check), cnnhld);
}
else
{
@@ -1421,7 +1426,7 @@ static void remmina_connection_holder_toolbar_preferences(GtkWidget* widget, Rem
domain = remmina_protocol_widget_get_domain(REMMINA_PROTOCOL_WIDGET(cnnobj->proto));
menu = gtk_menu_new();
for (feature = remmina_protocol_widget_get_features(REMMINA_PROTOCOL_WIDGET(cnnobj->proto)); feature && feature->type;
- feature++)
+ feature++)
{
if (feature->type != REMMINA_PROTOCOL_FEATURE_TYPE_PREF)
continue;
@@ -1436,20 +1441,20 @@ static void remmina_connection_holder_toolbar_preferences(GtkWidget* widget, Rem
enabled = remmina_protocol_widget_query_feature_by_ref(REMMINA_PROTOCOL_WIDGET(cnnobj->proto), feature);
switch (GPOINTER_TO_INT(feature->opt1))
{
- case REMMINA_PROTOCOL_FEATURE_PREF_RADIO:
- remmina_connection_holder_toolbar_preferences_radio(cnnhld, cnnobj->remmina_file, menu, feature,
- domain, enabled);
- separator = TRUE;
- break;
- case REMMINA_PROTOCOL_FEATURE_PREF_CHECK:
- remmina_connection_holder_toolbar_preferences_check(cnnhld, cnnobj->remmina_file, menu, feature,
- domain, enabled);
- break;
+ case REMMINA_PROTOCOL_FEATURE_PREF_RADIO:
+ remmina_connection_holder_toolbar_preferences_radio(cnnhld, cnnobj->remmina_file, menu, feature,
+ domain, enabled);
+ separator = TRUE;
+ break;
+ case REMMINA_PROTOCOL_FEATURE_PREF_CHECK:
+ remmina_connection_holder_toolbar_preferences_check(cnnhld, cnnobj->remmina_file, menu, feature,
+ domain, enabled);
+ break;
}
}
g_signal_connect(G_OBJECT(menu), "deactivate", G_CALLBACK(remmina_connection_holder_toolbar_preferences_popdown),
- cnnhld);
+ cnnhld);
gtk_menu_popup(GTK_MENU(menu), NULL, NULL, remmina_public_popup_position, widget, 0, gtk_get_current_event_time());
}
@@ -1477,7 +1482,7 @@ static void remmina_connection_holder_toolbar_tools(GtkWidget* widget, RemminaCo
domain = remmina_protocol_widget_get_domain(REMMINA_PROTOCOL_WIDGET(cnnobj->proto));
menu = gtk_menu_new();
for (feature = remmina_protocol_widget_get_features(REMMINA_PROTOCOL_WIDGET(cnnobj->proto)); feature && feature->type;
- feature++)
+ feature++)
{
if (feature->type != REMMINA_PROTOCOL_FEATURE_TYPE_TOOL)
continue;
@@ -1499,7 +1504,7 @@ static void remmina_connection_holder_toolbar_tools(GtkWidget* widget, RemminaCo
g_object_set_data(G_OBJECT(menuitem), "feature-type", (gpointer) feature);
g_signal_connect(G_OBJECT(menuitem), "activate",
- G_CALLBACK(remmina_connection_holder_call_protocol_feature_activate), cnnhld);
+ G_CALLBACK(remmina_connection_holder_call_protocol_feature_activate), cnnhld);
}
else
{
@@ -1530,11 +1535,11 @@ static void remmina_connection_holder_toolbar_tools(GtkWidget* widget, RemminaCo
{
/* Add the keystroke if no description was available */
menuitem = gtk_menu_item_new_with_label(
- g_strdup(keystroke_values[strlen(keystroke_values[0]) ? 0 : 1]));
+ g_strdup(keystroke_values[strlen(keystroke_values[0]) ? 0 : 1]));
g_object_set_data(G_OBJECT(menuitem), "keystrokes", g_strdup(keystroke_values[1]));
g_signal_connect_swapped(G_OBJECT(menuitem), "activate",
- G_CALLBACK(remmina_protocol_widget_send_keystrokes),
- REMMINA_PROTOCOL_WIDGET(cnnobj->proto));
+ G_CALLBACK(remmina_protocol_widget_send_keystrokes),
+ REMMINA_PROTOCOL_WIDGET(cnnobj->proto));
gtk_widget_show(menuitem);
gtk_menu_shell_append(GTK_MENU_SHELL(submenu_keystrokes), menuitem);
}
@@ -1547,6 +1552,123 @@ static void remmina_connection_holder_toolbar_tools(GtkWidget* widget, RemminaCo
gtk_menu_popup(GTK_MENU(menu), NULL, NULL, remmina_public_popup_position, widget, 0, gtk_get_current_event_time());
}
+static void remmina_connection_holder_toolbar_screenshot(GtkWidget* widget, RemminaConnectionHolder* cnnhld)
+{
+ TRACE_CALL("remmina_connection_holder_toolbar_screenshot");
+
+ GdkPixbuf *screenshot;
+ GdkWindow *active_window;
+ cairo_t *cr;
+ gint width, height;
+ const gchar* remminafile;
+ gchar* pngname;
+ gchar* pngdate;
+ GtkWidget* dialog;
+ RemminaProtocolWidget *gp;
+ RemminaPluginScreenshotData rpsd;
+ cairo_surface_t *srcsurface;
+ cairo_format_t cairo_format;
+ cairo_surface_t *surface;
+ int stride;
+
+ GDateTime *date = g_date_time_new_now_utc ();
+
+ // We will take a screenshot of the currently displayed RemminaProtocolWidget.
+ // DECLARE_CNNOBJ already did part of the job for us.
+ DECLARE_CNNOBJ
+ gp = REMMINA_PROTOCOL_WIDGET(cnnobj->proto);
+
+ // Ask the plugin if it can give us a screenshot
+ if (remmina_protocol_widget_plugin_screenshot(gp, &rpsd)) {
+ // Good, we have a screenshot from the plugin !
+
+ remmina_log_printf("Screenshot from plugin: w=%d h=%d bpp=%d bytespp=%d\n",
+ rpsd.width, rpsd.height, rpsd.bitsPerPixel, rpsd.bytesPerPixel);
+
+ width = rpsd.width;
+ height = rpsd.height;
+
+ if (rpsd.bitsPerPixel == 32)
+ cairo_format = CAIRO_FORMAT_ARGB32;
+ else
+ cairo_format = CAIRO_FORMAT_RGB16_565;
+
+ stride = cairo_format_stride_for_width(cairo_format, width);
+
+ srcsurface = cairo_image_surface_create_for_data(rpsd.buffer, cairo_format, width, height, stride);
+
+ surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24, width, height);
+ cr = cairo_create(surface);
+ cairo_set_source_surface(cr, srcsurface, 0, 0);
+ cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
+ cairo_paint(cr);
+ cairo_surface_destroy(srcsurface);
+
+ free(rpsd.buffer);
+
+ } else {
+ // The plugin is not releasing us a screenshot, just try to catch one via GTK
+
+ /* Warn the user if image is distorted */
+ if (cnnobj->plugin_can_scale &&
+ remmina_protocol_widget_get_scale(gp)) {
+ dialog = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_WARNING, GTK_BUTTONS_OK,
+ _("Warning: screenshot is scaled or distorted. Disable scaling to have better screenshot."));
+ g_signal_connect(G_OBJECT(dialog), "response", G_CALLBACK(gtk_widget_destroy), NULL);
+ gtk_widget_show(dialog);
+ }
+
+ // Get the screenshot.
+ active_window = gtk_widget_get_window(GTK_WIDGET(gp));
+ // width = gdk_window_get_width(gtk_widget_get_window(GTK_WIDGET(cnnhld->cnnwin)));
+ width = gdk_window_get_width (active_window);
+ // height = gdk_window_get_height(gtk_widget_get_window(GTK_WIDGET(cnnhld->cnnwin)));
+ height = gdk_window_get_height (active_window);
+
+ screenshot = gdk_pixbuf_get_from_window (active_window, 0, 0, width, height);
+ if (screenshot == NULL)
+ g_print("gdk_pixbuf_get_from_window failed\n");
+
+ // Prepare the destination cairo surface.
+ surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24, width, height);
+ cr = cairo_create(surface);
+
+ // Copy the source pixbuf to the surface and paint it.
+ gdk_cairo_set_source_pixbuf(cr, screenshot, 0, 0);
+ cairo_paint(cr);
+
+ // Deallocate screenshot pixbuf
+ g_object_unref(screenshot);
+
+ }
+
+ remminafile = remmina_file_get_filename(cnnobj->remmina_file);
+ //imagedir = g_get_user_special_dir(G_USER_DIRECTORY_PICTURES);
+ /* TODO: Improve file name (DONE:8743571d) + give the user the option */
+ pngdate = g_strdup_printf("%d-%d-%d-%d:%d:%f",
+ g_date_time_get_year (date),
+ g_date_time_get_month (date),
+ g_date_time_get_day_of_month (date),
+ g_date_time_get_hour (date),
+ g_date_time_get_minute (date),
+ g_date_time_get_seconds (date));
+
+ g_date_time_unref (date);
+ pngname = g_strdup_printf("%s/%s-%s.png", remmina_pref.screenshot_path,
+ g_path_get_basename(remminafile), pngdate);
+
+ cairo_surface_write_to_png(surface, pngname);
+
+ /* send a desktop notification */
+ remmina_public_send_notification ("remmina-screenshot-is-ready-id", "Screenshot taken", pngname);
+
+ //Clean up and return.
+ cairo_destroy(cr);
+ cairo_surface_destroy(surface);
+
+
+}
+
static void remmina_connection_holder_toolbar_minimize(GtkWidget* widget, RemminaConnectionHolder* cnnhld)
{
TRACE_CALL("remmina_connection_holder_toolbar_minimize");
@@ -1566,11 +1688,11 @@ static void remmina_connection_holder_toolbar_grab(GtkWidget* widget, RemminaCon
DECLARE_CNNOBJ
remmina_file_set_int(cnnobj->remmina_file, "keyboard_grab",
- gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(widget)));
+ gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(widget)));
remmina_connection_holder_keyboard_grab(cnnhld);
}
-static GtkWidget*
+ static GtkWidget*
remmina_connection_holder_create_toolbar(RemminaConnectionHolder* cnnhld, gint mode)
{
TRACE_CALL("remmina_connection_holder_create_toolbar");
@@ -1593,7 +1715,7 @@ remmina_connection_holder_create_toolbar(RemminaConnectionHolder* cnnhld, gint m
toolitem = gtk_tool_button_new(NULL, NULL);
gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(toolitem), "remmina-fit-window");
remmina_connection_holder_set_tooltip(GTK_WIDGET(toolitem), _("Resize the window to fit in remote resolution"),
- remmina_pref.shortcutkey_autofit, 0);
+ remmina_pref.shortcutkey_autofit, 0);
g_signal_connect(G_OBJECT(toolitem), "clicked", G_CALLBACK(remmina_connection_holder_toolbar_autofit), cnnhld);
priv->toolitem_autofit = toolitem;
gtk_toolbar_insert(GTK_TOOLBAR(toolbar), toolitem, -1);
@@ -1603,7 +1725,7 @@ remmina_connection_holder_create_toolbar(RemminaConnectionHolder* cnnhld, gint m
toolitem = gtk_toggle_tool_button_new();
gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(toolitem), "remmina-fullscreen");
remmina_connection_holder_set_tooltip(GTK_WIDGET(toolitem), _("Toggle fullscreen mode"),
- remmina_pref.shortcutkey_fullscreen, 0);
+ remmina_pref.shortcutkey_fullscreen, 0);
gtk_toolbar_insert(GTK_TOOLBAR(toolbar), toolitem, -1);
gtk_widget_show(GTK_WIDGET(toolitem));
priv->toolitem_fullscreen = toolitem;
@@ -1643,7 +1765,7 @@ remmina_connection_holder_create_toolbar(RemminaConnectionHolder* cnnhld, gint m
toolitem = gtk_toggle_tool_button_new();
gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(toolitem), "remmina-switch-page");
remmina_connection_holder_set_tooltip(GTK_WIDGET(toolitem), _("Switch tab pages"), remmina_pref.shortcutkey_prevtab,
- remmina_pref.shortcutkey_nexttab);
+ remmina_pref.shortcutkey_nexttab);
gtk_toolbar_insert(GTK_TOOLBAR(toolbar), toolitem, -1);
gtk_widget_show(GTK_WIDGET(toolitem));
g_signal_connect(G_OBJECT(toolitem), "toggled", G_CALLBACK(remmina_connection_holder_toolbar_switch_page), cnnhld);
@@ -1690,7 +1812,7 @@ remmina_connection_holder_create_toolbar(RemminaConnectionHolder* cnnhld, gint m
toolitem = gtk_toggle_tool_button_new();
gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(toolitem), "input-keyboard");
remmina_connection_holder_set_tooltip(GTK_WIDGET(toolitem), _("Grab all keyboard events"),
- remmina_pref.shortcutkey_grab, 0);
+ remmina_pref.shortcutkey_grab, 0);
gtk_toolbar_insert(GTK_TOOLBAR(toolbar), toolitem, -1);
gtk_widget_show(GTK_WIDGET(toolitem));
g_signal_connect(G_OBJECT(toolitem), "toggled", G_CALLBACK(remmina_connection_holder_toolbar_grab), cnnhld);
@@ -1717,6 +1839,13 @@ remmina_connection_holder_create_toolbar(RemminaConnectionHolder* cnnhld, gint m
gtk_toolbar_insert(GTK_TOOLBAR(toolbar), toolitem, -1);
gtk_widget_show(GTK_WIDGET(toolitem));
+ toolitem = gtk_tool_button_new(NULL, "_Screenshot");
+ gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON (toolitem), "camera-photo");
+ remmina_connection_holder_set_tooltip(GTK_WIDGET(toolitem), _("Screenshot"), remmina_pref.shortcutkey_screenshot, 0);
+ gtk_toolbar_insert(GTK_TOOLBAR(toolbar), toolitem, -1);
+ gtk_widget_show(GTK_WIDGET(toolitem));
+ g_signal_connect(G_OBJECT(toolitem), "clicked", G_CALLBACK(remmina_connection_holder_toolbar_screenshot), cnnhld);
+
toolitem = gtk_tool_button_new(NULL, "_Bottom");
gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON (toolitem), "go-bottom");
remmina_connection_holder_set_tooltip(GTK_WIDGET(toolitem), _("Minimize window"), remmina_pref.shortcutkey_minimize, 0);
@@ -1775,7 +1904,7 @@ static void remmina_connection_holder_update_toolbar(RemminaConnectionHolder* cn
{
TRACE_CALL("remmina_connection_holder_update_toolbar");
DECLARE_CNNOBJ
- RemminaConnectionWindowPriv* priv = cnnhld->cnnwin->priv;
+ RemminaConnectionWindowPriv* priv = cnnhld->cnnwin->priv;
GtkToolItem* toolitem;
gboolean bval;
gboolean test_floating_toolbar;
@@ -1792,21 +1921,21 @@ static void remmina_connection_holder_update_toolbar(RemminaConnectionHolder* cn
gtk_widget_set_sensitive(GTK_WIDGET(priv->scaler_option_button), bval);
bval = remmina_protocol_widget_query_feature_by_type(REMMINA_PROTOCOL_WIDGET(cnnobj->proto),
- REMMINA_PROTOCOL_FEATURE_TYPE_SCALE);
+ REMMINA_PROTOCOL_FEATURE_TYPE_SCALE);
gtk_widget_set_sensitive(GTK_WIDGET(toolitem), bval);
toolitem = priv->toolitem_grab;
gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(toolitem),
- remmina_file_get_int(cnnobj->remmina_file, "keyboard_grab", FALSE));
+ remmina_file_get_int(cnnobj->remmina_file, "keyboard_grab", FALSE));
toolitem = priv->toolitem_preferences;
bval = remmina_protocol_widget_query_feature_by_type(REMMINA_PROTOCOL_WIDGET(cnnobj->proto),
- REMMINA_PROTOCOL_FEATURE_TYPE_PREF);
+ REMMINA_PROTOCOL_FEATURE_TYPE_PREF);
gtk_widget_set_sensitive(GTK_WIDGET(toolitem), bval);
toolitem = priv->toolitem_tools;
bval = remmina_protocol_widget_query_feature_by_type(REMMINA_PROTOCOL_WIDGET(cnnobj->proto),
- REMMINA_PROTOCOL_FEATURE_TYPE_TOOL);
+ REMMINA_PROTOCOL_FEATURE_TYPE_TOOL);
gtk_widget_set_sensitive(GTK_WIDGET(toolitem), bval);
gtk_window_set_title(GTK_WINDOW(cnnhld->cnnwin), remmina_file_get_string(cnnobj->remmina_file, "name"));
@@ -1819,7 +1948,7 @@ static void remmina_connection_holder_update_toolbar(RemminaConnectionHolder* cn
if (test_floating_toolbar)
{
gtk_label_set_text(GTK_LABEL(priv->floating_toolbar_label),
- remmina_file_get_string(cnnobj->remmina_file, "name"));
+ remmina_file_get_string(cnnobj->remmina_file, "name"));
}
}
@@ -1834,8 +1963,8 @@ static void remmina_connection_holder_showhide_toolbar(RemminaConnectionHolder*
if (priv->view_mode == SCROLLED_WINDOW_MODE)
{
if (resize
- && (gdk_window_get_state(gtk_widget_get_window(GTK_WIDGET(cnnhld->cnnwin)))
- & GDK_WINDOW_STATE_MAXIMIZED) == 0)
+ && (gdk_window_get_state(gtk_widget_get_window(GTK_WIDGET(cnnhld->cnnwin)))
+ & GDK_WINDOW_STATE_MAXIMIZED) == 0)
{
gtk_window_get_size(GTK_WINDOW(cnnhld->cnnwin), &width, &height);
@@ -1866,7 +1995,7 @@ static void remmina_connection_holder_showhide_toolbar(RemminaConnectionHolder*
}
static gboolean remmina_connection_holder_floating_toolbar_on_enter(GtkWidget* widget, GdkEventCrossing* event,
- RemminaConnectionHolder* cnnhld)
+ RemminaConnectionHolder* cnnhld)
{
TRACE_CALL("remmina_connection_holder_floating_toolbar_on_enter");
remmina_connection_holder_floating_toolbar_show(cnnhld, TRUE);
@@ -1874,7 +2003,7 @@ static gboolean remmina_connection_holder_floating_toolbar_on_enter(GtkWidget* w
}
static gboolean remmina_connection_object_enter_protocol_widget(GtkWidget* widget, GdkEventCrossing* event,
- RemminaConnectionObject* cnnobj)
+ RemminaConnectionObject* cnnobj)
{
TRACE_CALL("remmina_connection_object_enter_protocol_widget");
RemminaConnectionHolder* cnnhld = cnnobj->cnnhld;
@@ -1887,8 +2016,6 @@ static gboolean remmina_connection_object_enter_protocol_widget(GtkWidget* widge
return FALSE;
}
-
-
static gboolean remmina_connection_window_focus_in(GtkWidget* widget, GdkEventFocus* event, RemminaConnectionHolder* cnnhld)
{
TRACE_CALL("remmina_connection_window_focus_in");
@@ -1906,9 +2033,9 @@ static gboolean remmina_connection_window_focus_in(GtkWidget* widget, GdkEventFo
static gboolean remmina_connection_window_focus_out(GtkWidget* widget, GdkEventFocus* event, RemminaConnectionHolder* cnnhld)
{
TRACE_CALL("remmina_connection_window_focus_out");
- DECLARE_CNNOBJ_WITH_RETURN(FALSE)
+DECLARE_CNNOBJ_WITH_RETURN(FALSE)
#if !FLOATING_TOOLBAR_WIDGET
- RemminaConnectionWindowPriv* priv = cnnhld->cnnwin->priv;
+ RemminaConnectionWindowPriv* priv = cnnhld->cnnwin->priv;
#endif
cnnhld->hostkey_activated = FALSE;
@@ -1924,7 +2051,7 @@ static gboolean remmina_connection_window_focus_out(GtkWidget* widget, GdkEventF
remmina_scrolled_viewport_remove_motion(REMMINA_SCROLLED_VIEWPORT(cnnobj->scrolled_container));
}
remmina_protocol_widget_call_feature_by_type(REMMINA_PROTOCOL_WIDGET(cnnobj->proto),
- REMMINA_PROTOCOL_FEATURE_TYPE_UNFOCUS, 0);
+ REMMINA_PROTOCOL_FEATURE_TYPE_UNFOCUS, 0);
return FALSE;
}
@@ -1933,7 +2060,7 @@ static gboolean remmina_connection_window_on_enter(GtkWidget* widget, GdkEventCr
{
TRACE_CALL("remmina_connection_window_on_enter");
if (event->detail == GDK_NOTIFY_VIRTUAL || event->detail == GDK_NOTIFY_NONLINEAR
- || event->detail == GDK_NOTIFY_NONLINEAR_VIRTUAL)
+ || event->detail == GDK_NOTIFY_NONLINEAR_VIRTUAL)
{
remmina_connection_holder_keyboard_grab(cnnhld);
}
@@ -1949,7 +2076,7 @@ static gboolean remmina_connection_window_on_leave(GtkWidget* widget, GdkEventCr
GdkDevice *device = NULL;
if (event->detail == GDK_NOTIFY_VIRTUAL || event->detail == GDK_NOTIFY_NONLINEAR
- || event->detail == GDK_NOTIFY_NONLINEAR_VIRTUAL)
+ || event->detail == GDK_NOTIFY_NONLINEAR_VIRTUAL)
{
display = gtk_widget_get_display(widget);
manager = gdk_display_get_device_manager(display);
@@ -1967,7 +2094,7 @@ static gboolean remmina_connection_window_on_leave(GtkWidget* widget, GdkEventCr
}
static gboolean remmina_connection_holder_floating_toolbar_on_scroll(GtkWidget* widget, GdkEventScroll* event,
- RemminaConnectionHolder* cnnhld)
+ RemminaConnectionHolder* cnnhld)
{
TRACE_CALL("remmina_connection_holder_floating_toolbar_on_scroll");
DECLARE_CNNOBJ_WITH_RETURN(FALSE)
@@ -1976,46 +2103,46 @@ static gboolean remmina_connection_holder_floating_toolbar_on_scroll(GtkWidget*
opacity = remmina_file_get_int(cnnobj->remmina_file, "toolbar_opacity", 0);
switch (event->direction)
{
- case GDK_SCROLL_UP:
- if (opacity > 0)
- {
- remmina_file_set_int(cnnobj->remmina_file, "toolbar_opacity", opacity - 1);
- remmina_connection_holder_update_toolbar_opacity(cnnhld);
- return TRUE;
- }
- break;
- case GDK_SCROLL_DOWN:
- if (opacity < TOOLBAR_OPACITY_LEVEL)
- {
- remmina_file_set_int(cnnobj->remmina_file, "toolbar_opacity", opacity + 1);
- remmina_connection_holder_update_toolbar_opacity(cnnhld);
- return TRUE;
- }
- break;
+ case GDK_SCROLL_UP:
+ if (opacity > 0)
+ {
+ remmina_file_set_int(cnnobj->remmina_file, "toolbar_opacity", opacity - 1);
+ remmina_connection_holder_update_toolbar_opacity(cnnhld);
+ return TRUE;
+ }
+ break;
+ case GDK_SCROLL_DOWN:
+ if (opacity < TOOLBAR_OPACITY_LEVEL)
+ {
+ remmina_file_set_int(cnnobj->remmina_file, "toolbar_opacity", opacity + 1);
+ remmina_connection_holder_update_toolbar_opacity(cnnhld);
+ return TRUE;
+ }
+ break;
#ifdef GDK_SCROLL_SMOOTH
- case GDK_SCROLL_SMOOTH:
- if (event->delta_y < 0 && opacity > 0)
- {
- remmina_file_set_int(cnnobj->remmina_file, "toolbar_opacity", opacity - 1);
- remmina_connection_holder_update_toolbar_opacity(cnnhld);
- return TRUE;
- }
- if (event->delta_y > 0 && opacity < TOOLBAR_OPACITY_LEVEL)
- {
- remmina_file_set_int(cnnobj->remmina_file, "toolbar_opacity", opacity + 1);
- remmina_connection_holder_update_toolbar_opacity(cnnhld);
- return TRUE;
- }
- break;
+ case GDK_SCROLL_SMOOTH:
+ if (event->delta_y < 0 && opacity > 0)
+ {
+ remmina_file_set_int(cnnobj->remmina_file, "toolbar_opacity", opacity - 1);
+ remmina_connection_holder_update_toolbar_opacity(cnnhld);
+ return TRUE;
+ }
+ if (event->delta_y > 0 && opacity < TOOLBAR_OPACITY_LEVEL)
+ {
+ remmina_file_set_int(cnnobj->remmina_file, "toolbar_opacity", opacity + 1);
+ remmina_connection_holder_update_toolbar_opacity(cnnhld);
+ return TRUE;
+ }
+ break;
#endif
- default:
- break;
+ default:
+ break;
}
return FALSE;
}
static gboolean remmina_connection_window_on_configure(GtkWidget* widget, GdkEventConfigure* event,
- RemminaConnectionHolder* cnnhld)
+ RemminaConnectionHolder* cnnhld)
{
TRACE_CALL("remmina_connection_window_on_configure");
DECLARE_CNNOBJ_WITH_RETURN(FALSE)
@@ -2027,7 +2154,7 @@ static gboolean remmina_connection_window_on_configure(GtkWidget* widget, GdkEve
#endif
if (cnnhld->cnnwin && gtk_widget_get_window(GTK_WIDGET(cnnhld->cnnwin))
- && cnnhld->cnnwin->priv->view_mode == SCROLLED_WINDOW_MODE)
+ && cnnhld->cnnwin->priv->view_mode == SCROLLED_WINDOW_MODE)
{
/* Here we store the window state in real-time */
if ((gdk_window_get_state(gtk_widget_get_window(GTK_WIDGET(cnnhld->cnnwin))) & GDK_WINDOW_STATE_MAXIMIZED) == 0)
@@ -2069,12 +2196,12 @@ static void remmina_connection_holder_update_pin(RemminaConnectionHolder* cnnhld
if (cnnhld->cnnwin->priv->pin_down)
{
gtk_button_set_image(GTK_BUTTON(cnnhld->cnnwin->priv->pin_button),
- gtk_image_new_from_icon_name("remmina-pin-down", GTK_ICON_SIZE_MENU));
+ gtk_image_new_from_icon_name("remmina-pin-down", GTK_ICON_SIZE_MENU));
}
else
{
gtk_button_set_image(GTK_BUTTON(cnnhld->cnnwin->priv->pin_button),
- gtk_image_new_from_icon_name("remmina-pin-up", GTK_ICON_SIZE_MENU));
+ gtk_image_new_from_icon_name("remmina-pin-up", GTK_ICON_SIZE_MENU));
}
}
@@ -2243,10 +2370,10 @@ static gboolean remmina_connection_window_state_event(GtkWidget* widget, GdkEven
screen = gdk_screen_get_default();
if (remmina_pref.minimize_to_tray && (event->changed_mask & GDK_WINDOW_STATE_ICONIFIED) != 0
- && (event->new_window_state & GDK_WINDOW_STATE_ICONIFIED) != 0
- && remmina_public_get_current_workspace(screen)
- == remmina_public_get_window_workspace(GTK_WINDOW(widget))
- && gdk_screen_get_number(screen) == gdk_screen_get_number(gtk_widget_get_screen(widget)))
+ && (event->new_window_state & GDK_WINDOW_STATE_ICONIFIED) != 0
+ && remmina_public_get_current_workspace(screen)
+ == remmina_public_get_window_workspace(GTK_WINDOW(widget))
+ && gdk_screen_get_number(screen) == gdk_screen_get_number(gtk_widget_get_screen(widget)))
{
gtk_widget_hide(widget);
return TRUE;
@@ -2255,7 +2382,7 @@ static gboolean remmina_connection_window_state_event(GtkWidget* widget, GdkEven
return FALSE; // moved here because a function should return a value. Should be correct
}
-static GtkWidget*
+ static GtkWidget*
remmina_connection_window_new_from_holder(RemminaConnectionHolder* cnnhld)
{
TRACE_CALL("remmina_connection_window_new_from_holder");
@@ -2289,15 +2416,15 @@ static void remmina_connection_window_update_tag(RemminaConnectionWindow* cnnwin
switch (remmina_pref.tab_mode)
{
- case REMMINA_TAB_BY_GROUP:
- tag = g_strdup(remmina_file_get_string(cnnobj->remmina_file, "group"));
- break;
- case REMMINA_TAB_BY_PROTOCOL:
- tag = g_strdup(remmina_file_get_string(cnnobj->remmina_file, "protocol"));
- break;
- default:
- tag = NULL;
- break;
+ case REMMINA_TAB_BY_GROUP:
+ tag = g_strdup(remmina_file_get_string(cnnobj->remmina_file, "group"));
+ break;
+ case REMMINA_TAB_BY_PROTOCOL:
+ tag = g_strdup(remmina_file_get_string(cnnobj->remmina_file, "protocol"));
+ break;
+ default:
+ tag = NULL;
+ break;
}
g_object_set_data_full(G_OBJECT(cnnwin), "tag", tag, (GDestroyNotify) g_free);
}
@@ -2392,7 +2519,7 @@ static GtkWidget* remmina_connection_object_create_tab(RemminaConnectionObject*
}
static gint remmina_connection_object_append_page(RemminaConnectionObject* cnnobj, GtkNotebook* notebook, GtkWidget* tab,
- gint view_mode)
+ gint view_mode)
{
TRACE_CALL("remmina_connection_object_append_page");
gint i;
@@ -2407,7 +2534,7 @@ static gint remmina_connection_object_append_page(RemminaConnectionObject* cnnob
}
static void remmina_connection_window_initialize_notebook(GtkNotebook* to, GtkNotebook* from, RemminaConnectionObject* cnnobj,
- gint view_mode)
+ gint view_mode)
{
TRACE_CALL("remmina_connection_window_initialize_notebook");
gint i, n, c;
@@ -2440,14 +2567,14 @@ static void remmina_connection_window_initialize_notebook(GtkNotebook* to, GtkNo
remmina_connection_object_append_page(cnnobj, to, tab, view_mode);
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
- gtk_widget_reparent(cnnobj->viewport, cnnobj->scrolled_container);
+ gtk_widget_reparent(cnnobj->viewport, cnnobj->scrolled_container);
G_GNUC_END_IGNORE_DEPRECATIONS
- if (cnnobj->window)
- {
- gtk_widget_destroy(cnnobj->window);
- cnnobj->window = NULL;
- }
+ if (cnnobj->window)
+ {
+ gtk_widget_destroy(cnnobj->window);
+ cnnobj->window = NULL;
+ }
}
}
else
@@ -2467,7 +2594,7 @@ static void remmina_connection_window_initialize_notebook(GtkNotebook* to, GtkNo
/* Reparent cnnobj->viewport */
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
- gtk_widget_reparent(tc->viewport, tc->scrolled_container);
+ gtk_widget_reparent(tc->viewport, tc->scrolled_container);
G_GNUC_END_IGNORE_DEPRECATIONS
}
gtk_notebook_set_current_page(to, c);
@@ -2488,15 +2615,15 @@ static void remmina_connection_holder_update_notebook(RemminaConnectionHolder* c
switch (cnnhld->cnnwin->priv->view_mode)
{
- case SCROLLED_WINDOW_MODE:
- n = gtk_notebook_get_n_pages(notebook);
- gtk_notebook_set_show_tabs(notebook, remmina_pref.always_show_tab ? TRUE : n > 1);
- gtk_notebook_set_show_border(notebook, remmina_pref.always_show_tab ? TRUE : n > 1);
- break;
- default:
- gtk_notebook_set_show_tabs(notebook, FALSE);
- gtk_notebook_set_show_border(notebook, FALSE);
- break;
+ case SCROLLED_WINDOW_MODE:
+ n = gtk_notebook_get_n_pages(notebook);
+ gtk_notebook_set_show_tabs(notebook, remmina_pref.always_show_tab ? TRUE : n > 1);
+ gtk_notebook_set_show_border(notebook, remmina_pref.always_show_tab ? TRUE : n > 1);
+ break;
+ default:
+ gtk_notebook_set_show_tabs(notebook, FALSE);
+ gtk_notebook_set_show_border(notebook, FALSE);
+ break;
}
}
@@ -2520,7 +2647,7 @@ static gboolean remmina_connection_holder_on_switch_page_real(gpointer data)
}
static void remmina_connection_holder_on_switch_page(GtkNotebook* notebook, GtkWidget* page, guint page_num,
- RemminaConnectionHolder* cnnhld)
+ RemminaConnectionHolder* cnnhld)
{
TRACE_CALL("remmina_connection_holder_on_switch_page");
RemminaConnectionWindowPriv* priv = cnnhld->cnnwin->priv;
@@ -2532,14 +2659,14 @@ static void remmina_connection_holder_on_switch_page(GtkNotebook* notebook, GtkW
}
static void remmina_connection_holder_on_page_added(GtkNotebook* notebook, GtkWidget* child, guint page_num,
- RemminaConnectionHolder* cnnhld)
+ RemminaConnectionHolder* cnnhld)
{
if (gtk_notebook_get_n_pages(GTK_NOTEBOOK(cnnhld->cnnwin->priv->notebook)) > 0)
remmina_connection_holder_update_notebook(cnnhld);
}
static void remmina_connection_holder_on_page_removed(GtkNotebook* notebook, GtkWidget* child, guint page_num,
- RemminaConnectionHolder* cnnhld)
+ RemminaConnectionHolder* cnnhld)
{
TRACE_CALL("remmina_connection_holder_on_page_removed");
@@ -2554,7 +2681,7 @@ static void remmina_connection_holder_on_page_removed(GtkNotebook* notebook, Gtk
}
-GtkNotebook*
+ GtkNotebook*
remmina_connection_holder_on_notebook_create_window(GtkNotebook* notebook, GtkWidget* page, gint x, gint y, gpointer data)
{
/* This signal callback is called by GTK when a detachable tab is dropped on the root window */
@@ -2601,12 +2728,12 @@ remmina_connection_holder_on_notebook_create_window(GtkNotebook* notebook, GtkWi
}
remmina_protocol_widget_set_hostkey_func(REMMINA_PROTOCOL_WIDGET(cnnobj->proto),
- (RemminaHostkeyFunc) remmina_connection_window_hostkey_func, cnnobj->cnnhld);
+ (RemminaHostkeyFunc) remmina_connection_window_hostkey_func, cnnobj->cnnhld);
return GTK_NOTEBOOK(cnnobj->cnnhld->cnnwin->priv->notebook);
}
-static GtkWidget*
+ static GtkWidget*
remmina_connection_holder_create_notebook(RemminaConnectionHolder* cnnhld)
{
TRACE_CALL("remmina_connection_holder_create_notebook");
@@ -2618,7 +2745,7 @@ remmina_connection_holder_create_notebook(RemminaConnectionHolder* cnnhld)
gtk_widget_show(notebook);
g_signal_connect(G_OBJECT(notebook), "create-window", G_CALLBACK(remmina_connection_holder_on_notebook_create_window),
- cnnhld);
+ cnnhld);
g_signal_connect(G_OBJECT(notebook), "switch-page", G_CALLBACK(remmina_connection_holder_on_switch_page), cnnhld);
g_signal_connect(G_OBJECT(notebook), "page-added", G_CALLBACK(remmina_connection_holder_on_page_added), cnnhld);
g_signal_connect(G_OBJECT(notebook), "page-removed", G_CALLBACK(remmina_connection_holder_on_page_removed), cnnhld);
@@ -2691,13 +2818,13 @@ static void remmina_connection_holder_create_scrolled(RemminaConnectionHolder* c
/* Add drag capabilities to the toolbar */
gtk_drag_source_set(GTK_WIDGET(toolbar), GDK_BUTTON1_MASK,
- dnd_targets_tb, sizeof dnd_targets_tb / sizeof *dnd_targets_tb, GDK_ACTION_MOVE);
+ dnd_targets_tb, sizeof dnd_targets_tb / sizeof *dnd_targets_tb, GDK_ACTION_MOVE);
g_signal_connect_after(GTK_WIDGET(toolbar), "drag-begin", G_CALLBACK(remmina_connection_window_tb_drag_begin), cnnhld);
g_signal_connect(GTK_WIDGET(toolbar), "drag-failed", G_CALLBACK(remmina_connection_window_tb_drag_failed), cnnhld);
/* Add drop capabilities to the drop/dest target for the toolbar (the notebook) */
gtk_drag_dest_set(GTK_WIDGET(notebook), GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_HIGHLIGHT,
- dnd_targets_tb, sizeof dnd_targets_tb / sizeof *dnd_targets_tb, GDK_ACTION_MOVE);
+ dnd_targets_tb, sizeof dnd_targets_tb / sizeof *dnd_targets_tb, GDK_ACTION_MOVE);
gtk_drag_dest_set_track_motion(GTK_WIDGET(notebook), TRUE);
g_signal_connect(GTK_WIDGET(notebook), "drag-drop", G_CALLBACK(remmina_connection_window_tb_drag_drop), cnnhld);
@@ -2712,8 +2839,8 @@ static void remmina_connection_holder_create_scrolled(RemminaConnectionHolder* c
gtk_widget_show(GTK_WIDGET(cnnhld->cnnwin));
remmina_connection_window_initialize_notebook(GTK_NOTEBOOK(notebook),
- (oldwindow ? GTK_NOTEBOOK(REMMINA_CONNECTION_WINDOW(oldwindow)->priv->notebook) : NULL), cnnobj,
- SCROLLED_WINDOW_MODE);
+ (oldwindow ? GTK_NOTEBOOK(REMMINA_CONNECTION_WINDOW(oldwindow)->priv->notebook) : NULL), cnnobj,
+ SCROLLED_WINDOW_MODE);
if (cnnobj)
{
@@ -2840,13 +2967,13 @@ static void remmina_connection_holder_create_overlay_ftb_overlay(RemminaConnecti
/* Add drag and drop capabilities to the source */
gtk_drag_source_set(GTK_WIDGET(priv->overlay_ftb_overlay), GDK_BUTTON1_MASK,
- dnd_targets_ftb, sizeof dnd_targets_ftb / sizeof *dnd_targets_ftb, GDK_ACTION_MOVE);
+ dnd_targets_ftb, sizeof dnd_targets_ftb / sizeof *dnd_targets_ftb, GDK_ACTION_MOVE);
g_signal_connect_after(GTK_WIDGET(priv->overlay_ftb_overlay), "drag-begin", G_CALLBACK(remmina_connection_window_ftb_drag_begin), cnnhld);
}
static gboolean remmina_connection_window_ftb_drag_drop(GtkWidget *widget, GdkDragContext *context,
- gint x, gint y, guint time, gpointer user_data)
+ gint x, gint y, guint time, gpointer user_data)
{
TRACE_CALL("remmina_connection_window_ftb_drag_drop");
GtkAllocation wa;
@@ -2916,7 +3043,7 @@ static void remmina_connection_window_ftb_drag_begin(GtkWidget *widget, GdkDragC
#endif
static void remmina_connection_holder_create_fullscreen(RemminaConnectionHolder* cnnhld, RemminaConnectionObject* cnnobj,
- gint view_mode)
+ gint view_mode)
{
TRACE_CALL("remmina_connection_holder_create_fullscreen");
GtkWidget* window;
@@ -2953,8 +3080,8 @@ static void remmina_connection_holder_create_fullscreen(RemminaConnectionHolder*
cnnhld->fullscreen_view_mode = view_mode;
remmina_connection_window_initialize_notebook(GTK_NOTEBOOK(notebook),
- (oldwindow ? GTK_NOTEBOOK(REMMINA_CONNECTION_WINDOW(oldwindow)->priv->notebook) : NULL), cnnobj,
- view_mode);
+ (oldwindow ? GTK_NOTEBOOK(REMMINA_CONNECTION_WINDOW(oldwindow)->priv->notebook) : NULL), cnnobj,
+ view_mode);
if (cnnobj)
{
@@ -2972,7 +3099,7 @@ static void remmina_connection_holder_create_fullscreen(RemminaConnectionHolder*
remmina_connection_holder_create_overlay_ftb_overlay(cnnhld);
/* Add drag and drop capabilities to the drop/dest target for floating toolbar */
gtk_drag_dest_set(GTK_WIDGET(priv->overlay), GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_HIGHLIGHT,
- dnd_targets_ftb, sizeof dnd_targets_ftb / sizeof *dnd_targets_ftb, GDK_ACTION_MOVE);
+ dnd_targets_ftb, sizeof dnd_targets_ftb / sizeof *dnd_targets_ftb, GDK_ACTION_MOVE);
gtk_drag_dest_set_track_motion(GTK_WIDGET(priv->notebook), TRUE);
g_signal_connect(GTK_WIDGET(priv->overlay), "drag-drop", G_CALLBACK(remmina_connection_window_ftb_drag_drop), cnnhld);
#else
@@ -3001,7 +3128,7 @@ static void remmina_connection_holder_create_fullscreen(RemminaConnectionHolder*
}
static gboolean remmina_connection_window_hostkey_func(RemminaProtocolWidget* gp, guint keyval, gboolean release,
- RemminaConnectionHolder* cnnhld)
+ RemminaConnectionHolder* cnnhld)
{
TRACE_CALL("remmina_connection_window_hostkey_func");
DECLARE_CNNOBJ_WITH_RETURN(FALSE);
@@ -3049,19 +3176,19 @@ static gboolean remmina_connection_window_hostkey_func(RemminaProtocolWidget* gp
{
switch (priv->view_mode)
{
- case SCROLLED_WINDOW_MODE:
- remmina_connection_holder_create_fullscreen(
- cnnhld,
- NULL,
- cnnhld->fullscreen_view_mode ?
- cnnhld->fullscreen_view_mode : VIEWPORT_FULLSCREEN_MODE);
- break;
- case SCROLLED_FULLSCREEN_MODE:
- case VIEWPORT_FULLSCREEN_MODE:
- remmina_connection_holder_create_scrolled(cnnhld, NULL);
- break;
- default:
- break;
+ case SCROLLED_WINDOW_MODE:
+ remmina_connection_holder_create_fullscreen(
+ cnnhld,
+ NULL,
+ cnnhld->fullscreen_view_mode ?
+ cnnhld->fullscreen_view_mode : VIEWPORT_FULLSCREEN_MODE);
+ break;
+ case SCROLLED_FULLSCREEN_MODE:
+ case VIEWPORT_FULLSCREEN_MODE:
+ remmina_connection_holder_create_scrolled(cnnhld, NULL);
+ break;
+ default:
+ break;
}
}
else if (keyval == remmina_pref.shortcutkey_autofit)
@@ -3090,24 +3217,29 @@ static gboolean remmina_connection_window_hostkey_func(RemminaProtocolWidget* gp
if (gtk_widget_is_sensitive(GTK_WIDGET(priv->toolitem_scale)))
{
gtk_toggle_tool_button_set_active(
- GTK_TOGGLE_TOOL_BUTTON(priv->toolitem_scale),
- !gtk_toggle_tool_button_get_active(
- GTK_TOGGLE_TOOL_BUTTON(
- priv->toolitem_scale)));
+ GTK_TOGGLE_TOOL_BUTTON(priv->toolitem_scale),
+ !gtk_toggle_tool_button_get_active(
+ GTK_TOGGLE_TOOL_BUTTON(
+ priv->toolitem_scale)));
}
}
else if (keyval == remmina_pref.shortcutkey_grab)
{
gtk_toggle_tool_button_set_active(
- GTK_TOGGLE_TOOL_BUTTON(priv->toolitem_grab),
- !gtk_toggle_tool_button_get_active(
- GTK_TOGGLE_TOOL_BUTTON(
- priv->toolitem_grab)));
+ GTK_TOGGLE_TOOL_BUTTON(priv->toolitem_grab),
+ !gtk_toggle_tool_button_get_active(
+ GTK_TOGGLE_TOOL_BUTTON(
+ priv->toolitem_grab)));
}
else if (keyval == remmina_pref.shortcutkey_minimize)
{
remmina_connection_holder_toolbar_minimize(GTK_WIDGET(gp),
- cnnhld);
+ cnnhld);
+ }
+ else if (keyval == remmina_pref.shortcutkey_screenshot)
+ {
+ remmina_connection_holder_toolbar_screenshot(GTK_WIDGET(gp),
+ cnnhld);
}
else if (keyval == remmina_pref.shortcutkey_disconnect)
{
@@ -3118,30 +3250,30 @@ static gboolean remmina_connection_window_hostkey_func(RemminaProtocolWidget* gp
if (priv->view_mode == SCROLLED_WINDOW_MODE)
{
remmina_pref.hide_connection_toolbar =
- !remmina_pref.hide_connection_toolbar;
+ !remmina_pref.hide_connection_toolbar;
remmina_connection_holder_showhide_toolbar(
- cnnhld, TRUE);
+ cnnhld, TRUE);
}
}
else
{
for (feature =
- remmina_protocol_widget_get_features(
- REMMINA_PROTOCOL_WIDGET(
- cnnobj->proto));
- feature && feature->type;
- feature++)
+ remmina_protocol_widget_get_features(
+ REMMINA_PROTOCOL_WIDGET(
+ cnnobj->proto));
+ feature && feature->type;
+ feature++)
{
if (feature->type
- == REMMINA_PROTOCOL_FEATURE_TYPE_TOOL
- && GPOINTER_TO_UINT(
- feature->opt3)
- == keyval)
+ == REMMINA_PROTOCOL_FEATURE_TYPE_TOOL
+ && GPOINTER_TO_UINT(
+ feature->opt3)
+ == keyval)
{
remmina_protocol_widget_call_feature_by_ref(
- REMMINA_PROTOCOL_WIDGET(
- cnnobj->proto),
- feature);
+ REMMINA_PROTOCOL_WIDGET(
+ cnnobj->proto),
+ feature);
break;
}
}
@@ -3157,18 +3289,18 @@ static RemminaConnectionWindow* remmina_connection_window_find(RemminaFile* remm
switch (remmina_pref.tab_mode)
{
- case REMMINA_TAB_BY_GROUP:
- tag = remmina_file_get_string(remminafile, "group");
- break;
- case REMMINA_TAB_BY_PROTOCOL:
- tag = remmina_file_get_string(remminafile, "protocol");
- break;
- case REMMINA_TAB_ALL:
- tag = NULL;
- break;
- case REMMINA_TAB_NONE:
- default:
- return NULL;
+ case REMMINA_TAB_BY_GROUP:
+ tag = remmina_file_get_string(remminafile, "group");
+ break;
+ case REMMINA_TAB_BY_PROTOCOL:
+ tag = remmina_file_get_string(remminafile, "protocol");
+ break;
+ case REMMINA_TAB_ALL:
+ tag = NULL;
+ break;
+ case REMMINA_TAB_NONE:
+ default:
+ return NULL;
}
return REMMINA_CONNECTION_WINDOW(remmina_widget_pool_find(REMMINA_TYPE_CONNECTION_WINDOW, tag));
}
@@ -3205,13 +3337,13 @@ static void remmina_connection_object_on_connect(RemminaProtocolWidget* gp, Remm
cnnobj->connected = TRUE;
remmina_protocol_widget_set_hostkey_func(REMMINA_PROTOCOL_WIDGET(cnnobj->proto),
- (RemminaHostkeyFunc) remmina_connection_window_hostkey_func, cnnhld);
+ (RemminaHostkeyFunc) remmina_connection_window_hostkey_func, cnnhld);
/* Remember recent list for quick connect */
if (remmina_file_get_filename(cnnobj->remmina_file) == NULL)
{
remmina_pref_add_recent(remmina_file_get_string(cnnobj->remmina_file, "protocol"),
- remmina_file_get_string(cnnobj->remmina_file, "server"));
+ remmina_file_get_string(cnnobj->remmina_file, "server"));
}
/* Save credentials */
@@ -3222,26 +3354,26 @@ static void remmina_connection_object_on_connect(RemminaProtocolWidget* gp, Remm
i = remmina_file_get_int(cnnobj->remmina_file, "viewmode", 0);
switch (i)
{
- case SCROLLED_FULLSCREEN_MODE:
- case VIEWPORT_FULLSCREEN_MODE:
- remmina_connection_holder_create_fullscreen(cnnhld, cnnobj, i);
- break;
- case SCROLLED_WINDOW_MODE:
- default:
- remmina_connection_holder_create_scrolled(cnnhld, cnnobj);
- break;
+ case SCROLLED_FULLSCREEN_MODE:
+ case VIEWPORT_FULLSCREEN_MODE:
+ remmina_connection_holder_create_fullscreen(cnnhld, cnnobj, i);
+ break;
+ case SCROLLED_WINDOW_MODE:
+ default:
+ remmina_connection_holder_create_scrolled(cnnhld, cnnobj);
+ break;
}
}
else
{
tab = remmina_connection_object_create_tab(cnnobj);
i = remmina_connection_object_append_page(cnnobj, GTK_NOTEBOOK(cnnhld->cnnwin->priv->notebook), tab,
- cnnhld->cnnwin->priv->view_mode);
+ cnnhld->cnnwin->priv->view_mode);
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
- gtk_widget_reparent(cnnobj->viewport, cnnobj->scrolled_container);
+ gtk_widget_reparent(cnnobj->viewport, cnnobj->scrolled_container);
G_GNUC_END_IGNORE_DEPRECATIONS
- gtk_window_present(GTK_WINDOW(cnnhld->cnnwin));
+ gtk_window_present(GTK_WINDOW(cnnhld->cnnwin));
gtk_notebook_set_current_page(GTK_NOTEBOOK(cnnhld->cnnwin->priv->notebook), i);
}
@@ -3268,7 +3400,7 @@ static void remmina_connection_object_on_disconnect(RemminaProtocolWidget* gp, R
/* Detach the protocol widget from the notebook now, or we risk that a
* window delete will destroy cnnobj->proto before we complete disconnection.
- */
+ */
pparent = gtk_widget_get_parent(cnnobj->proto);
if (pparent != NULL)
{
@@ -3297,7 +3429,7 @@ static void remmina_connection_object_on_disconnect(RemminaProtocolWidget* gp, R
if (remmina_protocol_widget_has_error(gp))
{
dialog = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK,
- remmina_protocol_widget_get_error_message(gp), NULL);
+ remmina_protocol_widget_get_error_message(gp), NULL);
g_signal_connect(G_OBJECT(dialog), "response", G_CALLBACK(gtk_widget_destroy), NULL);
gtk_widget_show(dialog);
remmina_widget_pool_register(dialog);
@@ -3306,9 +3438,9 @@ static void remmina_connection_object_on_disconnect(RemminaProtocolWidget* gp, R
if (cnnhld && cnnhld->cnnwin && cnnobj->scrolled_container)
{
gtk_notebook_remove_page(
- GTK_NOTEBOOK(cnnhld->cnnwin->priv->notebook),
- gtk_notebook_page_num(GTK_NOTEBOOK(cnnhld->cnnwin->priv->notebook),
- cnnobj->scrolled_container));
+ GTK_NOTEBOOK(cnnhld->cnnwin->priv->notebook),
+ gtk_notebook_page_num(GTK_NOTEBOOK(cnnhld->cnnwin->priv->notebook),
+ cnnobj->scrolled_container));
}
cnnobj->remmina_file = NULL;
@@ -3345,7 +3477,7 @@ gboolean remmina_connection_window_open_from_filename(const gchar* filename)
else
{
dialog = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE,
- _("File %s not found."), filename);
+ _("File %s not found."), filename);
g_signal_connect(G_OBJECT(dialog), "response", G_CALLBACK(gtk_widget_destroy), NULL);
gtk_widget_show(dialog);
remmina_widget_pool_register(dialog);
@@ -3359,7 +3491,7 @@ void remmina_connection_window_open_from_file(RemminaFile* remminafile)
remmina_connection_window_open_from_file_full(remminafile, NULL, NULL, NULL);
}
-GtkWidget*
+ GtkWidget*
remmina_connection_window_open_from_file_full(RemminaFile* remminafile, GCallback disconnect_cb, gpointer data, guint* handler)
{
TRACE_CALL("remmina_connection_window_open_from_file_full");
@@ -3395,9 +3527,9 @@ remmina_connection_window_open_from_file_full(RemminaFile* remminafile, GCallbac
}
g_signal_connect(G_OBJECT(cnnobj->proto), "disconnect", G_CALLBACK(remmina_connection_object_on_disconnect), cnnobj);
g_signal_connect(G_OBJECT(cnnobj->proto), "desktop-resize", G_CALLBACK(remmina_connection_object_on_desktop_resize),
- cnnobj);
+ cnnobj);
g_signal_connect(G_OBJECT(cnnobj->proto), "update-align", G_CALLBACK(remmina_connection_object_on_update_align),
- cnnobj);
+ cnnobj);
/* Create the viewport to make the RemminaProtocolWidget scrollable */
cnnobj->viewport = gtk_viewport_new(NULL, NULL);
@@ -3408,8 +3540,8 @@ remmina_connection_window_open_from_file_full(RemminaFile* remminafile, GCallbac
/* Determine whether the plugin can scale or not. If the plugin can scale and we do
* not want to expand, then we add a GtkAspectFrame to maintain aspect ratio during scaling */
cnnobj->plugin_can_scale = remmina_plugin_manager_query_feature_by_type(REMMINA_PLUGIN_TYPE_PROTOCOL,
- remmina_file_get_string(remminafile, "protocol"),
- REMMINA_PROTOCOL_FEATURE_TYPE_SCALE);
+ remmina_file_get_string(remminafile, "protocol"),
+ REMMINA_PROTOCOL_FEATURE_TYPE_SCALE);
cnnobj->aspectframe = NULL;
gtk_container_add(GTK_CONTAINER(cnnobj->viewport), cnnobj->proto);
diff --git a/remmina/src/remmina_file_editor.c b/remmina/src/remmina_file_editor.c
index aefee7fb4..3d8f3bd5b 100644
--- a/remmina/src/remmina_file_editor.c
+++ b/remmina/src/remmina_file_editor.c
@@ -101,6 +101,7 @@ struct _RemminaFileEditorPriv
GtkWidget* save_button;
GtkWidget* config_box;
+ GtkWidget* config_scrollable;
GtkWidget* config_container;
GtkWidget* server_combo;
@@ -210,9 +211,18 @@ static void remmina_file_editor_create_notebook_container(RemminaFileEditor* gfe
TRACE_CALL("remmina_file_editor_create_notebook_container");
/* Create the notebook */
gfe->priv->config_container = gtk_notebook_new();
- gtk_container_add(GTK_CONTAINER(gfe->priv->config_box), gfe->priv->config_container);
- gtk_container_set_border_width(GTK_CONTAINER(gfe->priv->config_container), 4);
+
+ gfe->priv->config_scrollable = gtk_scrolled_window_new (NULL, NULL);
+ gtk_container_set_border_width (GTK_CONTAINER (gfe->priv->config_scrollable), 2);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (gfe->priv->config_scrollable),
+ GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
+ gtk_widget_show (gfe->priv->config_scrollable);
+
+ gtk_container_add (GTK_CONTAINER (gfe->priv->config_scrollable), gfe->priv->config_container);
+ gtk_container_set_border_width(GTK_CONTAINER(gfe->priv->config_container), 2);
gtk_widget_show(gfe->priv->config_container);
+
+ gtk_container_add(GTK_CONTAINER(gfe->priv->config_box), gfe->priv->config_scrollable);
}
static GtkWidget* remmina_file_editor_create_notebook_tab(RemminaFileEditor* gfe,
@@ -971,6 +981,8 @@ static void remmina_file_editor_protocol_combo_on_changed(GtkComboBox* combo, Re
{
gtk_widget_destroy(priv->config_container);
priv->config_container = NULL;
+ gtk_widget_destroy(priv->config_scrollable);
+ priv->config_scrollable = NULL;
}
priv->server_combo = NULL;
@@ -1235,7 +1247,7 @@ static void remmina_file_editor_init(RemminaFileEditor* gfe)
g_signal_connect(G_OBJECT(widget), "clicked", G_CALLBACK(remmina_file_editor_on_connect), gfe);
gtk_dialog_set_default_response(GTK_DIALOG(gfe), GTK_RESPONSE_OK);
- gtk_window_set_default_size(GTK_WINDOW(gfe), 450, 500);
+ gtk_window_set_default_size(GTK_WINDOW(gfe), 800, 600);
g_signal_connect(G_OBJECT(gfe), "destroy", G_CALLBACK(remmina_file_editor_destroy), NULL);
g_signal_connect(G_OBJECT(gfe), "realize", G_CALLBACK(remmina_file_editor_on_realize), NULL);
@@ -1441,6 +1453,7 @@ GtkWidget* remmina_file_editor_new_from_file(RemminaFile* remminafile)
priv->config_box = widget;
priv->config_container = NULL;
+ priv->config_scrollable = NULL;
remmina_file_editor_protocol_combo_on_changed(GTK_COMBO_BOX(priv->protocol_combo), gfe);
diff --git a/remmina/src/remmina_pref.c b/remmina/src/remmina_pref.c
index ef2a9372c..df0c7f4ea 100644
--- a/remmina/src/remmina_pref.c
+++ b/remmina/src/remmina_pref.c
@@ -391,6 +391,12 @@ void remmina_pref_init(void)
else
remmina_pref.ssh_loglevel = DEFAULT_SSH_LOGLEVEL;
+ if (g_key_file_has_key(gkeyfile, "remmina_pref", "screenshot_path", NULL)) {
+ remmina_pref.screenshot_path = g_key_file_get_string(gkeyfile, "remmina_pref", "screenshot_path", NULL);
+ }else{
+ remmina_pref.screenshot_path = g_strdup("");
+ }
+
if (g_key_file_has_key(gkeyfile, "remmina_pref", "ssh_parseconfig", NULL))
remmina_pref.ssh_parseconfig = g_key_file_get_boolean(gkeyfile, "remmina_pref", "ssh_parseconfig", NULL);
else
@@ -504,11 +510,15 @@ void remmina_pref_init(void)
remmina_pref.shortcutkey_grab = GDK_KEY_Control_R;
if (g_key_file_has_key(gkeyfile, "remmina_pref", "shortcutkey_minimize", NULL))
- remmina_pref.shortcutkey_minimize = g_key_file_get_integer(gkeyfile, "remmina_pref", "shortcutkey_minimize",
- NULL);
+ remmina_pref.shortcutkey_minimize = g_key_file_get_integer(gkeyfile, "remmina_pref", "shortcutkey_minimize", NULL);
else
remmina_pref.shortcutkey_minimize = GDK_KEY_F9;
+ if (g_key_file_has_key(gkeyfile, "remmina_pref", "shortcutkey_screenshot", NULL))
+ remmina_pref.shortcutkey_screenshot = g_key_file_get_integer(gkeyfile, "remmina_pref", "shortcutkey_screenshot", NULL);
+ else
+ remmina_pref.shortcutkey_screenshot = GDK_KEY_F12;
+
if (g_key_file_has_key(gkeyfile, "remmina_pref", "shortcutkey_disconnect", NULL))
remmina_pref.shortcutkey_disconnect = g_key_file_get_integer(gkeyfile, "remmina_pref", "shortcutkey_disconnect",
NULL);
@@ -615,6 +625,7 @@ void remmina_pref_save(void)
g_key_file_set_integer(gkeyfile, "remmina_pref", "default_action", remmina_pref.default_action);
g_key_file_set_integer(gkeyfile, "remmina_pref", "scale_quality", remmina_pref.scale_quality);
g_key_file_set_integer(gkeyfile, "remmina_pref", "ssh_loglevel", remmina_pref.ssh_loglevel);
+ g_key_file_set_string(gkeyfile, "remmina_pref", "screenshot_path", remmina_pref.screenshot_path);
g_key_file_set_boolean(gkeyfile, "remmina_pref", "ssh_parseconfig", remmina_pref.ssh_parseconfig);
g_key_file_set_boolean(gkeyfile, "remmina_pref", "hide_toolbar", remmina_pref.hide_toolbar);
g_key_file_set_boolean(gkeyfile, "remmina_pref", "hide_statusbar", remmina_pref.hide_statusbar);
@@ -649,6 +660,7 @@ void 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_screenshot", remmina_pref.shortcutkey_screenshot);
g_key_file_set_integer(gkeyfile, "remmina_pref", "shortcutkey_minimize", remmina_pref.shortcutkey_minimize);
g_key_file_set_integer(gkeyfile, "remmina_pref", "shortcutkey_disconnect", remmina_pref.shortcutkey_disconnect);
g_key_file_set_integer(gkeyfile, "remmina_pref", "shortcutkey_toolbar", remmina_pref.shortcutkey_toolbar);
diff --git a/remmina/src/remmina_pref.h b/remmina/src/remmina_pref.h
index 8e6f97d2d..bbaef281b 100644
--- a/remmina/src/remmina_pref.h
+++ b/remmina/src/remmina_pref.h
@@ -93,9 +93,7 @@ typedef struct _RemminaPref
gboolean survey;
gint default_action;
gint scale_quality;
- gint ssh_loglevel;
- gboolean ssh_parseconfig;
- gint sshtunnel_port;
+ gchar *screenshot_path;
gint auto_scroll_step;
gint recent_maximum;
gchar *resolutions;
@@ -112,6 +110,10 @@ typedef struct _RemminaPref
gboolean applet_new_ontop;
gboolean applet_hide_count;
gboolean disable_tray_icon;
+ /* In RemminaPrefDialog SSH Option tab */
+ gint ssh_loglevel;
+ gboolean ssh_parseconfig;
+ gint sshtunnel_port;
/* In RemminaPrefDialog keyboard tab */
guint hostkey;
guint shortcutkey_fullscreen;
@@ -120,6 +122,7 @@ typedef struct _RemminaPref
guint shortcutkey_nexttab;
guint shortcutkey_scale;
guint shortcutkey_grab;
+ guint shortcutkey_screenshot;
guint shortcutkey_minimize;
guint shortcutkey_disconnect;
guint shortcutkey_toolbar;
diff --git a/remmina/src/remmina_pref_dialog.c b/remmina/src/remmina_pref_dialog.c
index fd43f1c56..3215208f9 100644
--- a/remmina/src/remmina_pref_dialog.c
+++ b/remmina/src/remmina_pref_dialog.c
@@ -136,9 +136,9 @@ void remmina_pref_on_dialog_destroy(GtkWidget *widget, gpointer user_data)
remmina_pref.show_buttons_icons = gtk_combo_box_get_active(remmina_pref_dialog->comboboxtext_appearance_show_buttons_icons);
remmina_pref.show_menu_icons = gtk_combo_box_get_active(remmina_pref_dialog->comboboxtext_appearance_show_menu_icons);
remmina_pref.scale_quality = gtk_combo_box_get_active(remmina_pref_dialog->comboboxtext_options_scale_quality);
+ remmina_pref.screenshot_path = gtk_file_chooser_get_filename(remmina_pref_dialog->filechooserbutton_options_screenshots_path);
remmina_pref.ssh_loglevel = gtk_combo_box_get_active(remmina_pref_dialog->comboboxtext_options_ssh_loglevel);
remmina_pref.ssh_parseconfig = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(remmina_pref_dialog->checkbutton_options_ssh_parseconfig));
-
remmina_pref.sshtunnel_port = atoi(gtk_entry_get_text(remmina_pref_dialog->entry_options_ssh_port));
if (remmina_pref.sshtunnel_port <= 0)
remmina_pref.sshtunnel_port = DEFAULT_SSHTUNNEL_PORT;
@@ -178,6 +178,7 @@ void remmina_pref_on_dialog_destroy(GtkWidget *widget, gpointer user_data)
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_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_minimize = remmina_key_chooser_get_keyval(gtk_button_get_label(remmina_pref_dialog->button_keyboard_minimize));
remmina_pref.shortcutkey_disconnect = remmina_key_chooser_get_keyval(gtk_button_get_label(remmina_pref_dialog->button_keyboard_disconnect));
remmina_pref.shortcutkey_toolbar = remmina_key_chooser_get_keyval(gtk_button_get_label(remmina_pref_dialog->button_keyboard_toolbar));
@@ -307,6 +308,7 @@ static void remmina_pref_dialog_init(void)
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_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_minimize, remmina_pref.shortcutkey_minimize);
remmina_pref_dialog_set_button_label(remmina_pref_dialog->button_keyboard_disconnect, remmina_pref.shortcutkey_disconnect);
remmina_pref_dialog_set_button_label(remmina_pref_dialog->button_keyboard_toolbar, remmina_pref.shortcutkey_toolbar);
@@ -355,6 +357,11 @@ static void remmina_pref_dialog_init(void)
gtk_combo_box_set_active(remmina_pref_dialog->comboboxtext_appearance_show_menu_icons, remmina_pref.show_menu_icons);
gtk_combo_box_set_active(remmina_pref_dialog->comboboxtext_options_scale_quality, remmina_pref.scale_quality);
gtk_combo_box_set_active(remmina_pref_dialog->comboboxtext_options_ssh_loglevel, remmina_pref.ssh_loglevel);
+ if (remmina_pref.screenshot_path != NULL){
+ gtk_file_chooser_set_filename(remmina_pref_dialog->filechooserbutton_options_screenshots_path, remmina_pref.screenshot_path);
+ }else{
+ gtk_file_chooser_set_filename(remmina_pref_dialog->filechooserbutton_options_screenshots_path, g_get_home_dir());
+ }
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(remmina_pref_dialog->checkbutton_options_ssh_parseconfig), remmina_pref.ssh_parseconfig);
remmina_pref_dialog_set_button_label(remmina_pref_dialog->button_keyboard_copy, remmina_pref.vte_shortcutkey_copy);
@@ -394,6 +401,7 @@ GtkDialog* remmina_pref_dialog_new(gint default_tab, GtkWindow *parent)
remmina_pref_dialog->comboboxtext_options_scale_quality = GTK_COMBO_BOX(GET_OBJECT("comboboxtext_options_scale_quality"));
remmina_pref_dialog->checkbutton_options_ssh_parseconfig = GTK_CHECK_BUTTON(GET_OBJECT("checkbutton_options_ssh_parseconfig"));
remmina_pref_dialog->comboboxtext_options_ssh_loglevel = GTK_COMBO_BOX(GET_OBJECT("comboboxtext_options_ssh_loglevel"));
+ remmina_pref_dialog->filechooserbutton_options_screenshots_path = GTK_FILE_CHOOSER(GET_OBJECT("filechooserbutton_options_screenshots_path"));
remmina_pref_dialog->entry_options_ssh_port = GTK_ENTRY(GET_OBJECT("entry_options_ssh_port"));
remmina_pref_dialog->entry_options_scroll = GTK_ENTRY(GET_OBJECT("entry_options_scroll"));
remmina_pref_dialog->entry_options_recent_items = GTK_ENTRY(GET_OBJECT("entry_options_recent_items"));
@@ -411,6 +419,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_screenshot = GTK_BUTTON(GET_OBJECT("button_keyboard_screenshot"));
remmina_pref_dialog->button_keyboard_minimize = GTK_BUTTON(GET_OBJECT("button_keyboard_minimize"));
remmina_pref_dialog->button_keyboard_disconnect = GTK_BUTTON(GET_OBJECT("button_keyboard_disconnect"));
remmina_pref_dialog->button_keyboard_toolbar = GTK_BUTTON(GET_OBJECT("button_keyboard_toolbar"));
diff --git a/remmina/src/remmina_pref_dialog.h b/remmina/src/remmina_pref_dialog.h
index 3fd3c3629..cc00ecbe4 100644
--- a/remmina/src/remmina_pref_dialog.h
+++ b/remmina/src/remmina_pref_dialog.h
@@ -63,6 +63,7 @@ typedef struct _RemminaPrefDialog
GtkComboBox *comboboxtext_appearance_show_menu_icons;
GtkComboBox *comboboxtext_options_scale_quality;
GtkComboBox *comboboxtext_options_ssh_loglevel;
+ GtkFileChooser *filechooserbutton_options_screenshots_path;
GtkCheckButton *checkbutton_options_ssh_parseconfig;
GtkEntry *entry_options_ssh_port;
GtkEntry *entry_options_scroll;
@@ -82,6 +83,7 @@ typedef struct _RemminaPrefDialog
GtkButton *button_keyboard_switch_tab_right;
GtkButton *button_keyboard_scaled;
GtkButton *button_keyboard_grab_keyboard;
+ GtkButton *button_keyboard_screenshot;
GtkButton *button_keyboard_minimize;
GtkButton *button_keyboard_disconnect;
GtkButton *button_keyboard_toolbar;
diff --git a/remmina/src/remmina_protocol_widget.c b/remmina/src/remmina_protocol_widget.c
index 32586b792..6c9d9544a 100644
--- a/remmina/src/remmina_protocol_widget.c
+++ b/remmina/src/remmina_protocol_widget.c
@@ -51,6 +51,7 @@
#include "remmina_protocol_widget.h"
#include "remmina_public.h"
#include "remmina_ssh.h"
+#include "remmina_log.h"
#include "remmina/remmina_trace_calls.h"
struct _RemminaProtocolWidgetPriv
@@ -437,6 +438,17 @@ void remmina_protocol_widget_send_keystrokes(RemminaProtocolWidget* gp, GtkMenuI
return;
}
+gboolean remmina_protocol_widget_plugin_screenshot(RemminaProtocolWidget* gp, RemminaPluginScreenshotData *rpsd)
+{
+ if (!gp->priv->plugin->get_plugin_screenshot) {
+ remmina_log_printf("plugin screenshot function is not implemented\n");
+ return FALSE;
+ }
+
+ return gp->priv->plugin->get_plugin_screenshot(gp, rpsd);
+
+}
+
void remmina_protocol_widget_emit_signal(RemminaProtocolWidget* gp, const gchar* signal_name)
{
diff --git a/remmina/src/remmina_protocol_widget.h b/remmina/src/remmina_protocol_widget.h
index 2b4213626..8519af483 100644
--- a/remmina/src/remmina_protocol_widget.h
+++ b/remmina/src/remmina_protocol_widget.h
@@ -148,6 +148,8 @@ void remmina_protocol_widget_send_keys_signals(GtkWidget *widget, const guint *k
gboolean remmina_protocol_widget_plugin_receives_keystrokes(RemminaProtocolWidget* gp);
/* Send to the plugin some keystrokes */
void remmina_protocol_widget_send_keystrokes(RemminaProtocolWidget* gp, GtkMenuItem *widget);
+/* Take screenshot of plugin */
+gboolean remmina_protocol_widget_plugin_screenshot(RemminaProtocolWidget* gp, RemminaPluginScreenshotData *rpsd);
G_END_DECLS
diff --git a/remmina/src/remmina_public.c b/remmina/src/remmina_public.c
index ace2f9512..d41f8250a 100644
--- a/remmina/src/remmina_public.c
+++ b/remmina/src/remmina_public.c
@@ -621,28 +621,6 @@ void remmina_public_gtk_widget_reparent(GtkWidget *widget, GtkContainer *contain
g_object_unref(widget);
}
-/* Replaces all occurences of search in a new copy of string by replacement. */
-gchar* remmina_public_str_replace(const gchar *string, const gchar *search, const gchar *replacement)
-{
- TRACE_CALL("remmina_public_str_replace")
- gchar *str, **arr;
-
- g_return_val_if_fail (string != NULL, NULL);
- g_return_val_if_fail (search != NULL, NULL);
-
- if (replacement == NULL)
- replacement = "";
-
- arr = g_strsplit (string, search, -1);
- if (arr != NULL && arr[0] != NULL)
- str = g_strjoinv (replacement, arr);
- else
- str = g_strdup (string);
-
- g_strfreev (arr);
- return str;
-}
-
/* Validate the inserted value for a new resolution */
gboolean remmina_public_resolution_validation_func(const gchar *new_str, gchar **error)
{
@@ -691,6 +669,40 @@ gboolean remmina_public_resolution_validation_func(const gchar *new_str, gchar *
return result;
}
+/* Used to send desktop notifications */
+void remmina_public_send_notification (const gchar *notification_id,
+ const gchar *notification_title, const gchar *notification_message)
+{
+ TRACE_CALL("remmina_public_send_notification");
+
+ GNotification *notification = g_notification_new (notification_title);
+ g_notification_set_body (notification, notification_message);
+ g_application_send_notification (g_application_get_default (), notification_id, notification);
+ g_object_unref (notification);
+}
+
+/* Replaces all occurences of search in a new copy of string by replacement. */
+gchar* remmina_public_str_replace(const gchar *string, const gchar *search, const gchar *replacement)
+{
+ TRACE_CALL("remmina_public_str_replace")
+ gchar *str, **arr;
+
+ g_return_val_if_fail (string != NULL, NULL);
+ g_return_val_if_fail (search != NULL, NULL);
+
+ if (replacement == NULL)
+ replacement = "";
+
+ arr = g_strsplit (string, search, -1);
+ if (arr != NULL && arr[0] != NULL)
+ str = g_strjoinv (replacement, arr);
+ else
+ str = g_strdup (string);
+
+ g_strfreev (arr);
+ return str;
+}
+
/* Replaces all occurences of search in a new copy of string by replacement
* and overwrites the original string */
gchar* remmina_public_str_replace_in_place(gchar *string, const gchar *search, const gchar *replacement)
@@ -701,3 +713,4 @@ gchar* remmina_public_str_replace_in_place(gchar *string, const gchar *search, c
string = g_strdup(new_string);
return string;
}
+
diff --git a/remmina/src/remmina_public.h b/remmina/src/remmina_public.h
index eca102c8b..204d83d13 100644
--- a/remmina/src/remmina_public.h
+++ b/remmina/src/remmina_public.h
@@ -103,10 +103,13 @@ gboolean remmina_public_get_modifier_for_keycode(GdkKeymap *keymap, guint16 keyc
GtkBuilder* remmina_public_gtk_builder_new_from_file(gchar *filename);
/* Change parent container for a widget */
void remmina_public_gtk_widget_reparent(GtkWidget *widget, GtkContainer *container);
-/* Replaces all occurences of search in a new copy of string by replacement. */
-gchar* remmina_public_str_replace(const gchar *string, const gchar *search, const gchar *replacement);
+/* Used to send desktop notifications */
+void remmina_public_send_notification (const gchar *notification_id,
+ const gchar *notification_title, const gchar *notification_message);
/* Validate the inserted value for a new resolution */
gboolean remmina_public_resolution_validation_func(const gchar *new_str, gchar **error);
+/* Replaces all occurences of search in a new copy of string by replacement. */
+gchar* remmina_public_str_replace(const gchar *string, const gchar *search, const gchar *replacement);
/* Replaces all occurences of search in a new copy of string by replacement
* and overwrites the original string */
gchar* remmina_public_str_replace_in_place(gchar *string, const gchar *search, const gchar *replacement);
diff --git a/remmina/ui/remmina_about.glade b/remmina/ui/remmina_about.glade
index 3e3088218..dc47a5f12 100644
--- a/remmina/ui/remmina_about.glade
+++ b/remmina/ui/remmina_about.glade
@@ -29,6 +29,7 @@ Benjamin Podszun &lt;benjamin.podszun@gmail.com&gt;
Ben Kohler &lt;bkohler@gmail.com&gt;
Christopher Rawlings &lt;chris.rawlings+git@gmail.com&gt;
Daniel M. Weeks &lt;dan@danweeks.net&gt;
+Daniele Tieghi &lt;notdisclosed&gt;
Dmitry Kubatkin &lt;maelnor@gmail.com&gt;
dupondje &lt;jean-louis@dupondje.be&gt;
Emmanuel Grognet &lt;emmanuel@grognet.fr&gt;
@@ -46,6 +47,7 @@ Kirill MĂ¼ller &lt;krlmlr@users.noreply.github.com&gt;
Kyle Sanderson &lt;kyle.leet@gmail.com&gt;
Luca Falavigna &lt;dktrkranz@debian.org&gt;
Marc-André Moreau &lt;marcandre.moreau@gmail.com&gt;
+Michele Sartori &lt;mik.thrasher@aol.com&gt;
Mike Dalessio &lt;mike@csa.net&gt;
Mike Gilbert &lt;floppym@gentoo.org&gt;
Fabio Castelli (muflone) &lt;muflone@vbsimple.net&gt;
diff --git a/remmina/ui/remmina_preferences.glade b/remmina/ui/remmina_preferences.glade
index b5234f605..4c08fc324 100644
--- a/remmina/ui/remmina_preferences.glade
+++ b/remmina/ui/remmina_preferences.glade
@@ -1,11 +1,38 @@
<?xml version="1.0" encoding="UTF-8"?>
-<!-- Generated with glade 3.18.3 -->
+<!-- Generated with glade 3.18.3
+
+Remmina Preferences Dialog -
+Copyright (C) Antenore Gatta & Giovanni Panozzo 2014-2016
+
+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.
+
+Author: Antenore Gatta
+
+-->
<interface>
- <requires lib="gtk+" version="3.0"/>
+ <requires lib="gtk+" version="3.4"/>
+ <!-- interface-license-type gplv2 -->
+ <!-- interface-name Remmina Preferences Dialog -->
+ <!-- interface-copyright Antenore Gatta & Giovanni Panozzo 2014-2016 -->
+ <!-- interface-authors Antenore Gatta -->
+ <object class="GtkActionGroup" id="actiongroup1"/>
<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>
@@ -28,16 +55,18 @@
<property name="layout_style">end</property>
<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="use_underline">True</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
- <property name="position">1</property>
+ <property name="position">0</property>
</packing>
</child>
</object>
@@ -100,8 +129,8 @@
<object class="GtkLabel" id="label_options_double_click">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="xalign">0</property>
<property name="label" translatable="yes">Double-click action</property>
+ <property name="xalign">0</property>
</object>
<packing>
<property name="left_attach">0</property>
@@ -128,8 +157,8 @@
<object class="GtkLabel" id="label_options_scale_quality">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="xalign">0</property>
<property name="label" translatable="yes">Scale quality</property>
+ <property name="xalign">0</property>
</object>
<packing>
<property name="left_attach">0</property>
@@ -155,39 +184,15 @@
</packing>
</child>
<child>
- <object class="GtkLabel" id="label_options_ssh_port">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">SSH tunnel local port</property>
- </object>
- <packing>
- <property name="left_attach">0</property>
- <property name="top_attach">5</property>
- </packing>
- </child>
- <child>
- <object class="GtkEntry" id="entry_options_ssh_port">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="max_length">5</property>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="top_attach">5</property>
- <property name="width">2</property>
- </packing>
- </child>
- <child>
<object class="GtkLabel" id="label_options_scroll">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="xalign">0</property>
<property name="label" translatable="yes">Auto scroll step size</property>
+ <property name="xalign">0</property>
</object>
<packing>
<property name="left_attach">0</property>
- <property name="top_attach">9</property>
+ <property name="top_attach">7</property>
</packing>
</child>
<child>
@@ -198,7 +203,7 @@
</object>
<packing>
<property name="left_attach">1</property>
- <property name="top_attach">9</property>
+ <property name="top_attach">7</property>
<property name="width">2</property>
</packing>
</child>
@@ -206,12 +211,12 @@
<object class="GtkLabel" id="label_options_recent_items">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="xalign">0</property>
<property name="label" translatable="yes">Maximum recent items</property>
+ <property name="xalign">0</property>
</object>
<packing>
<property name="left_attach">0</property>
- <property name="top_attach">8</property>
+ <property name="top_attach">6</property>
</packing>
</child>
<child>
@@ -223,7 +228,7 @@
</object>
<packing>
<property name="left_attach">1</property>
- <property name="top_attach">8</property>
+ <property name="top_attach">6</property>
</packing>
</child>
<child>
@@ -232,23 +237,22 @@
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
- <signal name="clicked" handler="remmina_pref_dialog_clear_recent" swapped="no"/>
</object>
<packing>
<property name="left_attach">2</property>
- <property name="top_attach">8</property>
+ <property name="top_attach">6</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label_options_resolutions">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="xalign">0</property>
<property name="label" translatable="yes">Resolutions</property>
+ <property name="xalign">0</property>
</object>
<packing>
<property name="left_attach">0</property>
- <property name="top_attach">10</property>
+ <property name="top_attach">8</property>
</packing>
</child>
<child>
@@ -257,11 +261,10 @@
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
- <signal name="clicked" handler="remmina_pref_on_button_resolutions_clicked" swapped="no"/>
</object>
<packing>
<property name="left_attach">1</property>
- <property name="top_attach">10</property>
+ <property name="top_attach">8</property>
<property name="width">2</property>
</packing>
</child>
@@ -269,12 +272,12 @@
<object class="GtkLabel" id="label_options_keystrokes">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="xalign">0</property>
<property name="label" translatable="yes">Keystrokes</property>
+ <property name="xalign">0</property>
</object>
<packing>
<property name="left_attach">0</property>
- <property name="top_attach">11</property>
+ <property name="top_attach">9</property>
</packing>
</child>
<child>
@@ -283,17 +286,16 @@
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
- <signal name="clicked" handler="remmina_pref_on_button_keystrokes_clicked" swapped="no"/>
</object>
<packing>
<property name="left_attach">1</property>
- <property name="top_attach">11</property>
+ <property name="top_attach">9</property>
<property name="width">2</property>
</packing>
</child>
<child>
- <object class="GtkCheckButton" id="checkbutton_options_ssh_parseconfig">
- <property name="label" translatable="yes">Parse ~/.ssh/config</property>
+ <object class="GtkCheckButton" id="checkbutton_options_survey">
+ <property name="label" translatable="yes">Activate survey dialog on startup</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
@@ -302,54 +304,35 @@
</object>
<packing>
<property name="left_attach">0</property>
- <property name="top_attach">7</property>
+ <property name="top_attach">2</property>
<property name="width">3</property>
</packing>
</child>
<child>
- <object class="GtkComboBoxText" id="comboboxtext_options_ssh_loglevel">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="hexpand">True</property>
- <items>
- <item id="0" translatable="yes">SSH_LOG_NOLOG</item>
- <item id="1" translatable="yes">SSH_LOG_RARE</item>
- <item id="2" translatable="yes">SSH_LOG_ENTRY</item>
- <item id="3" translatable="yes">SSH_LOG_PACKET</item>
- <item id="4" translatable="yes">SSH_LOG_FUNCTIONS</item>
- </items>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="top_attach">6</property>
- <property name="width">2</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="label_options_ssh_loglevel">
+ <object class="GtkLabel" id="label_options_screenshot_folder">
<property name="visible">True</property>
<property name="can_focus">False</property>
+ <property name="label" translatable="yes">Screenshots folder</property>
<property name="xalign">0</property>
- <property name="label" translatable="yes">SSH log level</property>
</object>
<packing>
<property name="left_attach">0</property>
- <property name="top_attach">6</property>
+ <property name="top_attach">5</property>
</packing>
</child>
<child>
- <object class="GtkCheckButton" id="checkbutton_options_survey">
- <property name="label" translatable="yes">Activate survey dialog on startup</property>
+ <object class="GtkFileChooserButton" id="filechooserbutton_options_screenshots_path">
<property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="xalign">0</property>
- <property name="draw_indicator">True</property>
+ <property name="can_focus">False</property>
+ <property name="tooltip_text" translatable="yes">Choose the directory where you want to save Remmina screenshots.</property>
+ <property name="hexpand">True</property>
+ <property name="action">select-folder</property>
+ <property name="title" translatable="yes">Select a Directory</property>
</object>
<packing>
- <property name="left_attach">0</property>
- <property name="top_attach">2</property>
- <property name="width">3</property>
+ <property name="left_attach">1</property>
+ <property name="top_attach">5</property>
+ <property name="width">2</property>
</packing>
</child>
</object>
@@ -429,8 +412,8 @@
<object class="GtkLabel" id="label_appearance_view_mode">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="xalign">0</property>
<property name="label" translatable="yes">Default view mode</property>
+ <property name="xalign">0</property>
</object>
<packing>
<property name="left_attach">0</property>
@@ -459,8 +442,8 @@
<object class="GtkLabel" id="label_appearance_tab_interface">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="xalign">0</property>
<property name="label" translatable="yes">Tab interface</property>
+ <property name="xalign">0</property>
</object>
<packing>
<property name="left_attach">0</property>
@@ -489,8 +472,8 @@
<object class="GtkLabel" id="label_appearance_show_buttons_icons">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="xalign">0</property>
<property name="label" translatable="yes">Show buttons icons</property>
+ <property name="xalign">0</property>
</object>
<packing>
<property name="left_attach">0</property>
@@ -519,8 +502,8 @@
<object class="GtkLabel" id="label_appearance_show_menu_icons">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="xalign">0</property>
<property name="label" translatable="yes">Show menu icons</property>
+ <property name="xalign">0</property>
</object>
<packing>
<property name="left_attach">0</property>
@@ -618,7 +601,6 @@
<property name="hexpand">True</property>
<property name="xalign">0</property>
<property name="draw_indicator">True</property>
- <signal name="toggled" handler="remmina_pref_dialog_disable_tray_icon_on_toggled" swapped="no"/>
</object>
<packing>
<property name="left_attach">0</property>
@@ -679,8 +661,8 @@
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
- <property name="xalign">0</property>
<property name="label" translatable="yes">Host key</property>
+ <property name="xalign">0</property>
</object>
<packing>
<property name="left_attach">0</property>
@@ -694,7 +676,6 @@
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
- <signal name="clicked" handler="remmina_pref_dialog_on_key_chooser" swapped="no"/>
</object>
<packing>
<property name="left_attach">1</property>
@@ -707,8 +688,8 @@
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
- <property name="xalign">0</property>
<property name="label" translatable="yes">Toggle fullscreen mode</property>
+ <property name="xalign">0</property>
</object>
<packing>
<property name="left_attach">0</property>
@@ -722,7 +703,6 @@
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
- <signal name="clicked" handler="remmina_pref_dialog_on_key_chooser" swapped="no"/>
</object>
<packing>
<property name="left_attach">1</property>
@@ -735,8 +715,8 @@
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
- <property name="xalign">0</property>
<property name="label" translatable="yes">Auto-fit window</property>
+ <property name="xalign">0</property>
</object>
<packing>
<property name="left_attach">0</property>
@@ -750,7 +730,6 @@
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
- <signal name="clicked" handler="remmina_pref_dialog_on_key_chooser" swapped="no"/>
</object>
<packing>
<property name="left_attach">1</property>
@@ -763,8 +742,8 @@
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
- <property name="xalign">0</property>
<property name="label" translatable="yes">Switch tab pages</property>
+ <property name="xalign">0</property>
</object>
<packing>
<property name="left_attach">0</property>
@@ -778,7 +757,6 @@
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
- <signal name="clicked" handler="remmina_pref_dialog_on_key_chooser" swapped="no"/>
</object>
<packing>
<property name="left_attach">1</property>
@@ -792,7 +770,6 @@
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
- <signal name="clicked" handler="remmina_pref_dialog_on_key_chooser" swapped="no"/>
</object>
<packing>
<property name="left_attach">2</property>
@@ -804,8 +781,8 @@
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
- <property name="xalign">0</property>
<property name="label" translatable="yes">Toggle scaled mode</property>
+ <property name="xalign">0</property>
</object>
<packing>
<property name="left_attach">0</property>
@@ -819,7 +796,6 @@
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
- <signal name="clicked" handler="remmina_pref_dialog_on_key_chooser" swapped="no"/>
</object>
<packing>
<property name="left_attach">1</property>
@@ -832,8 +808,8 @@
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
- <property name="xalign">0</property>
<property name="label" translatable="yes">Grab keyboard</property>
+ <property name="xalign">0</property>
</object>
<packing>
<property name="left_attach">0</property>
@@ -847,7 +823,6 @@
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
- <signal name="clicked" handler="remmina_pref_dialog_on_key_chooser" swapped="no"/>
</object>
<packing>
<property name="left_attach">1</property>
@@ -860,8 +835,8 @@
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
- <property name="xalign">0</property>
<property name="label" translatable="yes">Minimize window</property>
+ <property name="xalign">0</property>
</object>
<packing>
<property name="left_attach">0</property>
@@ -875,7 +850,6 @@
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
- <signal name="clicked" handler="remmina_pref_dialog_on_key_chooser" swapped="no"/>
</object>
<packing>
<property name="left_attach">1</property>
@@ -888,8 +862,8 @@
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
- <property name="xalign">0</property>
<property name="label" translatable="yes">Disconnect</property>
+ <property name="xalign">0</property>
</object>
<packing>
<property name="left_attach">0</property>
@@ -903,7 +877,6 @@
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
- <signal name="clicked" handler="remmina_pref_dialog_on_key_chooser" swapped="no"/>
</object>
<packing>
<property name="left_attach">1</property>
@@ -916,8 +889,8 @@
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
- <property name="xalign">0</property>
<property name="label" translatable="yes">Show / hide toolbar</property>
+ <property name="xalign">0</property>
</object>
<packing>
<property name="left_attach">0</property>
@@ -931,7 +904,6 @@
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
- <signal name="clicked" handler="remmina_pref_dialog_on_key_chooser" swapped="no"/>
</object>
<packing>
<property name="left_attach">1</property>
@@ -939,6 +911,34 @@
<property name="width">2</property>
</packing>
</child>
+ <child>
+ <object class="GtkLabel" id="label_keyboard_screenshot">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="label" translatable="yes">Screenshot</property>
+ <property name="ellipsize">start</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">9</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="button_keyboard_screenshot">
+ <property name="label" translatable="yes">SCREENSHOT</property>
+ <property name="width_request">100</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">9</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
</object>
</child>
</object>
@@ -958,6 +958,108 @@
</packing>
</child>
<child>
+ <object class="GtkAlignment" id="alignment_ssh">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="top_padding">4</property>
+ <property name="bottom_padding">7</property>
+ <property name="left_padding">7</property>
+ <property name="right_padding">7</property>
+ <child>
+ <object class="GtkGrid" id="grid_ssh">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">5</property>
+ <property name="column_spacing">7</property>
+ <child>
+ <object class="GtkLabel" id="label_options_ssh_port">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">SSH tunnel local port</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="entry_options_ssh_port">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="max_length">5</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="checkbutton_options_ssh_parseconfig">
+ <property name="label" translatable="yes">Parse ~/.ssh/config</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="xalign">0</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ <property name="width">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="comboboxtext_options_ssh_loglevel">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <items>
+ <item id="0" translatable="yes">SSH_LOG_NOLOG</item>
+ <item id="1" translatable="yes">SSH_LOG_RARE</item>
+ <item id="2" translatable="yes">SSH_LOG_ENTRY</item>
+ <item id="3" translatable="yes">SSH_LOG_PACKET</item>
+ <item id="4" translatable="yes">SSH_LOG_FUNCTIONS</item>
+ </items>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">2</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label_options_ssh_loglevel">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">SSH log level</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="position">4</property>
+ </packing>
+ </child>
+ <child type="tab">
+ <object class="GtkLabel" id="label_tab_ssh">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">SSH Options</property>
+ </object>
+ <packing>
+ <property name="position">4</property>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
+ <child>
<object class="GtkAlignment" id="alignment_terminal">
<property name="visible">True</property>
<property name="can_focus">False</property>
@@ -976,8 +1078,8 @@
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
- <property name="xalign">0</property>
<property name="label" translatable="yes">Font</property>
+ <property name="xalign">0</property>
</object>
<packing>
<property name="left_attach">0</property>
@@ -989,8 +1091,8 @@
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
- <property name="xalign">0</property>
<property name="label" translatable="yes">Colors</property>
+ <property name="xalign">0</property>
</object>
<packing>
<property name="left_attach">0</property>
@@ -1002,8 +1104,8 @@
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
- <property name="xalign">0</property>
<property name="label" translatable="yes">Foreground color</property>
+ <property name="xalign">0</property>
</object>
<packing>
<property name="left_attach">0</property>
@@ -1015,8 +1117,8 @@
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
- <property name="xalign">0</property>
<property name="label" translatable="yes">Background color</property>
+ <property name="xalign">0</property>
</object>
<packing>
<property name="left_attach">0</property>
@@ -1028,8 +1130,8 @@
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
- <property name="xalign">0</property>
<property name="label" translatable="yes">Scrollback lines</property>
+ <property name="xalign">0</property>
</object>
<packing>
<property name="left_attach">0</property>
@@ -1041,8 +1143,8 @@
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
- <property name="xalign">0</property>
<property name="label" translatable="yes">Keyboard</property>
+ <property name="xalign">0</property>
</object>
<packing>
<property name="left_attach">0</property>
@@ -1070,7 +1172,6 @@
<property name="hexpand">True</property>
<property name="xalign">0</property>
<property name="draw_indicator">True</property>
- <signal name="toggled" handler="remmina_pref_dialog_vte_font_on_toggled" swapped="no"/>
</object>
<packing>
<property name="left_attach">1</property>
@@ -1191,8 +1292,8 @@
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
- <property name="xalign">0</property>
<property name="label" translatable="yes">Copy</property>
+ <property name="xalign">0</property>
</object>
<packing>
<property name="left_attach">1</property>
@@ -1218,7 +1319,6 @@
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="hexpand">False</property>
- <signal name="clicked" handler="remmina_pref_dialog_on_key_chooser" swapped="no"/>
</object>
<packing>
<property name="left_attach">3</property>
@@ -1230,8 +1330,8 @@
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
- <property name="xalign">0</property>
<property name="label" translatable="yes">Paste</property>
+ <property name="xalign">0</property>
</object>
<packing>
<property name="left_attach">1</property>
@@ -1257,7 +1357,6 @@
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="hexpand">False</property>
- <signal name="clicked" handler="remmina_pref_dialog_on_key_chooser" swapped="no"/>
</object>
<packing>
<property name="left_attach">3</property>
@@ -1268,7 +1367,7 @@
</child>
</object>
<packing>
- <property name="position">4</property>
+ <property name="position">5</property>
</packing>
</child>
<child type="tab">
@@ -1278,7 +1377,7 @@
<property name="label" translatable="yes">Terminal</property>
</object>
<packing>
- <property name="position">4</property>
+ <property name="position">5</property>
<property name="tab_fill">False</property>
</packing>
</child>