my_application.cc 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. #include "my_application.h"
  2. #include <flutter_linux/flutter_linux.h>
  3. #ifdef GDK_WINDOWING_X11
  4. #include <gdk/gdkx.h>
  5. #endif
  6. #include "flutter/generated_plugin_registrant.h"
  7. struct _MyApplication {
  8. GtkApplication parent_instance;
  9. char** dart_entrypoint_arguments;
  10. };
  11. G_DEFINE_TYPE(MyApplication, my_application, GTK_TYPE_APPLICATION)
  12. GtkWidget *find_gl_area(GtkWidget *widget);
  13. void try_set_transparent(GtkWindow* window, GdkScreen* screen, FlView* view);
  14. extern bool gIsConnectionManager;
  15. GtkWidget *find_gl_area(GtkWidget *widget);
  16. // Implements GApplication::activate.
  17. static void my_application_activate(GApplication* application) {
  18. MyApplication* self = MY_APPLICATION(application);
  19. GtkWindow* window =
  20. GTK_WINDOW(gtk_application_window_new(GTK_APPLICATION(application)));
  21. gtk_window_set_decorated(window, FALSE);
  22. // try setting icon for rustdesk, which uses the system cache
  23. GtkIconTheme* theme = gtk_icon_theme_get_default();
  24. gint icons[4] = {256, 128, 64, 32};
  25. for (int i = 0; i < 4; i++) {
  26. GdkPixbuf* icon = gtk_icon_theme_load_icon(theme, "rustdesk", icons[i], GTK_ICON_LOOKUP_NO_SVG, NULL);
  27. if (icon != nullptr) {
  28. gtk_window_set_icon(window, icon);
  29. }
  30. }
  31. // Use a header bar when running in GNOME as this is the common style used
  32. // by applications and is the setup most users will be using (e.g. Ubuntu
  33. // desktop).
  34. // If running on X and not using GNOME then just use a traditional title bar
  35. // in case the window manager does more exotic layout, e.g. tiling.
  36. // If running on Wayland assume the header bar will work (may need changing
  37. // if future cases occur).
  38. gboolean use_header_bar = TRUE;
  39. GdkScreen* screen = NULL;
  40. #ifdef GDK_WINDOWING_X11
  41. screen = gtk_window_get_screen(window);
  42. if (screen != NULL && GDK_IS_X11_SCREEN(screen)) {
  43. const gchar* wm_name = gdk_x11_screen_get_window_manager_name(screen);
  44. if (g_strcmp0(wm_name, "GNOME Shell") != 0) {
  45. use_header_bar = FALSE;
  46. }
  47. }
  48. #endif
  49. if (use_header_bar) {
  50. GtkHeaderBar* header_bar = GTK_HEADER_BAR(gtk_header_bar_new());
  51. gtk_widget_show(GTK_WIDGET(header_bar));
  52. gtk_header_bar_set_title(header_bar, "rustdesk");
  53. gtk_header_bar_set_show_close_button(header_bar, TRUE);
  54. gtk_window_set_titlebar(window, GTK_WIDGET(header_bar));
  55. } else {
  56. gtk_window_set_title(window, "rustdesk");
  57. }
  58. // auto bdw = bitsdojo_window_from(window); // <--- add this line
  59. // bdw->setCustomFrame(true); // <-- add this line
  60. int width = 800, height = 600;
  61. if (gIsConnectionManager) {
  62. width = 300;
  63. height = 490;
  64. }
  65. gtk_window_set_default_size(window, width, height); // <-- comment this line
  66. // gtk_widget_show(GTK_WIDGET(window));
  67. gtk_widget_set_opacity(GTK_WIDGET(window), 0);
  68. g_autoptr(FlDartProject) project = fl_dart_project_new();
  69. fl_dart_project_set_dart_entrypoint_arguments(project, self->dart_entrypoint_arguments);
  70. FlView* view = fl_view_new(project);
  71. gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(view));
  72. try_set_transparent(window, gtk_window_get_screen(window), view);
  73. gtk_widget_show(GTK_WIDGET(window));
  74. gtk_widget_show(GTK_WIDGET(view));
  75. fl_register_plugins(FL_PLUGIN_REGISTRY(view));
  76. gtk_widget_grab_focus(GTK_WIDGET(view));
  77. }
  78. // Implements GApplication::local_command_line.
  79. static gboolean my_application_local_command_line(GApplication* application, gchar*** arguments, int* exit_status) {
  80. MyApplication* self = MY_APPLICATION(application);
  81. // Strip out the first argument as it is the binary name.
  82. self->dart_entrypoint_arguments = g_strdupv(*arguments + 1);
  83. g_autoptr(GError) error = nullptr;
  84. if (!g_application_register(application, nullptr, &error)) {
  85. g_warning("Failed to register: %s", error->message);
  86. *exit_status = 1;
  87. return TRUE;
  88. }
  89. g_application_activate(application);
  90. *exit_status = 0;
  91. return TRUE;
  92. }
  93. // Implements GObject::dispose.
  94. static void my_application_dispose(GObject* object) {
  95. MyApplication* self = MY_APPLICATION(object);
  96. g_clear_pointer(&self->dart_entrypoint_arguments, g_strfreev);
  97. G_OBJECT_CLASS(my_application_parent_class)->dispose(object);
  98. }
  99. static void my_application_class_init(MyApplicationClass* klass) {
  100. G_APPLICATION_CLASS(klass)->activate = my_application_activate;
  101. G_APPLICATION_CLASS(klass)->local_command_line = my_application_local_command_line;
  102. G_OBJECT_CLASS(klass)->dispose = my_application_dispose;
  103. }
  104. static void my_application_init(MyApplication* self) {}
  105. MyApplication* my_application_new() {
  106. return MY_APPLICATION(g_object_new(my_application_get_type(),
  107. "application-id", APPLICATION_ID,
  108. "flags", G_APPLICATION_NON_UNIQUE,
  109. nullptr));
  110. }
  111. GtkWidget *find_gl_area(GtkWidget *widget)
  112. {
  113. if (GTK_IS_GL_AREA(widget)) {
  114. return widget;
  115. }
  116. if (GTK_IS_CONTAINER(widget)) {
  117. GList *children = gtk_container_get_children(GTK_CONTAINER(widget));
  118. for (GList *iter = children; iter != NULL; iter = g_list_next(iter)) {
  119. GtkWidget *child = GTK_WIDGET(iter->data);
  120. GtkWidget *gl_area = find_gl_area(child);
  121. if (gl_area != NULL) {
  122. g_list_free(children);
  123. return gl_area;
  124. }
  125. }
  126. g_list_free(children);
  127. }
  128. return NULL;
  129. }
  130. // https://github.com/flutter/flutter/issues/152154
  131. // Remove this workaround when flutter version is updated.
  132. void try_set_transparent(GtkWindow* window, GdkScreen* screen, FlView* view)
  133. {
  134. GtkWidget *gl_area = NULL;
  135. printf("Try setting transparent\n");
  136. gl_area = find_gl_area(GTK_WIDGET(view));
  137. if (gl_area != NULL) {
  138. gtk_gl_area_set_has_alpha(GTK_GL_AREA(gl_area), TRUE);
  139. }
  140. if (screen != NULL) {
  141. GdkVisual *visual = NULL;
  142. gtk_widget_set_app_paintable(GTK_WIDGET(window), TRUE);
  143. visual = gdk_screen_get_rgba_visual(screen);
  144. if (visual != NULL && gdk_screen_is_composited(screen)) {
  145. gtk_widget_set_visual(GTK_WIDGET(window), visual);
  146. }
  147. }
  148. }