Merge pull request #3014 from 21pages/dialog-style

opt ui
This commit is contained in:
RustDesk 2023-01-31 09:55:58 +08:00 committed by GitHub
commit 1a3dcbd275
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 242 additions and 172 deletions

View File

@ -205,6 +205,9 @@ class MyTheme {
splashColor: Colors.transparent, splashColor: Colors.transparent,
highlightColor: Colors.transparent, highlightColor: Colors.transparent,
splashFactory: isDesktop ? NoSplash.splashFactory : null, splashFactory: isDesktop ? NoSplash.splashFactory : null,
outlinedButtonTheme: OutlinedButtonThemeData(
style:
OutlinedButton.styleFrom(side: BorderSide(color: Colors.white38))),
textButtonTheme: isDesktop textButtonTheme: isDesktop
? TextButtonThemeData( ? TextButtonThemeData(
style: ButtonStyle(splashFactory: NoSplash.splashFactory), style: ButtonStyle(splashFactory: NoSplash.splashFactory),
@ -613,6 +616,7 @@ class CustomAlertDialog extends StatelessWidget {
Future.delayed(Duration.zero, () { Future.delayed(Duration.zero, () {
if (!scopeNode.hasFocus) scopeNode.requestFocus(); if (!scopeNode.hasFocus) scopeNode.requestFocus();
}); });
const double padding = 16;
return FocusScope( return FocusScope(
node: scopeNode, node: scopeNode,
autofocus: true, autofocus: true,
@ -637,17 +641,18 @@ class CustomAlertDialog extends StatelessWidget {
child: AlertDialog( child: AlertDialog(
scrollable: true, scrollable: true,
title: title, title: title,
contentPadding: EdgeInsets.symmetric( contentPadding: EdgeInsets.fromLTRB(
horizontal: contentPadding ?? 25, vertical: 10), contentPadding ?? padding, 25, contentPadding ?? padding, 10),
content: ConstrainedBox( content: ConstrainedBox(
constraints: contentBoxConstraints, constraints: contentBoxConstraints,
child: Theme( child: Theme(
data: ThemeData( data: Theme.of(context).copyWith(
inputDecorationTheme: InputDecorationTheme( inputDecorationTheme: InputDecorationTheme(
isDense: true, contentPadding: EdgeInsets.all(15)), isDense: true, contentPadding: EdgeInsets.all(15))),
child: content),
), ),
child: content)),
actions: actions, actions: actions,
actionsPadding: EdgeInsets.fromLTRB(0, 0, padding, padding),
), ),
); );
} }
@ -701,9 +706,8 @@ void msgBox(String id, String type, String title, String text, String link,
} }
dialogManager.show( dialogManager.show(
(setState, close) => CustomAlertDialog( (setState, close) => CustomAlertDialog(
title: _msgBoxTitle(title), title: null,
content: content: msgboxContent(type, title, text),
SelectableText(translate(text), style: const TextStyle(fontSize: 15)),
actions: buttons, actions: buttons,
onSubmit: hasOk ? submit : null, onSubmit: hasOk ? submit : null,
onCancel: hasCancel == true ? cancel : null, onCancel: hasCancel == true ? cancel : null,
@ -712,30 +716,74 @@ void msgBox(String id, String type, String title, String text, String link,
); );
} }
Widget msgBoxButton(String text, void Function() onPressed) { Color? _msgboxColor(String type) {
return ButtonTheme( if (type == "input-password" || type == "custom-os-password") {
padding: EdgeInsets.symmetric(horizontal: 20, vertical: 10), return Color(0xFFAD448E);
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, }
//limits the touch area to the button area if (type.contains("success")) {
minWidth: 0, return Color(0xFF32bea6);
//wraps child's width }
height: 0, if (type.contains("error") || type == "re-input-password") {
child: TextButton( return Color(0xFFE04F5F);
style: flatButtonStyle, }
onPressed: onPressed, return Color(0xFF2C8CFF);
child:
Text(translate(text), style: TextStyle(color: MyTheme.accent))));
} }
Widget _msgBoxTitle(String title) => Widget msgboxIcon(String type) {
Text(translate(title), style: TextStyle(fontSize: 21)); IconData? iconData;
if (type.contains("error") || type == "re-input-password") {
iconData = Icons.cancel;
}
if (type.contains("success")) {
iconData = Icons.check_circle;
}
if (type == "wait-uac" || type == "wait-remote-accept-nook") {
iconData = Icons.hourglass_top;
}
if (type == 'on-uac' || type == 'on-foreground-elevated') {
iconData = Icons.admin_panel_settings;
}
if (type == "info") {
iconData = Icons.info;
}
if (iconData != null) {
return Icon(iconData, size: 50, color: _msgboxColor(type))
.marginOnly(right: 16);
}
return Offstage();
}
// title should be null
Widget msgboxContent(String type, String title, String text) {
return Row(
children: [
msgboxIcon(type),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
translate(title),
style: TextStyle(fontSize: 21),
).marginOnly(bottom: 10),
Text(translate(text), style: const TextStyle(fontSize: 15)),
],
),
),
],
);
}
void msgBoxCommon(OverlayDialogManager dialogManager, String title, void msgBoxCommon(OverlayDialogManager dialogManager, String title,
Widget content, List<Widget> buttons, Widget content, List<Widget> buttons,
{bool hasCancel = true}) { {bool hasCancel = true}) {
dialogManager.dismissAll(); dialogManager.dismissAll();
dialogManager.show((setState, close) => CustomAlertDialog( dialogManager.show((setState, close) => CustomAlertDialog(
title: _msgBoxTitle(title), title: Text(
translate(title),
style: TextStyle(fontSize: 21),
),
content: content, content: content,
actions: buttons, actions: buttons,
onCancel: hasCancel ? close : null, onCancel: hasCancel ? close : null,
@ -1589,7 +1637,8 @@ class ServerConfig {
Widget dialogButton(String text, Widget dialogButton(String text,
{required VoidCallback? onPressed, {required VoidCallback? onPressed,
bool isOutline = false, bool isOutline = false,
TextStyle? style}) { TextStyle? style,
ButtonStyle? buttonStyle}) {
if (isDesktop) { if (isDesktop) {
if (isOutline) { if (isOutline) {
return OutlinedButton( return OutlinedButton(
@ -1598,7 +1647,7 @@ Widget dialogButton(String text,
); );
} else { } else {
return ElevatedButton( return ElevatedButton(
style: ElevatedButton.styleFrom(elevation: 0), style: ElevatedButton.styleFrom(elevation: 0).merge(buttonStyle),
onPressed: onPressed, onPressed: onPressed,
child: Text(translate(text), style: style), child: Text(translate(text), style: style),
); );

View File

@ -1,3 +1,4 @@
import 'package:auto_size_text/auto_size_text.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_hbb/common.dart'; import 'package:flutter_hbb/common.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
@ -316,42 +317,47 @@ class _DraggableState extends State<Draggable> {
} }
class QualityMonitor extends StatelessWidget { class QualityMonitor extends StatelessWidget {
static const textStyle = TextStyle(color: MyTheme.grayBg);
final QualityMonitorModel qualityMonitorModel; final QualityMonitorModel qualityMonitorModel;
QualityMonitor(this.qualityMonitorModel); QualityMonitor(this.qualityMonitorModel);
Widget _row(String info, String? value) {
return Row(
children: [
Expanded(
flex: 8,
child: AutoSizeText(info,
style: TextStyle(color: MyTheme.grayBg),
textAlign: TextAlign.right,
maxLines: 1)),
Spacer(flex: 1),
Expanded(
flex: 8,
child: AutoSizeText(value ?? '',
style: TextStyle(color: MyTheme.grayBg), maxLines: 1)),
],
);
}
@override @override
Widget build(BuildContext context) => ChangeNotifierProvider.value( Widget build(BuildContext context) => ChangeNotifierProvider.value(
value: qualityMonitorModel, value: qualityMonitorModel,
child: Consumer<QualityMonitorModel>( child: Consumer<QualityMonitorModel>(
builder: (context, qualityMonitorModel, child) => builder: (context, qualityMonitorModel, child) => qualityMonitorModel
qualityMonitorModel.show .show
? Container( ? Container(
constraints: BoxConstraints(maxWidth: 200),
padding: const EdgeInsets.all(8), padding: const EdgeInsets.all(8),
color: MyTheme.canvasColor.withAlpha(120), color: MyTheme.canvasColor.withAlpha(120),
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Text( _row("Speed", qualityMonitorModel.data.speed ?? ''),
"Speed: ${qualityMonitorModel.data.speed ?? ''}", _row("FPS", qualityMonitorModel.data.fps ?? ''),
style: textStyle, _row(
), "Delay", "${qualityMonitorModel.data.delay ?? ''}ms"),
Text( _row("Target Bitrate",
"FPS: ${qualityMonitorModel.data.fps ?? ''}", "${qualityMonitorModel.data.targetBitrate ?? ''}kb"),
style: textStyle, _row("Codec", qualityMonitorModel.data.codecFormat ?? ''),
),
Text(
"Delay: ${qualityMonitorModel.data.delay ?? ''} ms",
style: textStyle,
),
Text(
"Target Bitrate: ${qualityMonitorModel.data.targetBitrate ?? ''}kb",
style: textStyle,
),
Text(
"Codec: ${qualityMonitorModel.data.codecFormat ?? ''}",
style: textStyle,
),
], ],
), ),
) )

View File

@ -1432,12 +1432,8 @@ void showConfirmSwitchSidesDialog(
} }
return CustomAlertDialog( return CustomAlertDialog(
title: Text(translate('Switch Sides')), content: msgboxContent('info', 'Switch Sides',
content: Column( 'Please confirm if you want to share your desktop?'),
children: [
Text(translate('Please confirm if you want to share your desktop?')),
],
),
actions: [ actions: [
dialogButton('Cancel', onPressed: close, isOutline: true), dialogButton('Cancel', onPressed: close, isOutline: true),
dialogButton('OK', onPressed: submit), dialogButton('OK', onPressed: submit),

View File

@ -9,7 +9,7 @@ import '../../models/model.dart';
import '../../models/platform_model.dart'; import '../../models/platform_model.dart';
void clientClose(String id, OverlayDialogManager dialogManager) { void clientClose(String id, OverlayDialogManager dialogManager) {
msgBox(id, '', 'Close', 'Are you sure to close the connection?', '', msgBox(id, 'info', 'Close', 'Are you sure to close the connection?', '',
dialogManager); dialogManager);
} }
@ -33,8 +33,10 @@ void showRestartRemoteDevice(
]), ]),
content: Text( content: Text(
"${translate('Are you sure you want to restart')} \n${pi.username}@${pi.hostname}($id) ?"), "${translate('Are you sure you want to restart')} \n${pi.username}@${pi.hostname}($id) ?"),
onCancel: close,
onSubmit: () => close(true),
actions: [ actions: [
dialogButton("Cancel", onPressed: () => close(), isOutline: true), dialogButton("Cancel", onPressed: close, isOutline: true),
dialogButton("OK", onPressed: () => close(true)), dialogButton("OK", onPressed: () => close(true)),
], ],
)); ));
@ -48,6 +50,18 @@ void setPermanentPasswordDialog(OverlayDialogManager dialogManager) async {
var validateLength = false; var validateLength = false;
var validateSame = false; var validateSame = false;
dialogManager.show((setState, close) { dialogManager.show((setState, close) {
submit() async {
close();
dialogManager.showLoading(translate("Waiting"));
if (await gFFI.serverModel.setPermanentPassword(p0.text)) {
dialogManager.dismissAll();
showSuccess();
} else {
dialogManager.dismissAll();
showError();
}
}
return CustomAlertDialog( return CustomAlertDialog(
title: Text(translate('Set your own password')), title: Text(translate('Set your own password')),
content: Form( content: Form(
@ -94,29 +108,17 @@ void setPermanentPasswordDialog(OverlayDialogManager dialogManager) async {
}, },
), ),
])), ])),
onCancel: close,
onSubmit: (validateLength && validateSame) ? submit : null,
actions: [ actions: [
dialogButton( dialogButton(
'Cancel', 'Cancel',
onPressed: () { onPressed: close,
close();
},
isOutline: true, isOutline: true,
), ),
dialogButton( dialogButton(
'OK', 'OK',
onPressed: (validateLength && validateSame) onPressed: (validateLength && validateSame) ? submit : null,
? () async {
close();
dialogManager.showLoading(translate("Waiting"));
if (await gFFI.serverModel.setPermanentPassword(p0.text)) {
dialogManager.dismissAll();
showSuccess();
} else {
dialogManager.dismissAll();
showError();
}
}
: null,
), ),
], ],
); );
@ -205,26 +207,36 @@ void enterPasswordDialog(String id, OverlayDialogManager dialogManager) async {
}); });
} }
void wrongPasswordDialog(String id, OverlayDialogManager dialogManager) { void wrongPasswordDialog(
dialogManager.show((setState, close) => CustomAlertDialog( String id, OverlayDialogManager dialogManager, type, title, text) {
title: Text(translate('Wrong Password')), dialogManager.dismissAll();
content: Text(translate('Do you want to enter again?')), dialogManager.show((setState, close) {
cancel() {
close();
closeConnection();
}
submit() {
enterPasswordDialog(id, dialogManager);
}
return CustomAlertDialog(
title: null,
content: msgboxContent(type, title, text),
onSubmit: submit,
onCancel: cancel,
actions: [ actions: [
dialogButton( dialogButton(
'Cancel', 'Cancel',
onPressed: () { onPressed: cancel,
close();
closeConnection();
},
isOutline: true, isOutline: true,
), ),
dialogButton( dialogButton(
'Retry', 'Retry',
onPressed: () { onPressed: submit,
enterPasswordDialog(id, dialogManager);
},
), ),
])); ]);
});
} }
void showServerSettingsWithValue( void showServerSettingsWithValue(
@ -352,13 +364,15 @@ void showServerSettingsWithValue(
}); });
} }
void showWaitUacDialog(String id, OverlayDialogManager dialogManager) { void showWaitUacDialog(
String id, OverlayDialogManager dialogManager, String type) {
dialogManager.dismissAll(); dialogManager.dismissAll();
dialogManager.show( dialogManager.show(
tag: '$id-wait-uac', tag: '$id-wait-uac',
(setState, close) => CustomAlertDialog( (setState, close) => CustomAlertDialog(
title: Text(translate('Wait')), title: null,
content: Text(translate('wait_accept_uac_tip')).marginAll(10), content: msgboxContent(type, 'Wait', 'wait_accept_uac_tip')
.marginOnly(bottom: 10),
)); ));
} }
@ -516,16 +530,6 @@ void showOnBlockDialog(
dialogManager.existing('$id-request-elevation')) { dialogManager.existing('$id-request-elevation')) {
return; return;
} }
var content = Column(children: [
Align(
alignment: Alignment.centerLeft,
child: Text(
"${translate(text)}${type.contains('uac') ? '\n' : '\n\n'}${translate('request_elevation_tip')}",
textAlign: TextAlign.left,
style: TextStyle(fontWeight: FontWeight.w400),
).marginSymmetric(vertical: 15),
),
]);
dialogManager.show(tag: '$id-$type', (setState, close) { dialogManager.show(tag: '$id-$type', (setState, close) {
void submit() { void submit() {
close(); close();
@ -533,12 +537,11 @@ void showOnBlockDialog(
} }
return CustomAlertDialog( return CustomAlertDialog(
title: Text(translate(title)), title: null,
content: content, content: msgboxContent(type, title,
"${translate(text)}${type.contains('uac') ? '\n' : '\n\n'}${translate('request_elevation_tip')}"),
actions: [ actions: [
dialogButton('Wait', onPressed: () { dialogButton('Wait', onPressed: close, isOutline: true),
close();
}, isOutline: true),
dialogButton('Request Elevation', onPressed: submit), dialogButton('Request Elevation', onPressed: submit),
], ],
onSubmit: submit, onSubmit: submit,
@ -556,8 +559,8 @@ void showElevationError(String id, String type, String title, String text,
} }
return CustomAlertDialog( return CustomAlertDialog(
title: Text(translate(title)), title: null,
content: Text(translate(text)), content: msgboxContent(type, title, text),
actions: [ actions: [
dialogButton('Cancel', onPressed: () { dialogButton('Cancel', onPressed: () {
close(); close();
@ -570,6 +573,25 @@ void showElevationError(String id, String type, String title, String text,
}); });
} }
void showWaitAcceptDialog(String id, String type, String title, String text,
OverlayDialogManager dialogManager) {
dialogManager.dismissAll();
dialogManager.show((setState, close) {
onCancel() {
closeConnection();
}
return CustomAlertDialog(
title: null,
content: msgboxContent(type, title, text),
actions: [
dialogButton('Cancel', onPressed: onCancel, isOutline: true),
],
onCancel: onCancel,
);
});
}
Future<String?> validateAsync(String value) async { Future<String?> validateAsync(String value) async {
value = value.trim(); value = value.trim();
if (value.isEmpty) { if (value.isEmpty) {

View File

@ -264,19 +264,18 @@ class FfiModel with ChangeNotifier {
final text = evt['text']; final text = evt['text'];
final link = evt['link']; final link = evt['link'];
if (type == 're-input-password') { if (type == 're-input-password') {
wrongPasswordDialog(id, dialogManager); wrongPasswordDialog(id, dialogManager, type, title, text);
} else if (type == 'input-password') { } else if (type == 'input-password') {
enterPasswordDialog(id, dialogManager); enterPasswordDialog(id, dialogManager);
} else if (type == 'restarting') { } else if (type == 'restarting') {
showMsgBox(id, type, title, text, link, false, dialogManager, showMsgBox(id, type, title, text, link, false, dialogManager,
hasCancel: false); hasCancel: false);
} else if (type == 'wait-remote-accept-nook') { } else if (type == 'wait-remote-accept-nook') {
msgBoxCommon(dialogManager, title, Text(translate(text)), showWaitAcceptDialog(id, type, title, text, dialogManager);
[dialogButton("Cancel", onPressed: closeConnection)]);
} else if (type == 'on-uac' || type == 'on-foreground-elevated') { } else if (type == 'on-uac' || type == 'on-foreground-elevated') {
showOnBlockDialog(id, type, title, text, dialogManager); showOnBlockDialog(id, type, title, text, dialogManager);
} else if (type == 'wait-uac') { } else if (type == 'wait-uac') {
showWaitUacDialog(id, dialogManager); showWaitUacDialog(id, dialogManager, type);
} else if (type == 'elevation-error') { } else if (type == 'elevation-error') {
showElevationError(id, type, title, text, dialogManager); showElevationError(id, type, title, text, dialogManager);
} else { } else {

View File

@ -1104,7 +1104,7 @@ impl<T: InvokeUiSession> Remote<T> {
Some(misc::Union::PortableServiceRunning(b)) => { Some(misc::Union::PortableServiceRunning(b)) => {
if b { if b {
self.handler.msgbox( self.handler.msgbox(
"custom-nocancel", "custom-nocancel-success",
"Successful", "Successful",
"Elevate successfully", "Elevate successfully",
"", "",

View File

@ -1745,3 +1745,13 @@ pub fn create_process_with_logon(user: &str, pwd: &str, exe: &str, arg: &str) ->
} }
return Ok(()); return Ok(());
} }
pub fn set_path_permission(dir: &PathBuf, permission: &str) -> ResultType<()> {
std::process::Command::new("icacls")
.arg(dir.as_os_str())
.arg("/grant")
.arg(format!("Everyone:(OI)(CI){}", permission))
.arg("/T")
.spawn()?;
Ok(())
}

View File

@ -2,9 +2,7 @@ use core::slice;
use hbb_common::{ use hbb_common::{
allow_err, allow_err,
anyhow::anyhow, anyhow::anyhow,
bail, bail, log,
config::Config,
log,
message_proto::{KeyEvent, MouseEvent}, message_proto::{KeyEvent, MouseEvent},
protobuf::Message, protobuf::Message,
tokio::{self, sync::mpsc}, tokio::{self, sync::mpsc},
@ -15,6 +13,7 @@ use shared_memory::*;
use std::{ use std::{
mem::size_of, mem::size_of,
ops::{Deref, DerefMut}, ops::{Deref, DerefMut},
path::PathBuf,
sync::{Arc, Mutex}, sync::{Arc, Mutex},
time::Duration, time::Duration,
}; };
@ -25,6 +24,7 @@ use winapi::{
use crate::{ use crate::{
ipc::{self, new_listener, Connection, Data, DataPortableService}, ipc::{self, new_listener, Connection, Data, DataPortableService},
platform::set_path_permission,
video_service::get_current_display, video_service::get_current_display,
}; };
@ -72,7 +72,7 @@ impl DerefMut for SharedMemory {
impl SharedMemory { impl SharedMemory {
pub fn create(name: &str, size: usize) -> ResultType<Self> { pub fn create(name: &str, size: usize) -> ResultType<Self> {
let flink = Self::flink(name.to_string()); let flink = Self::flink(name.to_string())?;
let shmem = match ShmemConf::new() let shmem = match ShmemConf::new()
.size(size) .size(size)
.flink(&flink) .flink(&flink)
@ -91,12 +91,12 @@ impl SharedMemory {
} }
}; };
log::info!("Create shared memory, size:{}, flink:{}", size, flink); log::info!("Create shared memory, size:{}, flink:{}", size, flink);
Self::set_all_perm(&flink); set_path_permission(&PathBuf::from(flink), "F").ok();
Ok(SharedMemory { inner: shmem }) Ok(SharedMemory { inner: shmem })
} }
pub fn open_existing(name: &str) -> ResultType<Self> { pub fn open_existing(name: &str) -> ResultType<Self> {
let flink = Self::flink(name.to_string()); let flink = Self::flink(name.to_string())?;
let shmem = match ShmemConf::new().flink(&flink).allow_raw(true).open() { let shmem = match ShmemConf::new().flink(&flink).allow_raw(true).open() {
Ok(m) => m, Ok(m) => m,
Err(e) => { Err(e) => {
@ -116,30 +116,29 @@ impl SharedMemory {
} }
} }
fn flink(name: String) -> String { fn flink(name: String) -> ResultType<String> {
let mut shmem_flink = format!("shared_memory{}", name); let disk = std::env::var("SystemDrive").unwrap_or("C:".to_string());
if cfg!(windows) { let mut dir = PathBuf::from(disk);
let df = "C:\\ProgramData"; let dir1 = dir.join("ProgramData");
let df = if std::path::Path::new(df).exists() { let dir2 = std::env::var("TEMP")
df.to_owned() .map(|d| PathBuf::from(d))
.unwrap_or(dir.join("Windows").join("Temp"));
if dir1.exists() {
dir = dir1;
} else if dir2.exists() {
dir = dir2;
} else { } else {
std::env::var("TEMP").unwrap_or("C:\\Windows\\TEMP".to_owned()) bail!("no vaild flink directory");
};
let df = format!("{}\\{}", df, *hbb_common::config::APP_NAME.read().unwrap());
std::fs::create_dir(&df).ok();
shmem_flink = format!("{}\\{}", df, shmem_flink);
} else {
shmem_flink = Config::ipc_path("").replace("ipc", "") + &shmem_flink;
} }
return shmem_flink; dir = dir.join(hbb_common::config::APP_NAME.read().unwrap().clone());
} if !dir.exists() {
std::fs::create_dir(&dir)?;
fn set_all_perm(_p: &str) { set_path_permission(&dir, "F").ok();
#[cfg(not(windows))]
{
use std::os::unix::fs::PermissionsExt;
std::fs::set_permissions(_p, std::fs::Permissions::from_mode(0o0777)).ok();
} }
Ok(dir
.join(format!("shared_memory{}", name))
.to_string_lossy()
.to_string())
} }
} }
@ -451,7 +450,6 @@ pub mod server {
// functions called in main process. // functions called in main process.
pub mod client { pub mod client {
use hbb_common::anyhow::Context; use hbb_common::anyhow::Context;
use std::path::PathBuf;
use super::*; use super::*;
@ -515,7 +513,7 @@ pub mod client {
#[cfg(feature = "flutter")] #[cfg(feature = "flutter")]
{ {
if let Some(dir) = PathBuf::from(&exe).parent() { if let Some(dir) = PathBuf::from(&exe).parent() {
if !set_dir_permission(&PathBuf::from(dir)) { if set_path_permission(&PathBuf::from(dir), "RX").is_err() {
*SHMEM.lock().unwrap() = None; *SHMEM.lock().unwrap() = None;
bail!("Failed to set permission of {:?}", dir); bail!("Failed to set permission of {:?}", dir);
} }
@ -533,7 +531,7 @@ pub mod client {
let dst = dir.join("rustdesk.exe"); let dst = dir.join("rustdesk.exe");
if std::fs::copy(&exe, &dst).is_ok() { if std::fs::copy(&exe, &dst).is_ok() {
if dst.exists() { if dst.exists() {
if set_dir_permission(&dir) { if set_path_permission(&dir, "RX").is_ok() {
exe = dst.to_string_lossy().to_string(); exe = dst.to_string_lossy().to_string();
} }
} }
@ -566,16 +564,6 @@ pub mod client {
*QUICK_SUPPORT.lock().unwrap() = v; *QUICK_SUPPORT.lock().unwrap() = v;
} }
fn set_dir_permission(dir: &PathBuf) -> bool {
// // give Everyone RX permission
std::process::Command::new("icacls")
.arg(dir.as_os_str())
.arg("/grant")
.arg("Everyone:(OI)(CI)RX")
.arg("/T")
.spawn()
.is_ok()
}
pub struct CapturerPortable; pub struct CapturerPortable;
impl CapturerPortable { impl CapturerPortable {

View File

@ -16,7 +16,7 @@ div#quality-monitor {
padding: 5px; padding: 5px;
min-width: 150px; min-width: 150px;
color: azure; color: azure;
border: solid azure; border: 0.5px solid azure;
} }
video#handler { video#handler {