Skip to content

Commit

Permalink
fix: linux, window, workaround, mint, mate (rustdesk#10146)
Browse files Browse the repository at this point in the history
* refact: linux, window, workaround, mint, mate

Signed-off-by: fufesou <[email protected]>

* refact: case insensitive

Signed-off-by: fufesou <[email protected]>

---------

Signed-off-by: fufesou <[email protected]>
  • Loading branch information
fufesou authored Dec 2, 2024
1 parent b8d36b6 commit bd0a33e
Show file tree
Hide file tree
Showing 6 changed files with 161 additions and 17 deletions.
30 changes: 30 additions & 0 deletions flutter/lib/common.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'dart:async';
import 'dart:convert';
import 'dart:math';
import 'dart:io';

import 'package:back_button_interceptor/back_button_interceptor.dart';
import 'package:desktop_multi_window/desktop_multi_window.dart';
Expand Down Expand Up @@ -3459,6 +3460,35 @@ Widget buildPresetPasswordWarning() {
);
}

bool get isLinuxMateDesktop =>
isLinux &&
(Platform.environment['XDG_CURRENT_DESKTOP']?.toLowerCase() == 'mate' ||
Platform.environment['XDG_SESSION_DESKTOP']?.toLowerCase() == 'mate' ||
Platform.environment['DESKTOP_SESSION']?.toLowerCase() == 'mate');

Map<String, dynamic>? _linuxOsDistro;

String getLinuxOsDistroId() {
if (_linuxOsDistro == null) {
String osInfo = bind.getOsDistroInfo();
if (osInfo.isEmpty) {
_linuxOsDistro = {};
} else {
try {
_linuxOsDistro = jsonDecode(osInfo);
} catch (e) {
debugPrint('Failed to parse os info: $e');
// Don't call `bind.getOsDistroInfo()` again if failed to parse osInfo.
_linuxOsDistro = {};
}
}
}
return (_linuxOsDistro?['id'] ?? '') as String;
}

bool get isLinuxMint =>
getLinuxOsDistroId().toLowerCase().contains('linuxmint');

// https://github.com/leanflutter/window_manager/blob/87dd7a50b4cb47a375b9fc697f05e56eea0a2ab3/lib/src/widgets/virtual_window_frame.dart#L44
Widget buildVirtualWindowFrame(BuildContext context, Widget child) {
boxShadow() => isMainDesktopWindow
Expand Down
11 changes: 10 additions & 1 deletion flutter/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -483,7 +483,16 @@ class _AppState extends State<App> with WidgetsBindingObserver {
child = keyListenerBuilder(context, child);
}
if (isLinux) {
child = buildVirtualWindowFrame(context, child);
// `(!(isLinuxMateDesktop || isLinuxMint))` is not used here for clarity.
// `isLinuxMint` will call ffi function.
if (!isLinuxMateDesktop) {
if (!isLinuxMint) {
debugPrint(
'Linux distro is not linuxmint, and desktop is not mate, '
'so we build virtual window frame.');
child = buildVirtualWindowFrame(context, child);
}
}
}
return child;
},
Expand Down
4 changes: 4 additions & 0 deletions flutter/lib/web/bridge.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1828,5 +1828,9 @@ class RustdeskImpl {
throw UnimplementedError("sessionGetConnToken");
}

String getOsDistroInfo({dynamic hint}) {
return '';
}

void dispose() {}
}
98 changes: 83 additions & 15 deletions flutter/linux/my_application.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ G_DEFINE_TYPE(MyApplication, my_application, GTK_TYPE_APPLICATION)
extern bool gIsConnectionManager;

GtkWidget *find_gl_area(GtkWidget *widget);
void try_set_transparent(GtkWindow* window, GdkScreen* screen, FlView* view);

// Implements GApplication::activate.
static void my_application_activate(GApplication* application) {
Expand Down Expand Up @@ -79,21 +80,7 @@ static void my_application_activate(GApplication* application) {
gtk_widget_show(GTK_WIDGET(view));
gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(view));

// https://github.com/flutter/flutter/issues/152154
// Remove this workaround when flutter version is updated.
GtkWidget *gl_area = find_gl_area(GTK_WIDGET(view));
if (gl_area != NULL) {
gtk_gl_area_set_has_alpha(GTK_GL_AREA(gl_area), TRUE);
}

if (screen != NULL) {
GdkVisual *visual = NULL;
gtk_widget_set_app_paintable(GTK_WIDGET(window), TRUE);
visual = gdk_screen_get_rgba_visual(screen);
if (visual != NULL && gdk_screen_is_composited(screen)) {
gtk_widget_set_visual(GTK_WIDGET(window), visual);
}
}
try_set_transparent(window, screen, view);

fl_register_plugins(FL_PLUGIN_REGISTRY(view));

Expand Down Expand Up @@ -162,3 +149,84 @@ GtkWidget *find_gl_area(GtkWidget *widget)

return NULL;
}

