mirror of
https://github.com/rustdesk/rustdesk.git
synced 2026-04-13 11:01:29 +03:00
Compare commits
6 Commits
4abdb2e08b
...
nightly
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
80a5865db3 | ||
|
|
9cb6f38aea | ||
|
|
cd7e3e4505 | ||
|
|
1833cb0655 | ||
|
|
e4208aa9cf | ||
|
|
bb3501a4f9 |
@@ -3938,9 +3938,7 @@ void earlyAssert() {
|
|||||||
|
|
||||||
void checkUpdate() {
|
void checkUpdate() {
|
||||||
if (!isWeb) {
|
if (!isWeb) {
|
||||||
final isWindowsInstalled = isWindows && bind.mainIsInstalled();
|
if (!bind.isCustomClient()) {
|
||||||
final shouldCheckUpdate = isWindowsInstalled || !bind.isCustomClient();
|
|
||||||
if (shouldCheckUpdate) {
|
|
||||||
platformFFI.registerEventHandler(
|
platformFFI.registerEventHandler(
|
||||||
kCheckSoftwareUpdateFinish, kCheckSoftwareUpdateFinish,
|
kCheckSoftwareUpdateFinish, kCheckSoftwareUpdateFinish,
|
||||||
(Map<String, dynamic> evt) async {
|
(Map<String, dynamic> evt) async {
|
||||||
|
|||||||
@@ -430,12 +430,10 @@ class _DesktopHomePageState extends State<DesktopHomePage>
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget buildHelpCards(String updateUrl) {
|
Widget buildHelpCards(String updateUrl) {
|
||||||
final isWindowsInstalled = isWindows && bind.mainIsInstalled();
|
if (!bind.isCustomClient() &&
|
||||||
if (updateUrl.isNotEmpty &&
|
updateUrl.isNotEmpty &&
|
||||||
!isCardClosed &&
|
!isCardClosed &&
|
||||||
(isWindowsInstalled ||
|
bind.mainUriPrefixSync().contains('rustdesk')) {
|
||||||
(!bind.isCustomClient() &&
|
|
||||||
bind.mainUriPrefixSync().contains('rustdesk')))) {
|
|
||||||
final isToUpdate = (isWindows || isMacOS) && bind.mainIsInstalled();
|
final isToUpdate = (isWindows || isMacOS) && bind.mainIsInstalled();
|
||||||
String btnText = isToUpdate ? 'Update' : 'Download';
|
String btnText = isToUpdate ? 'Update' : 'Download';
|
||||||
GestureTapCallback onPressed = () async {
|
GestureTapCallback onPressed = () async {
|
||||||
|
|||||||
@@ -365,6 +365,16 @@ class InputModel {
|
|||||||
final isPhysicalMouse = false.obs;
|
final isPhysicalMouse = false.obs;
|
||||||
int _lastButtons = 0;
|
int _lastButtons = 0;
|
||||||
Offset lastMousePos = Offset.zero;
|
Offset lastMousePos = Offset.zero;
|
||||||
|
int _lastWheelTsUs = 0;
|
||||||
|
|
||||||
|
// Wheel acceleration thresholds.
|
||||||
|
static const int _wheelAccelFastThresholdUs = 40000; // 40ms
|
||||||
|
static const int _wheelAccelMediumThresholdUs = 80000; // 80ms
|
||||||
|
static const double _wheelBurstVelocityThreshold =
|
||||||
|
0.002; // delta units per microsecond
|
||||||
|
// Wheel burst acceleration (empirical tuning).
|
||||||
|
// Applies only to fast, non-smooth bursts to preserve single-step scrolling.
|
||||||
|
// Flutter uses microseconds for dt, so velocity is in delta/us.
|
||||||
|
|
||||||
// Relative mouse mode (for games/3D apps).
|
// Relative mouse mode (for games/3D apps).
|
||||||
final relativeMouseMode = false.obs;
|
final relativeMouseMode = false.obs;
|
||||||
@@ -964,6 +974,7 @@ class InputModel {
|
|||||||
toReleaseRawKeys.release(handleRawKeyEvent);
|
toReleaseRawKeys.release(handleRawKeyEvent);
|
||||||
_pointerMovedAfterEnter = false;
|
_pointerMovedAfterEnter = false;
|
||||||
_pointerInsideImage = enter;
|
_pointerInsideImage = enter;
|
||||||
|
_lastWheelTsUs = 0;
|
||||||
|
|
||||||
// Fix status
|
// Fix status
|
||||||
if (!enter) {
|
if (!enter) {
|
||||||
@@ -1407,17 +1418,44 @@ class InputModel {
|
|||||||
if (isViewOnly) return;
|
if (isViewOnly) return;
|
||||||
if (isViewCamera) return;
|
if (isViewCamera) return;
|
||||||
if (e is PointerScrollEvent) {
|
if (e is PointerScrollEvent) {
|
||||||
var dx = e.scrollDelta.dx.toInt();
|
final rawDx = e.scrollDelta.dx;
|
||||||
var dy = e.scrollDelta.dy.toInt();
|
final rawDy = e.scrollDelta.dy;
|
||||||
|
final dominantDelta = rawDx.abs() > rawDy.abs() ? rawDx.abs() : rawDy.abs();
|
||||||
|
final isSmooth = dominantDelta < 1;
|
||||||
|
final nowUs = DateTime.now().microsecondsSinceEpoch;
|
||||||
|
final dtUs = _lastWheelTsUs == 0 ? 0 : nowUs - _lastWheelTsUs;
|
||||||
|
_lastWheelTsUs = nowUs;
|
||||||
|
int accel = 1;
|
||||||
|
if (!isSmooth &&
|
||||||
|
dtUs > 0 &&
|
||||||
|
dtUs <= _wheelAccelMediumThresholdUs &&
|
||||||
|
(isWindows || isLinux) &&
|
||||||
|
peerPlatform == kPeerPlatformMacOS) {
|
||||||
|
final velocity = dominantDelta / dtUs;
|
||||||
|
if (velocity >= _wheelBurstVelocityThreshold) {
|
||||||
|
if (dtUs < _wheelAccelFastThresholdUs) {
|
||||||
|
accel = 3;
|
||||||
|
} else {
|
||||||
|
accel = 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var dx = rawDx.toInt();
|
||||||
|
var dy = rawDy.toInt();
|
||||||
|
if (rawDx.abs() > rawDy.abs()) {
|
||||||
|
dy = 0;
|
||||||
|
} else {
|
||||||
|
dx = 0;
|
||||||
|
}
|
||||||
if (dx > 0) {
|
if (dx > 0) {
|
||||||
dx = -1;
|
dx = -accel;
|
||||||
} else if (dx < 0) {
|
} else if (dx < 0) {
|
||||||
dx = 1;
|
dx = accel;
|
||||||
}
|
}
|
||||||
if (dy > 0) {
|
if (dy > 0) {
|
||||||
dy = -1;
|
dy = -accel;
|
||||||
} else if (dy < 0) {
|
} else if (dy < 0) {
|
||||||
dy = 1;
|
dy = accel;
|
||||||
}
|
}
|
||||||
bind.sessionSendMouse(
|
bind.sessionSendMouse(
|
||||||
sessionId: sessionId,
|
sessionId: sessionId,
|
||||||
|
|||||||
@@ -12,9 +12,7 @@ if [ "$1" = configure ]; then
|
|||||||
if [ -e /etc/systemd/system/rustdesk.service ]; then
|
if [ -e /etc/systemd/system/rustdesk.service ]; then
|
||||||
rm /etc/systemd/system/rustdesk.service /usr/lib/systemd/system/rustdesk.service /usr/lib/systemd/user/rustdesk.service >/dev/null 2>&1
|
rm /etc/systemd/system/rustdesk.service /usr/lib/systemd/system/rustdesk.service /usr/lib/systemd/user/rustdesk.service >/dev/null 2>&1
|
||||||
fi
|
fi
|
||||||
version=$(python3 -V 2>&1 | grep -Po '(?<=Python )(.+)')
|
mkdir -p /usr/lib/systemd/system/
|
||||||
parsedVersion=$(echo "${version//./}")
|
|
||||||
mkdir -p /usr/lib/systemd/system/
|
|
||||||
cp /usr/share/rustdesk/files/systemd/rustdesk.service /usr/lib/systemd/system/rustdesk.service
|
cp /usr/share/rustdesk/files/systemd/rustdesk.service /usr/lib/systemd/system/rustdesk.service
|
||||||
# try fix error in Ubuntu 18.04
|
# try fix error in Ubuntu 18.04
|
||||||
# Failed to reload rustdesk.service: Unit rustdesk.service is not loaded properly: Exec format error.
|
# Failed to reload rustdesk.service: Unit rustdesk.service is not loaded properly: Exec format error.
|
||||||
|
|||||||
@@ -940,9 +940,7 @@ pub fn is_modifier(evt: &KeyEvent) -> bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn check_software_update() {
|
pub fn check_software_update() {
|
||||||
let is_windows_installed = cfg!(target_os = "windows") && is_installed();
|
if is_custom_client() {
|
||||||
let should_check_update = is_windows_installed || !is_custom_client();
|
|
||||||
if !should_check_update {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let opt = LocalConfig::get_option(keys::OPTION_ENABLE_CHECK_UPDATE);
|
let opt = LocalConfig::get_option(keys::OPTION_ENABLE_CHECK_UPDATE);
|
||||||
|
|||||||
@@ -42,9 +42,16 @@ static PRIVILEGES_SCRIPTS_DIR: Dir =
|
|||||||
include_dir!("$CARGO_MANIFEST_DIR/src/platform/privileges_scripts");
|
include_dir!("$CARGO_MANIFEST_DIR/src/platform/privileges_scripts");
|
||||||
static mut LATEST_SEED: i32 = 0;
|
static mut LATEST_SEED: i32 = 0;
|
||||||
|
|
||||||
// Using a fixed temporary directory for updates is preferable to
|
#[inline]
|
||||||
// using one that includes the custom client name.
|
fn get_update_temp_dir() -> PathBuf {
|
||||||
const UPDATE_TEMP_DIR: &str = "/tmp/.rustdeskupdate";
|
let euid = unsafe { hbb_common::libc::geteuid() };
|
||||||
|
Path::new("/tmp").join(format!(".rustdeskupdate-{}", euid))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn get_update_temp_dir_string() -> String {
|
||||||
|
get_update_temp_dir().to_string_lossy().into_owned()
|
||||||
|
}
|
||||||
|
|
||||||
/// Global mutex to serialize CoreGraphics cursor operations.
|
/// Global mutex to serialize CoreGraphics cursor operations.
|
||||||
/// This prevents race conditions between cursor visibility (hide depth tracking)
|
/// This prevents race conditions between cursor visibility (hide depth tracking)
|
||||||
@@ -279,24 +286,12 @@ fn update_daemon_agent(agent_plist_file: String, update_source_dir: String, sync
|
|||||||
Err(e) => {
|
Err(e) => {
|
||||||
log::error!("run osascript failed: {}", e);
|
log::error!("run osascript failed: {}", e);
|
||||||
}
|
}
|
||||||
|
Ok(status) if !status.success() => {
|
||||||
|
log::warn!("run osascript failed with status: {}", status);
|
||||||
|
}
|
||||||
_ => {
|
_ => {
|
||||||
let installed = std::path::Path::new(&agent_plist_file).exists();
|
let installed = std::path::Path::new(&agent_plist_file).exists();
|
||||||
log::info!("Agent file {} installed: {}", &agent_plist_file, installed);
|
log::info!("Agent file {} installed: {}", &agent_plist_file, installed);
|
||||||
if installed {
|
|
||||||
// Unload first, or load may not work if already loaded.
|
|
||||||
// We hope that the load operation can immediately trigger a start.
|
|
||||||
std::process::Command::new("launchctl")
|
|
||||||
.args(&["unload", "-w", &agent_plist_file])
|
|
||||||
.stdin(Stdio::null())
|
|
||||||
.stdout(Stdio::null())
|
|
||||||
.stderr(Stdio::null())
|
|
||||||
.status()
|
|
||||||
.ok();
|
|
||||||
let status = std::process::Command::new("launchctl")
|
|
||||||
.args(&["load", "-w", &agent_plist_file])
|
|
||||||
.status();
|
|
||||||
log::info!("launch server, status: {:?}", &status);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -415,7 +410,9 @@ pub fn set_cursor_pos(x: i32, y: i32) -> bool {
|
|||||||
let _guard = match CG_CURSOR_MUTEX.try_lock() {
|
let _guard = match CG_CURSOR_MUTEX.try_lock() {
|
||||||
Ok(guard) => guard,
|
Ok(guard) => guard,
|
||||||
Err(std::sync::TryLockError::WouldBlock) => {
|
Err(std::sync::TryLockError::WouldBlock) => {
|
||||||
log::error!("[BUG] set_cursor_pos: CG_CURSOR_MUTEX is already held - potential deadlock!");
|
log::error!(
|
||||||
|
"[BUG] set_cursor_pos: CG_CURSOR_MUTEX is already held - potential deadlock!"
|
||||||
|
);
|
||||||
debug_assert!(false, "Re-entrant call to set_cursor_pos detected");
|
debug_assert!(false, "Re-entrant call to set_cursor_pos detected");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -822,7 +819,8 @@ pub fn quit_gui() {
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn try_remove_temp_update_dir(dir: Option<&str>) {
|
pub fn try_remove_temp_update_dir(dir: Option<&str>) {
|
||||||
let target_path = Path::new(dir.unwrap_or(UPDATE_TEMP_DIR));
|
let target_path_buf = dir.map(PathBuf::from).unwrap_or_else(get_update_temp_dir);
|
||||||
|
let target_path = target_path_buf.as_path();
|
||||||
if target_path.exists() {
|
if target_path.exists() {
|
||||||
std::fs::remove_dir_all(target_path).ok();
|
std::fs::remove_dir_all(target_path).ok();
|
||||||
}
|
}
|
||||||
@@ -851,32 +849,33 @@ pub fn update_me() -> ResultType<()> {
|
|||||||
if is_installed_daemon && !is_service_stopped {
|
if is_installed_daemon && !is_service_stopped {
|
||||||
let agent = format!("{}_server.plist", crate::get_full_name());
|
let agent = format!("{}_server.plist", crate::get_full_name());
|
||||||
let agent_plist_file = format!("/Library/LaunchAgents/{}", agent);
|
let agent_plist_file = format!("/Library/LaunchAgents/{}", agent);
|
||||||
std::process::Command::new("launchctl")
|
|
||||||
.args(&["unload", "-w", &agent_plist_file])
|
|
||||||
.stdin(Stdio::null())
|
|
||||||
.stdout(Stdio::null())
|
|
||||||
.stderr(Stdio::null())
|
|
||||||
.status()
|
|
||||||
.ok();
|
|
||||||
update_daemon_agent(agent_plist_file, app_dir, true);
|
update_daemon_agent(agent_plist_file, app_dir, true);
|
||||||
} else {
|
} else {
|
||||||
// `kill -9` may not work without "administrator privileges"
|
// `kill -9` may not work without "administrator privileges"
|
||||||
let update_body = format!(
|
let update_body = r#"
|
||||||
r#"
|
on run {app_name, cur_pid, app_dir, user_name}
|
||||||
do shell script "
|
set app_bundle to "/Applications/" & app_name & ".app"
|
||||||
pgrep -x '{app_name}' | grep -v {pid} | xargs kill -9 && rm -rf '/Applications/{app_name}.app' && ditto '{app_dir}' '/Applications/{app_name}.app' && chown -R {user}:staff '/Applications/{app_name}.app' && xattr -r -d com.apple.quarantine '/Applications/{app_name}.app'
|
set app_bundle_q to quoted form of app_bundle
|
||||||
" with prompt "{app_name} wants to update itself" with administrator privileges
|
set app_dir_q to quoted form of app_dir
|
||||||
"#,
|
set user_name_q to quoted form of user_name
|
||||||
app_name = app_name,
|
|
||||||
pid = std::process::id(),
|
set kill_others to "pids=$(pgrep -x '" & app_name & "' | grep -vx " & cur_pid & " || true); if [ -n \"$pids\" ]; then echo \"$pids\" | xargs kill -9 || true; fi;"
|
||||||
app_dir = app_dir,
|
set copy_files to "rm -rf " & app_bundle_q & " && ditto " & app_dir_q & " " & app_bundle_q & " && chown -R " & user_name_q & ":staff " & app_bundle_q & " && (xattr -r -d com.apple.quarantine " & app_bundle_q & " || true);"
|
||||||
user = get_active_username()
|
set sh to "set -e;" & kill_others & copy_files
|
||||||
);
|
|
||||||
match Command::new("osascript")
|
do shell script sh with prompt app_name & " wants to update itself" with administrator privileges
|
||||||
|
end run
|
||||||
|
"#;
|
||||||
|
let active_user = get_active_username();
|
||||||
|
let status = Command::new("osascript")
|
||||||
.arg("-e")
|
.arg("-e")
|
||||||
.arg(update_body)
|
.arg(update_body)
|
||||||
.status()
|
.arg(app_name.to_string())
|
||||||
{
|
.arg(std::process::id().to_string())
|
||||||
|
.arg(app_dir)
|
||||||
|
.arg(active_user)
|
||||||
|
.status();
|
||||||
|
match status {
|
||||||
Ok(status) if !status.success() => {
|
Ok(status) if !status.success() => {
|
||||||
log::error!("osascript execution failed with status: {}", status);
|
log::error!("osascript execution failed with status: {}", status);
|
||||||
}
|
}
|
||||||
@@ -897,25 +896,28 @@ pgrep -x '{app_name}' | grep -v {pid} | xargs kill -9 && rm -rf '/Applications/{
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn update_from_dmg(dmg_path: &str) -> ResultType<()> {
|
pub fn update_from_dmg(dmg_path: &str) -> ResultType<()> {
|
||||||
|
let update_temp_dir = get_update_temp_dir_string();
|
||||||
println!("Starting update from DMG: {}", dmg_path);
|
println!("Starting update from DMG: {}", dmg_path);
|
||||||
extract_dmg(dmg_path, UPDATE_TEMP_DIR)?;
|
extract_dmg(dmg_path, &update_temp_dir)?;
|
||||||
println!("DMG extracted");
|
println!("DMG extracted");
|
||||||
update_extracted(UPDATE_TEMP_DIR)?;
|
update_extracted(&update_temp_dir)?;
|
||||||
println!("Update process started");
|
println!("Update process started");
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update_to(_file: &str) -> ResultType<()> {
|
pub fn update_to(_file: &str) -> ResultType<()> {
|
||||||
update_extracted(UPDATE_TEMP_DIR)?;
|
let update_temp_dir = get_update_temp_dir_string();
|
||||||
|
update_extracted(&update_temp_dir)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn extract_update_dmg(file: &str) {
|
pub fn extract_update_dmg(file: &str) {
|
||||||
|
let update_temp_dir = get_update_temp_dir_string();
|
||||||
let mut evt: HashMap<&str, String> =
|
let mut evt: HashMap<&str, String> =
|
||||||
HashMap::from([("name", "extract-update-dmg".to_string())]);
|
HashMap::from([("name", "extract-update-dmg".to_string())]);
|
||||||
match extract_dmg(file, UPDATE_TEMP_DIR) {
|
match extract_dmg(file, &update_temp_dir) {
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
log::info!("Extracted dmg file to {}", UPDATE_TEMP_DIR);
|
log::info!("Extracted dmg file to {}", update_temp_dir);
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
evt.insert("err", e.to_string());
|
evt.insert("err", e.to_string());
|
||||||
|
|||||||
@@ -1,18 +1,25 @@
|
|||||||
on run {daemon_file, agent_file, user, cur_pid, source_dir}
|
on run {daemon_file, agent_file, user, cur_pid, source_dir}
|
||||||
|
|
||||||
set unload_service to "launchctl unload -w /Library/LaunchDaemons/com.carriez.RustDesk_service.plist || true;"
|
set agent_plist to "/Library/LaunchAgents/com.carriez.RustDesk_server.plist"
|
||||||
|
set daemon_plist to "/Library/LaunchDaemons/com.carriez.RustDesk_service.plist"
|
||||||
|
set app_bundle to "/Applications/RustDesk.app"
|
||||||
|
|
||||||
set kill_others to "pgrep -x 'RustDesk' | grep -v " & cur_pid & " | xargs kill -9;"
|
set resolve_uid to "uid=$(id -u " & quoted form of user & " 2>/dev/null || true);"
|
||||||
|
set unload_agent to "if [ -n \"$uid\" ]; then launchctl bootout gui/$uid " & quoted form of agent_plist & " 2>/dev/null || launchctl bootout user/$uid " & quoted form of agent_plist & " 2>/dev/null || launchctl unload -w " & quoted form of agent_plist & " || true; else launchctl unload -w " & quoted form of agent_plist & " || true; fi;"
|
||||||
|
set unload_service to "launchctl unload -w " & daemon_plist & " || true;"
|
||||||
|
set kill_others to "pids=$(pgrep -x 'RustDesk' | grep -vx " & cur_pid & " || true); if [ -n \"$pids\" ]; then echo \"$pids\" | xargs kill -9 || true; fi;"
|
||||||
|
|
||||||
set copy_files to "rm -rf /Applications/RustDesk.app && ditto " & source_dir & " /Applications/RustDesk.app && chown -R " & quoted form of user & ":staff /Applications/RustDesk.app && xattr -r -d com.apple.quarantine /Applications/RustDesk.app;"
|
set copy_files to "(rm -rf " & quoted form of app_bundle & " && ditto " & quoted form of source_dir & " " & quoted form of app_bundle & " && chown -R " & quoted form of user & ":staff " & quoted form of app_bundle & " && (xattr -r -d com.apple.quarantine " & quoted form of app_bundle & " || true)) || exit 1;"
|
||||||
|
|
||||||
set sh1 to "echo " & quoted form of daemon_file & " > /Library/LaunchDaemons/com.carriez.RustDesk_service.plist && chown root:wheel /Library/LaunchDaemons/com.carriez.RustDesk_service.plist;"
|
set write_daemon_plist to "echo " & quoted form of daemon_file & " > " & daemon_plist & " && chown root:wheel " & daemon_plist & ";"
|
||||||
|
set write_agent_plist to "echo " & quoted form of agent_file & " > " & agent_plist & " && chown root:wheel " & agent_plist & ";"
|
||||||
|
set load_service to "launchctl load -w " & daemon_plist & ";"
|
||||||
|
set agent_label_cmd to "agent_label=$(basename " & quoted form of agent_plist & " .plist);"
|
||||||
|
set bootstrap_agent to "if [ -n \"$uid\" ]; then launchctl bootstrap gui/$uid " & quoted form of agent_plist & " 2>/dev/null || launchctl bootstrap user/$uid " & quoted form of agent_plist & " 2>/dev/null || launchctl load -w " & quoted form of agent_plist & " || true; else launchctl load -w " & quoted form of agent_plist & " || true; fi;"
|
||||||
|
set kickstart_agent to "if [ -n \"$uid\" ]; then launchctl kickstart -k gui/$uid/$agent_label 2>/dev/null || launchctl kickstart -k user/$uid/$agent_label 2>/dev/null || true; fi;"
|
||||||
|
set load_agent to agent_label_cmd & bootstrap_agent & kickstart_agent
|
||||||
|
|
||||||
set sh2 to "echo " & quoted form of agent_file & " > /Library/LaunchAgents/com.carriez.RustDesk_server.plist && chown root:wheel /Library/LaunchAgents/com.carriez.RustDesk_server.plist;"
|
set sh to "set -e;" & resolve_uid & unload_agent & unload_service & kill_others & copy_files & write_daemon_plist & write_agent_plist & load_service & load_agent
|
||||||
|
|
||||||
set sh3 to "launchctl load -w /Library/LaunchDaemons/com.carriez.RustDesk_service.plist;"
|
|
||||||
|
|
||||||
set sh to unload_service & kill_others & copy_files & sh1 & sh2 & sh3
|
|
||||||
|
|
||||||
do shell script sh with prompt "RustDesk wants to update itself" with administrator privileges
|
do shell script sh with prompt "RustDesk wants to update itself" with administrator privileges
|
||||||
end run
|
end run
|
||||||
|
|||||||
@@ -142,6 +142,14 @@ function resetWheel() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var INERTIA_ACCELERATION = 30;
|
var INERTIA_ACCELERATION = 30;
|
||||||
|
var WHEEL_ACCEL_VELOCITY_THRESHOLD = 5000;
|
||||||
|
var WHEEL_ACCEL_DT_FAST = 0.04;
|
||||||
|
var WHEEL_ACCEL_DT_MEDIUM = 0.08;
|
||||||
|
var WHEEL_ACCEL_VALUE_FAST = 3;
|
||||||
|
var WHEEL_ACCEL_VALUE_MEDIUM = 2;
|
||||||
|
// Wheel burst acceleration (empirical tuning).
|
||||||
|
// Applies only on fast, non-smooth wheel bursts to keep single-step scroll unchanged.
|
||||||
|
// Sciter uses seconds for dt, so velocity is in delta/sec.
|
||||||
|
|
||||||
// not good, precision not enough to simulate acceleration effect,
|
// not good, precision not enough to simulate acceleration effect,
|
||||||
// seems have to use pixel based rather line based delta
|
// seems have to use pixel based rather line based delta
|
||||||
@@ -237,12 +245,28 @@ function handler.onMouse(evt)
|
|||||||
// mouseWheelDistance = 8 * [currentUserDefs floatForKey:@"com.apple.scrollwheel.scaling"];
|
// mouseWheelDistance = 8 * [currentUserDefs floatForKey:@"com.apple.scrollwheel.scaling"];
|
||||||
mask = 3;
|
mask = 3;
|
||||||
{
|
{
|
||||||
var (dx, dy) = evt.wheelDeltas;
|
var now = getTime();
|
||||||
if (dx > 0) dx = 1;
|
var dt = last_wheel_time > 0 ? (now - last_wheel_time) / 1000 : 0;
|
||||||
else if (dx < 0) dx = -1;
|
var (raw_dx, raw_dy) = evt.wheelDeltas;
|
||||||
if (dy > 0) dy = 1;
|
var dx = 0;
|
||||||
else if (dy < 0) dy = -1;
|
var dy = 0;
|
||||||
if (Math.abs(dx) > Math.abs(dy)) {
|
var abs_dx = Math.abs(raw_dx);
|
||||||
|
var abs_dy = Math.abs(raw_dy);
|
||||||
|
var dominant = abs_dx > abs_dy ? abs_dx : abs_dy;
|
||||||
|
var is_smooth = dominant < 1;
|
||||||
|
var accel = 1;
|
||||||
|
if (!is_smooth && dt > 0 && (is_win || is_linux) && get_peer_platform() == "Mac OS") {
|
||||||
|
var velocity = dominant / dt;
|
||||||
|
if (velocity >= WHEEL_ACCEL_VELOCITY_THRESHOLD) {
|
||||||
|
if (dt < WHEEL_ACCEL_DT_FAST) accel = WHEEL_ACCEL_VALUE_FAST;
|
||||||
|
else if (dt < WHEEL_ACCEL_DT_MEDIUM) accel = WHEEL_ACCEL_VALUE_MEDIUM;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (raw_dx > 0) dx = accel;
|
||||||
|
else if (raw_dx < 0) dx = -accel;
|
||||||
|
if (raw_dy > 0) dy = accel;
|
||||||
|
else if (raw_dy < 0) dy = -accel;
|
||||||
|
if (abs_dx > abs_dy) {
|
||||||
dy = 0;
|
dy = 0;
|
||||||
} else {
|
} else {
|
||||||
dx = 0;
|
dx = 0;
|
||||||
@@ -253,8 +277,6 @@ function handler.onMouse(evt)
|
|||||||
wheel_delta_y = acc_wheel_delta_y.toInteger();
|
wheel_delta_y = acc_wheel_delta_y.toInteger();
|
||||||
acc_wheel_delta_x -= wheel_delta_x;
|
acc_wheel_delta_x -= wheel_delta_x;
|
||||||
acc_wheel_delta_y -= wheel_delta_y;
|
acc_wheel_delta_y -= wheel_delta_y;
|
||||||
var now = getTime();
|
|
||||||
var dt = last_wheel_time > 0 ? (now - last_wheel_time) / 1000 : 0;
|
|
||||||
if (dt > 0) {
|
if (dt > 0) {
|
||||||
var vx = dx / dt;
|
var vx = dx / dt;
|
||||||
var vy = dy / dt;
|
var vy = dy / dt;
|
||||||
@@ -297,11 +319,13 @@ function handler.onMouse(evt)
|
|||||||
entered = true;
|
entered = true;
|
||||||
stdout.println("enter");
|
stdout.println("enter");
|
||||||
handler.enter(handler.get_keyboard_mode());
|
handler.enter(handler.get_keyboard_mode());
|
||||||
|
last_wheel_time = 0;
|
||||||
return keyboard_enabled;
|
return keyboard_enabled;
|
||||||
case Event.MOUSE_LEAVE:
|
case Event.MOUSE_LEAVE:
|
||||||
entered = false;
|
entered = false;
|
||||||
stdout.println("leave");
|
stdout.println("leave");
|
||||||
handler.leave(handler.get_keyboard_mode());
|
handler.leave(handler.get_keyboard_mode());
|
||||||
|
last_wheel_time = 0;
|
||||||
if (is_left_down && get_peer_platform() == "Android") {
|
if (is_left_down && get_peer_platform() == "Android") {
|
||||||
is_left_down = false;
|
is_left_down = false;
|
||||||
handler.send_mouse((1 << 3) | 2, 0, 0, evt.altKey,
|
handler.send_mouse((1 << 3) | 2, 0, 0, evt.altKey,
|
||||||
|
|||||||
Reference in New Issue
Block a user