39 #include <cairo/cairo-xlib.h> 41 #include <gdk/gdkkeysyms.h> 42 #include <glib/gi18n.h> 62 #ifdef GDK_WINDOWING_WAYLAND 63 #include <gdk/gdkwayland.h> 67 #define DEBUG_KB_GRABBING 0 75 #define MOTION_TIME 100 78 #define TB_HIDE_TIME_TIME 1000 82 struct _RemminaConnectionWindowPriv {
83 RemminaConnectionHolder* cnnhld;
87 guint switch_page_handler;
89 GtkWidget* floating_toolbar_widget;
92 GtkWidget* overlay_ftb_overlay;
94 GtkWidget* floating_toolbar_label;
95 gdouble floating_toolbar_opacity;
97 guint floating_toolbar_motion_handler;
99 guint ftb_hide_eventsource;
104 guint savestate_eventsourceid;
110 GtkToolItem* toolitem_autofit;
111 GtkToolItem* toolitem_fullscreen;
112 GtkToolItem* toolitem_switch_page;
113 GtkToolItem* toolitem_dynres;
114 GtkToolItem* toolitem_scale;
115 GtkToolItem* toolitem_grab;
116 GtkToolItem* toolitem_preferences;
117 GtkToolItem* toolitem_tools;
118 GtkToolItem* toolitem_screenshot;
119 GtkWidget* fullscreen_option_button;
120 GtkWidget* fullscreen_scaler_button;
121 GtkWidget* scaler_option_button;
123 GtkWidget* pin_button;
130 gboolean toolbar_is_reconfiguring;
135 gboolean mouse_pointer_entered;
181 #define DECLARE_CNNOBJ \ 182 if (!cnnhld || !cnnhld->cnnwin || gtk_notebook_get_current_page(GTK_NOTEBOOK(cnnhld->cnnwin->priv->notebook)) < 0) return; \ 183 RemminaConnectionObject* cnnobj = (RemminaConnectionObject*)g_object_get_data( \ 184 G_OBJECT(gtk_notebook_get_nth_page(GTK_NOTEBOOK(cnnhld->cnnwin->priv->notebook), \ 185 gtk_notebook_get_current_page(GTK_NOTEBOOK(cnnhld->cnnwin->priv->notebook)))), "cnnobj"); 187 #define DECLARE_CNNOBJ_WITH_RETURN(r) \ 188 if (!cnnhld || !cnnhld->cnnwin || gtk_notebook_get_current_page(GTK_NOTEBOOK(cnnhld->cnnwin->priv->notebook)) < 0) return r; \ 189 RemminaConnectionObject* cnnobj = (RemminaConnectionObject*)g_object_get_data( \ 190 G_OBJECT(gtk_notebook_get_nth_page(GTK_NOTEBOOK(cnnhld->cnnwin->priv->notebook), \ 191 gtk_notebook_get_current_page(GTK_NOTEBOOK(cnnhld->cnnwin->priv->notebook)))), "cnnobj"); 208 (
char*)
"text/x-remmina-ftb",
209 GTK_TARGET_SAME_APP | GTK_TARGET_OTHER_WIDGET,
217 (
char*)
"text/x-remmina-tb",
225 TRACE_CALL(__func__);
226 GtkCssProvider *provider;
228 provider = gtk_css_provider_new();
234 #if GTK_CHECK_VERSION(3, 14, 0) 235 gtk_css_provider_load_from_data(provider,
236 "#remmina-cw-viewport, #remmina-cw-aspectframe {\n" 239 " background-color: black;\n" 244 " -GtkWidget-window-dragging: 0;\n" 246 "#remmina-connection-window-fullscreen {\n" 247 " border-color: black;\n" 249 "#remmina-small-button {\n" 250 " outline-offset: 0;\n" 251 " outline-width: 0;\n" 255 "#remmina-pin-button {\n" 256 " outline-offset: 0;\n" 257 " outline-width: 0;\n" 261 "#remmina-tab-page {\n" 262 " background-color: black;\n" 264 "#remmina-scrolled-container {\n" 266 "#remmina-scrolled-container.undershoot {\n" 267 " background: none;\n" 269 "#remmina-tab-page {\n" 272 " background-color: white;\n" 274 " border-style: none solid solid solid;\n" 275 " border-width: 1px;\n" 276 " border-radius: 4px;\n" 280 " background-color: white;\n" 282 " border-style: solid solid none solid;\n" 283 " border-width: 1px;\n" 284 " border-radius: 4px;\n" 290 " border: 0px solid;\n" 291 " padding: 20px 20px 20px 20px;\n" 293 ".message_panel entry {\n" 294 " background-image: none;\n" 295 " border-width: 4px;\n" 296 " border-radius: 8px;\n" 298 ".message_panel .title_label {\n" 299 " font-size: 2em; \n" 304 gtk_css_provider_load_from_data(provider,
305 "#remmina-cw-viewport, #remmina-cw-aspectframe {\n" 308 " background-color: black;\n" 310 "#remmina-cw-message-panel {\n" 315 " -GtkWidget-window-dragging: 0;\n" 317 "#remmina-connection-window-fullscreen {\n" 318 " border-color: black;\n" 320 "#remmina-small-button {\n" 321 " -GtkWidget-focus-padding: 0;\n" 322 " -GtkWidget-focus-line-width: 0;\n" 326 "#remmina-pin-button {\n" 327 " -GtkWidget-focus-padding: 0;\n" 328 " -GtkWidget-focus-line-width: 0;\n" 332 "#remmina-scrolled-container {\n" 334 "#remmina-scrolled-container.undershoot {\n" 335 " background: none\n" 337 "#remmina-tab-page {\n" 340 " border-style: none solid solid solid;\n" 341 " border-width: 1px;\n" 342 " border-radius: 4px;\n" 346 " border-style: solid solid none solid;\n" 347 " border-width: 1px;\n" 348 " border-radius: 4px;\n" 357 gtk_style_context_add_provider_for_screen(gdk_screen_get_default(),
358 GTK_STYLE_PROVIDER(provider),
359 GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
361 g_object_unref(provider);
364 remmina_connection_window_signals[
TOOLBARPLACE_SIGNAL] = g_signal_new(
"toolbar-place", G_TYPE_FROM_CLASS(klass),
366 g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
372 TRACE_CALL(__func__);
374 gboolean plugin_has_dynres, plugin_can_scale;
393 *scale_avail = plugin_can_scale;
403 TRACE_CALL(__func__);
413 TRACE_CALL(__func__);
415 #if GTK_CHECK_VERSION(3, 20, 0) 418 GdkDeviceManager *manager;
420 GdkDevice *keyboard = NULL;
422 if (cnnhld->grab_retry_eventsourceid) {
423 g_source_remove(cnnhld->grab_retry_eventsourceid);
424 cnnhld->grab_retry_eventsourceid = 0;
427 display = gtk_widget_get_display(GTK_WIDGET(cnnhld->cnnwin));
428 #if GTK_CHECK_VERSION(3, 20, 0) 429 seat = gdk_display_get_default_seat(display);
430 keyboard = gdk_seat_get_pointer(seat);
432 manager = gdk_display_get_device_manager(display);
433 keyboard = gdk_device_manager_get_client_pointer(manager);
436 if (!cnnhld->cnnwin->priv->kbcaptured) {
440 if (keyboard != NULL) {
441 if ( gdk_device_get_source(keyboard) != GDK_SOURCE_KEYBOARD ) {
442 keyboard = gdk_device_get_associated_device(keyboard);
444 #if DEBUG_KB_GRABBING 445 printf(
"DEBUG_KB_GRABBING: --- ungrabbing\n");
448 #if GTK_CHECK_VERSION(3, 24, 0) 450 gdk_seat_ungrab(seat);
452 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
453 gdk_device_ungrab(keyboard, GDK_CURRENT_TIME);
454 G_GNUC_END_IGNORE_DEPRECATIONS
456 cnnhld->cnnwin->priv->kbcaptured = FALSE;
463 TRACE_CALL(__func__);
464 RemminaConnectionHolder* cnnhld;
465 cnnhld = (RemminaConnectionHolder *)user_data;
468 cnnhld->grab_retry_eventsourceid = 0;
469 return G_SOURCE_REMOVE;
474 TRACE_CALL(__func__);
477 #if GTK_CHECK_VERSION(3, 20, 0) 480 GdkDeviceManager *manager;
483 GdkDevice *keyboard = NULL;
485 if (cnnhld->cnnwin->priv->kbcaptured || !cnnhld->cnnwin->priv->mouse_pointer_entered) {
489 display = gtk_widget_get_display(GTK_WIDGET(cnnhld->cnnwin));
490 #if GTK_CHECK_VERSION(3, 20, 0) 491 seat = gdk_display_get_default_seat(display);
492 keyboard = gdk_seat_get_pointer(seat);
494 manager = gdk_display_get_device_manager(display);
495 keyboard = gdk_device_manager_get_client_pointer(manager);
498 if (keyboard != NULL) {
500 if ( gdk_device_get_source(keyboard) != GDK_SOURCE_KEYBOARD) {
501 keyboard = gdk_device_get_associated_device( keyboard );
505 #if DEBUG_KB_GRABBING 506 printf(
"DEBUG_KB_GRABBING: profile asks for grabbing, let’s try.\n");
516 #if GTK_CHECK_VERSION(3, 24, 0) 517 ggs = gdk_seat_grab(seat, gtk_widget_get_window(GTK_WIDGET(cnnhld->cnnwin)),
518 GDK_SEAT_CAPABILITY_KEYBOARD, FALSE, NULL, NULL, NULL, NULL);
520 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
521 ggs = gdk_device_grab(keyboard, gtk_widget_get_window(GTK_WIDGET(cnnhld->cnnwin)), GDK_OWNERSHIP_WINDOW,
522 TRUE, GDK_KEY_PRESS | GDK_KEY_RELEASE, NULL, GDK_CURRENT_TIME);
523 G_GNUC_END_IGNORE_DEPRECATIONS
525 if ( ggs != GDK_GRAB_SUCCESS )
528 #if DEBUG_KB_GRABBING 529 printf(
"GRAB FAILED. GdkGrabStatus: %d\n", (
int)ggs);
532 if (cnnhld->grab_retry_eventsourceid == 0) {
536 #if DEBUG_KB_GRABBING 537 printf(
"GRAB SUCCESS\n");
539 if (cnnhld->grab_retry_eventsourceid != 0) {
540 g_source_remove(cnnhld->grab_retry_eventsourceid);
541 cnnhld->grab_retry_eventsourceid = 0;
543 cnnhld->cnnwin->priv->kbcaptured = TRUE;
554 GtkNotebook* notebook = GTK_NOTEBOOK(priv->notebook);
559 if (GTK_IS_WIDGET(notebook)) {
560 n = gtk_notebook_get_n_pages(notebook);
561 for (i = n - 1; i >= 0; i--) {
562 w = gtk_notebook_get_nth_page(notebook, i);
573 TRACE_CALL(__func__);
575 RemminaConnectionHolder *cnnhld = cnnwin->
priv->cnnhld;
576 GtkNotebook* notebook = GTK_NOTEBOOK(priv->notebook);
580 if (!REMMINA_IS_CONNECTION_WINDOW(cnnwin))
584 n = gtk_notebook_get_n_pages(notebook);
586 dialog = gtk_message_dialog_new(GTK_WINDOW(cnnwin), GTK_DIALOG_MODAL, GTK_MESSAGE_QUESTION,
588 _(
"There are %i active connections in the current window. Are you sure to close?"), n);
589 i = gtk_dialog_run(GTK_DIALOG(dialog));
590 gtk_widget_destroy(dialog);
591 if (i != GTK_RESPONSE_YES)
600 if (cnnhld->cnnwin != NULL && GTK_IS_WIDGET(cnnhld->cnnwin))
601 gtk_widget_destroy(GTK_WIDGET(cnnhld->cnnwin));
602 cnnhld->cnnwin = NULL;
609 TRACE_CALL(__func__);
616 TRACE_CALL(__func__);
619 if (priv->kbcaptured)
622 if (priv->floating_toolbar_motion_handler) {
623 g_source_remove(priv->floating_toolbar_motion_handler);
624 priv->floating_toolbar_motion_handler = 0;
626 if (priv->ftb_hide_eventsource) {
627 g_source_remove(priv->ftb_hide_eventsource);
628 priv->ftb_hide_eventsource = 0;
630 if (priv->savestate_eventsourceid) {
631 g_source_remove(priv->savestate_eventsourceid);
632 priv->savestate_eventsourceid = 0;
639 if (priv->hidetb_timer) {
640 g_source_remove(priv->hidetb_timer);
641 priv->hidetb_timer = 0;
643 if (priv->switch_page_handler) {
644 g_source_remove(priv->switch_page_handler);
645 priv->switch_page_handler = 0;
649 if (GTK_WIDGET(cnnhld->cnnwin) == widget) {
650 cnnhld->cnnwin->priv = NULL;
651 cnnhld->cnnwin = NULL;
658 TRACE_CALL(__func__);
661 if (G_TYPE_CHECK_INSTANCE_TYPE(widget, rcwtype)) {
662 g_signal_emit_by_name(G_OBJECT(widget),
"toolbar-place");
669 GtkDragResult result, gpointer user_data)
671 TRACE_CALL(__func__);
672 RemminaConnectionHolder* cnnhld;
675 cnnhld = (RemminaConnectionHolder*)user_data;
676 priv = cnnhld->cnnwin->priv;
679 gtk_widget_show(GTK_WIDGET(priv->toolbar));
685 gint x, gint y, guint time, gpointer user_data)
687 TRACE_CALL(__func__);
689 gint new_toolbar_placement;
690 RemminaConnectionHolder* cnnhld;
693 cnnhld = (RemminaConnectionHolder*)user_data;
694 priv = cnnhld->cnnwin->priv;
696 gtk_widget_get_allocation(widget, &wa);
698 if (wa.width * y >= wa.height * x) {
699 if (wa.width * y > wa.height * ( wa.width - x) )
704 if (wa.width * y > wa.height * ( wa.width - x) )
710 gtk_drag_finish(context, TRUE, TRUE, time);
722 gtk_widget_show(GTK_WIDGET(priv->toolbar));
730 TRACE_CALL(__func__);
732 cairo_surface_t *surface;
735 double dashes[] = { 10 };
737 gtk_widget_get_allocation(widget, &wa);
739 surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 16, 16);
740 cr = cairo_create(surface);
741 cairo_set_source_rgb(cr, 0.6, 0.6, 0.6);
742 cairo_set_line_width(cr, 4);
743 cairo_set_dash(cr, dashes, 1, 0 );
744 cairo_rectangle(cr, 0, 0, 16, 16);
748 gtk_widget_hide(widget);
750 gtk_drag_set_icon_surface(context, surface);
756 TRACE_CALL(__func__);
760 priv->floating_toolbar_opacity = (1.0 - TOOLBAR_OPACITY_MIN) / ((gdouble)TOOLBAR_OPACITY_LEVEL)
762 + TOOLBAR_OPACITY_MIN;
763 if (priv->floating_toolbar_widget) {
764 gtk_widget_set_opacity(GTK_WIDGET(priv->overlay_ftb_overlay), priv->floating_toolbar_opacity);
770 TRACE_CALL(__func__);
772 gtk_widget_set_opacity(GTK_WIDGET(priv->overlay_ftb_overlay), 0.0);
773 priv->ftb_hide_eventsource = 0;
779 TRACE_CALL(__func__);
782 if (priv->floating_toolbar_widget == NULL)
785 if (show || priv->pin_down) {
789 if (priv->ftb_hide_eventsource) {
790 g_source_remove(priv->ftb_hide_eventsource);
791 priv->ftb_hide_eventsource = 0;
797 if (priv->ftb_hide_eventsource == 0)
802 gtk_revealer_set_reveal_child(GTK_REVEALER(priv->revealer), show || priv->pin_down);
808 TRACE_CALL(__func__);
825 TRACE_CALL(__func__);
828 gtk_scrolled_window_set_policy(scrolled_window,
835 TRACE_CALL(__func__);
836 DECLARE_CNNOBJ_WITH_RETURN(FALSE)
838 gint dwidth, dheight;
839 GtkAllocation nba, ca, ta;
841 if (priv->toolbar_is_reconfiguring)
846 gtk_widget_get_allocation(priv->notebook, &nba);
848 gtk_widget_get_allocation(priv->toolbar, &ta);
851 gtk_window_resize(GTK_WINDOW(cnnhld->cnnwin), MAX(1, dwidth + ta.width + nba.width - ca.width),
852 MAX(1, dheight + nba.height - ca.height));
854 gtk_window_resize(GTK_WINDOW(cnnhld->cnnwin), MAX(1, dwidth + nba.width - ca.width),
855 MAX(1, dheight + ta.height + nba.height - ca.height));
857 gtk_container_check_resize(GTK_CONTAINER(cnnhld->cnnwin));
867 TRACE_CALL(__func__);
871 if ((gdk_window_get_state(gtk_widget_get_window(GTK_WIDGET(cnnhld->cnnwin))) & GDK_WINDOW_STATE_MAXIMIZED) != 0) {
872 gtk_window_unmaximize(GTK_WINDOW(cnnhld->cnnwin));
877 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(cnnobj->
scrolled_container), GTK_POLICY_NEVER,
888 TRACE_CALL(__func__);
893 GdkRectangle monitor_geometry;
895 sz->x = sz->y = sz->width = sz->height = 0;
899 if (!cnnobj->
cnnhld->cnnwin)
901 if (!gtk_widget_is_visible(GTK_WIDGET(cnnobj->
cnnhld->cnnwin)))
904 #if GTK_CHECK_VERSION(3, 22, 0) 907 display = gtk_widget_get_display(GTK_WIDGET(cnnobj->
cnnhld->cnnwin));
908 monitor = gdk_display_get_monitor_at_window(display, gtk_widget_get_window(GTK_WIDGET(cnnobj->
cnnhld->cnnwin)));
912 screen = gtk_window_get_screen(GTK_WINDOW(cnnobj->
cnnhld->cnnwin));
913 monitor = gdk_screen_get_monitor_at_window(screen, gtk_widget_get_window(GTK_WIDGET(cnnobj->
cnnhld->cnnwin)));
916 #if GTK_CHECK_VERSION(3, 22, 0) 917 gdk_monitor_get_workarea(monitor, &monitor_geometry);
922 #ifdef GDK_WINDOWING_WAYLAND 923 if (GDK_IS_WAYLAND_DISPLAY(display)) {
924 int monitor_scale_factor = gdk_monitor_get_scale_factor(monitor);
925 monitor_geometry.width *= monitor_scale_factor;
926 monitor_geometry.height *= monitor_scale_factor;
929 #elif gdk_screen_get_monitor_workarea 930 gdk_screen_get_monitor_workarea(screen, monitor, &monitor_geometry);
932 gdk_screen_get_monitor_geometry(screen, monitor, &monitor_geometry);
934 *sz = monitor_geometry;
942 TRACE_CALL(__func__);
944 gboolean scroll_required = FALSE;
946 GdkRectangle monitor_geometry;
947 gint rd_width, rd_height;
960 (monitor_geometry.width < rd_width || monitor_geometry.height < rd_height) &&
962 scroll_required = TRUE;
965 switch (cnnhld->cnnwin->priv->view_mode) {
967 gtk_window_resize(GTK_WINDOW(cnnhld->cnnwin), monitor_geometry.width, monitor_geometry.height);
969 (scroll_required ? GTK_POLICY_AUTOMATIC : GTK_POLICY_NEVER),
970 (scroll_required ? GTK_POLICY_AUTOMATIC : GTK_POLICY_NEVER));
974 bordersz = scroll_required ? SCROLL_BORDER_SIZE : 0;
975 gtk_window_resize(GTK_WINDOW(cnnhld->cnnwin), monitor_geometry.width, monitor_geometry.height);
986 gtk_window_set_default_size(GTK_WINDOW(cnnhld->cnnwin),
987 MIN(rd_width, monitor_geometry.width), MIN(rd_height, monitor_geometry.height));
988 if (rd_width >= monitor_geometry.width || rd_height >= monitor_geometry.height) {
989 gtk_window_maximize(GTK_WINDOW(cnnhld->cnnwin));
997 gtk_window_maximize(GTK_WINDOW(cnnhld->cnnwin));
1009 TRACE_CALL(__func__);
1013 if (remmina_pref.
hostkey && key1) {
1015 s1 = g_strdup_printf(
" (%s + %s,%s)", gdk_keyval_name(remmina_pref.
hostkey),
1016 gdk_keyval_name(gdk_keyval_to_upper(key1)), gdk_keyval_name(gdk_keyval_to_upper(key2)));
1017 }
else if (key1 == remmina_pref.
hostkey) {
1018 s1 = g_strdup_printf(
" (%s)", gdk_keyval_name(remmina_pref.
hostkey));
1020 s1 = g_strdup_printf(
" (%s + %s)", gdk_keyval_name(remmina_pref.
hostkey),
1021 gdk_keyval_name(gdk_keyval_to_upper(key1)));
1026 s2 = g_strdup_printf(
"%s%s", tip, s1 ? s1 :
"");
1027 gtk_widget_set_tooltip_text(item, s2);
1034 TRACE_CALL(__func__);
1036 gboolean scaledexpandedmode;
1037 int rdwidth, rdheight;
1043 gtk_widget_set_halign(GTK_WIDGET(cnnobj->
proto), GTK_ALIGN_FILL);
1044 gtk_widget_set_valign(GTK_WIDGET(cnnobj->
proto), GTK_ALIGN_FILL);
1056 aratio = (gfloat)rdwidth / (gfloat)rdheight;
1059 cnnobj->
aspectframe = gtk_aspect_frame_new(NULL, 0.5, 0.5, aratio, FALSE);
1060 gtk_widget_set_name(cnnobj->
aspectframe,
"remmina-cw-aspectframe");
1061 gtk_frame_set_shadow_type(GTK_FRAME(cnnobj->
aspectframe), GTK_SHADOW_NONE);
1062 g_object_ref(cnnobj->
proto);
1063 gtk_container_remove(GTK_CONTAINER(cnnobj->
viewport), cnnobj->
proto);
1066 g_object_unref(cnnobj->
proto);
1068 if (cnnobj->
cnnhld != NULL && cnnobj->
cnnhld->cnnwin != NULL && cnnobj->
cnnhld->cnnwin->priv->notebook != NULL)
1071 gtk_aspect_frame_set(GTK_ASPECT_FRAME(cnnobj->
aspectframe), 0.5, 0.5, aratio, FALSE);
1078 g_object_ref(cnnobj->
proto);
1083 gtk_container_add(GTK_CONTAINER(cnnobj->
viewport), cnnobj->
proto);
1084 g_object_unref(cnnobj->
proto);
1085 if (cnnobj->
cnnhld != NULL && cnnobj->
cnnhld->cnnwin != NULL && cnnobj->
cnnhld->cnnwin->priv->notebook != NULL)
1094 gtk_widget_set_halign(GTK_WIDGET(cnnobj->
proto), GTK_ALIGN_FILL);
1095 gtk_widget_set_valign(GTK_WIDGET(cnnobj->
proto), GTK_ALIGN_FILL);
1099 gtk_widget_set_halign(GTK_WIDGET(cnnobj->
proto), GTK_ALIGN_CENTER);
1100 gtk_widget_set_valign(GTK_WIDGET(cnnobj->
proto), GTK_ALIGN_CENTER);
1108 TRACE_CALL(__func__);
1112 if (priv->toolbar_is_reconfiguring)
1115 if (gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(widget))) {
1124 TRACE_CALL(__func__);
1125 if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget)))
1133 TRACE_CALL(__func__);
1134 if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget)))
1142 TRACE_CALL(__func__);
1145 priv->sticky = FALSE;
1147 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(priv->fullscreen_option_button), FALSE);
1153 TRACE_CALL(__func__);
1156 GtkWidget* menuitem;
1159 if (priv->toolbar_is_reconfiguring)
1162 if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)))
1165 priv->sticky = TRUE;
1167 menu = gtk_menu_new();
1169 menuitem = gtk_radio_menu_item_new_with_label(NULL, _(
"Viewport fullscreen mode"));
1170 gtk_widget_show(menuitem);
1171 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
1172 group = gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(menuitem));
1174 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menuitem), TRUE);
1178 menuitem = gtk_radio_menu_item_new_with_label(group, _(
"Scrolled fullscreen mode"));
1179 gtk_widget_show(menuitem);
1180 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
1182 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menuitem), TRUE);
1188 #if GTK_CHECK_VERSION(3, 22, 0) 1189 gtk_menu_popup_at_widget(GTK_MENU(menu), widget,
1190 GDK_GRAVITY_SOUTH_WEST, GDK_GRAVITY_NORTH_WEST, NULL);
1193 gtk_get_current_event_time());
1200 TRACE_CALL(__func__);
1202 if (priv->toolbar_is_reconfiguring)
1204 priv->sticky = FALSE;
1205 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(priv->scaler_option_button), FALSE);
1211 TRACE_CALL(__func__);
1213 if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget)))
1221 TRACE_CALL(__func__);
1223 if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget)))
1232 TRACE_CALL(__func__);
1236 GtkWidget* menuitem;
1238 gboolean scaler_expand;
1240 if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)))
1245 priv->sticky = TRUE;
1247 menu = gtk_menu_new();
1249 menuitem = gtk_radio_menu_item_new_with_label(NULL, _(
"Keep aspect ratio when scaled"));
1250 gtk_widget_show(menuitem);
1251 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
1252 group = gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(menuitem));
1253 if (!scaler_expand) {
1254 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menuitem), TRUE);
1258 menuitem = gtk_radio_menu_item_new_with_label(group, _(
"Fill client window when scaled"));
1259 gtk_widget_show(menuitem);
1260 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
1261 if (scaler_expand) {
1262 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menuitem), TRUE);
1268 #if GTK_CHECK_VERSION(3, 22, 0) 1269 gtk_menu_popup_at_widget(GTK_MENU(menu), widget,
1270 GDK_GRAVITY_SOUTH_WEST, GDK_GRAVITY_NORTH_WEST, NULL);
1273 gtk_get_current_event_time());
1279 TRACE_CALL(__func__);
1283 page_num = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(menuitem),
"new-page-num"));
1284 gtk_notebook_set_current_page(GTK_NOTEBOOK(priv->notebook), page_num);
1289 TRACE_CALL(__func__);
1292 priv->sticky = FALSE;
1294 gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(priv->toolitem_switch_page), FALSE);
1300 TRACE_CALL(__func__);
1304 GtkWidget* menuitem;
1309 if (priv->toolbar_is_reconfiguring)
1312 if (!gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(widget)))
1315 priv->sticky = TRUE;
1317 menu = gtk_menu_new();
1319 n = gtk_notebook_get_n_pages(GTK_NOTEBOOK(priv->notebook));
1320 for (i = 0; i < n; i++) {
1321 page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(priv->notebook), i);
1327 gtk_widget_show(menuitem);
1328 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
1331 gtk_widget_show(image);
1333 g_object_set_data(G_OBJECT(menuitem),
"new-page-num", GINT_TO_POINTER(i));
1336 if (i == gtk_notebook_get_current_page(GTK_NOTEBOOK(priv->notebook))) {
1337 gtk_widget_set_sensitive(menuitem, FALSE);
1344 #if GTK_CHECK_VERSION(3, 22, 0) 1345 gtk_menu_popup_at_widget(GTK_MENU(menu), widget,
1346 GDK_GRAVITY_SOUTH_WEST, GDK_GRAVITY_NORTH_WEST, NULL);
1355 TRACE_CALL(__func__);
1358 GtkToolItem* toolitem;
1361 toolitem = priv->toolitem_autofit;
1364 gtk_widget_set_sensitive(GTK_WIDGET(toolitem), FALSE);
1404 TRACE_CALL(__func__);
1406 gboolean bdyn, bscale;
1409 if (priv->toolbar_is_reconfiguring)
1413 bdyn = gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(widget));
1414 bscale = gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(priv->toolitem_scale));
1416 if (bdyn && bscale) {
1417 gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(priv->toolitem_scale), FALSE);
1428 TRACE_CALL(__func__);
1429 gboolean bdyn, bscale;
1432 if (priv->toolbar_is_reconfiguring)
1435 bdyn = gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(priv->toolitem_dynres));
1436 bscale = gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(widget));
1438 if (bdyn && bscale) {
1439 gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(priv->toolitem_dynres), FALSE);
1448 TRACE_CALL(__func__);
1451 if (priv->toolbar_is_reconfiguring)
1454 priv->sticky = FALSE;
1456 gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(priv->toolitem_preferences), FALSE);
1462 TRACE_CALL(__func__);
1465 if (priv->toolbar_is_reconfiguring)
1468 priv->sticky = FALSE;
1470 gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(priv->toolitem_tools), FALSE);
1476 TRACE_CALL(__func__);
1481 if (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem))) {
1483 value = g_object_get_data(G_OBJECT(menuitem),
"feature-value");
1492 TRACE_CALL(__func__);
1498 value = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem));
1505 TRACE_CALL(__func__);
1516 TRACE_CALL(__func__);
1517 GtkWidget* menuitem;
1525 list = (
const gchar**)feature->
opt3;
1526 for (i = 0; list[i]; i += 2) {
1527 menuitem = gtk_radio_menu_item_new_with_label(group, g_dgettext(domain, list[i + 1]));
1528 group = gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(menuitem));
1529 gtk_widget_show(menuitem);
1530 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
1533 g_object_set_data(G_OBJECT(menuitem),
"feature-type", (gpointer)feature);
1534 g_object_set_data(G_OBJECT(menuitem),
"feature-value", (gpointer)list[i]);
1536 if (value && g_strcmp0(list[i], value) == 0) {
1537 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menuitem), TRUE);
1540 g_signal_connect(G_OBJECT(menuitem),
"toggled",
1543 gtk_widget_set_sensitive(menuitem, FALSE);
1551 TRACE_CALL(__func__);
1552 GtkWidget* menuitem;
1554 menuitem = gtk_check_menu_item_new_with_label(g_dgettext(domain, (
const gchar*)feature->
opt3));
1555 gtk_widget_show(menuitem);
1556 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
1559 g_object_set_data(G_OBJECT(menuitem),
"feature-type", (gpointer)feature);
1561 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menuitem),
1564 g_signal_connect(G_OBJECT(menuitem),
"toggled",
1567 gtk_widget_set_sensitive(menuitem, FALSE);
1573 TRACE_CALL(__func__);
1578 GtkWidget* menuitem;
1583 if (priv->toolbar_is_reconfiguring)
1586 if (!gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(widget)))
1589 priv->sticky = TRUE;
1594 menu = gtk_menu_new();
1601 menuitem = gtk_separator_menu_item_new();
1602 gtk_widget_show(menuitem);
1603 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
1607 switch (GPOINTER_TO_INT(feature->
opt1)) {
1608 case REMMINA_PROTOCOL_FEATURE_PREF_RADIO:
1613 case REMMINA_PROTOCOL_FEATURE_PREF_CHECK:
1625 #if GTK_CHECK_VERSION(3, 22, 0) 1626 gtk_menu_popup_at_widget(GTK_MENU(menu), widget,
1627 GDK_GRAVITY_SOUTH_WEST, GDK_GRAVITY_NORTH_WEST, NULL);
1636 TRACE_CALL(__func__);
1641 GtkWidget* menuitem = NULL;
1642 GtkMenu *submenu_keystrokes;
1643 const gchar* domain;
1646 gchar **keystroke_values;
1649 if (priv->toolbar_is_reconfiguring)
1652 if (!gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(widget)))
1655 priv->sticky = TRUE;
1658 menu = gtk_menu_new();
1664 if (feature->
opt1) {
1665 menuitem = gtk_menu_item_new_with_label(g_dgettext(domain, (
const gchar*)feature->
opt1));
1667 if (feature->
opt3) {
1670 gtk_widget_show(menuitem);
1671 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
1675 g_object_set_data(G_OBJECT(menuitem),
"feature-type", (gpointer)feature);
1677 g_signal_connect(G_OBJECT(menuitem),
"activate",
1680 gtk_widget_set_sensitive(menuitem, FALSE);
1689 keystrokes = g_strsplit(remmina_pref.
keystrokes, STRING_DELIMITOR, -1);
1690 if (g_strv_length(keystrokes)) {
1692 menuitem = gtk_menu_item_new_with_label(_(
"Keystrokes"));
1693 submenu_keystrokes = GTK_MENU(gtk_menu_new());
1694 gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), GTK_WIDGET(submenu_keystrokes));
1695 gtk_widget_show(menuitem);
1696 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
1698 for (i = 0; i < g_strv_length(keystrokes); i++) {
1699 keystroke_values = g_strsplit(keystrokes[i], STRING_DELIMITOR2, -1);
1700 if (g_strv_length(keystroke_values) > 1) {
1702 menuitem = gtk_menu_item_new_with_label(
1703 g_strdup(keystroke_values[strlen(keystroke_values[0]) ? 0 : 1]));
1704 g_object_set_data(G_OBJECT(menuitem),
"keystrokes", g_strdup(keystroke_values[1]));
1705 g_signal_connect_swapped(G_OBJECT(menuitem),
"activate",
1707 REMMINA_PROTOCOL_WIDGET(cnnobj->
proto));
1708 gtk_widget_show(menuitem);
1709 gtk_menu_shell_append(GTK_MENU_SHELL(submenu_keystrokes), menuitem);
1711 g_strfreev(keystroke_values);
1714 g_strfreev(keystrokes);
1716 #if GTK_CHECK_VERSION(3, 22, 0) 1717 gtk_menu_popup_at_widget(GTK_MENU(menu), widget,
1718 GDK_GRAVITY_SOUTH_WEST, GDK_GRAVITY_NORTH_WEST, NULL);
1727 TRACE_CALL(__func__);
1729 GdkPixbuf *screenshot;
1730 GdkWindow *active_window;
1738 cairo_surface_t *srcsurface;
1739 cairo_format_t cairo_format;
1740 cairo_surface_t *surface;
1743 if (cnnhld->cnnwin->priv->toolbar_is_reconfiguring)
1746 GDateTime *date = g_date_time_new_now_utc();
1751 gp = REMMINA_PROTOCOL_WIDGET(cnnobj->
proto);
1753 GtkClipboard *c = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
1765 cairo_format = CAIRO_FORMAT_ARGB32;
1767 cairo_format = CAIRO_FORMAT_RGB24;
1769 cairo_format = CAIRO_FORMAT_RGB16_565;
1771 stride = cairo_format_stride_for_width(cairo_format, width);
1773 srcsurface = cairo_image_surface_create_for_data(rpsd.
buffer, cairo_format, width, height, stride);
1776 gtk_clipboard_set_image (c, gdk_pixbuf_get_from_surface (
1777 srcsurface, 0, 0, width, height));
1779 surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24, width, height);
1780 cr = cairo_create(surface);
1781 cairo_set_source_surface(cr, srcsurface, 0, 0);
1782 cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
1784 cairo_surface_destroy(srcsurface);
1794 dialog = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_WARNING, GTK_BUTTONS_OK,
1795 _(
"Warning: screenshot is scaled or distorted. Disable scaling to have better screenshot."));
1796 g_signal_connect(G_OBJECT(dialog),
"response", G_CALLBACK(gtk_widget_destroy), NULL);
1797 gtk_widget_show(dialog);
1801 active_window = gtk_widget_get_window(GTK_WIDGET(gp));
1803 width = gdk_window_get_width(active_window);
1805 height = gdk_window_get_height(active_window);
1807 screenshot = gdk_pixbuf_get_from_window(active_window, 0, 0, width, height);
1808 if (screenshot == NULL)
1809 g_print(
"gdk_pixbuf_get_from_window failed\n");
1813 gtk_clipboard_set_image (c, screenshot);
1816 surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24, width, height);
1817 cr = cairo_create(surface);
1820 gdk_cairo_set_source_pixbuf(cr, screenshot, 0, 0);
1824 g_object_unref(screenshot);
1831 pngstr = g_string_new(g_strdup_printf(
"%s/%s.png",
1839 g_strdup_printf(
"%d", g_date_time_get_year(date)));
1841 g_date_time_get_month(date)));
1843 g_strdup_printf(
"%d", g_date_time_get_day_of_month(date)));
1845 g_strdup_printf(
"%d", g_date_time_get_hour(date)));
1847 g_strdup_printf(
"%d", g_date_time_get_minute(date)));
1849 g_strdup_printf(
"%f", g_date_time_get_seconds(date)));
1850 g_date_time_unref(date);
1851 pngname = g_string_free(pngstr, FALSE);
1853 cairo_surface_write_to_png(surface, pngname);
1860 cairo_surface_destroy(surface);
1865 TRACE_CALL(__func__);
1867 if (cnnhld->cnnwin->priv->toolbar_is_reconfiguring)
1870 gtk_window_iconify(GTK_WINDOW(cnnhld->cnnwin));
1875 TRACE_CALL(__func__);
1876 if (cnnhld->cnnwin->priv->toolbar_is_reconfiguring)
1883 TRACE_CALL(__func__);
1887 if (cnnhld->cnnwin->priv->toolbar_is_reconfiguring)
1890 capture = gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(widget));
1893 #if DEBUG_KB_GRABBING 1894 printf(
"DEBUG_KB_GRABBING: Grabbing for button\n");
1905 TRACE_CALL(__func__);
1908 GtkToolItem* toolitem;
1912 priv->toolbar_is_reconfiguring = TRUE;
1914 toolbar = gtk_toolbar_new();
1915 gtk_widget_show(toolbar);
1916 gtk_toolbar_set_style(GTK_TOOLBAR(toolbar), GTK_TOOLBAR_ICONS);
1917 gtk_toolbar_set_icon_size(GTK_TOOLBAR(toolbar), GTK_ICON_SIZE_SMALL_TOOLBAR);
1918 gtk_toolbar_set_show_arrow(GTK_TOOLBAR(toolbar), FALSE);
1921 toolitem = gtk_tool_button_new(NULL, NULL);
1922 gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(toolitem),
"remmina-fit-window-symbolic");
1926 priv->toolitem_autofit = toolitem;
1927 gtk_toolbar_insert(GTK_TOOLBAR(toolbar), toolitem, -1);
1928 gtk_widget_show(GTK_WIDGET(toolitem));
1932 toolitem = gtk_toggle_tool_button_new();
1933 gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(toolitem),
"remmina-fullscreen-symbolic");
1936 gtk_toolbar_insert(GTK_TOOLBAR(toolbar), toolitem, -1);
1937 gtk_widget_show(GTK_WIDGET(toolitem));
1938 priv->toolitem_fullscreen = toolitem;
1940 gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(toolitem), FALSE);
1942 gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(toolitem), mode !=
SCROLLED_WINDOW_MODE);
1947 toolitem = gtk_tool_item_new();
1948 gtk_widget_show(GTK_WIDGET(toolitem));
1949 gtk_toolbar_insert(GTK_TOOLBAR(toolbar), toolitem, -1);
1950 widget = gtk_toggle_button_new();
1951 gtk_widget_show(widget);
1952 gtk_container_set_border_width(GTK_CONTAINER(widget), 0);
1953 gtk_button_set_relief(GTK_BUTTON(widget), GTK_RELIEF_NONE);
1954 #if GTK_CHECK_VERSION(3, 20, 0) 1955 gtk_widget_set_focus_on_click(GTK_WIDGET(widget), FALSE);
1957 gtk_widget_set_name(widget,
"remmina-small-button");
1960 gtk_button_set_focus_on_click(GTK_BUTTON(widget), FALSE);
1962 gtk_container_add(GTK_CONTAINER(toolitem), widget);
1964 #if GTK_CHECK_VERSION(3, 14, 0) 1965 arrow = gtk_image_new_from_icon_name(
"remmina-pan-down-symbolic", GTK_ICON_SIZE_SMALL_TOOLBAR);
1967 arrow = gtk_arrow_new(GTK_ARROW_DOWN, GTK_SHADOW_NONE);
1969 gtk_widget_show(arrow);
1970 gtk_container_add(GTK_CONTAINER(widget), arrow);
1972 priv->fullscreen_option_button = widget;
1974 gtk_widget_set_sensitive(GTK_WIDGET(widget), FALSE);
1978 toolitem = gtk_toggle_tool_button_new();
1979 gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(toolitem),
"remmina-switch-page-symbolic");
1982 gtk_toolbar_insert(GTK_TOOLBAR(toolbar), toolitem, -1);
1983 gtk_widget_show(GTK_WIDGET(toolitem));
1985 priv->toolitem_switch_page = toolitem;
1987 toolitem = gtk_separator_tool_item_new();
1988 gtk_toolbar_insert(GTK_TOOLBAR(toolbar), toolitem, -1);
1989 gtk_widget_show(GTK_WIDGET(toolitem));
1992 toolitem = gtk_toggle_tool_button_new();
1993 gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(toolitem),
"remmina-dynres-symbolic");
1996 gtk_toolbar_insert(GTK_TOOLBAR(toolbar), toolitem, -1);
1997 gtk_widget_show(GTK_WIDGET(toolitem));
1999 priv->toolitem_dynres = toolitem;
2002 toolitem = gtk_toggle_tool_button_new();
2003 gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(toolitem),
"remmina-scale-symbolic");
2005 gtk_toolbar_insert(GTK_TOOLBAR(toolbar), toolitem, -1);
2006 gtk_widget_show(GTK_WIDGET(toolitem));
2008 priv->toolitem_scale = toolitem;
2011 toolitem = gtk_tool_item_new();
2012 gtk_widget_show(GTK_WIDGET(toolitem));
2013 gtk_toolbar_insert(GTK_TOOLBAR(toolbar), toolitem, -1);
2014 widget = gtk_toggle_button_new();
2015 gtk_widget_show(widget);
2016 gtk_container_set_border_width(GTK_CONTAINER(widget), 0);
2017 gtk_button_set_relief(GTK_BUTTON(widget), GTK_RELIEF_NONE);
2018 #if GTK_CHECK_VERSION(3, 20, 0) 2019 gtk_widget_set_focus_on_click(GTK_WIDGET(widget), FALSE);
2021 gtk_button_set_focus_on_click(GTK_BUTTON(widget), FALSE);
2024 gtk_widget_set_name(widget,
"remmina-small-button");
2026 gtk_container_add(GTK_CONTAINER(toolitem), widget);
2027 #if GTK_CHECK_VERSION(3, 14, 0) 2028 arrow = gtk_image_new_from_icon_name(
"remmina-pan-down-symbolic", GTK_ICON_SIZE_SMALL_TOOLBAR);
2030 arrow = gtk_arrow_new(GTK_ARROW_DOWN, GTK_SHADOW_NONE);
2032 gtk_widget_show(arrow);
2033 gtk_container_add(GTK_CONTAINER(widget), arrow);
2035 priv->scaler_option_button = widget;
2038 toolitem = gtk_toggle_tool_button_new();
2039 gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(toolitem),
"remmina-keyboard-symbolic");
2042 gtk_toolbar_insert(GTK_TOOLBAR(toolbar), toolitem, -1);
2043 gtk_widget_show(GTK_WIDGET(toolitem));
2045 priv->toolitem_grab = toolitem;
2047 toolitem = gtk_toggle_tool_button_new();
2048 gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(toolitem),
"remmina-preferences-system-symbolic");
2049 gtk_tool_item_set_tooltip_text(toolitem, _(
"Preferences"));
2050 gtk_toolbar_insert(GTK_TOOLBAR(toolbar), toolitem, -1);
2051 gtk_widget_show(GTK_WIDGET(toolitem));
2053 priv->toolitem_preferences = toolitem;
2055 toolitem = gtk_toggle_tool_button_new();
2056 gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(toolitem),
"remmina-system-run-symbolic");
2057 gtk_tool_button_set_label(GTK_TOOL_BUTTON(toolitem), _(
"Tools"));
2058 gtk_tool_item_set_tooltip_text(toolitem, _(
"Tools"));
2059 gtk_toolbar_insert(GTK_TOOLBAR(toolbar), toolitem, -1);
2060 gtk_widget_show(GTK_WIDGET(toolitem));
2062 priv->toolitem_tools = toolitem;
2064 toolitem = gtk_separator_tool_item_new();
2065 gtk_toolbar_insert(GTK_TOOLBAR(toolbar), toolitem, -1);
2066 gtk_widget_show(GTK_WIDGET(toolitem));
2068 toolitem = gtk_tool_button_new(NULL,
"_Screenshot");
2069 gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(toolitem),
"remmina-camera-photo-symbolic");
2071 gtk_toolbar_insert(GTK_TOOLBAR(toolbar), toolitem, -1);
2072 gtk_widget_show(GTK_WIDGET(toolitem));
2074 priv->toolitem_screenshot = toolitem;
2076 toolitem = gtk_tool_button_new(NULL,
"_Bottom");
2077 gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(toolitem),
"remmina-go-bottom-symbolic");
2079 gtk_toolbar_insert(GTK_TOOLBAR(toolbar), toolitem, -1);
2080 gtk_widget_show(GTK_WIDGET(toolitem));
2083 gtk_widget_set_sensitive(GTK_WIDGET(toolitem), FALSE);
2086 toolitem = gtk_tool_button_new(NULL,
"_Disconnect");
2087 gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(toolitem),
"remmina-disconnect-symbolic");
2089 gtk_toolbar_insert(GTK_TOOLBAR(toolbar), toolitem, -1);
2090 gtk_widget_show(GTK_WIDGET(toolitem));
2093 priv->toolbar_is_reconfiguring = FALSE;
2102 gtk_orientable_set_orientation(GTK_ORIENTABLE(toolbar), GTK_ORIENTATION_VERTICAL);
2104 gtk_orientable_set_orientation(GTK_ORIENTABLE(toolbar), GTK_ORIENTATION_HORIZONTAL);
2107 switch (toolbar_placement) {
2109 gtk_widget_set_hexpand(GTK_WIDGET(toolbar), TRUE);
2110 gtk_widget_set_vexpand(GTK_WIDGET(toolbar), FALSE);
2111 gtk_grid_attach_next_to(GTK_GRID(grid), GTK_WIDGET(toolbar), sibling, GTK_POS_TOP, 1, 1);
2114 gtk_widget_set_vexpand(GTK_WIDGET(toolbar), TRUE);
2115 gtk_widget_set_hexpand(GTK_WIDGET(toolbar), FALSE);
2116 gtk_grid_attach_next_to(GTK_GRID(grid), GTK_WIDGET(toolbar), sibling, GTK_POS_RIGHT, 1, 1);
2119 gtk_widget_set_hexpand(GTK_WIDGET(toolbar), TRUE);
2120 gtk_widget_set_vexpand(GTK_WIDGET(toolbar), FALSE);
2121 gtk_grid_attach_next_to(GTK_GRID(grid), GTK_WIDGET(toolbar), sibling, GTK_POS_BOTTOM, 1, 1);
2124 gtk_widget_set_vexpand(GTK_WIDGET(toolbar), TRUE);
2125 gtk_widget_set_hexpand(GTK_WIDGET(toolbar), FALSE);
2126 gtk_grid_attach_next_to(GTK_GRID(grid), GTK_WIDGET(toolbar), sibling, GTK_POS_LEFT, 1, 1);
2134 TRACE_CALL(__func__);
2137 GtkToolItem* toolitem;
2138 gboolean bval, dynres_avail, scale_avail;
2139 gboolean test_floating_toolbar;
2142 priv->toolbar_is_reconfiguring = TRUE;
2147 toolitem = priv->toolitem_switch_page;
2151 bval = (gtk_notebook_get_n_pages(GTK_NOTEBOOK(priv->notebook)) > 1);
2153 gtk_widget_set_sensitive(GTK_WIDGET(toolitem), bval);
2156 gtk_widget_set_sensitive(GTK_WIDGET(priv->toolitem_dynres), dynres_avail && cnnobj->
connected);
2157 gtk_widget_set_sensitive(GTK_WIDGET(priv->toolitem_scale), scale_avail && cnnobj->
connected);
2159 switch (scalemode) {
2161 gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(priv->toolitem_dynres), FALSE);
2162 gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(priv->toolitem_scale), FALSE);
2163 gtk_widget_set_sensitive(GTK_WIDGET(priv->scaler_option_button), FALSE);
2166 gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(priv->toolitem_dynres), FALSE);
2167 gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(priv->toolitem_scale), TRUE);
2168 gtk_widget_set_sensitive(GTK_WIDGET(priv->scaler_option_button), TRUE && cnnobj->
connected);
2171 gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(priv->toolitem_dynres), TRUE);
2172 gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(priv->toolitem_scale), FALSE);
2173 gtk_widget_set_sensitive(GTK_WIDGET(priv->scaler_option_button), FALSE);
2177 toolitem = priv->toolitem_grab;
2178 gtk_widget_set_sensitive(GTK_WIDGET(toolitem), cnnobj->
connected);
2179 gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(toolitem),
2182 toolitem = priv->toolitem_preferences;
2183 gtk_widget_set_sensitive(GTK_WIDGET(toolitem), cnnobj->
connected);
2186 gtk_widget_set_sensitive(GTK_WIDGET(toolitem), bval);
2188 toolitem = priv->toolitem_tools;
2191 gtk_widget_set_sensitive(GTK_WIDGET(toolitem), bval && cnnobj->
connected);
2193 gtk_widget_set_sensitive(GTK_WIDGET(priv->toolitem_screenshot), cnnobj->
connected);
2197 test_floating_toolbar = (priv->floating_toolbar_widget != NULL);
2198 if (test_floating_toolbar) {
2199 gtk_label_set_text(GTK_LABEL(priv->floating_toolbar_label),
2203 priv->toolbar_is_reconfiguring = FALSE;
2209 TRACE_CALL(__func__);
2215 gtk_widget_hide(priv->toolbar);
2217 gtk_widget_show(priv->toolbar);
2223 RemminaConnectionHolder* cnnhld)
2225 TRACE_CALL(__func__);
2233 TRACE_CALL(__func__);
2234 RemminaConnectionHolder* cnnhld = cnnobj->
cnnhld;
2236 if (!priv->sticky && event->mode == GDK_CROSSING_NORMAL) {
2245 TRACE_CALL(__func__);
2255 TRACE_CALL(__func__);
2259 cnnhld->hostkey_activated = FALSE;
2274 TRACE_CALL(__func__);
2275 #if DEBUG_KB_GRABBING 2276 printf(
"DEBUG_KB_GRABBING: focus out and mouse_pointer_entered is %s\n", cnnhld->cnnwin->priv->mouse_pointer_entered ?
"true" :
"false");
2284 TRACE_CALL(__func__);
2285 #if DEBUG_KB_GRABBING 2286 printf(
"DEBUG_KB_GRABBING: focus in and mouse_pointer_entered is %s\n", cnnhld->cnnwin->priv->mouse_pointer_entered ?
"true" :
"false");
2294 TRACE_CALL(__func__);
2295 cnnhld->cnnwin->priv->mouse_pointer_entered = TRUE;
2296 DECLARE_CNNOBJ_WITH_RETURN(FALSE);
2298 #if DEBUG_KB_GRABBING 2299 printf(
"DEBUG_KB_GRABBING: enter detail=");
2300 switch (event->detail) {
2301 case GDK_NOTIFY_ANCESTOR: printf(
"GDK_NOTIFY_ANCESTOR");
break;
2302 case GDK_NOTIFY_VIRTUAL: printf(
"GDK_NOTIFY_VIRTUAL");
break;
2303 case GDK_NOTIFY_NONLINEAR: printf(
"GDK_NOTIFY_NONLINEAR");
break;
2304 case GDK_NOTIFY_NONLINEAR_VIRTUAL: printf(
"GDK_NOTIFY_NONLINEAR_VIRTUAL");
break;
2305 case GDK_NOTIFY_UNKNOWN: printf(
"GDK_NOTIFY_UNKNOWN");
break;
2306 case GDK_NOTIFY_INFERIOR: printf(
"GDK_NOTIFY_INFERIOR");
break;
2310 if (gtk_window_is_active(GTK_WINDOW(cnnhld->cnnwin))) {
2320 TRACE_CALL(__func__);
2321 #if DEBUG_KB_GRABBING 2322 printf(
"DEBUG_KB_GRABBING: leave detail=");
2323 switch (event->detail) {
2324 case GDK_NOTIFY_ANCESTOR: printf(
"GDK_NOTIFY_ANCESTOR");
break;
2325 case GDK_NOTIFY_VIRTUAL: printf(
"GDK_NOTIFY_VIRTUAL");
break;
2326 case GDK_NOTIFY_NONLINEAR: printf(
"GDK_NOTIFY_NONLINEAR");
break;
2327 case GDK_NOTIFY_NONLINEAR_VIRTUAL: printf(
"GDK_NOTIFY_NONLINEAR_VIRTUAL");
break;
2328 case GDK_NOTIFY_UNKNOWN: printf(
"GDK_NOTIFY_UNKNOWN");
break;
2329 case GDK_NOTIFY_INFERIOR: printf(
"GDK_NOTIFY_INFERIOR");
break;
2331 printf(
" x=%f y=%f\n", event->x, event->y);
2332 printf(
" focus=%s\n", event->focus ?
"yes" :
"no");
2340 if (event->detail == GDK_NOTIFY_VIRTUAL || event->detail == GDK_NOTIFY_ANCESTOR ||
2341 event->detail == GDK_NOTIFY_NONLINEAR_VIRTUAL || event->detail == GDK_NOTIFY_NONLINEAR) {
2342 cnnhld->cnnwin->priv->mouse_pointer_entered = FALSE;
2351 TRACE_CALL(__func__);
2353 priv->hidetb_timer = 0;
2359 RemminaConnectionHolder* cnnhld)
2361 TRACE_CALL(__func__);
2362 DECLARE_CNNOBJ_WITH_RETURN(FALSE)
2366 switch (event->direction) {
2374 case GDK_SCROLL_DOWN:
2375 if (opacity < TOOLBAR_OPACITY_LEVEL) {
2381 #ifdef GDK_SCROLL_SMOOTH 2382 case GDK_SCROLL_SMOOTH:
2383 if (event->delta_y < 0 && opacity > 0) {
2388 if (event->delta_y > 0 && opacity < TOOLBAR_OPACITY_LEVEL) {
2403 TRACE_CALL(__func__);
2408 RemminaConnectionHolder* cnnhld;
2410 cnnhld = (RemminaConnectionHolder*)user_data;
2412 s = gdk_window_get_state(gtk_widget_get_window(GTK_WIDGET(cnnhld->cnnwin)));
2414 if (!cnnhld || !cnnhld->cnnwin)
2419 npages = gtk_notebook_get_n_pages(GTK_NOTEBOOK(cnnhld->cnnwin->priv->notebook));
2420 for (ipg = 0; ipg < npages; ipg++) {
2421 cnnobj = g_object_get_data(
2422 G_OBJECT(gtk_notebook_get_nth_page(GTK_NOTEBOOK(cnnhld->cnnwin->priv->notebook), ipg)),
2424 if (s & GDK_WINDOW_STATE_MAXIMIZED) {
2427 gtk_window_get_size(GTK_WINDOW(cnnhld->cnnwin), &width, &height);
2433 cnnhld->cnnwin->priv->savestate_eventsourceid = 0;
2438 RemminaConnectionHolder* cnnhld)
2440 TRACE_CALL(__func__);
2441 DECLARE_CNNOBJ_WITH_RETURN(FALSE)
2443 if (cnnhld->cnnwin->priv->savestate_eventsourceid) {
2444 g_source_remove(cnnhld->cnnwin->priv->savestate_eventsourceid);
2445 cnnhld->cnnwin->priv->savestate_eventsourceid = 0;
2448 if (cnnhld->cnnwin && gtk_widget_get_window(GTK_WIDGET(cnnhld->cnnwin))
2465 TRACE_CALL(__func__);
2466 if (cnnhld->cnnwin->priv->pin_down) {
2467 gtk_button_set_image(GTK_BUTTON(cnnhld->cnnwin->priv->pin_button),
2468 gtk_image_new_from_icon_name(
"remmina-pin-down-symbolic", GTK_ICON_SIZE_MENU));
2470 gtk_button_set_image(GTK_BUTTON(cnnhld->cnnwin->priv->pin_button),
2471 gtk_image_new_from_icon_name(
"remmina-pin-up-symbolic", GTK_ICON_SIZE_MENU));
2477 TRACE_CALL(__func__);
2478 remmina_pref.
toolbar_pin_down = cnnhld->cnnwin->priv->pin_down = !cnnhld->cnnwin->priv->pin_down;
2485 TRACE_CALL(__func__);
2488 GtkWidget* ftb_widget;
2492 GtkWidget* pinbutton;
2497 ftb_widget = gtk_event_box_new();
2499 vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
2500 gtk_widget_show(vbox);
2502 gtk_container_add(GTK_CONTAINER(ftb_widget), vbox);
2505 hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
2506 gtk_widget_show(hbox);
2510 pinbutton = gtk_button_new();
2511 gtk_widget_show(pinbutton);
2512 gtk_box_pack_start(GTK_BOX(hbox), pinbutton, FALSE, FALSE, 0);
2513 gtk_button_set_relief(GTK_BUTTON(pinbutton), GTK_RELIEF_NONE);
2514 #if GTK_CHECK_VERSION(3, 20, 0) 2515 gtk_widget_set_focus_on_click(GTK_WIDGET(pinbutton), FALSE);
2517 gtk_button_set_focus_on_click(GTK_BUTTON(pinbutton), FALSE);
2519 gtk_widget_set_name(pinbutton,
"remmina-pin-button");
2521 priv->pin_button = pinbutton;
2527 gtk_label_set_max_width_chars(GTK_LABEL(label), 50);
2528 gtk_widget_show(label);
2530 gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, TRUE, 0);
2532 priv->floating_toolbar_label = label;
2536 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
2537 gtk_box_pack_start(GTK_BOX(vbox), tb, FALSE, FALSE, 0);
2539 gtk_box_pack_start(GTK_BOX(vbox), tb, FALSE, FALSE, 0);
2540 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
2543 priv->floating_toolbar_widget = ftb_widget;
2544 gtk_widget_show(ftb_widget);
2550 TRACE_CALL(__func__);
2553 priv = cnnwin->
priv;
2555 if (priv->toolbar && priv->grid) {
2556 g_object_ref(priv->toolbar);
2557 gtk_container_remove(GTK_CONTAINER(priv->grid), priv->toolbar);
2559 g_object_unref(priv->toolbar);
2566 TRACE_CALL(__func__);
2570 cnnwin->
priv = priv;
2576 priv->floating_toolbar_opacity = 1.0;
2577 priv->kbcaptured = FALSE;
2578 priv->mouse_pointer_entered = FALSE;
2580 gtk_container_set_border_width(GTK_CONTAINER(cnnwin), 0);
2589 TRACE_CALL(__func__);
2591 if (event->changed_mask & GDK_WINDOW_STATE_FOCUSED) {
2592 if (event->new_window_state & GDK_WINDOW_STATE_FOCUSED)
2598 #ifdef ENABLE_MINIMIZE_TO_TRAY 2601 screen = gdk_screen_get_default();
2602 if (remmina_pref.minimize_to_tray && (event->changed_mask & GDK_WINDOW_STATE_ICONIFIED) != 0
2603 && (event->new_window_state & GDK_WINDOW_STATE_ICONIFIED) != 0
2606 && gdk_screen_get_number(screen) == gdk_screen_get_number(gtk_widget_get_screen(widget))) {
2607 gtk_widget_hide(widget);
2617 TRACE_CALL(__func__);
2620 cnnwin = REMMINA_CONNECTION_WINDOW(g_object_new(REMMINA_TYPE_CONNECTION_WINDOW, NULL));
2621 cnnwin->
priv->cnnhld = cnnhld;
2639 return GTK_WIDGET(cnnwin);
2647 TRACE_CALL(__func__);
2661 g_object_set_data_full(G_OBJECT(cnnwin),
"tag", tag, (GDestroyNotify)g_free);
2666 TRACE_CALL(__func__);
2667 GtkWidget* container;
2672 container = gtk_scrolled_window_new(NULL, NULL);
2674 gtk_container_set_border_width(GTK_CONTAINER(container), 0);
2675 gtk_widget_set_can_focus(container, FALSE);
2678 gtk_widget_set_name(container,
"remmina-scrolled-container");
2680 gtk_widget_show(container);
2689 TRACE_CALL(__func__);
2693 child = gtk_notebook_get_nth_page(notebook, gtk_notebook_get_current_page(notebook));
2694 cnnobj = g_object_get_data(G_OBJECT(child),
"cnnobj");
2695 if (GTK_IS_WIDGET(cnnobj->
proto)) {
2702 TRACE_CALL(__func__);
2704 RemminaConnectionHolder* cnnhld = cnnobj->
cnnhld;
2706 if (cnnhld && cnnhld->cnnwin) {
2707 gtk_notebook_remove_page(
2708 GTK_NOTEBOOK(cnnhld->cnnwin->priv->notebook),
2709 gtk_notebook_page_num(GTK_NOTEBOOK(cnnhld->cnnwin->priv->notebook),
2721 TRACE_CALL(__func__);
2722 if (REMMINA_IS_PROTOCOL_WIDGET(cnnobj->
proto)) {
2732 TRACE_CALL(__func__);
2738 hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 4);
2739 gtk_widget_show(hbox);
2742 gtk_widget_show(widget);
2743 gtk_box_pack_start(GTK_BOX(hbox), widget, FALSE, FALSE, 0);
2746 gtk_widget_set_valign(widget, GTK_ALIGN_CENTER);
2747 gtk_widget_set_halign(widget, GTK_ALIGN_CENTER);
2749 gtk_widget_show(widget);
2750 gtk_box_pack_start(GTK_BOX(hbox), widget, TRUE, TRUE, 0);
2752 button = gtk_button_new();
2753 gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE);
2754 #if GTK_CHECK_VERSION(3, 20, 0) 2755 gtk_widget_set_focus_on_click(GTK_WIDGET(widget), FALSE);
2757 gtk_button_set_focus_on_click(GTK_BUTTON(button), FALSE);
2759 gtk_widget_set_name(button,
"remmina-small-button");
2760 gtk_widget_show(button);
2762 widget = gtk_image_new_from_icon_name(
"window-close", GTK_ICON_SIZE_MENU);
2763 gtk_widget_show(widget);
2764 gtk_container_add(GTK_CONTAINER(button), widget);
2766 gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
2776 TRACE_CALL(__func__);
2779 cnnobj->
page = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
2780 g_object_set_data(G_OBJECT(cnnobj->
page),
"cnnobj", cnnobj);
2781 gtk_widget_set_name(cnnobj->
page,
"remmina-tab-page");
2785 i = gtk_notebook_append_page(notebook, cnnobj->
page, tab);
2787 gtk_notebook_set_tab_reorderable(notebook, cnnobj->
page, TRUE);
2788 gtk_notebook_set_tab_detachable(notebook, cnnobj->
page, TRUE);
2790 gtk_widget_set_can_focus(gtk_widget_get_parent(tab), FALSE);
2792 gtk_widget_show(cnnobj->
page);
2800 TRACE_CALL(__func__);
2804 GtkWidget* frompage;
2812 n = gtk_notebook_get_n_pages(from);
2813 for (i = 0; i < n; i++) {
2814 widget = gtk_notebook_get_nth_page(from, i);
2834 gtk_notebook_set_current_page(to, 0);
2839 if (from != NULL && GTK_IS_NOTEBOOK(from)) {
2840 c = gtk_notebook_get_current_page(from);
2841 n = gtk_notebook_get_n_pages(from);
2842 for (i = 0; i < n; i++) {
2843 frompage = gtk_notebook_get_nth_page(from, i);
2849 lst = gtk_container_get_children(GTK_CONTAINER(frompage));
2850 for (l = lst; l != NULL; l = l->next) {
2851 if (REMMINA_IS_MESSAGE_PANEL(l->data)) {
2852 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
2853 gtk_widget_reparent(l->data, tc->
page);
2854 G_GNUC_END_IGNORE_DEPRECATIONS
2855 gtk_box_reorder_child(GTK_BOX(tc->
page), GTK_WIDGET(l->data), 0);
2861 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
2863 G_GNUC_END_IGNORE_DEPRECATIONS
2865 gtk_notebook_set_current_page(to, c);
2872 TRACE_CALL(__func__);
2873 GtkNotebook* notebook;
2876 if (!cnnhld->cnnwin)
2879 notebook = GTK_NOTEBOOK(cnnhld->cnnwin->priv->notebook);
2881 switch (cnnhld->cnnwin->priv->view_mode) {
2883 n = gtk_notebook_get_n_pages(notebook);
2884 gtk_notebook_set_show_tabs(notebook, remmina_pref.
always_show_tab ? TRUE : n > 1);
2885 gtk_notebook_set_show_border(notebook, remmina_pref.
always_show_tab ? TRUE : n > 1);
2888 gtk_notebook_set_show_tabs(notebook, FALSE);
2889 gtk_notebook_set_show_border(notebook, FALSE);
2896 TRACE_CALL(__func__);
2897 RemminaConnectionHolder* cnnhld = (RemminaConnectionHolder*)data;
2900 if (GTK_IS_WIDGET(cnnhld->cnnwin)) {
2902 if (!priv->hidetb_timer)
2903 priv->hidetb_timer = g_timeout_add(TB_HIDE_TIME_TIME, (GSourceFunc)
2912 priv->switch_page_handler = 0;
2917 RemminaConnectionHolder* cnnhld)
2919 TRACE_CALL(__func__);
2922 if (!priv->switch_page_handler) {
2928 RemminaConnectionHolder* cnnhld)
2930 if (gtk_notebook_get_n_pages(GTK_NOTEBOOK(cnnhld->cnnwin->priv->notebook)) > 0)
2935 RemminaConnectionHolder* cnnhld)
2937 TRACE_CALL(__func__);
2939 if (!cnnhld->cnnwin)
2942 if (gtk_notebook_get_n_pages(GTK_NOTEBOOK(cnnhld->cnnwin->priv->notebook)) <= 0) {
2943 gtk_widget_destroy(GTK_WIDGET(cnnhld->cnnwin));
2944 cnnhld->cnnwin = NULL;
2954 TRACE_CALL(__func__);
2960 #if GTK_CHECK_VERSION(3, 20, 0) 2963 GdkDeviceManager *manager;
2965 GdkDevice* device = NULL;
2967 #if GTK_CHECK_VERSION(3, 20, 0) 2968 seat = gdk_display_get_default_seat(gdk_display_get_default());
2969 device = gdk_seat_get_pointer(seat);
2971 manager = gdk_display_get_device_manager(gdk_display_get_default());
2972 device = gdk_device_manager_get_client_pointer(manager);
2975 window = gdk_device_get_window_at_position(device, &x, &y);
2976 srccnnwin = REMMINA_CONNECTION_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(notebook)));
2979 if (srccnnwin == dstcnnwin)
2982 if (gtk_notebook_get_n_pages(GTK_NOTEBOOK(srccnnwin->
priv->notebook)) == 1 && !dstcnnwin)
2990 cnnobj->
cnnhld = g_new0(RemminaConnectionHolder, 1);
2991 if (!cnnobj->
cnnhld->cnnwin) {
2994 cnnobj->
cnnhld->cnnwin = srccnnwin;
3002 return GTK_NOTEBOOK(cnnobj->
cnnhld->cnnwin->priv->notebook);
3008 TRACE_CALL(__func__);
3009 GtkWidget* notebook;
3011 notebook = gtk_notebook_new();
3013 gtk_notebook_set_scrollable(GTK_NOTEBOOK(notebook), TRUE);
3014 gtk_widget_show(notebook);
3021 gtk_widget_set_can_focus(notebook, FALSE);
3029 TRACE_CALL(__func__);
3031 GtkWidget* oldwindow;
3034 GtkWidget* notebook;
3037 int newwin_width, newwin_height;
3039 oldwindow = GTK_WIDGET(cnnhld->cnnwin);
3041 gtk_widget_realize(window);
3042 cnnhld->cnnwin = REMMINA_CONNECTION_WINDOW(window);
3045 newwin_width = newwin_height = 100;
3057 np = gtk_notebook_get_current_page(GTK_NOTEBOOK(REMMINA_CONNECTION_WINDOW(oldwindow)->priv->notebook));
3058 page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(REMMINA_CONNECTION_WINDOW(oldwindow)->priv->notebook), np);
3064 gtk_window_set_default_size(GTK_WINDOW(cnnhld->cnnwin), newwin_width, newwin_height);
3073 grid = gtk_grid_new();
3074 gtk_grid_attach(GTK_GRID(grid), notebook, 0, 0, 1, 1);
3076 gtk_widget_set_hexpand(notebook, TRUE);
3077 gtk_widget_set_vexpand(notebook, TRUE);
3082 gtk_container_add(GTK_CONTAINER(window), grid);
3084 chain = g_list_append(NULL, notebook);
3085 gtk_container_set_focus_chain(GTK_CONTAINER(grid), chain);
3089 gtk_drag_source_set(GTK_WIDGET(toolbar), GDK_BUTTON1_MASK,
3090 dnd_targets_tb,
sizeof dnd_targets_tb /
sizeof *dnd_targets_tb, GDK_ACTION_MOVE);
3095 gtk_drag_dest_set(GTK_WIDGET(notebook), GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_HIGHLIGHT,
3096 dnd_targets_tb,
sizeof dnd_targets_tb /
sizeof *dnd_targets_tb, GDK_ACTION_MOVE);
3097 gtk_drag_dest_set_track_motion(GTK_WIDGET(notebook), TRUE);
3101 cnnhld->cnnwin->priv->toolbar = toolbar;
3102 cnnhld->cnnwin->priv->grid = grid;
3103 cnnhld->cnnwin->priv->notebook = notebook;
3107 gtk_widget_show(grid);
3108 gtk_widget_show(GTK_WIDGET(cnnhld->cnnwin));
3111 (oldwindow ? GTK_NOTEBOOK(REMMINA_CONNECTION_WINDOW(oldwindow)->priv->notebook) : NULL), cnnobj,
3119 gtk_window_maximize(GTK_WINDOW(cnnhld->cnnwin));
3124 tag = g_strdup((gchar*)g_object_get_data(G_OBJECT(oldwindow),
"tag"));
3125 g_object_set_data_full(G_OBJECT(cnnhld->cnnwin),
"tag", tag, (GDestroyNotify)g_free);
3127 gtk_widget_destroy(oldwindow);
3138 TRACE_CALL(__func__);
3139 RemminaConnectionHolder* cnnhld;
3141 cnnhld = (RemminaConnectionHolder*)data;
3143 #if GTK_CHECK_VERSION(3, 18, 0) 3145 gtk_window_fullscreen_on_monitor(GTK_WINDOW(cnnhld->cnnwin),
3146 gdk_screen_get_default(),
3147 gdk_screen_get_monitor_at_window
3148 (gdk_screen_get_default(), gtk_widget_get_window(GTK_WIDGET(cnnhld->cnnwin))
3152 gtk_window_fullscreen(GTK_WINDOW(cnnhld->cnnwin));
3155 remmina_log_print(
"Cannot fullscreen on a specific monitor, feature available from GTK 3.18");
3156 gtk_window_fullscreen(GTK_WINDOW(cnnhld->cnnwin));
3163 TRACE_CALL(__func__);
3165 GtkWidget* revealer;
3167 priv = cnnhld->cnnwin->priv;
3169 if (priv->overlay_ftb_overlay != NULL) {
3170 gtk_widget_destroy(priv->overlay_ftb_overlay);
3171 priv->overlay_ftb_overlay = NULL;
3172 priv->revealer = NULL;
3178 priv->overlay_ftb_overlay = gtk_event_box_new();
3180 GtkWidget* vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
3181 gtk_container_set_border_width(GTK_CONTAINER(vbox), 0);
3183 GtkWidget* handle = gtk_drawing_area_new();
3184 gtk_widget_set_size_request(handle, 4, 4);
3185 gtk_widget_set_name(handle,
"ftb-handle");
3187 revealer = gtk_revealer_new();
3189 gtk_widget_set_halign(GTK_WIDGET(priv->overlay_ftb_overlay), GTK_ALIGN_CENTER);
3192 gtk_box_pack_start(GTK_BOX(vbox), handle, FALSE, FALSE, 0);
3193 gtk_box_pack_start(GTK_BOX(vbox), revealer, FALSE, FALSE, 0);
3194 gtk_revealer_set_transition_type(GTK_REVEALER(revealer), GTK_REVEALER_TRANSITION_TYPE_SLIDE_UP);
3195 gtk_widget_set_valign(GTK_WIDGET(priv->overlay_ftb_overlay), GTK_ALIGN_END);
3197 gtk_box_pack_start(GTK_BOX(vbox), revealer, FALSE, FALSE, 0);
3198 gtk_box_pack_start(GTK_BOX(vbox), handle, FALSE, FALSE, 0);
3199 gtk_revealer_set_transition_type(GTK_REVEALER(revealer), GTK_REVEALER_TRANSITION_TYPE_SLIDE_DOWN);
3200 gtk_widget_set_valign(GTK_WIDGET(priv->overlay_ftb_overlay), GTK_ALIGN_START);
3204 gtk_container_add(GTK_CONTAINER(revealer), priv->floating_toolbar_widget);
3205 gtk_widget_set_halign(GTK_WIDGET(revealer), GTK_ALIGN_CENTER);
3206 gtk_widget_set_valign(GTK_WIDGET(revealer), GTK_ALIGN_START);
3208 priv->revealer = revealer;
3211 fr = gtk_frame_new(NULL);
3212 gtk_container_add(GTK_CONTAINER(priv->overlay_ftb_overlay), fr );
3213 gtk_container_add(GTK_CONTAINER(fr), vbox);
3215 gtk_widget_show(vbox);
3216 gtk_widget_show(revealer);
3217 gtk_widget_show(handle);
3218 gtk_widget_show(priv->overlay_ftb_overlay);
3219 gtk_widget_show(fr);
3222 gtk_widget_set_name(fr,
"ftbbox-lower");
3224 gtk_widget_set_name(fr,
"ftbbox-upper");
3227 gtk_overlay_add_overlay(GTK_OVERLAY(priv->overlay), priv->overlay_ftb_overlay);
3233 gtk_widget_add_events(GTK_WIDGET(priv->overlay_ftb_overlay), GDK_SCROLL_MASK);
3236 gtk_drag_source_set(GTK_WIDGET(priv->overlay_ftb_overlay), GDK_BUTTON1_MASK,
3237 dnd_targets_ftb,
sizeof dnd_targets_ftb /
sizeof *dnd_targets_ftb, GDK_ACTION_MOVE);
3238 g_signal_connect_after(GTK_WIDGET(priv->overlay_ftb_overlay),
"drag-begin", G_CALLBACK(remmina_connection_window_ftb_drag_begin), cnnhld);
3243 gint x, gint y, guint time, gpointer user_data)
3245 TRACE_CALL(__func__);
3247 gint new_floating_toolbar_placement;
3248 RemminaConnectionHolder* cnnhld;
3250 cnnhld = (RemminaConnectionHolder*)user_data;
3252 gtk_widget_get_allocation(widget, &wa);
3254 if (y >= wa.height / 2) {
3260 gtk_drag_finish(context, TRUE, TRUE, time);
3275 TRACE_CALL(__func__);
3277 cairo_surface_t *surface;
3280 double dashes[] = { 10 };
3282 gtk_widget_get_allocation(widget, &wa);
3284 surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, wa.width, wa.height);
3285 cr = cairo_create(surface);
3286 cairo_set_source_rgb(cr, 0.6, 0.6, 0.6);
3287 cairo_set_line_width(cr, 2);
3288 cairo_set_dash(cr, dashes, 1, 0 );
3289 cairo_rectangle(cr, 0, 0, wa.width, wa.height);
3293 gtk_drag_set_icon_surface(context, surface);
3300 TRACE_CALL(__func__);
3302 GtkWidget* oldwindow;
3303 GtkWidget* notebook;
3308 oldwindow = GTK_WIDGET(cnnhld->cnnwin);
3310 gtk_widget_set_name(GTK_WIDGET(window),
"remmina-connection-window-fullscreen");
3311 gtk_widget_realize(window);
3313 cnnhld->cnnwin = REMMINA_CONNECTION_WINDOW(window);
3314 priv = cnnhld->cnnwin->priv;
3321 priv->overlay = gtk_overlay_new();
3322 gtk_container_add(GTK_CONTAINER(window), priv->overlay);
3323 gtk_container_add(GTK_CONTAINER(priv->overlay), notebook);
3324 gtk_widget_show(GTK_WIDGET(priv->overlay));
3326 priv->notebook = notebook;
3327 priv->view_mode = view_mode;
3328 cnnhld->fullscreen_view_mode = view_mode;
3331 (oldwindow ? GTK_NOTEBOOK(REMMINA_CONNECTION_WINDOW(oldwindow)->priv->notebook) : NULL), cnnobj,
3338 tag = g_strdup((gchar*)g_object_get_data(G_OBJECT(oldwindow),
"tag"));
3339 g_object_set_data_full(G_OBJECT(cnnhld->cnnwin),
"tag", tag, (GDestroyNotify)g_free);
3340 gtk_widget_destroy(oldwindow);
3347 gtk_drag_dest_set(GTK_WIDGET(priv->overlay), GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_HIGHLIGHT,
3348 dnd_targets_ftb,
sizeof dnd_targets_ftb /
sizeof *dnd_targets_ftb, GDK_ACTION_MOVE);
3349 gtk_drag_dest_set_track_motion(GTK_WIDGET(priv->notebook), TRUE);
3355 gtk_widget_show(window);
3363 TRACE_CALL(__func__);
3365 RemminaConnectionHolder* cnnhld = cnnobj->
cnnhld;
3372 cnnhld->hostkey_activated = FALSE;
3373 if (cnnhld->hostkey_used) {
3381 else if (cnnhld->hostkey_activated) {
3390 }
else if (remmina_pref.
hostkey && keyval == remmina_pref.
hostkey) {
3392 cnnhld->hostkey_activated = TRUE;
3393 cnnhld->hostkey_used = FALSE;
3395 }
else if (!cnnhld->hostkey_activated) {
3400 cnnhld->hostkey_used = TRUE;
3401 keyval = gdk_keyval_to_lower(keyval);
3402 if (keyval == GDK_KEY_Up || keyval == GDK_KEY_Down
3403 || keyval == GDK_KEY_Left || keyval == GDK_KEY_Right) {
3404 DECLARE_CNNOBJ_WITH_RETURN(FALSE);
3405 GtkAdjustment *adjust;
3409 if (keyval == GDK_KEY_Up || keyval == GDK_KEY_Down)
3410 adjust = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(cnnobj->
scrolled_container));
3412 adjust = gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(cnnobj->
scrolled_container));
3414 if (keyval == GDK_KEY_Up || keyval == GDK_KEY_Left)
3417 pos = gtk_adjustment_get_upper(adjust);
3419 gtk_adjustment_set_value(adjust, pos);
3420 if (keyval == GDK_KEY_Up || keyval == GDK_KEY_Down)
3421 gtk_scrolled_window_set_vadjustment(GTK_SCROLLED_WINDOW(cnnobj->
scrolled_container), adjust);
3423 gtk_scrolled_window_set_hadjustment(GTK_SCROLLED_WINDOW(cnnobj->
scrolled_container), adjust);
3436 child = gtk_bin_get_child(GTK_BIN(gsv));
3437 if (!GTK_IS_VIEWPORT(child))
3440 gsvwin = gtk_widget_get_window(GTK_WIDGET(gsv));
3444 if (keyval == GDK_KEY_Up || keyval == GDK_KEY_Down) {
3445 sz = gdk_window_get_height(gsvwin) + 2;
3446 adj = gtk_scrollable_get_vadjustment(GTK_SCROLLABLE(child));
3448 sz = gdk_window_get_width(gsvwin) + 2;
3449 adj = gtk_scrollable_get_hadjustment(GTK_SCROLLABLE(child));
3452 if (keyval == GDK_KEY_Up || keyval == GDK_KEY_Left) {
3455 value = gtk_adjustment_get_upper(GTK_ADJUSTMENT(adj)) - (gdouble)sz + 2.0;
3458 gtk_adjustment_set_value(GTK_ADJUSTMENT(adj), value);
3463 switch (priv->view_mode) {
3468 cnnhld->fullscreen_view_mode ?
3479 if (priv->toolitem_autofit && gtk_widget_is_sensitive(GTK_WIDGET(priv->toolitem_autofit))) {
3483 i = gtk_notebook_get_current_page(GTK_NOTEBOOK(priv->notebook)) + 1;
3484 if (i >= gtk_notebook_get_n_pages(GTK_NOTEBOOK(priv->notebook)))
3486 gtk_notebook_set_current_page(GTK_NOTEBOOK(priv->notebook), i);
3488 i = gtk_notebook_get_current_page(GTK_NOTEBOOK(priv->notebook)) - 1;
3490 i = gtk_notebook_get_n_pages(GTK_NOTEBOOK(priv->notebook)) - 1;
3491 gtk_notebook_set_current_page(GTK_NOTEBOOK(priv->notebook), i);
3493 if (gtk_widget_is_sensitive(GTK_WIDGET(priv->toolitem_scale))) {
3494 gtk_toggle_tool_button_set_active(
3495 GTK_TOGGLE_TOOL_BUTTON(priv->toolitem_scale),
3496 !gtk_toggle_tool_button_get_active(
3497 GTK_TOGGLE_TOOL_BUTTON(
3498 priv->toolitem_scale)));
3501 gtk_toggle_tool_button_set_active(
3502 GTK_TOGGLE_TOOL_BUTTON(priv->toolitem_grab),
3503 !gtk_toggle_tool_button_get_active(
3504 GTK_TOGGLE_TOOL_BUTTON(
3505 priv->toolitem_grab)));
3527 REMMINA_PROTOCOL_WIDGET(
3529 feature && feature->
type;
3533 && GPOINTER_TO_UINT(
3537 REMMINA_PROTOCOL_WIDGET(
3544 cnnhld->hostkey_activated = FALSE;
3551 TRACE_CALL(__func__);
3576 gtk_window_present_with_time(GTK_WINDOW(cnnobj->
cnnhld->cnnwin), (guint32)(g_get_monotonic_time() / 1000));
3584 TRACE_CALL(__func__);
3587 RemminaConnectionHolder* cnnhld;
3588 gchar *last_success;
3590 GDateTime *date = g_date_time_new_now_utc();
3598 cnnhld = cnnwin->
priv->cnnhld;
3600 cnnhld = g_new0(RemminaConnectionHolder, 1);
3615 last_success = g_strdup_printf(
"%d%02d%02d",
3616 g_date_time_get_year(date),
3617 g_date_time_get_month(date),
3618 g_date_time_get_day_of_month(date));
3629 if (cnnhld->cnnwin->priv->floating_toolbar_widget) {
3630 gtk_widget_show(cnnhld->cnnwin->priv->floating_toolbar_widget);
3642 TRACE_CALL(__func__);
3648 TRACE_CALL(__func__);
3650 RemminaConnectionHolder* cnnhld = cnnobj->
cnnhld;
3657 pparent = gtk_widget_get_parent(cnnobj->
proto);
3658 if (pparent != NULL) {
3659 g_object_ref(cnnobj->
proto);
3660 gtk_container_remove(GTK_CONTAINER(pparent), cnnobj->
proto);
3666 if (cnnhld->cnnwin) {
3673 gtk_toggle_tool_button_set_active(
3674 GTK_TOGGLE_TOOL_BUTTON(priv->toolitem_grab),
3679 RemminaMessagePanel *mp;
3696 TRACE_CALL(__func__);
3705 TRACE_CALL(__func__);
3712 TRACE_CALL(__func__);
3720 TRACE_CALL(__func__);
3729 dialog = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE,
3730 _(
"File %s is corrupted, unreadable or not found."), filename);
3731 g_signal_connect(G_OBJECT(dialog),
"response", G_CALLBACK(gtk_widget_destroy), NULL);
3732 gtk_widget_show(dialog);
3765 TRACE_CALL(__func__);
3771 TRACE_CALL(__func__);
3788 gtk_widget_set_name(GTK_WIDGET(cnnobj->
proto),
"remmina-protocol-widget");
3790 gtk_widget_set_halign(GTK_WIDGET(cnnobj->
proto), GTK_ALIGN_FILL);
3791 gtk_widget_set_valign(GTK_WIDGET(cnnobj->
proto), GTK_ALIGN_FILL);
3794 g_object_set_data(G_OBJECT(cnnobj->
proto),
"user-data", data);
3798 cnnobj->
viewport = gtk_viewport_new(NULL, NULL);
3799 gtk_widget_set_name(cnnobj->
viewport,
"remmina-cw-viewport");
3801 gtk_container_set_border_width(GTK_CONTAINER(cnnobj->
viewport), 0);
3802 gtk_viewport_set_shadow_type(GTK_VIEWPORT(cnnobj->
viewport), GTK_SHADOW_NONE);
3812 gtk_container_add(GTK_CONTAINER(cnnobj->
viewport), cnnobj->
proto);
3820 cnnobj->
cnnhld = g_new0(RemminaConnectionHolder, 1);
3834 cnnwin = cnnobj->
cnnhld->cnnwin;
3839 cnnwin->
priv->view_mode);
3842 gtk_window_present(GTK_WINDOW(cnnwin));
3843 gtk_notebook_set_current_page(GTK_NOTEBOOK(cnnwin->
priv->notebook), i);
3849 gtk_widget_show(cnnobj->
proto);
3851 if (disconnect_cb) {
3852 *handler = g_signal_connect(G_OBJECT(cnnobj->
proto),
"disconnect", disconnect_cb, data);
3869 dialog = gtk_message_dialog_new(
3872 GTK_MESSAGE_WARNING,
3874 _(
"Warning: This plugin require GtkSocket, but it’s not available."));
3875 g_signal_connect(G_OBJECT(dialog),
"response", G_CALLBACK(gtk_widget_destroy), NULL);
3876 gtk_widget_show(dialog);
3880 if (cnnwin->
priv->floating_toolbar_widget) {
3881 gtk_widget_show(cnnwin->
priv->floating_toolbar_widget);
3885 printf(
"Ok, an error occurred in initializing the protocol plugin before connecting. The error is %s.\n" 3887 return cnnobj->
proto;
3899 return cnnobj->
proto;
3905 TRACE_CALL(__func__);
3906 cnnwin->
priv->on_delete_confirm_mode = mode;
3915 TRACE_CALL(__func__);
3917 RemminaMessagePanel *lastPanel;
3918 gboolean was_visible;
3920 childs = gtk_container_get_children(GTK_CONTAINER(cnnobj->
page));
3921 cc = g_list_first(childs);
3923 if ((RemminaMessagePanel*)cc->data == mp)
3925 cc = g_list_next(cc);
3927 g_list_free(childs);
3930 printf(
"REMMINA: warning, request to destroy a RemminaMessagePanel which is not on the page\n");
3933 was_visible = gtk_widget_is_visible(GTK_WIDGET(mp));
3934 gtk_widget_destroy(GTK_WIDGET(mp));
3938 childs = gtk_container_get_children(GTK_CONTAINER(cnnobj->
page));
3939 cc = g_list_first(childs);
3942 if (G_TYPE_CHECK_INSTANCE_TYPE(cc->data, REMMINA_TYPE_MESSAGE_PANEL))
3943 lastPanel = (RemminaMessagePanel*)cc->data;
3944 cc = g_list_next(cc);
3946 g_list_free(childs);
3948 gtk_widget_show(GTK_WIDGET(lastPanel));
3961 TRACE_CALL(__func__);
3965 childs = gtk_container_get_children(GTK_CONTAINER(cnnobj->
page));
3966 cc = g_list_first(childs);
3968 if (G_TYPE_CHECK_INSTANCE_TYPE(cc->data, REMMINA_TYPE_MESSAGE_PANEL))
3969 gtk_widget_hide(GTK_WIDGET(cc->data));
3970 cc = g_list_next(cc);
3972 g_list_free(childs);
3975 gtk_box_pack_start(GTK_BOX(cnnobj->
page), GTK_WIDGET(mp), FALSE, FALSE, 0);
3976 gtk_box_reorder_child(GTK_BOX(cnnobj->
page), GTK_WIDGET(mp), 0);
3979 gtk_widget_show_all(GTK_WIDGET(mp));
gchar * remmina_pref_file
static void remmina_connection_holder_disconnect_current_page(RemminaConnectionHolder *cnnhld)
guint shortcutkey_fullscreen
RemminaConnectionHolder * cnnhld
gulong deferred_open_size_allocate_handler
static gboolean remmina_connection_window_delete_event(GtkWidget *widget, GdkEvent *event, gpointer data)
gint floating_toolbar_placement
static void remmina_connection_holder_toolbar_disconnect(GtkWidget *widget, RemminaConnectionHolder *cnnhld)
static guint remmina_connection_window_signals[LAST_SIGNAL]
static gboolean remmina_connection_window_tb_drag_drop(GtkWidget *widget, GdkDragContext *context, gint x, gint y, guint time, gpointer user_data)
guint shortcutkey_minimize
gboolean remmina_connection_window_notify_widget_toolbar_placement(GtkWidget *widget, gpointer data)
static void remmina_connection_holder_viewport_fullscreen_mode(GtkWidget *widget, RemminaConnectionHolder *cnnhld)
static void remmina_connection_window_toolbar_place_signal(RemminaConnectionWindow *cnnwin, gpointer data)
const gchar * remmina_file_get_string(RemminaFile *remminafile, const gchar *setting)
static gboolean remmina_connection_holder_keyboard_grab_retry(gpointer user_data)
static gboolean remmina_connection_window_state_event(GtkWidget *widget, GdkEventWindowState *event, gpointer user_data)
static void remmina_connection_holder_scaler_option_popdown(GtkWidget *widget, RemminaConnectionHolder *cnnhld)
static void remmina_connection_holder_update_pin(RemminaConnectionHolder *cnnhld)
static gboolean remmina_connection_window_after_configure_scrolled(gpointer user_data)
static void remmina_connection_holder_call_protocol_feature_radio(GtkMenuItem *menuitem, RemminaConnectionHolder *cnnhld)
static const GtkTargetEntry dnd_targets_tb[]
static void remmina_connection_holder_toolbar_preferences(GtkWidget *widget, RemminaConnectionHolder *cnnhld)
const gchar * remmina_file_get_filename(RemminaFile *remminafile)
void remmina_public_send_notification(const gchar *notification_id, const gchar *notification_title, const gchar *notification_message)
guint shortcutkey_screenshot
typedefG_BEGIN_DECLS struct _RemminaFile RemminaFile
guint shortcutkey_prevtab
static void remmina_connection_holder_toolbar_preferences_popdown(GtkWidget *widget, RemminaConnectionHolder *cnnhld)
static RemminaScaleMode get_current_allowed_scale_mode(RemminaConnectionObject *cnnobj, gboolean *dynres_avail, gboolean *scale_avail)
static void rpw_size_allocated_on_connection(GtkWidget *w, GdkRectangle *allocation, gpointer user_data)
guint remmina_public_get_window_workspace(GtkWindow *gtkwindow)
static void remmina_connection_holder_keyboard_ungrab(RemminaConnectionHolder *cnnhld)
gboolean plugin_can_scale
static gboolean remmina_connection_object_enter_protocol_widget(GtkWidget *widget, GdkEventCrossing *event, RemminaConnectionObject *cnnobj)
static void remmina_protocol_widget_update_alignment(RemminaConnectionObject *cnnobj)
static gboolean remmina_connection_window_focus_in_event(GtkWidget *widget, GdkEvent *event, RemminaConnectionHolder *cnnhld)
static void remmina_connection_holder_toolbar_minimize(GtkWidget *widget, RemminaConnectionHolder *cnnhld)
static void remmina_connection_holder_scaler_keep_aspect(GtkWidget *widget, RemminaConnectionHolder *cnnhld)
static void remmina_connection_holder_switch_page_activate(GtkMenuItem *menuitem, RemminaConnectionHolder *cnnhld)
struct _RemminaConnectionObject RemminaConnectionObject
static void remmina_connection_holder_toolbar_tools_popdown(GtkWidget *widget, RemminaConnectionHolder *cnnhld)
static void remmina_connection_holder_create_floating_toolbar(RemminaConnectionHolder *cnnhld, gint mode)
static void remmina_connection_holder_update_toolbar_autofit_button(RemminaConnectionHolder *cnnhld)
void remmina_message_panel_focus_auth_entry(RemminaMessagePanel *mp)
static const GtkTargetEntry dnd_targets_ftb[]
static void remmina_connection_holder_grab_focus(GtkNotebook *notebook)
guint shortcutkey_autofit
static void remmina_connection_object_on_unlock_dynres(RemminaProtocolWidget *gp, gpointer data)
struct _RemminaConnectionWindowPriv RemminaConnectionWindowPriv
static gboolean remmina_connection_holder_on_switch_page_real(gpointer data)
void remmina_pref_add_recent(const gchar *protocol, const gchar *server)
GtkNotebook * remmina_connection_holder_on_notebook_create_window(GtkNotebook *notebook, GtkWidget *page, gint x, gint y, gpointer data)
gboolean deny_screenshot_clipboard
static void remmina_connection_holder_on_switch_page(GtkNotebook *notebook, GtkWidget *page, guint page_num, RemminaConnectionHolder *cnnhld)
static void remmina_connection_holder_set_tooltip(GtkWidget *item, const gchar *tip, guint key1, guint key2)
void remmina_connection_object_destroy_message_panel(RemminaConnectionObject *cnnobj, RemminaMessagePanel *mp)
Deletes a RemminaMessagePanel from the current cnnobj and if it was visible, make visible the last re...
static GtkWidget * remmina_connection_holder_create_notebook(RemminaConnectionHolder *cnnhld)
void remmina_connection_object_show_message_panel(RemminaConnectionObject *cnnobj, RemminaMessagePanel *mp)
Each cnnobj->page can have more than one RemminaMessagePanel, but 0 or 1 are visible.
static void remmina_connection_holder_get_desktop_size(RemminaConnectionHolder *cnnhld, gint *width, gint *height)
static gboolean remmina_connection_window_hostkey_func(RemminaProtocolWidget *gp, guint keyval, gboolean release)
static gboolean remmina_connection_window_focus_out_event(GtkWidget *widget, GdkEvent *event, RemminaConnectionHolder *cnnhld)
static void remmina_connection_object_create_scrolled_container(RemminaConnectionObject *cnnobj, gint view_mode)
static RemminaConnectionWindow * remmina_connection_window_find(RemminaFile *remminafile)
guint remmina_public_get_current_workspace(GdkScreen *screen)
General utility functions, non-GTK related.
static void remmina_connection_holder_toolbar_preferences_radio(RemminaConnectionHolder *cnnhld, RemminaFile *remminafile, GtkWidget *menu, const RemminaProtocolFeature *feature, const gchar *domain, gboolean enabled)
static void remmina_connection_holder_toolbar_scaler_option(GtkWidget *widget, RemminaConnectionHolder *cnnhld)
const gchar * screenshot_path
static void remmina_connection_holder_check_resize(RemminaConnectionHolder *cnnhld)
static void remmina_connection_holder_toolbar_grab(GtkWidget *widget, RemminaConnectionHolder *cnnhld)
static void remmina_connection_holder_floating_toolbar_show(RemminaConnectionHolder *cnnhld, gboolean show)
static void remmina_connection_object_on_desktop_resize(RemminaProtocolWidget *gp, gpointer data)
GType remmina_connection_window_get_type(void) G_GNUC_CONST
static void remmina_connection_holder_toolbar_tools(GtkWidget *widget, RemminaConnectionHolder *cnnhld)
static void remmina_connection_holder_on_page_removed(GtkNotebook *notebook, GtkWidget *child, guint page_num, RemminaConnectionHolder *cnnhld)
static void remmina_connection_object_on_update_align(RemminaProtocolWidget *gp, gpointer data)
RemminaProtocolFeatureType type
static void remmina_connection_object_on_close_button_clicked(GtkButton *button, RemminaConnectionObject *cnnobj)
static gboolean remmina_connection_object_delayed_window_present(gpointer user_data)
gboolean remmina_plugin_manager_query_feature_by_type(RemminaPluginType ptype, const gchar *name, RemminaProtocolFeatureType ftype)
static void remmina_connection_object_set_scrolled_policy(RemminaConnectionObject *cnnobj, GtkScrolledWindow *scrolled_window)
static void remmina_connection_window_tb_drag_begin(GtkWidget *widget, GdkDragContext *context, gpointer user_data)
void remmina_file_set_int(RemminaFile *remminafile, const gchar *setting, gint value)
guint shortcutkey_disconnect
gboolean remmina_gtksocket_available()
gboolean small_toolbutton
gboolean toolbar_pin_down
static gboolean remmina_connection_window_on_configure(GtkWidget *widget, GdkEventConfigure *event, RemminaConnectionHolder *cnnhld)
gboolean remmina_connection_window_delete(RemminaConnectionWindow *cnnwin)
static void remmina_connection_holder_call_protocol_feature_activate(GtkMenuItem *menuitem, RemminaConnectionHolder *cnnhld)
static void remmina_connection_holder_update_toolbar_opacity(RemminaConnectionHolder *cnnhld)
static void remmina_connection_holder_toolbar_pin(GtkWidget *widget, RemminaConnectionHolder *cnnhld)
static void remmina_connection_holder_toolbar_preferences_check(RemminaConnectionHolder *cnnhld, RemminaFile *remminafile, GtkWidget *menu, const RemminaProtocolFeature *feature, const gchar *domain, gboolean enabled)
gboolean periodic_usage_stats_permitted
gboolean remmina_connection_window_open_from_filename(const gchar *filename)
void remmina_public_popup_position(GtkMenu *menu, gint *x, gint *y, gboolean *push_in, gpointer user_data)
static GtkWidget * remmina_connection_window_new_from_holder(RemminaConnectionHolder *cnnhld)
static GtkWidget * remmina_connection_object_create_tab(RemminaConnectionObject *cnnobj)
static void remmina_connection_holder_create_scrolled(RemminaConnectionHolder *cnnhld, RemminaConnectionObject *cnnobj)
RemminaConnectionWindow * cnnwin
static void remmina_connection_window_ftb_drag_begin(GtkWidget *widget, GdkDragContext *context, gpointer user_data)
static void remmina_connection_holder_toolbar_fullscreen(GtkWidget *widget, RemminaConnectionHolder *cnnhld)
guint shortcutkey_nexttab
gint fullscreen_view_mode
RemminaConnectionWindowPriv * priv
static void remmina_connection_object_on_connect(RemminaProtocolWidget *gp, RemminaConnectionObject *cnnobj)
static void remmina_connection_holder_keyboard_grab(RemminaConnectionHolder *cnnhld)
static void remmina_connection_holder_toolbar_switch_page_popdown(GtkWidget *widget, RemminaConnectionHolder *cnnhld)
static gboolean remmina_connection_holder_floating_toolbar_hide(RemminaConnectionHolder *cnnhld)
static void remmina_connection_window_update_tag(RemminaConnectionWindow *cnnwin, RemminaConnectionObject *cnnobj)
gint remmina_file_get_int(RemminaFile *remminafile, const gchar *setting, gint default_value)
static void remmina_connection_object_on_disconnect(RemminaProtocolWidget *gp, gpointer data)
guint remmina_utils_string_replace_all(GString *haystack, const gchar *needle, const gchar *replace)
Replaces all occurrences of needle in haystack with replace.
static gboolean remmina_connection_window_tb_drag_failed(GtkWidget *widget, GdkDragContext *context, GtkDragResult result, gpointer user_data)
static void remmina_connection_holder_scaler_expand(GtkWidget *widget, RemminaConnectionHolder *cnnhld)
guint shortcutkey_toolbar
GtkWidget * scrolled_container
RemminaFile * remmina_file
static void remmina_connection_holder_create_overlay_ftb_overlay(RemminaConnectionHolder *cnnhld)
static void remmina_connection_holder_call_protocol_feature_check(GtkMenuItem *menuitem, RemminaConnectionHolder *cnnhld)
static gboolean remmina_connection_window_ftb_drag_drop(GtkWidget *widget, GdkDragContext *context, gint x, gint y, guint time, gpointer user_data)
gboolean remmina_pref_save(void)
static void remmina_connection_holder_toolbar_scaled_mode(GtkWidget *widget, RemminaConnectionHolder *cnnhld)
const gchar * screenshot_name
gboolean hide_connection_toolbar
static void remmina_connection_window_focus_in(GtkWidget *widget, RemminaConnectionHolder *cnnhld)
static void remmina_connection_holder_fullscreen_option_popdown(GtkWidget *widget, RemminaConnectionHolder *cnnhld)
static void remmina_connection_holder_place_toolbar(GtkToolbar *toolbar, GtkGrid *grid, GtkWidget *sibling, int toolbar_placement)
gboolean hostkey_activated
static gint remmina_connection_object_append_page(RemminaConnectionObject *cnnobj, GtkNotebook *notebook, GtkWidget *tab, gint view_mode)
void remmina_message_panel_setup_message(RemminaMessagePanel *mp, const gchar *message, RemminaMessagePanelCallback response_callback, gpointer response_callback_data)
void remmina_application_condexit(RemminaCondExitType why)
void remmina_log_printf(const gchar *fmt,...)
void remmina_file_set_string(RemminaFile *remminafile, const gchar *setting, const gchar *value)
static GtkWidget * remmina_connection_holder_create_toolbar(RemminaConnectionHolder *cnnhld, gint mode)
static gboolean open_connection_last_stage(gpointer user_data)
void remmina_file_save(RemminaFile *remminafile)
static void remmina_connection_holder_scrolled_fullscreen_mode(GtkWidget *widget, RemminaConnectionHolder *cnnhld)
static void cb_lasterror_confirmed(void *cbdata, int btn)
static gboolean remmina_connection_holder_floating_toolbar_on_scroll(GtkWidget *widget, GdkEventScroll *event, RemminaConnectionHolder *cnnhld)
static void remmina_connection_holder_update_toolbar(RemminaConnectionHolder *cnnhld)
static void remmina_connection_window_focus_out(GtkWidget *widget, RemminaConnectionHolder *cnnhld)
GtkWidget * remmina_connection_window_open_from_file_full(RemminaFile *remminafile, GCallback disconnect_cb, gpointer data, guint *handler)
void remmina_log_print(const gchar *text)
RemminaFile * remmina_file_manager_load_file(const gchar *filename)
static void remmina_connection_window_close_all_connections(RemminaConnectionWindow *cnnwin)
static void remmina_connection_holder_on_page_added(GtkNotebook *notebook, GtkWidget *child, guint page_num, RemminaConnectionHolder *cnnhld)
static gboolean remmina_connection_window_go_fullscreen(GtkWidget *widget, GdkEvent *event, gpointer data)
void remmina_connection_object_get_monitor_geometry(RemminaConnectionObject *cnnobj, GdkRectangle *sz)
static void remmina_connection_holder_showhide_toolbar(RemminaConnectionHolder *cnnhld, gboolean resize)
G_DEFINE_TYPE(RemminaConnectionWindow, remmina_connection_window, GTK_TYPE_WINDOW)
static void remmina_connection_object_closewin(RemminaProtocolWidget *gp)
static void remmina_connection_window_destroy(GtkWidget *widget, RemminaConnectionHolder *cnnhld)
static void remmina_connection_holder_change_scalemode(RemminaConnectionHolder *cnnhld, gboolean bdyn, gboolean bscale)
static void remmina_connection_holder_toolbar_screenshot(GtkWidget *widget, RemminaConnectionHolder *cnnhld)
static void remmina_connection_holder_toolbar_fullscreen_option(GtkWidget *widget, RemminaConnectionHolder *cnnhld)
static gboolean remmina_connection_holder_toolbar_autofit_restore(RemminaConnectionHolder *cnnhld)
gint grab_retry_eventsourceid
const gchar * remmina_file_get_icon_name(RemminaFile *remminafile)
static void remmina_connection_holder_update_notebook(RemminaConnectionHolder *cnnhld)
guint shortcutkey_viewonly
static void remmina_connection_window_initialize_notebook(GtkNotebook *to, GtkNotebook *from, RemminaConnectionObject *cnnobj, gint view_mode)
static gboolean remmina_connection_holder_floating_toolbar_make_invisible(gpointer data)
static void remmina_connection_holder_toolbar_autofit(GtkWidget *widget, RemminaConnectionHolder *cnnhld)
static gboolean remmina_connection_holder_floating_toolbar_on_enter(GtkWidget *widget, GdkEventCrossing *event, RemminaConnectionHolder *cnnhld)
gboolean fullscreen_on_auto
static void remmina_connection_holder_toolbar_switch_page(GtkWidget *widget, RemminaConnectionHolder *cnnhld)
static gboolean remmina_connection_window_on_enter(GtkWidget *widget, GdkEventCrossing *event, RemminaConnectionHolder *cnnhld)
void remmina_connection_window_open_from_file(RemminaFile *remminafile)
RemminaConnectionWindowOnDeleteConfirmMode
static void remmina_connection_holder_toolbar_dynres(GtkWidget *widget, RemminaConnectionHolder *cnnhld)
RemminaMessagePanel * remmina_message_panel_new()
static gboolean remmina_connection_window_on_leave(GtkWidget *widget, GdkEventCrossing *event, RemminaConnectionHolder *cnnhld)
gint fullscreen_toolbar_visibility
static void remmina_connection_window_init(RemminaConnectionWindow *cnnwin)
void remmina_connection_window_set_delete_confirm_mode(RemminaConnectionWindow *cnnwin, RemminaConnectionWindowOnDeleteConfirmMode mode)
static void remmina_connection_holder_create_fullscreen(RemminaConnectionHolder *cnnhld, RemminaConnectionObject *cnnobj, gint view_mode)
static void remmina_connection_window_class_init(RemminaConnectionWindowClass *klass)