Compare commits

...

4 Commits

Author SHA1 Message Date
rustdesk
0a0625126e fix https://github.com/rustdesk/rustdesk/issues/15326 2026-06-18 12:09:51 +08:00
Maison da Silva
8a955888bf Fix Portuguese translations for consistency (#15325)
Fix Portuguese translations for consistency
2026-06-18 10:28:34 +08:00
21pages
36e812e550 update hwcodec (#15323)
Signed-off-by: 21pages <sunboeasy@gmail.com>
2026-06-17 22:58:46 +08:00
rustdesk
8baa995c7a bump version 2026-06-17 22:18:45 +08:00
15 changed files with 139 additions and 38 deletions

View File

@@ -39,7 +39,7 @@ env:
# 2. Update the `VCPKG_COMMIT_ID` in `ci.yml` and `playground.yml`. # 2. Update the `VCPKG_COMMIT_ID` in `ci.yml` and `playground.yml`.
VCPKG_COMMIT_ID: "120deac3062162151622ca4860575a33844ba10b" VCPKG_COMMIT_ID: "120deac3062162151622ca4860575a33844ba10b"
ARMV7_VCPKG_COMMIT_ID: "6f29f12e82a8293156836ad81cc9bf5af41fe836" # 2025.01.13, got "/opt/artifacts/vcpkg/vcpkg: No such file or directory" with latest version ARMV7_VCPKG_COMMIT_ID: "6f29f12e82a8293156836ad81cc9bf5af41fe836" # 2025.01.13, got "/opt/artifacts/vcpkg/vcpkg: No such file or directory" with latest version
VERSION: "1.4.7" VERSION: "1.4.8"
NDK_VERSION: "r28c" NDK_VERSION: "r28c"
#signing keys env variable checks #signing keys env variable checks
ANDROID_SIGNING_KEY: "${{ secrets.ANDROID_SIGNING_KEY }}" ANDROID_SIGNING_KEY: "${{ secrets.ANDROID_SIGNING_KEY }}"

View File

@@ -17,7 +17,7 @@ env:
TAG_NAME: "nightly" TAG_NAME: "nightly"
VCPKG_BINARY_SOURCES: "clear;x-gha,readwrite" VCPKG_BINARY_SOURCES: "clear;x-gha,readwrite"
VCPKG_COMMIT_ID: "120deac3062162151622ca4860575a33844ba10b" VCPKG_COMMIT_ID: "120deac3062162151622ca4860575a33844ba10b"
VERSION: "1.4.7" VERSION: "1.4.8"
NDK_VERSION: "r26d" NDK_VERSION: "r26d"
#signing keys env variable checks #signing keys env variable checks
ANDROID_SIGNING_KEY: "${{ secrets.ANDROID_SIGNING_KEY }}" ANDROID_SIGNING_KEY: "${{ secrets.ANDROID_SIGNING_KEY }}"

6
Cargo.lock generated
View File

@@ -3952,7 +3952,7 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
[[package]] [[package]]
name = "hwcodec" name = "hwcodec"
version = "0.7.1" version = "0.7.1"
source = "git+https://github.com/rustdesk-org/hwcodec#398e5a8938dd8768ade0fcdc27ea80e8b4b38738" source = "git+https://github.com/rustdesk-org/hwcodec#778df1f99597722473b29443bac22ae6c23946fe"
dependencies = [ dependencies = [
"bindgen 0.59.2", "bindgen 0.59.2",
"cc", "cc",
@@ -7270,7 +7270,7 @@ dependencies = [
[[package]] [[package]]
name = "rustdesk" name = "rustdesk"
version = "1.4.7" version = "1.4.8"
dependencies = [ dependencies = [
"android-wakelock", "android-wakelock",
"android_logger", "android_logger",
@@ -7385,7 +7385,7 @@ dependencies = [
[[package]] [[package]]
name = "rustdesk-portable-packer" name = "rustdesk-portable-packer"
version = "1.4.7" version = "1.4.8"
dependencies = [ dependencies = [
"brotli", "brotli",
"dirs 5.0.1", "dirs 5.0.1",

View File

@@ -1,6 +1,6 @@
[package] [package]
name = "rustdesk" name = "rustdesk"
version = "1.4.7" version = "1.4.8"
authors = ["rustdesk <info@rustdesk.com>"] authors = ["rustdesk <info@rustdesk.com>"]
edition = "2021" edition = "2021"
build= "build.rs" build= "build.rs"

View File

@@ -18,7 +18,7 @@ AppDir:
id: rustdesk id: rustdesk
name: rustdesk name: rustdesk
icon: rustdesk icon: rustdesk
version: 1.4.7 version: 1.4.8
exec: usr/share/rustdesk/rustdesk exec: usr/share/rustdesk/rustdesk
exec_args: $@ exec_args: $@
apt: apt:

View File

@@ -18,7 +18,7 @@ AppDir:
id: rustdesk id: rustdesk
name: rustdesk name: rustdesk
icon: rustdesk icon: rustdesk
version: 1.4.7 version: 1.4.8
exec: usr/share/rustdesk/rustdesk exec: usr/share/rustdesk/rustdesk
exec_args: $@ exec_args: $@
apt: apt:

View File

@@ -16,7 +16,7 @@ publish_to: "none" # Remove this line if you wish to publish to pub.dev
# Read more about iOS versioning at # Read more about iOS versioning at
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
# 1.1.9-1 works for android, but for ios it becomes 1.1.91, need to set it to 1.1.9-a.1 for iOS, will get 1.1.9.1, but iOS store not allow 4 numbers # 1.1.9-1 works for android, but for ios it becomes 1.1.91, need to set it to 1.1.9-a.1 for iOS, will get 1.1.9.1, but iOS store not allow 4 numbers
version: 1.4.7+65 version: 1.4.8+66
environment: environment:
sdk: '^3.1.0' sdk: '^3.1.0'

View File

@@ -7,7 +7,8 @@ use fuser::MountOption;
use hbb_common::{config::APP_NAME, log}; use hbb_common::{config::APP_NAME, log};
use parking_lot::Mutex; use parking_lot::Mutex;
use std::{ use std::{
path::PathBuf, io,
path::{Path, PathBuf},
sync::{mpsc::Sender, Arc}, sync::{mpsc::Sender, Arc},
time::Duration, time::Duration,
}; };
@@ -53,8 +54,16 @@ pub fn init_fuse_context(is_client: bool) -> Result<(), CliprdrError> {
} else { } else {
FUSE_CONTEXT_SERVER.lock() FUSE_CONTEXT_SERVER.lock()
}; };
if fuse_context_lock.is_some() { if let Some(ctx) = fuse_context_lock.as_ref() {
return Ok(()); if is_mount_point_healthy(&ctx.mount_point) {
return Ok(());
}
log::warn!(
"clipboard FUSE mount {} is disconnected, remounting",
ctx.mount_point.display()
);
let stale_context = fuse_context_lock.take();
drop(stale_context);
} }
let mount_point = if is_client { let mount_point = if is_client {
FUSE_MOUNT_POINT_CLIENT.clone() FUSE_MOUNT_POINT_CLIENT.clone()
@@ -159,35 +168,100 @@ struct FuseContext {
} }
// this function must be called after the main IPC is up // this function must be called after the main IPC is up
fn prepare_fuse_mount_point(mount_point: &PathBuf) { fn prepare_fuse_mount_point(mount_point: &Path) {
use std::{ use std::{
fs::{self, Permissions}, fs::{self, Permissions},
os::unix::prelude::PermissionsExt, os::unix::prelude::PermissionsExt,
}; };
fs::create_dir(mount_point).ok(); if let Some(parent) = mount_point.parent() {
fs::set_permissions(mount_point, Permissions::from_mode(0o777)).ok(); if let Err(e) = fs::create_dir_all(parent) {
log::warn!("failed to create FUSE mount parent {:?}: {:?}", parent, e);
}
}
if let Err(e) = std::process::Command::new("umount") unmount_fuse_mount_point(mount_point);
.arg(mount_point)
.status() if let Err(e) = fs::create_dir_all(mount_point) {
{ log::warn!(
log::warn!("umount {:?} may fail: {:?}", mount_point, e); "failed to create FUSE mount point {:?}: {:?}",
mount_point,
e
);
}
if let Err(e) = fs::set_permissions(mount_point, Permissions::from_mode(0o777)) {
log::warn!(
"failed to set FUSE mount point permissions {:?}: {:?}",
mount_point,
e
);
} }
} }
fn uninit_fuse_context_(is_client: bool) { fn is_mount_point_healthy(mount_point: &Path) -> bool {
if is_client { is_mount_point_healthy_result(std::fs::metadata(mount_point))
let _ = FUSE_CONTEXT_CLIENT.lock().take(); }
} else {
let _ = FUSE_CONTEXT_SERVER.lock().take(); fn is_mount_point_healthy_result<T>(result: io::Result<T>) -> bool {
match result {
Ok(_) => true,
Err(e) => {
e.raw_os_error() != Some(libc::ENOTCONN) && e.kind() != io::ErrorKind::NotFound
}
} }
} }
fn unmount_fuse_mount_point(mount_point: &Path) {
if run_unmount_command("umount", &["-l"], mount_point) {
return;
}
if run_unmount_command("fusermount3", &["-uz"], mount_point) {
return;
}
run_unmount_command("fusermount", &["-uz"], mount_point);
}
fn run_unmount_command(program: &str, args: &[&str], mount_point: &Path) -> bool {
match std::process::Command::new(program)
.args(args)
.arg(mount_point)
.status()
{
Ok(status) if status.success() => {}
Ok(status) => {
log::debug!(
"{} {:?} exited with status {:?}",
program,
mount_point,
status.code()
);
return false;
}
Err(e) => {
log::debug!("failed to run {} for {:?}: {:?}", program, mount_point, e);
return false;
}
}
true
}
fn uninit_fuse_context_(is_client: bool) {
let mut fuse_context_lock = if is_client {
FUSE_CONTEXT_CLIENT.lock()
} else {
FUSE_CONTEXT_SERVER.lock()
};
let ctx = fuse_context_lock.take();
drop(ctx);
}
impl Drop for FuseContext { impl Drop for FuseContext {
fn drop(&mut self) { fn drop(&mut self) {
self.session.lock().take().map(|s| s.join());
log::info!("unmounting clipboard FUSE from {}", self.mount_point.display()); log::info!("unmounting clipboard FUSE from {}", self.mount_point.display());
unmount_fuse_mount_point(&self.mount_point);
if let Some(session) = self.session.lock().take() {
session.join();
}
} }
} }
@@ -223,3 +297,30 @@ impl FuseContext {
.collect()) .collect())
} }
} }
#[cfg(test)]
mod tests {
use super::*;
use std::{fs, io};
#[test]
fn reports_disconnected_fuse_mount_as_unhealthy() {
let err = io::Error::from_raw_os_error(libc::ENOTCONN);
assert!(!is_mount_point_healthy_result::<()>(Err(err)));
}
#[test]
fn reports_existing_directory_mount_point_as_healthy() {
let mount_point = std::env::temp_dir().join(format!(
"rustdesk-fuse-mount-health-test-{}",
std::process::id()
));
let _ = fs::remove_dir_all(&mount_point);
fs::create_dir(&mount_point).unwrap();
assert!(is_mount_point_healthy(&mount_point));
let _ = fs::remove_dir_all(&mount_point);
}
}

View File

@@ -1,6 +1,6 @@
[package] [package]
name = "rustdesk-portable-packer" name = "rustdesk-portable-packer"
version = "1.4.7" version = "1.4.8"
edition = "2021" edition = "2021"
description = "RustDesk Remote Desktop" description = "RustDesk Remote Desktop"

View File

@@ -1,5 +1,5 @@
pkgname=rustdesk pkgname=rustdesk
pkgver=1.4.7 pkgver=1.4.8
pkgrel=0 pkgrel=0
epoch= epoch=
pkgdesc="" pkgdesc=""

View File

@@ -1,3 +1,3 @@
#! /usr/bin/env bash #! /usr/bin/env bash
sed -i "s/$1/$2/g" res/*spec res/PKGBUILD flutter/pubspec.yaml Cargo.toml .github/workflows/*yml flatpak/*json appimage/*yml libs/portable/Cargo.toml sed -i "s/\b$1\b/$2/g" res/*spec res/PKGBUILD flutter/pubspec.yaml Cargo.toml .github/workflows/*yml flatpak/*json appimage/*yml libs/portable/Cargo.toml
cargo run # to bump version in cargo lock cargo run # to bump version in cargo lock

View File

@@ -1,5 +1,5 @@
Name: rustdesk Name: rustdesk
Version: 1.4.7 Version: 1.4.8
Release: 0 Release: 0
Summary: RPM package Summary: RPM package
License: GPL-3.0 License: GPL-3.0

View File

@@ -1,5 +1,5 @@
Name: rustdesk Name: rustdesk
Version: 1.4.7 Version: 1.4.8
Release: 0 Release: 0
Summary: RPM package Summary: RPM package
License: GPL-3.0 License: GPL-3.0

View File

@@ -1,5 +1,5 @@
Name: rustdesk Name: rustdesk
Version: 1.4.7 Version: 1.4.8
Release: 0 Release: 0
Summary: RPM package Summary: RPM package
License: GPL-3.0 License: GPL-3.0

View File

@@ -24,9 +24,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Refresh random password", "Atualizar senha aleatória"), ("Refresh random password", "Atualizar senha aleatória"),
("Set your own password", "Configure sua própria senha"), ("Set your own password", "Configure sua própria senha"),
("Enable keyboard/mouse", "Habilitar teclado/mouse"), ("Enable keyboard/mouse", "Habilitar teclado/mouse"),
("Enable clipboard", "Habilitar Área de Transferência"), ("Enable clipboard", "Habilitar área de transferência"),
("Enable file transfer", "Habilitar Transferência de Arquivos"), ("Enable file transfer", "Habilitar transferência de arquivos"),
("Enable TCP tunneling", "Habilitar Tunelamento TCP"), ("Enable TCP tunneling", "Habilitar tunelamento TCP"),
("IP Whitelisting", "Lista de IPs Confiáveis"), ("IP Whitelisting", "Lista de IPs Confiáveis"),
("ID/Relay Server", "Servidor ID/Relay"), ("ID/Relay Server", "Servidor ID/Relay"),
("Import server config", "Importar Configuração do Servidor"), ("Import server config", "Importar Configuração do Servidor"),
@@ -693,11 +693,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Enable IPv6 P2P connection", "Habilitar conexão IPv6 P2P"), ("Enable IPv6 P2P connection", "Habilitar conexão IPv6 P2P"),
("Enable UDP hole punching", "Habilitar UDP hole punching"), ("Enable UDP hole punching", "Habilitar UDP hole punching"),
("View camera", "Visualizar câmera"), ("View camera", "Visualizar câmera"),
("Enable camera", "Ativar câmera"), ("Enable camera", "Habilitar câmera"),
("No cameras", "Sem câmeras"), ("No cameras", "Nenhuma câmeras"),
("view_camera_unsupported_tip", "O dispositivo remoto não suporta visualização da câmera."), ("view_camera_unsupported_tip", "O dispositivo remoto não suporta visualização da câmera."),
("Terminal", "Terminal"), ("Terminal", "Terminal"),
("Enable terminal", "Habilitar Terminal"), ("Enable terminal", "Habilitar terminal"),
("New tab", "Nova aba"), ("New tab", "Nova aba"),
("Keep terminal sessions on disconnect", "Manter sessões de terminal ao desconectar"), ("Keep terminal sessions on disconnect", "Manter sessões de terminal ao desconectar"),
("Terminal (Run as administrator)", "Terminal (Executar como administrador)"), ("Terminal (Run as administrator)", "Terminal (Executar como administrador)"),