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:
-rw-r--r--plugins/rdp/rdp_event.c3
-rw-r--r--plugins/rdp/rdp_plugin.c18
-rw-r--r--src/include/remmina/types.h7
-rw-r--r--src/remmina_connection_window.c66
-rw-r--r--src/remmina_file_editor.c79
-rw-r--r--src/remmina_protocol_widget.c53
-rw-r--r--src/remmina_protocol_widget.h4
7 files changed, 178 insertions, 52 deletions
diff --git a/plugins/rdp/rdp_event.c b/plugins/rdp/rdp_event.c
index b6c643a10..23cb50bd3 100644
--- a/plugins/rdp/rdp_event.c
+++ b/plugins/rdp/rdp_event.c
@@ -314,9 +314,6 @@ static gboolean remmina_rdp_event_on_draw(GtkWidget* widget, cairo_t* context, R
if (!rfi->surface)
return FALSE;
- GtkAllocation a;
- gtk_widget_get_allocation(GTK_WIDGET(gp), &a);
-
if (rfi->scale == REMMINA_PROTOCOL_WIDGET_SCALE_MODE_SCALED)
cairo_scale(context, rfi->scale_x, rfi->scale_y);
diff --git a/plugins/rdp/rdp_plugin.c b/plugins/rdp/rdp_plugin.c
index 293370a44..6c25d9460 100644
--- a/plugins/rdp/rdp_plugin.c
+++ b/plugins/rdp/rdp_plugin.c
@@ -1424,17 +1424,25 @@ static void remmina_rdp_call_feature(RemminaProtocolWidget* gp, const RemminaPro
break;
case REMMINA_RDP_FEATURE_SCALE:
- rfi->scale = remmina_plugin_service->remmina_protocol_widget_get_current_scale_mode(gp);
- remmina_rdp_event_update_scale(gp);
+ if (rfi) {
+ rfi->scale = remmina_plugin_service->remmina_protocol_widget_get_current_scale_mode(gp);
+ remmina_rdp_event_update_scale(gp);
+ } else {
+ printf("REMMINA RDP PLUGIN WARNING: rfi is null in %s REMMINA_RDP_FEATURE_SCALE\n", __func__);
+ }
break;
case REMMINA_RDP_FEATURE_DYNRESUPDATE:
break;
case REMMINA_RDP_FEATURE_TOOL_REFRESH:
- gtk_widget_queue_draw_area(rfi->drawing_area, 0, 0,
- remmina_plugin_service->protocol_plugin_get_width(gp),
- remmina_plugin_service->protocol_plugin_get_height(gp));
+ if (rfi) {
+ gtk_widget_queue_draw_area(rfi->drawing_area, 0, 0,
+ remmina_plugin_service->protocol_plugin_get_width(gp),
+ remmina_plugin_service->protocol_plugin_get_height(gp));
+ } else {
+ printf("REMMINA RDP PLUGIN WARNING: rfi is null in %s REMMINA_RDP_FEATURE_TOOL_REFRESH\n", __func__);
+ }
break;
case REMMINA_RDP_FEATURE_TOOL_SENDCTRLALTDEL:
diff --git a/src/include/remmina/types.h b/src/include/remmina/types.h
index 46cb93afe..5178e151d 100644
--- a/src/include/remmina/types.h
+++ b/src/include/remmina/types.h
@@ -121,6 +121,13 @@ typedef enum {
REMMINA_PROTOCOL_WIDGET_SCALE_MODE_DYNRES = 2
} RemminaScaleMode;
+typedef enum {
+ RES_INVALID = -1,
+ RES_USE_CUSTOM = 0,
+ RES_USE_CLIENT = 1,
+ RES_USE_INITIAL_WINDOW_SIZE = 2
+} RemminaProtocolWidgetResolutionMode;
+
G_END_DECLS
diff --git a/src/remmina_connection_window.c b/src/remmina_connection_window.c
index ab91f3f12..0ab9e2575 100644
--- a/src/remmina_connection_window.c
+++ b/src/remmina_connection_window.c
@@ -158,6 +158,9 @@ typedef struct _RemminaConnectionObject {
gboolean connected;
gboolean dynres_unlocked;
+
+ gulong deferred_open_size_allocate_handler;
+
} RemminaConnectionObject;
struct _RemminaConnectionHolder {
@@ -3900,6 +3903,38 @@ gboolean remmina_connection_window_open_from_filename(const gchar* filename)
}
}
+static gboolean open_connection_last_stage(gpointer user_data)
+{
+ RemminaProtocolWidget *gp = (RemminaProtocolWidget *)user_data;
+
+ /* Now we have an allocated size for our RemminaProtocolWidget. We can proceed with the connection */
+ remmina_protocol_widget_update_remote_resolution(gp);
+ remmina_protocol_widget_open_connection(gp);
+
+ return FALSE;
+}
+
+static void rpw_size_allocated_on_connection(GtkWidget *w, GdkRectangle *allocation, gpointer user_data)
+{
+ RemminaProtocolWidget *gp = (RemminaProtocolWidget *)w;
+
+ /* Disconnect signal handler to avoid to be called again after a normal resize */
+ g_signal_handler_disconnect(w, gp->cnnobj->deferred_open_size_allocate_handler);
+
+ /* Schedule a connection ASAP */
+ if (remmina_file_get_int(gp->cnnobj->remmina_file, "resolution_mode", RES_INVALID) == RES_USE_INITIAL_WINDOW_SIZE) {
+ /* Allow the WM to decide the real size of our windows before reading current window
+ * size and connecting: some WM, i.e. GnomeShell/mutter with edge-tiling,
+ * will resize our window after creating it, so we must wait to be in a stable state
+ * before reading the window internal widgets allocated size for RES_USE_INTERNAL_WINDOW_SIZE */
+ g_timeout_add(200, open_connection_last_stage, gp);
+ }
+ else
+ g_idle_add(open_connection_last_stage, gp);
+
+ return;
+}
+
void remmina_connection_window_open_from_file(RemminaFile* remminafile)
{
TRACE_CALL(__func__);
@@ -3916,6 +3951,7 @@ GtkWidget* remmina_connection_window_open_from_file_full(RemminaFile* remminafil
RemminaConnectionWindow* cnnwin;
GtkWidget* tab;
gint i;
+ gboolean defer_connection_after_size_allocation;
/* Create the RemminaConnectionObject */
cnnobj = g_new0(RemminaConnectionObject, 1);
@@ -3934,14 +3970,6 @@ GtkWidget* remmina_connection_window_open_from_file_full(RemminaFile* remminafil
g_object_set_data(G_OBJECT(cnnobj->proto), "user-data", data);
}
-
- /* Set default remote desktop size in the profile, so the plugins can query
- * protocolwidget and know WxH that the user put on the profile settings */
- remmina_protocol_widget_update_remote_resolution((RemminaProtocolWidget*)cnnobj->proto,
- remmina_file_get_int(remminafile, "resolution_width", -1),
- remmina_file_get_int(remminafile, "resolution_height", -1)
- );
-
/* Create the viewport to make the RemminaProtocolWidget scrollable */
cnnobj->viewport = gtk_viewport_new(NULL, NULL);
gtk_widget_set_name(cnnobj->viewport, "remmina-cw-viewport");
@@ -4038,7 +4066,27 @@ GtkWidget* remmina_connection_window_open_from_file_full(RemminaFile* remminafil
return cnnobj->proto;
}
- remmina_protocol_widget_open_connection(REMMINA_PROTOCOL_WIDGET((RemminaProtocolWidget*)cnnobj->proto), remminafile);
+
+ /* GTK window setup is done here, and we are almost ready to call remmina_protocol_widget_open_connection().
+ * But size has not yet been allocated by GTK
+ * to the widgets. If we are in RES_USE_INITIAL_WINDOW_SIZE resolution mode,
+ * we should wait for a size allocation from GTK for cnnobj->proto
+ * before connecting */
+
+ defer_connection_after_size_allocation = FALSE;
+ if (remmina_file_get_int(remminafile, "resolution_mode", RES_INVALID) == RES_USE_INITIAL_WINDOW_SIZE) {
+ GtkAllocation al;
+ gtk_widget_get_allocation(cnnobj->proto, &al);
+ if (al.width < 10 || al.height < 10) {
+ defer_connection_after_size_allocation = TRUE;
+ }
+ }
+
+ if (defer_connection_after_size_allocation) {
+ cnnobj->deferred_open_size_allocate_handler = g_signal_connect(G_OBJECT(cnnobj->proto), "size-allocate", G_CALLBACK(rpw_size_allocated_on_connection), NULL);
+ } else {
+ g_idle_add(open_connection_last_stage, cnnobj->proto);
+ }
return cnnobj->proto;
diff --git a/src/remmina_file_editor.c b/src/remmina_file_editor.c
index 0597ad35d..1848a4d00 100644
--- a/src/remmina_file_editor.c
+++ b/src/remmina_file_editor.c
@@ -119,6 +119,7 @@ struct _RemminaFileEditorPriv {
GtkWidget* config_container;
GtkWidget* server_combo;
+ GtkWidget* resolution_iws_radio;
GtkWidget* resolution_auto_radio;
GtkWidget* resolution_custom_radio;
GtkWidget* resolution_custom_combo;
@@ -498,8 +499,26 @@ static void remmina_file_editor_create_resolution(RemminaFileEditor* gfe, const
TRACE_CALL(__func__);
GtkWidget* widget;
GtkWidget* hbox;
- const gchar *resolution_w, *resolution_h;
+ int resolution_w, resolution_h;
gchar *res_str;
+ RemminaProtocolWidgetResolutionMode res_mode;
+
+ res_mode = remmina_file_get_int(gfe->priv->remmina_file, "resolution_mode", RES_INVALID);
+ resolution_w = remmina_file_get_int(gfe->priv->remmina_file, "resolution_width", -1);
+ resolution_h = remmina_file_get_int(gfe->priv->remmina_file, "resolution_height", -1);
+
+ /* If resolution_mode is non-existent (-1), then we try to calculate it
+ * as we did before having resolution_mode */
+ if (res_mode == RES_INVALID) {
+ if (resolution_w <= 0 || resolution_h <= 0)
+ res_mode = RES_USE_INITIAL_WINDOW_SIZE;
+ else
+ res_mode = RES_USE_CUSTOM;
+ }
+ if (res_mode == RES_USE_CUSTOM)
+ res_str = g_strdup_printf("%dx%d", resolution_w, resolution_h);
+ else
+ res_str = NULL;
widget = gtk_label_new(_("Resolution"));
gtk_widget_show(widget);
@@ -507,27 +526,27 @@ static void remmina_file_editor_create_resolution(RemminaFileEditor* gfe, const
gtk_widget_set_halign(widget, GTK_ALIGN_START);
gtk_grid_attach(GTK_GRID(grid), widget, 0, row, 1, 1);
- widget = gtk_radio_button_new_with_label(NULL, setting->opt1 ? _("Use window size") : _("Use client resolution"));
+ hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
+ widget = gtk_radio_button_new_with_label(NULL, _("Use initial window size"));
gtk_widget_show(widget);
- gtk_grid_attach(GTK_GRID(grid), widget, 1, row, 1, 1);
+ gtk_box_pack_start(GTK_BOX(hbox), widget, TRUE, TRUE, 0);
+ gfe->priv->resolution_iws_radio = widget;
+ widget = gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(gfe->priv->resolution_iws_radio), _("Use client resolution"));
+ gtk_widget_show(widget);
+ gtk_box_pack_start(GTK_BOX(hbox), widget, TRUE, TRUE, 0);
gfe->priv->resolution_auto_radio = widget;
+ gtk_grid_attach(GTK_GRID(grid), hbox, 1, row, 1, 1);
+ gtk_widget_show(hbox);
hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
gtk_widget_show(hbox);
gtk_grid_attach(GTK_GRID(grid), hbox, 1, row + 1, 1, 1);
- widget = gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(gfe->priv->resolution_auto_radio), _("Custom"));
+ widget = gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(gfe->priv->resolution_iws_radio), _("Custom"));
gtk_widget_show(widget);
gtk_box_pack_start(GTK_BOX(hbox), widget, FALSE, FALSE, 0);
gfe->priv->resolution_custom_radio = widget;
- resolution_w = remmina_file_get_string(gfe->priv->remmina_file, "resolution_width");
- resolution_h = remmina_file_get_string(gfe->priv->remmina_file, "resolution_height");
-
- if (resolution_w && resolution_h && resolution_w[0] != 0 && resolution_h[0] != 0)
- res_str = g_strdup_printf("%sx%s", resolution_w, resolution_h);
- else
- res_str = NULL;
widget = remmina_public_create_combo_text_d(remmina_pref.resolutions, res_str, NULL);
gtk_widget_show(widget);
gtk_box_pack_start(GTK_BOX(hbox), widget, TRUE, TRUE, 0);
@@ -541,13 +560,16 @@ static void remmina_file_editor_create_resolution(RemminaFileEditor* gfe, const
g_signal_connect(G_OBJECT(gfe->priv->resolution_custom_radio), "toggled",
G_CALLBACK(remmina_file_editor_button_on_toggled), gfe->priv->resolution_custom_combo);
- if (res_str) {
+ if (res_mode == RES_USE_CUSTOM) {
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gfe->priv->resolution_custom_radio), TRUE);
- }else {
+ }else if (res_mode == RES_USE_CLIENT) {
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gfe->priv->resolution_auto_radio), TRUE);
- gtk_widget_set_sensitive(gfe->priv->resolution_custom_combo, FALSE);
+ }else {
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gfe->priv->resolution_iws_radio), TRUE);
}
+ gtk_widget_set_sensitive(gfe->priv->resolution_custom_combo, gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(gfe->priv->resolution_custom_radio)));
+
g_free(res_str);
}
@@ -701,7 +723,7 @@ static void remmina_file_editor_create_settings(RemminaFileEditor* gfe, GtkWidge
case REMMINA_PROTOCOL_SETTING_TYPE_RESOLUTION:
remmina_file_editor_create_resolution(gfe, settings, grid, grid_row);
- grid_row++;
+ grid_row += 1;
break;
case REMMINA_PROTOCOL_SETTING_TYPE_KEYMAP:
@@ -995,6 +1017,7 @@ static void remmina_file_editor_protocol_combo_on_changed(GtkComboBox* combo, Re
}
priv->server_combo = NULL;
+ priv->resolution_iws_radio = NULL;
priv->resolution_auto_radio = NULL;
priv->resolution_custom_radio = NULL;
priv->resolution_custom_combo = NULL;
@@ -1106,8 +1129,9 @@ static void remmina_file_editor_update_settings(RemminaFileEditor* gfe)
static void remmina_file_editor_update(RemminaFileEditor* gfe)
{
TRACE_CALL(__func__);
- gchar *custom_resolution, *res_w, *res_h;
- int w, h;
+ int res_w, res_h;
+ gchar *custom_resolution;
+ RemminaProtocolWidgetResolutionMode res_mode;
RemminaFileEditorPriv* priv = gfe->priv;
@@ -1127,21 +1151,26 @@ static void remmina_file_editor_update(RemminaFileEditor* gfe)
if (priv->resolution_auto_radio) {
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(priv->resolution_auto_radio))) {
- /* Resolution is set to auto */
- res_w = res_h = NULL;
+ /* Resolution is set to auto (which means: use client fullscreen resolution, aka use client resolution) */
+ res_w = res_h = 0;
+ res_mode = RES_USE_CLIENT;
+ }else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(priv->resolution_iws_radio))) {
+ /* Resolution is set to initial window size */
+ res_w = res_h = 0;
+ res_mode = RES_USE_INITIAL_WINDOW_SIZE;
}else {
/* Resolution is set to a value from the list */
custom_resolution = remmina_public_combo_get_active_text(GTK_COMBO_BOX(priv->resolution_custom_combo));
- if (remmina_public_split_resolution_string(custom_resolution, &w, &h)) {
- res_w = g_strdup_printf("%i", w);
- res_h = g_strdup_printf("%i", h);
+ if (remmina_public_split_resolution_string(custom_resolution, &res_w, &res_h)) {
+ res_mode = RES_USE_CUSTOM;
}else {
- res_w = res_h = NULL;
+ res_mode = RES_USE_INITIAL_WINDOW_SIZE;
}
g_free(custom_resolution);
}
- remmina_file_set_string_ref(priv->remmina_file, "resolution_width", res_w);
- remmina_file_set_string_ref(priv->remmina_file, "resolution_height", res_h);
+ remmina_file_set_int(priv->remmina_file, "resolution_mode", res_mode);
+ remmina_file_set_int(priv->remmina_file, "resolution_width", res_w);
+ remmina_file_set_int(priv->remmina_file, "resolution_height", res_h);
}
if (priv->keymap_combo) {
diff --git a/src/remmina_protocol_widget.c b/src/remmina_protocol_widget.c
index 38e8cbbc4..ca6f0e33b 100644
--- a/src/remmina_protocol_widget.c
+++ b/src/remmina_protocol_widget.c
@@ -216,6 +216,7 @@ static void remmina_protocol_widget_init(RemminaProtocolWidget* gp)
priv = g_new0(RemminaProtocolWidgetPriv, 1);
gp->priv = priv;
+ gp->priv->closed = TRUE;
g_signal_connect(G_OBJECT(gp), "destroy", G_CALLBACK(remmina_protocol_widget_destroy), NULL);
g_signal_connect(G_OBJECT(gp), "connect", G_CALLBACK(remmina_protocol_widget_on_connected), NULL);
@@ -232,6 +233,8 @@ void remmina_protocol_widget_open_connection_real(gpointer data)
gint num_plugin;
gint num_ssh;
+ gp->priv->closed = FALSE;
+
plugin = gp->priv->plugin;
plugin->init(gp);
@@ -282,26 +285,25 @@ static void cancel_open_connection_cb(void *cbdata, int btn)
remmina_protocol_widget_close_connection(gp);
}
-void remmina_protocol_widget_open_connection(RemminaProtocolWidget* gp, RemminaFile* remminafile)
+void remmina_protocol_widget_open_connection(RemminaProtocolWidget* gp)
{
TRACE_CALL(__func__);
gchar *s;
const gchar *name;
RemminaMessagePanel *mp;
- gp->priv->remmina_file = remminafile;
- gp->priv->scalemode = remmina_file_get_int(remminafile, "scale", FALSE);
- gp->priv->scaler_expand = remmina_file_get_int(remminafile, "scaler_expand", FALSE);
+ gp->priv->scalemode = remmina_file_get_int(gp->priv->remmina_file, "scale", FALSE);
+ gp->priv->scaler_expand = remmina_file_get_int(gp->priv->remmina_file, "scaler_expand", FALSE);
/* Exec precommand before everything else */
mp = remmina_message_panel_new();
remmina_message_panel_setup_progress(mp, _("Executing external commands..."), NULL, NULL);
remmina_connection_object_show_message_panel(gp->cnnobj, mp);
- remmina_ext_exec_new(remminafile, "precommand");
+ remmina_ext_exec_new(gp->priv->remmina_file, "precommand");
remmina_connection_object_destroy_message_panel(gp->cnnobj, mp);
- name = remmina_file_get_string(remminafile, "name");
+ name = remmina_file_get_string(gp->priv->remmina_file, "name");
s = g_strdup_printf(_("Connecting to '%s'..."), (name ? name : "*"));
mp = remmina_message_panel_new();
@@ -1573,7 +1575,7 @@ void remmina_protocol_widget_send_keys_signals(GtkWidget *widget, const guint *k
}
}
-void remmina_protocol_widget_update_remote_resolution(RemminaProtocolWidget* gp, gint w, gint h)
+void remmina_protocol_widget_update_remote_resolution(RemminaProtocolWidget* gp)
{
TRACE_CALL(__func__);
GdkDisplay *display;
@@ -1593,8 +1595,24 @@ void remmina_protocol_widget_update_remote_resolution(RemminaProtocolWidget* gp,
#endif
gint x, y;
GdkRectangle rect;
+ gint w, h;
+ gint wfile, hfile;
+ RemminaProtocolWidgetResolutionMode res_mode;
+
+ res_mode = remmina_file_get_int(gp->priv->remmina_file, "resolution_mode", RES_INVALID);
+ wfile = remmina_file_get_int(gp->priv->remmina_file, "resolution_width", -1);
+ hfile = remmina_file_get_int(gp->priv->remmina_file, "resolution_height", -1);
+
+ /* If resolution_mode is non-existent (-1), then we try to calculate it
+ * as we did before having resolution_mode */
+ if (res_mode == RES_INVALID) {
+ if (wfile <= 0 || hfile <= 0)
+ res_mode = RES_USE_INITIAL_WINDOW_SIZE;
+ else
+ res_mode = RES_USE_CUSTOM;
+ }
- if (w <= 0 || h <= 0) {
+ if (res_mode == RES_USE_CLIENT) {
display = gdk_display_get_default();
/* gdk_display_get_device_manager deprecated since 3.20, Use gdk_display_get_default_seat */
#if GTK_CHECK_VERSION(3, 20, 0)
@@ -1614,6 +1632,25 @@ void remmina_protocol_widget_update_remote_resolution(RemminaProtocolWidget* gp,
#endif
w = rect.width;
h = rect.height;
+ } else if (res_mode == RES_USE_INITIAL_WINDOW_SIZE) {
+ GtkAllocation al;
+ gtk_widget_get_allocation(gp, &al);
+ w = al.width;
+ h = al.height;
+ if (w < 10) {
+ printf("REMMINA WARNING: %s RemminaProtocolWidget w=%d h=%d are too small, adjusting to 640x480\n", __func__, w, h);
+ w = 640;
+ h = 480;
+ }
+ /* Workaround for FreeRDP issue 5119. This will make our horizontal resolution
+ * an even value, but it will add a vertical black 1 pixel line on the
+ * right of the desktop */
+ if ( w & 1 != 0)
+ w -= 1;
+
+ } else {
+ w = wfile;
+ h = hfile;
}
gp->priv->profile_remote_width = w;
gp->priv->profile_remote_height = h;
diff --git a/src/remmina_protocol_widget.h b/src/remmina_protocol_widget.h
index 0445d15e7..3251f41ad 100644
--- a/src/remmina_protocol_widget.h
+++ b/src/remmina_protocol_widget.h
@@ -93,7 +93,7 @@ void remmina_protocol_widget_set_error(RemminaProtocolWidget *gp, const gchar *f
gboolean remmina_protocol_widget_is_closed(RemminaProtocolWidget *gp);
RemminaFile* remmina_protocol_widget_get_file(RemminaProtocolWidget *gp);
-void remmina_protocol_widget_open_connection(RemminaProtocolWidget *gp, RemminaFile *remminafile);
+void remmina_protocol_widget_open_connection(RemminaProtocolWidget *gp);
gboolean remmina_protocol_widget_close_connection(RemminaProtocolWidget *gp);
void remmina_protocol_widget_grab_focus(RemminaProtocolWidget *gp);
const RemminaProtocolFeature* remmina_protocol_widget_get_features(RemminaProtocolWidget *gp);
@@ -159,7 +159,7 @@ void remmina_protocol_widget_send_keystrokes(RemminaProtocolWidget* gp, GtkMenuI
/* Take screenshot of plugin */
gboolean remmina_protocol_widget_plugin_screenshot(RemminaProtocolWidget* gp, RemminaPluginScreenshotData *rpsd);
-void remmina_protocol_widget_update_remote_resolution(RemminaProtocolWidget* gp, gint w, gint h);
+void remmina_protocol_widget_update_remote_resolution(RemminaProtocolWidget* gp);
/* Functions to support execution of GTK code on master thread */
RemminaMessagePanel* remmina_protocol_widget_mpprogress(RemminaConnectionObject* cnnobj, const gchar *msg, RemminaMessagePanelCallback response_callback, gpointer response_callback_data);