diff options
author | Antenore Gatta <antenore@simbiosi.org> | 2021-04-23 16:10:01 +0300 |
---|---|---|
committer | Antenore Gatta <antenore@simbiosi.org> | 2021-04-23 16:10:01 +0300 |
commit | 995159119f005aaff7db93781d3ee5bb98533055 (patch) | |
tree | abee2e632427b142fe5dc6ece528f423498df87e | |
parent | d82102f2ef222973ff517f31fd91e5c7b4def03a (diff) |
Fixing RemminaConnectionWindow map/unmap events
The remmina connection windows in fullscreen is a different object
than when is in scrolled mode, therefore the old logic to map and unmap
the windows from the plugin it was notr working.
Now the events are managed directly from the RCW object and the
RemminaProtocolWidget, with an API that can be used by any plugins.
When in multi monitor and fullscreen, this mechanism doesn't work,
Therefore, in the plugin itself I catch when we are in multi monitor fullscreen mode
And I ignore the event.
This last behaviour should be managed directly in the Remmina Protocol Widget (TODO).
Fixes #2475
Signed-off-by: Antenore Gatta <antenore@simbiosi.org>
-rw-r--r-- | plugins/exec/exec_plugin.c | 4 | ||||
-rw-r--r-- | plugins/nx/nx_plugin.c | 4 | ||||
-rw-r--r-- | plugins/rdp/rdp_event.c | 29 | ||||
-rw-r--r-- | plugins/rdp/rdp_event.h | 2 | ||||
-rw-r--r-- | plugins/rdp/rdp_plugin.c | 4 | ||||
-rw-r--r-- | plugins/spice/spice_plugin.c | 6 | ||||
-rw-r--r-- | plugins/st/st_plugin.c | 4 | ||||
-rw-r--r-- | plugins/tool_hello_world/plugin.c | 4 | ||||
-rw-r--r-- | plugins/vnc/vnc_plugin.c | 4 | ||||
-rw-r--r-- | plugins/www/www_plugin.c | 4 | ||||
-rw-r--r-- | plugins/xdmcp/xdmcp_plugin.c | 4 | ||||
-rw-r--r-- | src/include/remmina/plugin.h | 2 | ||||
-rw-r--r-- | src/rcw.c | 46 | ||||
-rw-r--r-- | src/remmina_protocol_widget.c | 24 | ||||
-rw-r--r-- | src/remmina_protocol_widget.h | 3 | ||||
-rw-r--r-- | src/remmina_sftp_plugin.c | 4 | ||||
-rw-r--r-- | src/remmina_ssh_plugin.c | 4 |
17 files changed, 133 insertions, 19 deletions
diff --git a/plugins/exec/exec_plugin.c b/plugins/exec/exec_plugin.c index 4b09f40b6..b6f334695 100644 --- a/plugins/exec/exec_plugin.c +++ b/plugins/exec/exec_plugin.c @@ -287,7 +287,9 @@ static RemminaProtocolPlugin remmina_plugin = { NULL, // Query for available features NULL, // Call a feature NULL, // Send a keystroke - NULL // No screenshot support available + NULL, // No screenshot support available + NULL, // RCW map event + NULL // RCW unmap event }; G_MODULE_EXPORT gboolean remmina_plugin_entry(RemminaPluginService *service) diff --git a/plugins/nx/nx_plugin.c b/plugins/nx/nx_plugin.c index 821a43e03..01791acaa 100644 --- a/plugins/nx/nx_plugin.c +++ b/plugins/nx/nx_plugin.c @@ -782,7 +782,9 @@ static RemminaProtocolPlugin remmina_plugin_nx = remmina_plugin_nx_query_feature, // Query for available features remmina_plugin_nx_call_feature, // Call a feature NULL, // Send a keystroke - NULL // Screenshot support unavailable + NULL, // No screenshot support available + NULL, // RCW map event + NULL // RCW unmap event }; G_MODULE_EXPORT gboolean diff --git a/plugins/rdp/rdp_event.c b/plugins/rdp/rdp_event.c index 6c47081b7..181abc948 100644 --- a/plugins/rdp/rdp_event.c +++ b/plugins/rdp/rdp_event.c @@ -45,7 +45,7 @@ #include <cairo/cairo-xlib.h> #include <freerdp/locale/keyboard.h> -static gboolean remmina_rdp_event_on_map(GtkWindow *window, GdkEvent *event, RemminaProtocolWidget *gp) +gboolean remmina_rdp_event_on_map(RemminaProtocolWidget *gp) { TRACE_CALL(__func__); rfContext* rfi = GET_PLUGIN_DATA(gp); @@ -62,7 +62,7 @@ static gboolean remmina_rdp_event_on_map(GtkWindow *window, GdkEvent *event, Rem return FALSE; } -static gboolean remmina_rdp_event_on_unmap(GtkWindow *window, GdkEvent *event, RemminaProtocolWidget *gp) +gboolean remmina_rdp_event_on_unmap(RemminaProtocolWidget *gp) { TRACE_CALL(__func__); rfContext* rfi = GET_PLUGIN_DATA(gp); @@ -71,6 +71,13 @@ static gboolean remmina_rdp_event_on_unmap(GtkWindow *window, GdkEvent *event, R if (rfi == NULL) return false; + GtkWidget *toplevel = gtk_widget_get_toplevel(GTK_WIDGET(gp)); + GdkWindow *window = gtk_widget_get_window(toplevel); + if (gdk_window_get_fullscreen_mode(window) == GDK_FULLSCREEN_ON_ALL_MONITORS) { + REMMINA_PLUGIN_DEBUG("Unmap event received, but cannot enable TS_SUPPRESS_OUTPUT_PDU when in fullscreen"); + return FALSE; + } + gdi = ((rdpContext *)rfi)->gdi; REMMINA_PLUGIN_DEBUG("Unmap event received, enabling TS_SUPPRESS_OUTPUT_PDU "); @@ -82,6 +89,7 @@ static gboolean remmina_rdp_event_on_unmap(GtkWindow *window, GdkEvent *event, R static gboolean remmina_rdp_event_on_focus_in(GtkWidget *widget, GdkEventKey *event, RemminaProtocolWidget *gp) { TRACE_CALL(__func__); + rfContext *rfi = GET_PLUGIN_DATA(gp); rdpInput *input; GdkModifierType state; @@ -93,6 +101,9 @@ static gboolean remmina_rdp_event_on_focus_in(GtkWidget *widget, GdkEventKey *ev #endif GdkDevice *keyboard = NULL; + const gchar *wname = gtk_widget_get_name(gtk_widget_get_toplevel(widget)); + REMMINA_PLUGIN_DEBUG("Top level name is: %s", wname); + if (!rfi || !rfi->connected || rfi->is_reconnecting) return FALSE; @@ -885,10 +896,16 @@ void remmina_rdp_event_init(RemminaProtocolWidget *gp) G_CALLBACK(remmina_rdp_event_on_key), gp); g_signal_connect(G_OBJECT(rfi->drawing_area), "focus-in-event", G_CALLBACK(remmina_rdp_event_on_focus_in), gp); - g_signal_connect(G_OBJECT(gtk_widget_get_toplevel(rfi->drawing_area)), "map-event", - G_CALLBACK(remmina_rdp_event_on_map), gp); - g_signal_connect(G_OBJECT(gtk_widget_get_toplevel(rfi->drawing_area)), "unmap-event", - G_CALLBACK(remmina_rdp_event_on_unmap), gp); + /** Fixme: This comment + * needed for TS_SUPPRESS_OUTPUT_PDU + * But it works only when we stay in the same window mode, if we switch to + * fullscreen, for instance, the object refernce is lost, so we loose these + * events. + */ + //g_signal_connect(G_OBJECT(gtk_widget_get_toplevel(rfi->drawing_area)), "map-event", + // G_CALLBACK(remmina_rdp_event_on_map), gp); + //g_signal_connect(G_OBJECT(gtk_widget_get_toplevel(rfi->drawing_area)), "unmap-event", + // G_CALLBACK(remmina_rdp_event_on_unmap), gp); if (!remmina_plugin_service->file_get_int(remminafile, "disableclipboard", FALSE)) { clipboard = gtk_widget_get_clipboard(rfi->drawing_area, GDK_SELECTION_CLIPBOARD); diff --git a/plugins/rdp/rdp_event.h b/plugins/rdp/rdp_event.h index 991f31ca7..8f310b91a 100644 --- a/plugins/rdp/rdp_event.h +++ b/plugins/rdp/rdp_event.h @@ -47,5 +47,7 @@ void remmina_rdp_event_update_rect(RemminaProtocolWidget *gp, gint x, gint y, gi void remmina_rdp_event_queue_ui_async(RemminaProtocolWidget *gp, RemminaPluginRdpUiObject *ui); int remmina_rdp_event_queue_ui_sync_retint(RemminaProtocolWidget *gp, RemminaPluginRdpUiObject *ui); void *remmina_rdp_event_queue_ui_sync_retptr(RemminaProtocolWidget *gp, RemminaPluginRdpUiObject *ui); +gboolean remmina_rdp_event_on_map(RemminaProtocolWidget *gp); +gboolean remmina_rdp_event_on_unmap(RemminaProtocolWidget *gp); G_END_DECLS diff --git a/plugins/rdp/rdp_plugin.c b/plugins/rdp/rdp_plugin.c index 174b2fc16..d13edd441 100644 --- a/plugins/rdp/rdp_plugin.c +++ b/plugins/rdp/rdp_plugin.c @@ -2658,7 +2658,9 @@ static RemminaProtocolPlugin remmina_rdp = remmina_rdp_query_feature, // Query for available features remmina_rdp_call_feature, // Call a feature remmina_rdp_keystroke, // Send a keystroke - remmina_rdp_get_screenshot // Screenshot + remmina_rdp_get_screenshot, // Screenshot + remmina_rdp_event_on_map, // RCW map event + remmina_rdp_event_on_unmap // RCW unmap event }; /* File plugin definition and features */ diff --git a/plugins/spice/spice_plugin.c b/plugins/spice/spice_plugin.c index f03247c16..e68ad1ba9 100644 --- a/plugins/spice/spice_plugin.c +++ b/plugins/spice/spice_plugin.c @@ -405,7 +405,7 @@ static void remmina_plugin_spice_display_ready_cb(GObject *display, GParamSpec * # if SPICE_GTK_CHECK_VERSION(0, 31, 0) SpiceImageCompression imagecompression = remmina_plugin_service->file_get_int(remminafile, "imagecompression", 0); if (imagecompression) { -# if SPICE_GTK_CHECK_VERSION(0, 35, 0) +# if SPICE_GTK_CHECK_VERSION(0, 35, 0) spice_display_channel_change_preferred_compression(SPICE_CHANNEL(gpdata->display_channel), imagecompression); # else @@ -641,7 +641,9 @@ static RemminaProtocolPlugin remmina_plugin_spice = remmina_plugin_spice_query_feature, // Query for available features remmina_plugin_spice_call_feature, // Call a feature remmina_plugin_spice_keystroke, // Send a keystroke - NULL // No screenshot support available + NULL, // No screenshot support available + NULL, // RCW map event + NULL // RCW unmap event }; void remmina_plugin_spice_remove_list_option(gpointer *option_list, const gchar *option_to_remove) { diff --git a/plugins/st/st_plugin.c b/plugins/st/st_plugin.c index 1a7a2f426..f5512a0b7 100644 --- a/plugins/st/st_plugin.c +++ b/plugins/st/st_plugin.c @@ -283,7 +283,9 @@ static RemminaProtocolPlugin remmina_plugin = remmina_st_query_feature, // Query for available features NULL, // Call a feature NULL, // Send a keystroke - NULL // Capture screenshot + NULL, // Capture screenshot + NULL, // RCW map event + NULL // RCW unmap event }; G_MODULE_EXPORT gboolean remmina_plugin_entry(RemminaPluginService *service) diff --git a/plugins/tool_hello_world/plugin.c b/plugins/tool_hello_world/plugin.c index abe6927f9..05dfd2e36 100644 --- a/plugins/tool_hello_world/plugin.c +++ b/plugins/tool_hello_world/plugin.c @@ -104,7 +104,9 @@ static RemminaProtocolPlugin remmina_plugin = { NULL, // Query for available features NULL, // Call a feature NULL, // Send a keystroke - NULL // No screenshot support available + NULL, // No screenshot support available + NULL, // RCW map event + NULL // RCW unmap event }; G_MODULE_EXPORT gboolean remmina_plugin_entry(RemminaPluginService *service) diff --git a/plugins/vnc/vnc_plugin.c b/plugins/vnc/vnc_plugin.c index e3f4c3c28..3daf4ef25 100644 --- a/plugins/vnc/vnc_plugin.c +++ b/plugins/vnc/vnc_plugin.c @@ -2055,7 +2055,9 @@ static RemminaProtocolPlugin remmina_plugin_vnci = remmina_plugin_vnc_query_feature, // Query for available features remmina_plugin_vnc_call_feature, // Call a feature remmina_plugin_vnc_keystroke, // Send a keystroke - NULL // No screenshot support available + NULL, // No screenshot support available + NULL, // RCW map event + NULL // RCW unmap event }; G_MODULE_EXPORT gboolean diff --git a/plugins/www/www_plugin.c b/plugins/www/www_plugin.c index 20633ec28..c9220b2bd 100644 --- a/plugins/www/www_plugin.c +++ b/plugins/www/www_plugin.c @@ -927,7 +927,9 @@ static RemminaProtocolPlugin remmina_plugin = remmina_www_query_feature, // Query for available features NULL, // Call feature NULL, // Send keystroke - remmina_plugin_www_get_snapshot // Capture screenshot + remmina_plugin_www_get_snapshot, // Capture screenshot + NULL, // RCW map event + NULL // RCW unmap event }; G_MODULE_EXPORT gboolean remmina_plugin_entry(RemminaPluginService *service) diff --git a/plugins/xdmcp/xdmcp_plugin.c b/plugins/xdmcp/xdmcp_plugin.c index 2caa96143..8e4fce325 100644 --- a/plugins/xdmcp/xdmcp_plugin.c +++ b/plugins/xdmcp/xdmcp_plugin.c @@ -403,7 +403,9 @@ static RemminaProtocolPlugin remmina_plugin_xdmcp = remmina_plugin_xdmcp_query_feature, // Query for available features remmina_plugin_xdmcp_call_feature, // Call a feature NULL, // Send a keystroke - NULL // No screenshot support available + NULL, // No screenshot support available + NULL, // RCW map event + NULL // RCW unmap event }; G_MODULE_EXPORT gboolean diff --git a/src/include/remmina/plugin.h b/src/include/remmina/plugin.h index 2e25cb5ab..b889ecb92 100644 --- a/src/include/remmina/plugin.h +++ b/src/include/remmina/plugin.h @@ -81,6 +81,8 @@ typedef struct _RemminaProtocolPlugin { 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); + gboolean (*map_event)(RemminaProtocolWidget *gp); + gboolean (*unmap_event)(RemminaProtocolWidget *gp); } RemminaProtocolPlugin; typedef struct _RemminaEntryPlugin { @@ -355,6 +355,7 @@ static void rcw_class_init(RemminaConnectionWindowClass *klass) rcw_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); + } static RemminaConnectionObject *rcw_get_cnnobj_at_page(RemminaConnectionWindow *cnnwin, gint npage) @@ -3081,13 +3082,49 @@ static gboolean rcw_state_event(GtkWidget *widget, GdkEventWindowState *event, g return FALSE; } +static gboolean rcw_map_event(GtkWidget *widget, GdkEvent *event, gpointer data) +{ + TRACE_CALL(__func__); + + RemminaConnectionWindow *cnnwin = (RemminaConnectionWindow*)widget; + RemminaConnectionObject *cnnobj; + RemminaProtocolWidget *gp; + if (cnnwin->priv->toolbar_is_reconfiguring) return FALSE; + if (!(cnnobj = rcw_get_visible_cnnobj(cnnwin))) return FALSE; + + gp = REMMINA_PROTOCOL_WIDGET(cnnobj->proto); + REMMINA_DEBUG ("Mapping: %s", gtk_widget_get_name(widget)); + if (remmina_protocol_widget_map_event(gp)) { + REMMINA_DEBUG ("Called plugin mapping function"); + } + return FALSE; +} + +static gboolean rcw_unmap_event(GtkWidget *widget, GdkEvent *event, gpointer data) +{ + TRACE_CALL(__func__); + + RemminaConnectionWindow *cnnwin = (RemminaConnectionWindow*)widget; + RemminaConnectionObject *cnnobj; + RemminaProtocolWidget *gp; + if (cnnwin->priv->toolbar_is_reconfiguring) return FALSE; + if (!(cnnobj = rcw_get_visible_cnnobj(cnnwin))) return FALSE; + + gp = REMMINA_PROTOCOL_WIDGET(cnnobj->proto); + REMMINA_DEBUG ("Unmapping: %s", gtk_widget_get_name(widget)); + if (remmina_protocol_widget_unmap_event(gp)) { + REMMINA_DEBUG ("Called plugin mapping function"); + } + return FALSE; +} + static gboolean rcw_map_event_fullscreen(GtkWidget *widget, GdkEvent *event, gpointer data) { TRACE_CALL(__func__); RemminaConnectionObject *cnnobj; gint target_monitor; - REMMINA_DEBUG ("Mapping Remmina connection window"); + REMMINA_DEBUG ("Mapping: %s", gtk_widget_get_name(widget)); if (!REMMINA_IS_CONNECTION_WINDOW(widget)) { REMMINA_DEBUG ("Remmina Connection Window undefined, cannot go fullscreen"); @@ -3133,6 +3170,10 @@ static gboolean rcw_map_event_fullscreen(GtkWidget *widget, GdkEvent *event, gpo gtk_window_fullscreen(GTK_WINDOW(widget)); #endif + if (remmina_protocol_widget_map_event(gp)) { + REMMINA_DEBUG ("Called plugin mapping function"); + } + return FALSE; } @@ -3148,6 +3189,9 @@ rcw_new(gboolean fullscreen, int full_screen_target_monitor) if (fullscreen) /* Put the window in fullscreen after it is mapped to have it appear on the same monitor */ g_signal_connect(G_OBJECT(cnnwin), "map-event", G_CALLBACK(rcw_map_event_fullscreen), GINT_TO_POINTER(full_screen_target_monitor)); + else + g_signal_connect(G_OBJECT(cnnwin), "map-event", G_CALLBACK(rcw_map_event), NULL); + g_signal_connect(G_OBJECT(cnnwin), "unmap-event", G_CALLBACK(rcw_unmap_event), NULL); gtk_container_set_border_width(GTK_CONTAINER(cnnwin), 0); g_signal_connect(G_OBJECT(cnnwin), "toolbar-place", G_CALLBACK(rcw_toolbar_place_signal), NULL); diff --git a/src/remmina_protocol_widget.c b/src/remmina_protocol_widget.c index 06bf9aedd..09eb0bfae 100644 --- a/src/remmina_protocol_widget.c +++ b/src/remmina_protocol_widget.c @@ -700,6 +700,30 @@ gboolean remmina_protocol_widget_plugin_screenshot(RemminaProtocolWidget *gp, Re return gp->priv->plugin->get_plugin_screenshot(gp, rpsd); } +gboolean remmina_protocol_widget_map_event(RemminaProtocolWidget *gp) +{ + TRACE_CALL(__func__); + if (!gp->priv->plugin->map_event) { + REMMINA_DEBUG("Map plugin function not implemented"); + return FALSE; + } + + REMMINA_DEBUG ("Calling plugin mapping function"); + return gp->priv->plugin->map_event(gp); +} + +gboolean remmina_protocol_widget_unmap_event(RemminaProtocolWidget *gp) +{ + TRACE_CALL(__func__); + if (!gp->priv->plugin->get_plugin_screenshot) { + REMMINA_DEBUG("Unmap plugin function not implemented"); + return FALSE; + } + + REMMINA_DEBUG ("Calling plugin unmapping function"); + return gp->priv->plugin->unmap_event(gp); +} + void remmina_protocol_widget_emit_signal(RemminaProtocolWidget *gp, const gchar *signal_name) { TRACE_CALL(__func__); diff --git a/src/remmina_protocol_widget.h b/src/remmina_protocol_widget.h index 9ad92c5fc..86c8f5c71 100644 --- a/src/remmina_protocol_widget.h +++ b/src/remmina_protocol_widget.h @@ -172,6 +172,9 @@ void remmina_protocol_widget_send_keystrokes(RemminaProtocolWidget *gp, GtkMenuI void remmina_protocol_widget_send_clipboard(RemminaProtocolWidget *gp, GtkMenuItem *widget); /* Take screenshot of plugin */ gboolean remmina_protocol_widget_plugin_screenshot(RemminaProtocolWidget *gp, RemminaPluginScreenshotData *rpsd); +/* Deal with the remimna connection window map/unmap events */ +gboolean remmina_protocol_widget_map_event(RemminaProtocolWidget *gp); +gboolean remmina_protocol_widget_unmap_event(RemminaProtocolWidget *gp); void remmina_protocol_widget_update_remote_resolution(RemminaProtocolWidget *gp); diff --git a/src/remmina_sftp_plugin.c b/src/remmina_sftp_plugin.c index c68143529..6379cd989 100644 --- a/src/remmina_sftp_plugin.c +++ b/src/remmina_sftp_plugin.c @@ -371,7 +371,9 @@ static RemminaProtocolPlugin remmina_plugin_sftp = remmina_plugin_sftp_query_feature, // Query for available features remmina_plugin_sftp_call_feature, // Call a feature NULL, // Send a keystroke - NULL // Screenshot support unavailable + NULL, // Screenshot support unavailable + NULL, // RCW map event + NULL // RCW unmap event }; void diff --git a/src/remmina_ssh_plugin.c b/src/remmina_ssh_plugin.c index 15d15e32b..25c5100ca 100644 --- a/src/remmina_ssh_plugin.c +++ b/src/remmina_ssh_plugin.c @@ -1482,7 +1482,9 @@ static RemminaProtocolPlugin remmina_plugin_ssh = remmina_plugin_ssh_query_feature, /**< Query for available features */ remmina_plugin_ssh_call_feature, /**< Call a feature */ remmina_ssh_keystroke, /**< Send a keystroke */ - NULL /**< No screenshot support available */ + NULL, /**< No screenshot support available */ + NULL, /**< RCW map event */ + NULL /**< RCW unmap event */ }; |