bool is_linux_mint()
{
bool is_mint = false;
char line[256];
FILE *fp = fopen("/etc/os-release", "r");
if (fp == NULL) {
return false;
}
while (fgets(line, sizeof(line), fp)) {
if (strstr(line, "ID=linuxmint") != NULL) {
is_mint = true;
break;
}
}
fclose(fp);

return is_mint;
}

bool is_desktop_mate()
{
const char* desktop = NULL;
desktop = getenv("XDG_CURRENT_DESKTOP");
printf("Linux desktop, XDG_CURRENT_DESKTOP: %s\n", desktop == NULL ? "" : desktop);
if (desktop == NULL) {
desktop = getenv("XDG_SESSION_DESKTOP");
printf("Linux desktop, XDG_SESSION_DESKTOP: %s\n", desktop == NULL ? "" : desktop);
}
if (desktop == NULL) {
desktop = getenv("DESKTOP_SESSION");
printf("Linux desktop, DESKTOP_SESSION: %s\n", desktop == NULL ? "" : desktop);
}
if (desktop != NULL && strcasecmp(desktop, "mate") == 0) {
return true;
}
return false;
}

bool skip_setting_transparent()
{
if (is_desktop_mate()) {
printf("Linux desktop, MATE\n");
return true;
}

if (is_linux_mint()) {
printf("Linux desktop, Linux Mint\n");
return true;
}

return false;
}

// https://github.com/flutter/flutter/issues/152154
// Remove this workaround when flutter version is updated.
void try_set_transparent(GtkWindow* window, GdkScreen* screen, FlView* view)
{
GtkWidget *gl_area = NULL;

if (skip_setting_transparent()) {
printf("Skip setting transparent\n");
return;
}

printf("Try setting transparent\n");

gl_area = find_gl_area(GTK_WIDGET(view));
if (gl_area != NULL) {
gtk_gl_area_set_has_alpha(GTK_GL_AREA(gl_area), TRUE);
}

if (screen != NULL) {
GdkVisual *visual = NULL;
gtk_widget_set_app_paintable(GTK_WIDGET(window), TRUE);
visual = gdk_screen_get_rgba_visual(screen);
if (visual != NULL && gdk_screen_is_composited(screen)) {
gtk_widget_set_visual(GTK_WIDGET(window), visual);
}
}
}
15 changes: 14 additions & 1 deletion libs/hbb_common/src/platform/linux.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,22 +13,35 @@ pub const XDG_CURRENT_DESKTOP: &str = "XDG_CURRENT_DESKTOP";

pub struct Distro {
pub name: String,
pub id: String,
pub version_id: String,
}

impl Distro {
fn new() -> Self {
// to-do:
// 1. Remove `run_cmds`, read file once
// 2. Add more distro infos
let name = run_cmds("awk -F'=' '/^NAME=/ {print $2}' /etc/os-release")
.unwrap_or_default()
.trim()
.trim_matches('"')
.to_string();
let id = run_cmds("awk -F'=' '/^ID=/ {print $2}' /etc/os-release")
.unwrap_or_default()
.trim()
.trim_matches('"')
.to_string();
let version_id = run_cmds("awk -F'=' '/^VERSION_ID=/ {print $2}' /etc/os-release")
.unwrap_or_default()
.trim()
.trim_matches('"')
.to_string();
Self { name, version_id }
Self {
name,
id,
version_id,
}
}
}

Expand Down
20 changes: 20 additions & 0 deletions src/flutter_ffi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ use hbb_common::allow_err;
use hbb_common::{
config::{self, LocalConfig, PeerConfig, PeerInfoSerde},
fs, lazy_static, log,
message_proto::Hash,
rendezvous_proto::ConnType,
ResultType,
};
Expand Down Expand Up @@ -2341,6 +2342,25 @@ pub fn main_audio_support_loopback() -> SyncReturn<bool> {
SyncReturn(is_surpport)
}

pub fn get_os_distro_info() -> SyncReturn<String> {
#[cfg(target_os = "linux")]
{
let distro = &hbb_common::platform::linux::DISTRO;
SyncReturn(
serde_json::to_string(&HashMap::from([
("name", distro.name.clone()),
("id", distro.id.clone()),
("version_id", distro.version_id.clone()),
]))
.unwrap_or_default(),
)
}
#[cfg(not(target_os = "linux"))]
{
SyncReturn("".to_owned())
}
}

#[cfg(target_os = "android")]
pub mod server_side {
use hbb_common::{config, log};
Expand Down

0 comments on commit bd0a33e

Please sign in to comment.