mirror of
https://github.com/rustdesk/rustdesk.git
synced 2024-11-23 19:49:05 +08:00
win,linux remove desktop wallpaper
Signed-off-by: 21pages <pages21@163.com>
This commit is contained in:
parent
1be5f2d647
commit
d3ce8203be
23
Cargo.lock
generated
23
Cargo.lock
generated
@ -1819,6 +1819,15 @@ dependencies = [
|
||||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "enquote"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "06c36cb11dbde389f4096111698d8b567c0720e3452fd5ac3e6b4e47e1939932"
|
||||
dependencies = [
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "enum-iterator"
|
||||
version = "1.4.1"
|
||||
@ -5214,6 +5223,7 @@ dependencies = [
|
||||
"users 0.11.0",
|
||||
"uuid",
|
||||
"virtual_display",
|
||||
"wallpaper",
|
||||
"whoami",
|
||||
"winapi 0.3.9",
|
||||
"windows-service",
|
||||
@ -6589,6 +6599,19 @@ dependencies = [
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wallpaper"
|
||||
version = "3.2.0"
|
||||
source = "git+https://github.com/21pages/wallpaper.rs#2bbb70acd93be179c69cb96cb8c3dda487e6f5fd"
|
||||
dependencies = [
|
||||
"dirs 5.0.1",
|
||||
"enquote",
|
||||
"rust-ini",
|
||||
"thiserror",
|
||||
"winapi 0.3.9",
|
||||
"winreg 0.11.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "want"
|
||||
version = "0.3.0"
|
||||
|
@ -88,6 +88,7 @@ clipboard = { path = "libs/clipboard" }
|
||||
ctrlc = "3.2"
|
||||
arboard = "3.2"
|
||||
system_shutdown = "4.0"
|
||||
shutdown_hooks = "0.1"
|
||||
|
||||
[target.'cfg(target_os = "windows")'.dependencies]
|
||||
winapi = { version = "0.3", features = ["winuser", "wincrypt", "shellscalingapi"] }
|
||||
@ -96,7 +97,6 @@ windows-service = "0.6"
|
||||
virtual_display = { path = "libs/virtual_display", optional = true }
|
||||
impersonate_system = { git = "https://github.com/21pages/impersonate-system" }
|
||||
shared_memory = "0.12"
|
||||
shutdown_hooks = "0.1"
|
||||
tauri-winrt-notification = "0.1.2"
|
||||
|
||||
[target.'cfg(target_os = "macos")'.dependencies]
|
||||
@ -118,6 +118,9 @@ image = "0.24"
|
||||
[target.'cfg(any(target_os = "macos", target_os = "linux"))'.dependencies]
|
||||
keepawake = { git = "https://github.com/rustdesk-org/keepawake-rs" }
|
||||
|
||||
[target.'cfg(any(target_os = "windows", target_os = "linux"))'.dependencies]
|
||||
wallpaper = { git = "https://github.com/21pages/wallpaper.rs" }
|
||||
|
||||
[target.'cfg(target_os = "linux")'.dependencies]
|
||||
psimple = { package = "libpulse-simple-binding", version = "2.27" }
|
||||
pulse = { package = "libpulse-binding", version = "2.27" }
|
||||
|
@ -1,3 +1,4 @@
|
||||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
@ -322,6 +323,24 @@ class _GeneralState extends State<_General> {
|
||||
'enable-confirm-closing-tabs',
|
||||
isServer: false),
|
||||
_OptionCheckBox(context, 'Adaptive bitrate', 'enable-abr'),
|
||||
if (Platform.isWindows || Platform.isLinux)
|
||||
Row(
|
||||
children: [
|
||||
Flexible(
|
||||
child: _OptionCheckBox(
|
||||
context,
|
||||
'Remove wallpaper during incoming sessions',
|
||||
'allow-remove-wallpaper'),
|
||||
),
|
||||
_CountDownButton(
|
||||
text: 'Test',
|
||||
second: 5,
|
||||
onPressed: () {
|
||||
bind.mainTestWallpaper(second: 5);
|
||||
},
|
||||
)
|
||||
],
|
||||
),
|
||||
_OptionCheckBox(
|
||||
context,
|
||||
'Open connection in new tab',
|
||||
@ -1873,6 +1892,69 @@ class _ComboBox extends StatelessWidget {
|
||||
}
|
||||
}
|
||||
|
||||
class _CountDownButton extends StatefulWidget {
|
||||
_CountDownButton({
|
||||
Key? key,
|
||||
required this.text,
|
||||
required this.second,
|
||||
required this.onPressed,
|
||||
}) : super(key: key);
|
||||
final String text;
|
||||
final VoidCallback? onPressed;
|
||||
final int second;
|
||||
|
||||
@override
|
||||
State<_CountDownButton> createState() => _CountDownButtonState();
|
||||
}
|
||||
|
||||
class _CountDownButtonState extends State<_CountDownButton> {
|
||||
bool _isButtonDisabled = false;
|
||||
|
||||
late int _countdownSeconds = widget.second;
|
||||
|
||||
Timer? _timer;
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_timer?.cancel();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
void _startCountdownTimer() {
|
||||
_timer = Timer.periodic(Duration(seconds: 1), (timer) {
|
||||
if (_countdownSeconds <= 0) {
|
||||
setState(() {
|
||||
_isButtonDisabled = false;
|
||||
});
|
||||
timer.cancel();
|
||||
} else {
|
||||
setState(() {
|
||||
_countdownSeconds--;
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ElevatedButton(
|
||||
onPressed: _isButtonDisabled
|
||||
? null
|
||||
: () {
|
||||
widget.onPressed?.call();
|
||||
setState(() {
|
||||
_isButtonDisabled = true;
|
||||
_countdownSeconds = widget.second;
|
||||
});
|
||||
_startCountdownTimer();
|
||||
},
|
||||
child: Text(
|
||||
_isButtonDisabled ? '$_countdownSeconds s' : translate(widget.text),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region dialogs
|
||||
|
@ -1613,6 +1613,18 @@ pub fn main_start_ipc_url_server() {
|
||||
std::thread::spawn(move || crate::server::start_ipc_url_server());
|
||||
}
|
||||
|
||||
pub fn main_test_wallpaper(_second: u64) {
|
||||
#[cfg(any(target_os = "windows", target_os = "linux"))]
|
||||
std::thread::spawn(move || match crate::platform::WallPaperRemover::new() {
|
||||
Ok(_remover) => {
|
||||
std::thread::sleep(std::time::Duration::from_secs(_second));
|
||||
}
|
||||
Err(e) => {
|
||||
log::info!("create wallpaper remover failed:{:?}", e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/// Send a url scheme throught the ipc.
|
||||
///
|
||||
/// * macOS only
|
||||
|
@ -555,6 +555,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Check for software update on startup", ""),
|
||||
("upgrade_rustdesk_server_pro_to_{}_tip", ""),
|
||||
("pull_group_failed_tip", ""),
|
||||
("Filter by intersection", "")
|
||||
("Filter by intersection", ""),
|
||||
("Remove wallpaper during incoming sessions", ""),
|
||||
("Test", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -555,6 +555,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Check for software update on startup", ""),
|
||||
("upgrade_rustdesk_server_pro_to_{}_tip", ""),
|
||||
("pull_group_failed_tip", ""),
|
||||
("Filter by intersection", "")
|
||||
("Filter by intersection", ""),
|
||||
("Remove wallpaper during incoming sessions", ""),
|
||||
("Test", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -555,6 +555,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Check for software update on startup", "启动时检查软件更新"),
|
||||
("upgrade_rustdesk_server_pro_to_{}_tip", "请升级专业版服务器到{}或更高版本!"),
|
||||
("pull_group_failed_tip", "获取组信息失败"),
|
||||
("Filter by intersection", "按交集过滤")
|
||||
("Filter by intersection", "按交集过滤"),
|
||||
("Remove wallpaper during incoming sessions", "接受会话时移除桌面壁纸"),
|
||||
("Test", "测试"),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -555,6 +555,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Check for software update on startup", "Kontrola aktualizace softwaru při spuštění"),
|
||||
("upgrade_rustdesk_server_pro_to_{}_tip", "Aktualizujte prosím RustDesk Server Pro na verzi {} nebo novější!"),
|
||||
("pull_group_failed_tip", "Nepodařilo se obnovit skupinu"),
|
||||
("Filter by intersection", "")
|
||||
("Filter by intersection", ""),
|
||||
("Remove wallpaper during incoming sessions", ""),
|
||||
("Test", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -555,6 +555,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Check for software update on startup", ""),
|
||||
("upgrade_rustdesk_server_pro_to_{}_tip", ""),
|
||||
("pull_group_failed_tip", ""),
|
||||
("Filter by intersection", "")
|
||||
("Filter by intersection", ""),
|
||||
("Remove wallpaper during incoming sessions", ""),
|
||||
("Test", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -555,6 +555,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Check for software update on startup", "Beim Start auf Softwareaktualisierung prüfen"),
|
||||
("upgrade_rustdesk_server_pro_to_{}_tip", "Bitte aktualisieren Sie RustDesk Server Pro auf die Version {} oder neuer!"),
|
||||
("pull_group_failed_tip", "Aktualisierung der Gruppe fehlgeschlagen"),
|
||||
("Filter by intersection", "")
|
||||
("Filter by intersection", ""),
|
||||
("Remove wallpaper during incoming sessions", ""),
|
||||
("Test", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -555,6 +555,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Check for software update on startup", ""),
|
||||
("upgrade_rustdesk_server_pro_to_{}_tip", ""),
|
||||
("pull_group_failed_tip", ""),
|
||||
("Filter by intersection", "")
|
||||
("Filter by intersection", ""),
|
||||
("Remove wallpaper during incoming sessions", ""),
|
||||
("Test", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -555,6 +555,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Check for software update on startup", ""),
|
||||
("upgrade_rustdesk_server_pro_to_{}_tip", ""),
|
||||
("pull_group_failed_tip", ""),
|
||||
("Filter by intersection", "")
|
||||
("Filter by intersection", ""),
|
||||
("Remove wallpaper during incoming sessions", ""),
|
||||
("Test", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -555,6 +555,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Check for software update on startup", "Comprobar actualización al iniciar"),
|
||||
("upgrade_rustdesk_server_pro_to_{}_tip", "¡Por favor, actualiza RustDesk Server Pro a la versión {} o superior"),
|
||||
("pull_group_failed_tip", "No se ha podido refrescar el grupo"),
|
||||
("Filter by intersection", "")
|
||||
("Filter by intersection", ""),
|
||||
("Remove wallpaper during incoming sessions", ""),
|
||||
("Test", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -555,6 +555,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Check for software update on startup", ""),
|
||||
("upgrade_rustdesk_server_pro_to_{}_tip", ""),
|
||||
("pull_group_failed_tip", ""),
|
||||
("Filter by intersection", "")
|
||||
("Filter by intersection", ""),
|
||||
("Remove wallpaper during incoming sessions", ""),
|
||||
("Test", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -555,6 +555,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Check for software update on startup", "Vérifier la disponibilité des mises à jour au démarrage"),
|
||||
("upgrade_rustdesk_server_pro_to_{}_tip", "Veuillez mettre à jour RustDesk Server Pro avec la version {} ou une version plus récente !"),
|
||||
("pull_group_failed_tip", "Échec de l'actualisation du groupe"),
|
||||
("Filter by intersection", "")
|
||||
("Filter by intersection", ""),
|
||||
("Remove wallpaper during incoming sessions", ""),
|
||||
("Test", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -555,6 +555,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Check for software update on startup", ""),
|
||||
("upgrade_rustdesk_server_pro_to_{}_tip", ""),
|
||||
("pull_group_failed_tip", ""),
|
||||
("Filter by intersection", "")
|
||||
("Filter by intersection", ""),
|
||||
("Remove wallpaper during incoming sessions", ""),
|
||||
("Test", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -555,6 +555,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Check for software update on startup", "Periksa pembaruan aplikasi saat sistem dinyalakan."),
|
||||
("upgrade_rustdesk_server_pro_to_{}_tip", "Silahkan perbarui RustDesk Server Pro ke versi {} atau yang lebih baru!"),
|
||||
("pull_group_failed_tip", "Gagal memperbarui grup"),
|
||||
("Filter by intersection", "")
|
||||
("Filter by intersection", ""),
|
||||
("Remove wallpaper during incoming sessions", ""),
|
||||
("Test", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -555,6 +555,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Check for software update on startup", "All'avvio verifica presenza aggiornamenti programma"),
|
||||
("upgrade_rustdesk_server_pro_to_{}_tip", "Aggiorna RustDesk Server Pro alla versione {} o successiva!"),
|
||||
("pull_group_failed_tip", "Impossibile aggiornare il gruppo"),
|
||||
("Filter by intersection", "Filtra per incrocio")
|
||||
("Filter by intersection", "Filtra per incrocio"),
|
||||
("Remove wallpaper during incoming sessions", ""),
|
||||
("Test", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -555,6 +555,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Check for software update on startup", ""),
|
||||
("upgrade_rustdesk_server_pro_to_{}_tip", ""),
|
||||
("pull_group_failed_tip", ""),
|
||||
("Filter by intersection", "")
|
||||
("Filter by intersection", ""),
|
||||
("Remove wallpaper during incoming sessions", ""),
|
||||
("Test", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -555,6 +555,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Check for software update on startup", ""),
|
||||
("upgrade_rustdesk_server_pro_to_{}_tip", ""),
|
||||
("pull_group_failed_tip", ""),
|
||||
("Filter by intersection", "")
|
||||
("Filter by intersection", ""),
|
||||
("Remove wallpaper during incoming sessions", ""),
|
||||
("Test", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -555,6 +555,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Check for software update on startup", ""),
|
||||
("upgrade_rustdesk_server_pro_to_{}_tip", ""),
|
||||
("pull_group_failed_tip", ""),
|
||||
("Filter by intersection", "")
|
||||
("Filter by intersection", ""),
|
||||
("Remove wallpaper during incoming sessions", ""),
|
||||
("Test", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -555,6 +555,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Check for software update on startup", ""),
|
||||
("upgrade_rustdesk_server_pro_to_{}_tip", ""),
|
||||
("pull_group_failed_tip", ""),
|
||||
("Filter by intersection", "")
|
||||
("Filter by intersection", ""),
|
||||
("Remove wallpaper during incoming sessions", ""),
|
||||
("Test", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -555,6 +555,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Check for software update on startup", "Startējot pārbaudīt, vai nav programmatūras atjauninājumu"),
|
||||
("upgrade_rustdesk_server_pro_to_{}_tip", "Lūdzu, jauniniet RustDesk Server Pro uz versiju {} vai jaunāku!"),
|
||||
("pull_group_failed_tip", "Neizdevās atsvaidzināt grupu"),
|
||||
("Filter by intersection", "Filtrēt pēc krustpunkta")
|
||||
("Filter by intersection", "Filtrēt pēc krustpunkta"),
|
||||
("Remove wallpaper during incoming sessions", ""),
|
||||
("Test", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -555,6 +555,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Check for software update on startup", "Checken voor updates bij opstarten"),
|
||||
("upgrade_rustdesk_server_pro_to_{}_tip", "Upgrade RustDesk Server Pro naar versie {} of nieuwer!"),
|
||||
("pull_group_failed_tip", "Vernieuwen van groep mislukt"),
|
||||
("Filter by intersection", "")
|
||||
("Filter by intersection", ""),
|
||||
("Remove wallpaper during incoming sessions", ""),
|
||||
("Test", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -555,6 +555,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Check for software update on startup", "Sprawdź aktualizacje przy starcie programu"),
|
||||
("upgrade_rustdesk_server_pro_to_{}_tip", "Proszę zaktualizować RustDesk Server Pro do wersji {} lub nowszej!"),
|
||||
("pull_group_failed_tip", "Błąd odświeżania grup"),
|
||||
("Filter by intersection", "")
|
||||
("Filter by intersection", ""),
|
||||
("Remove wallpaper during incoming sessions", ""),
|
||||
("Test", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -555,6 +555,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Check for software update on startup", ""),
|
||||
("upgrade_rustdesk_server_pro_to_{}_tip", ""),
|
||||
("pull_group_failed_tip", ""),
|
||||
("Filter by intersection", "")
|
||||
("Filter by intersection", ""),
|
||||
("Remove wallpaper during incoming sessions", ""),
|
||||
("Test", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -555,6 +555,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Check for software update on startup", ""),
|
||||
("upgrade_rustdesk_server_pro_to_{}_tip", ""),
|
||||
("pull_group_failed_tip", ""),
|
||||
("Filter by intersection", "")
|
||||
("Filter by intersection", ""),
|
||||
("Remove wallpaper during incoming sessions", ""),
|
||||
("Test", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -555,6 +555,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Check for software update on startup", ""),
|
||||
("upgrade_rustdesk_server_pro_to_{}_tip", ""),
|
||||
("pull_group_failed_tip", ""),
|
||||
("Filter by intersection", "")
|
||||
("Filter by intersection", ""),
|
||||
("Remove wallpaper during incoming sessions", ""),
|
||||
("Test", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -555,6 +555,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Check for software update on startup", "Проверять обновления программы при запуске"),
|
||||
("upgrade_rustdesk_server_pro_to_{}_tip", "Обновите RustDesk Server Pro до версии {} или новее!"),
|
||||
("pull_group_failed_tip", "Невозможно обновить группу"),
|
||||
("Filter by intersection", "Фильтровать по пересечению")
|
||||
("Filter by intersection", "Фильтровать по пересечению"),
|
||||
("Remove wallpaper during incoming sessions", ""),
|
||||
("Test", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -555,6 +555,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Check for software update on startup", ""),
|
||||
("upgrade_rustdesk_server_pro_to_{}_tip", ""),
|
||||
("pull_group_failed_tip", ""),
|
||||
("Filter by intersection", "")
|
||||
("Filter by intersection", ""),
|
||||
("Remove wallpaper during incoming sessions", ""),
|
||||
("Test", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -555,6 +555,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Check for software update on startup", ""),
|
||||
("upgrade_rustdesk_server_pro_to_{}_tip", ""),
|
||||
("pull_group_failed_tip", ""),
|
||||
("Filter by intersection", "")
|
||||
("Filter by intersection", ""),
|
||||
("Remove wallpaper during incoming sessions", ""),
|
||||
("Test", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -555,6 +555,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Check for software update on startup", ""),
|
||||
("upgrade_rustdesk_server_pro_to_{}_tip", ""),
|
||||
("pull_group_failed_tip", ""),
|
||||
("Filter by intersection", "")
|
||||
("Filter by intersection", ""),
|
||||
("Remove wallpaper during incoming sessions", ""),
|
||||
("Test", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -555,6 +555,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Check for software update on startup", ""),
|
||||
("upgrade_rustdesk_server_pro_to_{}_tip", ""),
|
||||
("pull_group_failed_tip", ""),
|
||||
("Filter by intersection", "")
|
||||
("Filter by intersection", ""),
|
||||
("Remove wallpaper during incoming sessions", ""),
|
||||
("Test", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -555,6 +555,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Check for software update on startup", ""),
|
||||
("upgrade_rustdesk_server_pro_to_{}_tip", ""),
|
||||
("pull_group_failed_tip", ""),
|
||||
("Filter by intersection", "")
|
||||
("Filter by intersection", ""),
|
||||
("Remove wallpaper during incoming sessions", ""),
|
||||
("Test", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -555,6 +555,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Check for software update on startup", ""),
|
||||
("upgrade_rustdesk_server_pro_to_{}_tip", ""),
|
||||
("pull_group_failed_tip", ""),
|
||||
("Filter by intersection", "")
|
||||
("Filter by intersection", ""),
|
||||
("Remove wallpaper during incoming sessions", ""),
|
||||
("Test", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -555,6 +555,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Check for software update on startup", "ตรวจสอบการอัปเดตโปรแกรมเมื่อเริ่มต้นใช้งาน"),
|
||||
("upgrade_rustdesk_server_pro_to_{}_tip", "กรุณาอัปเดต Rustdesk Server Pro ไปยังเวอร์ชัน {} หรือใหม่กว่า!"),
|
||||
("pull_group_failed_tip", "การเรียกใช้งานกลุ่มล้มเหลว"),
|
||||
("Filter by intersection", "")
|
||||
("Filter by intersection", ""),
|
||||
("Remove wallpaper during incoming sessions", ""),
|
||||
("Test", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -555,6 +555,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Check for software update on startup", ""),
|
||||
("upgrade_rustdesk_server_pro_to_{}_tip", ""),
|
||||
("pull_group_failed_tip", ""),
|
||||
("Filter by intersection", "")
|
||||
("Filter by intersection", ""),
|
||||
("Remove wallpaper during incoming sessions", ""),
|
||||
("Test", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -555,6 +555,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Check for software update on startup", ""),
|
||||
("upgrade_rustdesk_server_pro_to_{}_tip", ""),
|
||||
("pull_group_failed_tip", ""),
|
||||
("Filter by intersection", "")
|
||||
("Filter by intersection", ""),
|
||||
("Remove wallpaper during incoming sessions", ""),
|
||||
("Test", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -555,6 +555,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Check for software update on startup", ""),
|
||||
("upgrade_rustdesk_server_pro_to_{}_tip", ""),
|
||||
("pull_group_failed_tip", ""),
|
||||
("Filter by intersection", "")
|
||||
("Filter by intersection", ""),
|
||||
("Remove wallpaper during incoming sessions", ""),
|
||||
("Test", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -555,6 +555,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Check for software update on startup", ""),
|
||||
("upgrade_rustdesk_server_pro_to_{}_tip", ""),
|
||||
("pull_group_failed_tip", ""),
|
||||
("Filter by intersection", "")
|
||||
("Filter by intersection", ""),
|
||||
("Remove wallpaper during incoming sessions", ""),
|
||||
("Test", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -5,7 +5,9 @@ use desktop::Desktop;
|
||||
use hbb_common::config::CONFIG_OPTION_ALLOW_LINUX_HEADLESS;
|
||||
pub use hbb_common::platform::linux::*;
|
||||
use hbb_common::{
|
||||
allow_err, bail,
|
||||
allow_err,
|
||||
anyhow::anyhow,
|
||||
bail,
|
||||
config::Config,
|
||||
libc::{c_char, c_int, c_long, c_void},
|
||||
log,
|
||||
@ -26,6 +28,7 @@ use std::{
|
||||
time::{Duration, Instant},
|
||||
};
|
||||
use users::{get_user_by_name, os::unix::UserExt};
|
||||
use wallpaper;
|
||||
|
||||
type Xdo = *const c_void;
|
||||
|
||||
@ -1311,3 +1314,41 @@ NoDisplay=false
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub struct WallPaperRemover {
|
||||
old_path: String,
|
||||
old_path_dark: Option<String>, // ubuntu 22.04 light/dark theme have different uri
|
||||
}
|
||||
|
||||
impl WallPaperRemover {
|
||||
pub fn new() -> ResultType<Self> {
|
||||
let start = std::time::Instant::now();
|
||||
let old_path = wallpaper::get().map_err(|e| anyhow!(e.to_string()))?;
|
||||
let old_path_dark = wallpaper::get_dark().ok();
|
||||
if old_path.is_empty() && old_path_dark.clone().unwrap_or_default().is_empty() {
|
||||
bail!("already solid color");
|
||||
}
|
||||
wallpaper::set_from_path("").map_err(|e| anyhow!(e.to_string()))?;
|
||||
wallpaper::set_dark_from_path("").ok();
|
||||
log::info!(
|
||||
"created wallpaper remover, old_path:{:?}, old_path_dark:{:?}, elapsed:{:?}",
|
||||
old_path,
|
||||
old_path_dark,
|
||||
start.elapsed(),
|
||||
);
|
||||
Ok(Self {
|
||||
old_path,
|
||||
old_path_dark,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for WallPaperRemover {
|
||||
fn drop(&mut self) {
|
||||
allow_err!(wallpaper::set_from_path(&self.old_path).map_err(|e| anyhow!(e.to_string())));
|
||||
if let Some(old_path_dark) = &self.old_path_dark {
|
||||
allow_err!(wallpaper::set_dark_from_path(old_path_dark.as_str())
|
||||
.map_err(|e| anyhow!(e.to_string())));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -14,6 +14,7 @@ use hbb_common::{
|
||||
message_proto::Resolution,
|
||||
sleep, timeout, tokio,
|
||||
};
|
||||
use std::process::{Command, Stdio};
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
ffi::OsString,
|
||||
@ -26,6 +27,7 @@ use std::{
|
||||
sync::{atomic::Ordering, Arc, Mutex},
|
||||
time::{Duration, Instant},
|
||||
};
|
||||
use wallpaper;
|
||||
use winapi::{
|
||||
ctypes::c_void,
|
||||
shared::{minwindef::*, ntdef::NULL, windef::*, winerror::*},
|
||||
@ -2335,3 +2337,98 @@ fn get_license() -> Option<License> {
|
||||
}
|
||||
Some(lic)
|
||||
}
|
||||
|
||||
fn get_sid_of_user(username: &str) -> ResultType<String> {
|
||||
let mut output = Command::new("wmic")
|
||||
.args(&[
|
||||
"useraccount",
|
||||
"where",
|
||||
&format!("name='{}'", username),
|
||||
"get",
|
||||
"sid",
|
||||
"/value",
|
||||
])
|
||||
.creation_flags(CREATE_NO_WINDOW)
|
||||
.stdout(Stdio::piped())
|
||||
.spawn()?
|
||||
.stdout
|
||||
.ok_or_else(|| io::Error::new(io::ErrorKind::Other, "Failed to open stdout"))?;
|
||||
let mut result = String::new();
|
||||
output.read_to_string(&mut result)?;
|
||||
let sid_start_index = result
|
||||
.find('=')
|
||||
.map(|i| i + 1)
|
||||
.ok_or(anyhow!("bad output format"))?;
|
||||
if sid_start_index > 0 && sid_start_index < result.len() + 1 {
|
||||
Ok(result[sid_start_index..].trim().to_string())
|
||||
} else {
|
||||
bail!("bad output format");
|
||||
}
|
||||
}
|
||||
|
||||
pub struct WallPaperRemover {
|
||||
old_path: String,
|
||||
}
|
||||
|
||||
impl WallPaperRemover {
|
||||
pub fn new() -> ResultType<Self> {
|
||||
let start = std::time::Instant::now();
|
||||
if !Self::need_remove() {
|
||||
bail!("already solid color");
|
||||
}
|
||||
let old_path = match Self::get_recent_wallpaper() {
|
||||
Ok(old_path) => old_path,
|
||||
Err(e) => {
|
||||
log::info!("Failed to get recent wallpaper:{:?}, use fallback", e);
|
||||
wallpaper::get().map_err(|e| anyhow!(e.to_string()))?
|
||||
}
|
||||
};
|
||||
Self::set_wallpaper(None)?;
|
||||
log::info!(
|
||||
"created wallpaper remover, old_path:{:?}, elapsed:{:?}",
|
||||
old_path,
|
||||
start.elapsed(),
|
||||
);
|
||||
Ok(Self { old_path })
|
||||
}
|
||||
|
||||
fn get_recent_wallpaper() -> ResultType<String> {
|
||||
// SystemParametersInfoW may return %appdata%\Microsoft\Windows\Themes\TranscodedWallpaper, not real path and may not real cache
|
||||
// https://www.makeuseof.com/find-desktop-wallpapers-file-location-windows-11/
|
||||
// https://superuser.com/questions/1218413/write-to-current-users-registry-through-a-different-admin-account
|
||||
let (hkcu, sid) = if is_root() {
|
||||
let username = get_active_username();
|
||||
let sid = get_sid_of_user(&username)?;
|
||||
log::info!("username:{username}, sid:{sid}");
|
||||
(RegKey::predef(HKEY_USERS), format!("{}\\", sid))
|
||||
} else {
|
||||
(RegKey::predef(HKEY_CURRENT_USER), "".to_string())
|
||||
};
|
||||
let explorer_key = hkcu.open_subkey_with_flags(
|
||||
&format!(
|
||||
"{}Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Wallpapers",
|
||||
sid
|
||||
),
|
||||
KEY_READ,
|
||||
)?;
|
||||
Ok(explorer_key.get_value("BackgroundHistoryPath0")?)
|
||||
}
|
||||
|
||||
fn need_remove() -> bool {
|
||||
if let Ok(wallpaper) = wallpaper::get() {
|
||||
return !wallpaper.is_empty();
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
fn set_wallpaper(path: Option<String>) -> ResultType<()> {
|
||||
wallpaper::set_from_path(&path.unwrap_or_default()).map_err(|e| anyhow!(e.to_string()))
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for WallPaperRemover {
|
||||
fn drop(&mut self) {
|
||||
// If the old background is a slideshow, it will be converted into an image. AnyDesk does the same.
|
||||
allow_err!(Self::set_wallpaper(Some(self.old_path.clone())));
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,8 @@ use crate::common::update_clipboard;
|
||||
#[cfg(all(target_os = "linux", feature = "linux_headless"))]
|
||||
#[cfg(not(any(feature = "flatpak", feature = "appimage")))]
|
||||
use crate::platform::linux_desktop_manager;
|
||||
#[cfg(any(target_os = "windows", target_os = "linux"))]
|
||||
use crate::platform::WallPaperRemover;
|
||||
#[cfg(windows)]
|
||||
use crate::portable_service::client as portable_client;
|
||||
use crate::{
|
||||
@ -60,8 +62,14 @@ lazy_static::lazy_static! {
|
||||
static ref LOGIN_FAILURES: Arc::<Mutex<HashMap<String, (i32, i32, i32)>>> = Default::default();
|
||||
static ref SESSIONS: Arc::<Mutex<HashMap<String, Session>>> = Default::default();
|
||||
static ref ALIVE_CONNS: Arc::<Mutex<Vec<i32>>> = Default::default();
|
||||
static ref AUTHED_CONNS: Arc::<Mutex<Vec<(i32, AuthConnType)>>> = Default::default();
|
||||
static ref SWITCH_SIDES_UUID: Arc::<Mutex<HashMap<String, (Instant, uuid::Uuid)>>> = Default::default();
|
||||
}
|
||||
|
||||
#[cfg(any(target_os = "windows", target_os = "linux"))]
|
||||
lazy_static::lazy_static! {
|
||||
static ref WALLPAPER_REMOVER: Arc<Mutex<Option<WallPaperRemover>>> = Default::default();
|
||||
}
|
||||
pub static CLICK_TIME: AtomicI64 = AtomicI64::new(0);
|
||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||
pub static MOUSE_MOVE_TIME: AtomicI64 = AtomicI64::new(0);
|
||||
@ -143,6 +151,13 @@ struct StartCmIpcPara {
|
||||
tx_cm_stream_ready: mpsc::Sender<()>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
|
||||
pub enum AuthConnType {
|
||||
Remote,
|
||||
FileTransfer,
|
||||
PortForward,
|
||||
}
|
||||
|
||||
pub struct Connection {
|
||||
inner: ConnInner,
|
||||
stream: super::Stream,
|
||||
@ -205,6 +220,7 @@ pub struct Connection {
|
||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||
start_cm_ipc_para: Option<StartCmIpcPara>,
|
||||
auto_disconnect_timer: Option<(Instant, u64)>,
|
||||
authed_conn_id: Option<self::raii::AuthedConnID>,
|
||||
}
|
||||
|
||||
impl ConnInner {
|
||||
@ -345,6 +361,7 @@ impl Connection {
|
||||
tx_cm_stream_ready,
|
||||
}),
|
||||
auto_disconnect_timer: None,
|
||||
authed_conn_id: None,
|
||||
};
|
||||
let addr = hbb_common::try_into_v4(addr);
|
||||
if !conn.on_open(addr).await {
|
||||
@ -976,13 +993,17 @@ impl Connection {
|
||||
if self.authorized {
|
||||
return;
|
||||
}
|
||||
let conn_type = if self.file_transfer.is_some() {
|
||||
1
|
||||
let (conn_type, auth_conn_type) = if self.file_transfer.is_some() {
|
||||
(1, AuthConnType::FileTransfer)
|
||||
} else if self.port_forward_socket.is_some() {
|
||||
2
|
||||
(2, AuthConnType::PortForward)
|
||||
} else {
|
||||
0
|
||||
(0, AuthConnType::Remote)
|
||||
};
|
||||
self.authed_conn_id = Some(self::raii::AuthedConnID::new(
|
||||
self.inner.id(),
|
||||
auth_conn_type,
|
||||
));
|
||||
self.post_conn_audit(
|
||||
json!({"peer": ((&self.lr.my_id, &self.lr.my_name)), "type": conn_type}),
|
||||
);
|
||||
@ -1117,6 +1138,7 @@ impl Connection {
|
||||
*super::video_service::LAST_SYNC_DISPLAYS.write().unwrap() = displays;
|
||||
}
|
||||
}
|
||||
Self::on_remote_authorized();
|
||||
}
|
||||
let mut msg_out = Message::new();
|
||||
msg_out.set_login_response(res);
|
||||
@ -1155,6 +1177,29 @@ impl Connection {
|
||||
}
|
||||
}
|
||||
|
||||
fn on_remote_authorized() {
|
||||
use std::sync::Once;
|
||||
static ONCE: Once = Once::new();
|
||||
#[cfg(any(target_os = "windows", target_os = "linux"))]
|
||||
if !Config::get_option("allow-remove-wallpaper").is_empty() {
|
||||
// multi connections set once
|
||||
let mut wallpaper = WALLPAPER_REMOVER.lock().unwrap();
|
||||
if wallpaper.is_none() {
|
||||
match crate::platform::WallPaperRemover::new() {
|
||||
Ok(remover) => {
|
||||
*wallpaper = Some(remover);
|
||||
ONCE.call_once(|| {
|
||||
shutdown_hooks::add_shutdown_hook(shutdown_hook);
|
||||
});
|
||||
}
|
||||
Err(e) => {
|
||||
log::info!("create wallpaper remover failed:{:?}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn peer_keyboard_enabled(&self) -> bool {
|
||||
self.keyboard && !self.disable_keyboard
|
||||
}
|
||||
@ -2734,6 +2779,11 @@ impl LinuxHeadlessHandle {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(any(target_os = "windows", target_os = "linux"))]
|
||||
extern "C" fn shutdown_hook() {
|
||||
*WALLPAPER_REMOVER.lock().unwrap() = None;
|
||||
}
|
||||
|
||||
mod raii {
|
||||
use super::*;
|
||||
pub struct ConnectionID(i32);
|
||||
@ -2767,4 +2817,26 @@ mod raii {
|
||||
.on_connection_close(self.0);
|
||||
}
|
||||
}
|
||||
|
||||
pub struct AuthedConnID(i32);
|
||||
|
||||
impl AuthedConnID {
|
||||
pub fn new(id: i32, conn_type: AuthConnType) -> Self {
|
||||
AUTHED_CONNS.lock().unwrap().push((id, conn_type));
|
||||
Self(id)
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for AuthedConnID {
|
||||
fn drop(&mut self) {
|
||||
let mut lock = AUTHED_CONNS.lock().unwrap();
|
||||
lock.retain(|&c| c.0 != self.0);
|
||||
if lock.iter().filter(|c| c.1 == AuthConnType::Remote).count() == 0 {
|
||||
#[cfg(any(target_os = "windows", target_os = "linux"))]
|
||||
{
|
||||
*WALLPAPER_REMOVER.lock().unwrap() = None;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -65,14 +65,14 @@ pub fn make_tray() -> hbb_common::ResultType<()> {
|
||||
)
|
||||
}
|
||||
};
|
||||
let tray_icon = Some(
|
||||
let _tray_icon = Some(
|
||||
TrayIconBuilder::new()
|
||||
.with_menu(Box::new(tray_menu))
|
||||
.with_tooltip(tooltip(0))
|
||||
.with_icon(icon)
|
||||
.build()?,
|
||||
);
|
||||
let tray_icon = Arc::new(Mutex::new(tray_icon));
|
||||
let _tray_icon = Arc::new(Mutex::new(_tray_icon));
|
||||
|
||||
let menu_channel = MenuEvent::receiver();
|
||||
let tray_channel = TrayEvent::receiver();
|
||||
@ -149,7 +149,7 @@ pub fn make_tray() -> hbb_common::ResultType<()> {
|
||||
if let Ok(data) = ipc_receiver.try_recv() {
|
||||
match data {
|
||||
Data::ControlledSessionCount(count) => {
|
||||
tray_icon
|
||||
_tray_icon
|
||||
.lock()
|
||||
.unwrap()
|
||||
.as_mut()
|
||||
|
@ -217,6 +217,7 @@ class Enhancements: Reactor.Component {
|
||||
{has_hwcodec ? <li #enable-hwcodec><span>{svg_checkmark}</span>{translate("Hardware Codec")} (beta)</li> : ""}
|
||||
<li #enable-abr><span>{svg_checkmark}</span>{translate("Adaptive bitrate")} (beta)</li>
|
||||
<li #screen-recording>{translate("Recording")}</li>
|
||||
{is_osx ? "" : <li #allow-remove-wallpaper><span>{svg_checkmark}</span>{translate("Remove wallpaper during incoming sessions")}</li>}
|
||||
</menu>
|
||||
</li>;
|
||||
}
|
||||
@ -226,6 +227,9 @@ class Enhancements: Reactor.Component {
|
||||
if (el.id && el.id.indexOf("enable-") == 0) {
|
||||
var enabled = handler.get_option(el.id) != "N";
|
||||
el.attributes.toggleClass("selected", enabled);
|
||||
} else if (el.id && el.id.indexOf("allow-") == 0) {
|
||||
var enabled = handler.get_option(el.id) == "Y";
|
||||
el.attributes.toggleClass("selected", enabled);
|
||||
}
|
||||
}
|
||||
|
||||
@ -235,6 +239,8 @@ class Enhancements: Reactor.Component {
|
||||
var v = me.id;
|
||||
if (v.indexOf("enable-") == 0) {
|
||||
handler.set_option(v, handler.get_option(v) != 'N' ? 'N' : '');
|
||||
} else if (v.indexOf("allow-") == 0) {
|
||||
handler.set_option(v, handler.get_option(v) == 'Y' ? '' : 'Y');
|
||||
} else if (v == 'screen-recording') {
|
||||
var dir = handler.get_option("video-save-directory");
|
||||
if (!dir) dir = handler.default_video_save_directory();
|
||||
|
Loading…
Reference in New Issue
Block a user