diff --git a/flutter/lib/common/shared_state.dart b/flutter/lib/common/shared_state.dart index 5ae618dfe..ebac18dac 100644 --- a/flutter/lib/common/shared_state.dart +++ b/flutter/lib/common/shared_state.dart @@ -202,6 +202,28 @@ class RemoteCountState { static RxInt find() => Get.find(tag: tag()); } +class PeerBoolOption { + static String tag(String id, String opt) => 'peer_{$opt}_$id'; + + static void init(String id, String opt, bool Function() init_getter) { + final key = tag(id, opt); + if (!Get.isRegistered(tag: key)) { + final RxBool value = RxBool(init_getter()); + Get.put(value, tag: key); + } + } + + static void delete(String id, String opt) { + final key = tag(id, opt); + if (Get.isRegistered(tag: key)) { + Get.delete(tag: key); + } + } + + static RxBool find(String id, String opt) => + Get.find(tag: tag(id, opt)); +} + class PeerStringOption { static String tag(String id, String opt) => 'peer_{$opt}_$id'; diff --git a/flutter/lib/desktop/pages/remote_page.dart b/flutter/lib/desktop/pages/remote_page.dart index dae3fa612..117a0ab02 100644 --- a/flutter/lib/desktop/pages/remote_page.dart +++ b/flutter/lib/desktop/pages/remote_page.dart @@ -51,6 +51,7 @@ class _RemotePageState extends State String keyboardMode = "legacy"; final _cursorOverImage = false.obs; late RxBool _showRemoteCursor; + late RxBool _zoomCursor; late RxBool _remoteCursorMoved; late RxBool _keyboardEnabled; @@ -68,6 +69,10 @@ class _RemotePageState extends State KeyboardEnabledState.init(id); ShowRemoteCursorState.init(id); RemoteCursorMovedState.init(id); + final optZoomCursor = 'zoom-cursor'; + PeerBoolOption.init(id, optZoomCursor, + () => bind.sessionGetToggleOptionSync(id: id, arg: optZoomCursor)); + _zoomCursor = PeerBoolOption.find(id, optZoomCursor); _showRemoteCursor = ShowRemoteCursorState.find(id); _keyboardEnabled = KeyboardEnabledState.find(id); _remoteCursorMoved = RemoteCursorMovedState.find(id); @@ -216,6 +221,7 @@ class _RemotePageState extends State }); return ImagePaint( id: widget.id, + zoomCursor: _zoomCursor, cursorOverImage: _cursorOverImage, keyboardEnabled: _keyboardEnabled, remoteCursorMoved: _remoteCursorMoved, @@ -233,6 +239,7 @@ class _RemotePageState extends State visible: _showRemoteCursor.isTrue && _remoteCursorMoved.isTrue, child: CursorPaint( id: widget.id, + zoomCursor: _zoomCursor, )))); paints.add(QualityMonitor(_ffi.qualityMonitorModel)); paints.add(RemoteMenubar( @@ -253,6 +260,7 @@ class _RemotePageState extends State class ImagePaint extends StatefulWidget { final String id; + final Rx zoomCursor; final Rx cursorOverImage; final Rx keyboardEnabled; final Rx remoteCursorMoved; @@ -261,6 +269,7 @@ class ImagePaint extends StatefulWidget { ImagePaint( {Key? key, required this.id, + required this.zoomCursor, required this.cursorOverImage, required this.keyboardEnabled, required this.remoteCursorMoved, @@ -277,6 +286,7 @@ class _ImagePaintState extends State { final ScrollController _vertical = ScrollController(); String get id => widget.id; + Rx get zoomCursor => widget.zoomCursor; Rx get cursorOverImage => widget.cursorOverImage; Rx get keyboardEnabled => widget.keyboardEnabled; Rx get remoteCursorMoved => widget.remoteCursorMoved; @@ -357,7 +367,7 @@ class _ImagePaintState extends State { if (cache == null) { return MouseCursor.defer; } else { - final key = cache.updateGetKey(scale); + final key = cache.updateGetKey(scale, zoomCursor.value); cursor.addKey(key); return FlutterCustomMemoryImageCursor( pixbuf: cache.data, @@ -500,8 +510,13 @@ class _ImagePaintState extends State { class CursorPaint extends StatelessWidget { final String id; + final RxBool zoomCursor; - const CursorPaint({Key? key, required this.id}) : super(key: key); + const CursorPaint({ + Key? key, + required this.id, + required this.zoomCursor, + }) : super(key: key); @override Widget build(BuildContext context) { @@ -516,13 +531,21 @@ class CursorPaint extends StatelessWidget { hoty = m.defaultImage!.height / 2; } } - return CustomPaint( - painter: ImagePainter( - image: m.image ?? m.defaultImage, - x: m.x - hotx + c.x / c.scale, - y: m.y - hoty + c.y / c.scale, - scale: c.scale), - ); + return zoomCursor.isTrue + ? CustomPaint( + painter: ImagePainter( + image: m.image ?? m.defaultImage, + x: m.x - hotx + c.x / c.scale, + y: m.y - hoty + c.y / c.scale, + scale: c.scale), + ) + : CustomPaint( + painter: ImagePainter( + image: m.image ?? m.defaultImage, + x: (m.x - hotx) * c.scale + c.x, + y: (m.y - hoty) * c.scale + c.y, + scale: 1.0), + ); } } diff --git a/flutter/lib/desktop/widgets/remote_menubar.dart b/flutter/lib/desktop/widgets/remote_menubar.dart index cdbeb0bed..6db5a7fb7 100644 --- a/flutter/lib/desktop/widgets/remote_menubar.dart +++ b/flutter/lib/desktop/widgets/remote_menubar.dart @@ -47,7 +47,8 @@ class MenubarState { } _initSet(bool s, bool p) { - show = RxBool(s); + // Show remubar when connection is established. + show = RxBool(true); _pin = RxBool(p); } @@ -1109,6 +1110,25 @@ class _RemoteMenubarState extends State { ); }()); + /// Show remote cursor + displayMenu.add(() { + final opt = 'zoom-cursor'; + final state = PeerBoolOption.find(widget.id, opt); + return MenuEntrySwitch2( + switchType: SwitchType.scheckbox, + text: translate('Zoom cursor'), + getter: () { + return state; + }, + setter: (bool v) async { + state.value = v; + await bind.sessionToggleOption(id: widget.id, value: opt); + }, + padding: padding, + dismissOnClicked: true, + ); + }()); + /// Show quality monitor displayMenu.add(MenuEntrySwitch( switchType: SwitchType.scheckbox, diff --git a/flutter/lib/models/model.dart b/flutter/lib/models/model.dart index a39bc7d08..a074bf266 100644 --- a/flutter/lib/models/model.dart +++ b/flutter/lib/models/model.dart @@ -696,6 +696,8 @@ class CursorData { final img2.Image? image; double scale; Uint8List? data; + final double hotxOrigin; + final double hotyOrigin; double hotx; double hoty; final int width; @@ -707,45 +709,53 @@ class CursorData { required this.image, required this.scale, required this.data, - required this.hotx, - required this.hoty, + required this.hotxOrigin, + required this.hotyOrigin, required this.width, required this.height, - }); + }) : hotx = hotxOrigin * scale, + hoty = hotxOrigin * scale; int _doubleToInt(double v) => (v * 10e6).round().toInt(); - double _checkUpdateScale(double scale) { - // Update data if scale changed. - if (Platform.isWindows) { - final tgtWidth = (width * scale).toInt(); - final tgtHeight = (width * scale).toInt(); - if (tgtWidth < kMinCursorSize || tgtHeight < kMinCursorSize) { - double sw = kMinCursorSize.toDouble() / width; - double sh = kMinCursorSize.toDouble() / height; - scale = sw < sh ? sh : sw; + double _checkUpdateScale(double scale, bool shouldScale) { + double oldScale = this.scale; + if (!shouldScale) { + scale = 1.0; + } else { + // Update data if scale changed. + if (Platform.isWindows) { + final tgtWidth = (width * scale).toInt(); + final tgtHeight = (width * scale).toInt(); + if (tgtWidth < kMinCursorSize || tgtHeight < kMinCursorSize) { + double sw = kMinCursorSize.toDouble() / width; + double sh = kMinCursorSize.toDouble() / height; + scale = sw < sh ? sh : sw; + } } - if (_doubleToInt(this.scale) != _doubleToInt(scale)) { + } + + if (Platform.isWindows) { + if (_doubleToInt(oldScale) != _doubleToInt(scale)) { data = img2 .copyResize( image!, width: (width * scale).toInt(), height: (height * scale).toInt(), + interpolation: img2.Interpolation.average, ) .getBytes(format: img2.Format.bgra); } } + this.scale = scale; - if (hotx > 0 && hoty > 0) { - // default cursor data - hotx = (width * scale) / 2; - hoty = (height * scale) / 2; - } + hotx = hotxOrigin * scale; + hoty = hotyOrigin * scale; return scale; } - String updateGetKey(double scale) { - scale = _checkUpdateScale(scale); + String updateGetKey(double scale, bool shouldScale) { + scale = _checkUpdateScale(scale, shouldScale); return '${peerId}_${id}_${_doubleToInt(width * scale)}_${_doubleToInt(height * scale)}'; } } @@ -811,8 +821,6 @@ class CursorModel with ChangeNotifier { if (_defaultCache == null) { Uint8List data; double scale = 1.0; - double hotx = (defaultCursorImage!.width * scale) / 2; - double hoty = (defaultCursorImage!.height * scale) / 2; if (Platform.isWindows) { data = defaultCursorImage!.getBytes(format: img2.Format.bgra); } else { @@ -825,8 +833,8 @@ class CursorModel with ChangeNotifier { image: defaultCursorImage?.clone(), scale: scale, data: data, - hotx: hotx, - hoty: hoty, + hotxOrigin: defaultCursorImage!.width / 2, + hotyOrigin: defaultCursorImage!.height / 2, width: defaultCursorImage!.width, height: defaultCursorImage!.height, ); @@ -996,10 +1004,8 @@ class CursorModel with ChangeNotifier { image: Platform.isWindows ? img2.Image.fromBytes(w, h, data) : null, scale: 1.0, data: data, - hotx: 0, - hoty: 0, - // hotx: _hotx, - // hoty: _hoty, + hotxOrigin: _hotx, + hotyOrigin: _hoty, width: w, height: h, ); diff --git a/libs/hbb_common/src/fs.rs b/libs/hbb_common/src/fs.rs index 6cc795a0d..dd8a7530e 100644 --- a/libs/hbb_common/src/fs.rs +++ b/libs/hbb_common/src/fs.rs @@ -380,7 +380,7 @@ impl TransferJob { } } - pub async fn write(&mut self, block: FileTransferBlock, raw: Option<&[u8]>) -> ResultType<()> { + pub async fn write(&mut self, block: FileTransferBlock) -> ResultType<()> { if block.id != self.id { bail!("Wrong id"); } @@ -402,20 +402,15 @@ impl TransferJob { let path = format!("{}.download", get_string(&path)); self.file = Some(File::create(&path).await?); } - let data = if let Some(data) = raw { - data - } else { - &block.data - }; if block.compressed { - let tmp = decompress(data); + let tmp = decompress(&block.data); self.file.as_mut().unwrap().write_all(&tmp).await?; self.finished_size += tmp.len() as u64; } else { - self.file.as_mut().unwrap().write_all(data).await?; - self.finished_size += data.len() as u64; + self.file.as_mut().unwrap().write_all(&block.data).await?; + self.finished_size += block.data.len() as u64; } - self.transferred += data.len() as u64; + self.transferred += block.data.len() as u64; Ok(()) } diff --git a/src/client/io_loop.rs b/src/client/io_loop.rs index 6eb443103..86a9e2f2e 100644 --- a/src/client/io_loop.rs +++ b/src/client/io_loop.rs @@ -915,13 +915,8 @@ impl Remote { } } Some(file_response::Union::Block(block)) => { - log::info!( - "file response block, file id:{}, file num: {}", - block.id, - block.file_num - ); if let Some(job) = fs::get_job(block.id, &mut self.write_jobs) { - if let Err(_err) = job.write(block, None).await { + if let Err(_err) = job.write(block).await { // to-do: add "skip" for writing job } self.update_jobs_status(); diff --git a/src/lang/cn.rs b/src/lang/cn.rs index 68c5dbf60..16bbdb590 100644 --- a/src/lang/cn.rs +++ b/src/lang/cn.rs @@ -389,5 +389,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("or", "或"), ("Continue with", "使用"), ("Elevate", "提权"), + ("Zoom cursor", "缩放鼠标"), ].iter().cloned().collect(); } diff --git a/src/lang/cs.rs b/src/lang/cs.rs index 98bb9c5d3..0f262cd25 100644 --- a/src/lang/cs.rs +++ b/src/lang/cs.rs @@ -389,5 +389,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("or", ""), ("Continue with", ""), ("Elevate", ""), + ("Zoom cursor", ""), ].iter().cloned().collect(); } diff --git a/src/lang/da.rs b/src/lang/da.rs index b98e5ba3f..c7362e26f 100644 --- a/src/lang/da.rs +++ b/src/lang/da.rs @@ -389,5 +389,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("or", ""), ("Continue with", ""), ("Elevate", ""), + ("Zoom cursor", ""), ].iter().cloned().collect(); } diff --git a/src/lang/de.rs b/src/lang/de.rs index 1e8083915..acc22a461 100644 --- a/src/lang/de.rs +++ b/src/lang/de.rs @@ -389,5 +389,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("or", ""), ("Continue with", ""), ("Elevate", ""), + ("Zoom cursor", ""), ].iter().cloned().collect(); } diff --git a/src/lang/eo.rs b/src/lang/eo.rs index 93394a91f..206229859 100644 --- a/src/lang/eo.rs +++ b/src/lang/eo.rs @@ -389,5 +389,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("or", ""), ("Continue with", ""), ("Elevate", ""), + ("Zoom cursor", ""), ].iter().cloned().collect(); } diff --git a/src/lang/es.rs b/src/lang/es.rs index a00009b78..d0c569eff 100644 --- a/src/lang/es.rs +++ b/src/lang/es.rs @@ -389,5 +389,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("or", "o"), ("Continue with", "Continuar con"), ("Elevate", ""), + ("Zoom cursor", ""), ].iter().cloned().collect(); } diff --git a/src/lang/fa.rs b/src/lang/fa.rs index b6c3d002b..b602bd404 100644 --- a/src/lang/fa.rs +++ b/src/lang/fa.rs @@ -388,5 +388,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("This PC", "This PC"), ("or", "یا"), ("Continue with", "ادامه با"), + ("Zoom cursor", ""), ].iter().cloned().collect(); } diff --git a/src/lang/fr.rs b/src/lang/fr.rs index ff4e2e083..f4ff46cdf 100644 --- a/src/lang/fr.rs +++ b/src/lang/fr.rs @@ -389,5 +389,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("or", "ou"), ("Continue with", "Continuer avec"), ("Elevate", ""), + ("Zoom cursor", ""), ].iter().cloned().collect(); } diff --git a/src/lang/hu.rs b/src/lang/hu.rs index 9bd5de216..aaad2e9f9 100644 --- a/src/lang/hu.rs +++ b/src/lang/hu.rs @@ -389,5 +389,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("or", "vagy"), ("Continue with", "Folytatás a következővel"), ("Elevate", ""), + ("Zoom cursor", ""), ].iter().cloned().collect(); } diff --git a/src/lang/id.rs b/src/lang/id.rs index 7d4ae1634..96e7d38f4 100644 --- a/src/lang/id.rs +++ b/src/lang/id.rs @@ -389,5 +389,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("or", ""), ("Continue with", ""), ("Elevate", ""), + ("Zoom cursor", ""), ].iter().cloned().collect(); } diff --git a/src/lang/it.rs b/src/lang/it.rs index 3490a9b77..fc6b936bf 100644 --- a/src/lang/it.rs +++ b/src/lang/it.rs @@ -389,5 +389,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("or", ""), ("Continue with", ""), ("Elevate", ""), + ("Zoom cursor", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ja.rs b/src/lang/ja.rs index 2953f80cd..1ff301bba 100644 --- a/src/lang/ja.rs +++ b/src/lang/ja.rs @@ -389,5 +389,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("or", ""), ("Continue with", ""), ("Elevate", ""), + ("Zoom cursor", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ko.rs b/src/lang/ko.rs index 2473ef2de..aa6c01e3d 100644 --- a/src/lang/ko.rs +++ b/src/lang/ko.rs @@ -389,5 +389,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("or", ""), ("Continue with", ""), ("Elevate", ""), + ("Zoom cursor", ""), ].iter().cloned().collect(); } diff --git a/src/lang/kz.rs b/src/lang/kz.rs index 1ce728db3..05055d1a3 100644 --- a/src/lang/kz.rs +++ b/src/lang/kz.rs @@ -389,5 +389,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("or", ""), ("Continue with", ""), ("Elevate", ""), + ("Zoom cursor", ""), ].iter().cloned().collect(); } diff --git a/src/lang/pl.rs b/src/lang/pl.rs index ffe94432d..c62007778 100644 --- a/src/lang/pl.rs +++ b/src/lang/pl.rs @@ -389,5 +389,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("or", "albo"), ("Continue with", "Kontynuuj z"), ("Elevate", ""), + ("Zoom cursor", ""), ].iter().cloned().collect(); } diff --git a/src/lang/pt_PT.rs b/src/lang/pt_PT.rs index e7bb0e73c..ca0fcead9 100644 --- a/src/lang/pt_PT.rs +++ b/src/lang/pt_PT.rs @@ -389,5 +389,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("or", ""), ("Continue with", ""), ("Elevate", ""), + ("Zoom cursor", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ptbr.rs b/src/lang/ptbr.rs index bc35cfcb2..41459404b 100644 --- a/src/lang/ptbr.rs +++ b/src/lang/ptbr.rs @@ -389,5 +389,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("or", "ou"), ("Continue with", "Continuar com"), ("Elevate", ""), + ("Zoom cursor", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ru.rs b/src/lang/ru.rs index 9e9a60829..b5d747f9d 100644 --- a/src/lang/ru.rs +++ b/src/lang/ru.rs @@ -389,5 +389,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("or", "или"), ("Continue with", "Продолжить с"), ("Elevate", ""), + ("Zoom cursor", ""), ].iter().cloned().collect(); } diff --git a/src/lang/sk.rs b/src/lang/sk.rs index 3970ef3b9..0844c8442 100644 --- a/src/lang/sk.rs +++ b/src/lang/sk.rs @@ -389,5 +389,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("or", ""), ("Continue with", ""), ("Elevate", ""), + ("Zoom cursor", ""), ].iter().cloned().collect(); } diff --git a/src/lang/template.rs b/src/lang/template.rs index d9fd7b9bb..9f1779119 100644 --- a/src/lang/template.rs +++ b/src/lang/template.rs @@ -389,5 +389,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("or", ""), ("Continue with", ""), ("Elevate", ""), + ("Zoom cursor", ""), ].iter().cloned().collect(); } diff --git a/src/lang/tr.rs b/src/lang/tr.rs index cd2c8b269..6f3c9ba92 100644 --- a/src/lang/tr.rs +++ b/src/lang/tr.rs @@ -41,9 +41,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("About", "Hakkında"), ("Mute", "Sustur"), ("Audio Input", "Ses Girişi"), - ("Enhancements", ""), - ("Hardware Codec", ""), - ("Adaptive Bitrate", ""), + ("Enhancements", "Geliştirmeler"), + ("Hardware Codec", "Donanımsal Codec"), + ("Adaptive Bitrate", "Uyarlanabilir Bit Hızı"), ("ID Server", "ID Sunucu"), ("Relay Server", "Relay Sunucu"), ("API Server", "API Sunucu"), @@ -89,8 +89,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Delete", "Sil"), ("Properties", "Özellikler"), ("Multi Select", "Çoklu Seçim"), - ("Select All", ""), - ("Unselect All", ""), + ("Select All", "Tümünü Seç"), + ("Unselect All", "Tüm Seçimi Kaldır"), ("Empty Directory", "Boş Klasör"), ("Not an empty directory", "Klasör boş değil"), ("Are you sure you want to delete this file?", "Bu dosyayı silmek istediğinize emin misiniz?"), @@ -116,9 +116,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Good image quality", "İyi görüntü kalitesi"), ("Balanced", "Dengelenmiş"), ("Optimize reaction time", "Tepki süresini optimize et"), - ("Custom", ""), + ("Custom", "Özel"), ("Show remote cursor", "Uzaktaki fare imlecini göster"), - ("Show quality monitor", ""), + ("Show quality monitor", "Kalite monitörünü göster"), ("Disable clipboard", "Hafızadaki kopyalanmışları engelle"), ("Lock after session end", "Bağlantıdan sonra kilitle"), ("Insert", "Ekle"), @@ -161,8 +161,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Action", "Eylem"), ("Add", "Ekle"), ("Local Port", "Yerel Port"), - ("Local Address", ""), - ("Change Local Port", ""), + ("Local Address", "Yerel Adres"), + ("Change Local Port", "Yerel Port'u Değiştir"), ("setup_server_tip", "Daha hızlı bağlantı için kendi sunucunuzu kurun"), ("Too short, at least 6 characters.", "Çok kısa en az 6 karakter gerekli."), ("The confirmation is not identical.", "Doğrulama yapılamadı."), @@ -197,7 +197,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Reboot required", "Yeniden başlatma gerekli"), ("Unsupported display server ", "Desteklenmeyen görüntü sunucusu"), ("x11 expected", "x11 bekleniyor"), - ("Port", ""), + ("Port", "Port"), ("Settings", "Ayarlar"), ("Username", "Kullanıcı Adı"), ("Invalid port", "Geçersiz port"), @@ -278,7 +278,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("android_stop_service_tip", "Hizmetin kapatılması, kurulan tüm bağlantıları otomatik olarak kapatacaktır."), ("android_version_audio_tip", "Mevcut Android sürümü ses yakalamayı desteklemiyor, lütfen Android 10 veya sonraki bir sürüme yükseltin."), ("android_start_service_tip", "Ekran paylaşım hizmetini başlatmak için [Hizmeti Başlat] veya AÇ [Ekran Yakalama] iznine dokunun."), - ("Account", ""), + ("Account", "Hesap"), ("Overwrite", "üzerine yaz"), ("This file exists, skip or overwrite this file?", "Bu dosya var, bu dosya atlansın veya üzerine yazılsın mı?"), ("Quit", "Çıkış"), @@ -300,21 +300,21 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Ignore Battery Optimizations", ""), ("android_open_battery_optimizations_tip", ""), ("Connection not allowed", "bağlantıya izin verilmedi"), - ("Legacy mode", ""), - ("Map mode", ""), - ("Translate mode", ""), + ("Legacy mode", "Eski mod"), + ("Map mode", "Haritalama modu"), + ("Translate mode", "Çeviri modu"), ("Use temporary password", "Geçici şifre kullan"), ("Use permanent password", "Kalıcı şifre kullan"), ("Use both passwords", "İki şifreyide kullan"), ("Set permanent password", "Kalıcı şifre oluştur"), - ("Set temporary password length", ""), + ("Set temporary password length", "Geçici şifre oluştur"), ("Enable Remote Restart", "Uzaktan yeniden başlatmayı aktif et"), ("Allow remote restart", "Uzaktan yeniden başlatmaya izin ver"), ("Restart Remote Device", "Uzaktaki cihazı yeniden başlat"), ("Are you sure you want to restart", "Yeniden başlatmak istediğinize emin misin?"), ("Restarting Remote Device", "Uzaktan yeniden başlatılıyor"), - ("remote_restarting_tip", ""), - ("Copied", ""), + ("remote_restarting_tip", "remote_restarting_tip"), + ("Copied", "Kopyalandı"), ("Exit Fullscreen", "Tam ekrandan çık"), ("Fullscreen", "Tam ekran"), ("Mobile Actions", "Mobil İşlemler"), @@ -332,62 +332,63 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Insecure Connection", "Güvenli Bağlantı"), ("Scale original", "Orijinali ölçeklendir"), ("Scale adaptive", "Ölçek uyarlanabilir"), - ("General", ""), - ("Security", ""), - ("Account", ""), - ("Theme", ""), - ("Dark Theme", ""), - ("Dark", ""), - ("Light", ""), - ("Follow System", ""), - ("Enable hardware codec", ""), - ("Unlock Security Settings", ""), - ("Enable Audio", ""), - ("Temporary Password Length", ""), - ("Unlock Network Settings", ""), - ("Server", ""), - ("Direct IP Access", ""), - ("Proxy", ""), - ("Port", ""), - ("Apply", ""), - ("Disconnect all devices?", ""), - ("Clear", ""), - ("Audio Input Device", ""), - ("Deny remote access", ""), - ("Use IP Whitelisting", ""), - ("Network", ""), - ("Enable RDP", ""), + ("General", "Genel"), + ("Security", "Güvenlik"), + ("Account", "Hesap"), + ("Theme", "Tema"), + ("Dark Theme", "Koyu Tema"), + ("Dark", "Koyu"), + ("Light", "Açık"), + ("Follow System", "Sisteme Uy"), + ("Enable hardware codec", "Donanımsal codec aktif et"), + ("Unlock Security Settings", "Güvenlik Ayarlarını Aç"), + ("Enable Audio", "Sesi Aktif Et"), + ("Temporary Password Length", "Geçici Şifre Uzunluğu"), + ("Unlock Network Settings", "Ağ Ayarlarını Aç"), + ("Server", "Sunucu"), + ("Direct IP Access", "Direk IP Erişimi"), + ("Proxy", "Vekil"), + ("Port", "Port"), + ("Apply", "Uygula"), + ("Disconnect all devices?", "Tüm cihazların bağlantısını kes?"), + ("Clear", "Temizle"), + ("Audio Input Device", "Ses Giriş Aygıtı"), + ("Deny remote access", "Uzak erişime izin verme"), + ("Use IP Whitelisting", "IP Beyaz Listeyi Kullan"), + ("Network", "Ağ"), + ("Enable RDP", "RDP Aktif Et"), ("Pin menubar", "Menü çubuğunu sabitle"), ("Unpin menubar", "Menü çubuğunun sabitlemesini kaldır"), - ("Recording", ""), - ("Directory", ""), - ("Automatically record incoming sessions", ""), - ("Change", ""), - ("Start session recording", ""), - ("Stop session recording", ""), - ("Enable Recording Session", ""), - ("Allow recording session", ""), - ("Enable LAN Discovery", ""), - ("Deny LAN Discovery", ""), - ("Write a message", ""), + ("Recording", "Kayıt Ediliyor"), + ("Directory", "Klasör"), + ("Automatically record incoming sessions", "Gelen oturumları otomatik olarak kayıt et"), + ("Change", "Değiştir"), + ("Start session recording", "Oturum kaydını başlat"), + ("Stop session recording", "Oturum kaydını sonlandır"), + ("Enable Recording Session", "Kayıt Oturumunu Aktif Et"), + ("Allow recording session", "Oturum kaydına izin ver"), + ("Enable LAN Discovery", "Yerel Ağ Keşfine İzin Ver"), + ("Deny LAN Discovery", "Yerl Ağ Keşfine İzin Verme"), + ("Write a message", "Bir mesaj yazın"), ("Prompt", ""), - ("Please wait for confirmation of UAC...", ""), - ("elevated_foreground_window_tip", ""), - ("Disconnected", ""), - ("Other", ""), - ("Confirm before closing multiple tabs", ""), - ("Keyboard Settings", ""), - ("Custom", ""), - ("Full Access", ""), - ("Screen Share", ""), + ("Please wait for confirmation of UAC...", "UAC onayı için lütfen bekleyiniz..."), + ("elevated_foreground_window_tip", "elevated_foreground_window_tip"), + ("Disconnected", "Bağlantı Kesildi"), + ("Other", "Diğer"), + ("Confirm before closing multiple tabs", "Çoklu sekmeleri kapatmadan önce onayla"), + ("Keyboard Settings", "Klavye Ayarları"), + ("Custom", "Özel"), + ("Full Access", "Tam Erişim"), + ("Screen Share", "Ekran Paylaşımı"), ("Wayland requires Ubuntu 21.04 or higher version.", "Wayland, Ubuntu 21.04 veya daha yüksek bir sürüm gerektirir."), ("Wayland requires higher version of linux distro. Please try X11 desktop or change your OS.", "Wayland, linux dağıtımının daha yüksek bir sürümünü gerektirir. Lütfen X11 masaüstünü deneyin veya işletim sisteminizi değiştirin."), ("JumpLink", "View"), ("Please Select the screen to be shared(Operate on the peer side).", "Lütfen paylaşılacak ekranı seçiniz (Ekran tarafında çalıştırın)."), - ("Show RustDesk", ""), - ("This PC", ""), - ("or", ""), - ("Continue with", ""), - ("Elevate", ""), + ("Show RustDesk", "RustDesk'i Göster"), + ("This PC", "Bu PC"), + ("or", "veya"), + ("Continue with", "bununla devam et"), + ("Elevate", "Yükseltme"), + ("Zoom cursor", ""), ].iter().cloned().collect(); } diff --git a/src/lang/tw.rs b/src/lang/tw.rs index da57cf07c..900f25ccd 100644 --- a/src/lang/tw.rs +++ b/src/lang/tw.rs @@ -389,5 +389,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("or", ""), ("Continue with", ""), ("Elevate", "提權"), + ("Zoom cursor", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ua.rs b/src/lang/ua.rs index 10119d1e2..b336b1e36 100644 --- a/src/lang/ua.rs +++ b/src/lang/ua.rs @@ -389,5 +389,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("or", ""), ("Continue with", ""), ("Elevate", ""), + ("Zoom cursor", ""), ].iter().cloned().collect(); } diff --git a/src/lang/vn.rs b/src/lang/vn.rs index 8bb164a8f..c21fe8aa8 100644 --- a/src/lang/vn.rs +++ b/src/lang/vn.rs @@ -389,5 +389,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("or", ""), ("Continue with", ""), ("Elevate", ""), + ("Zoom cursor", ""), ].iter().cloned().collect(); } diff --git a/src/server/connection.rs b/src/server/connection.rs index 112d5f739..cb2ddc2c6 100644 --- a/src/server/connection.rs +++ b/src/server/connection.rs @@ -1629,7 +1629,8 @@ async fn start_ipc( file_num, data, compressed}) = data { - stream.send(&Data::FS(ipc::FS::WriteBlock{id, file_num, data, compressed})).await?; + stream.send(&Data::FS(ipc::FS::WriteBlock{id, file_num, data: Bytes::new(), compressed})).await?; + stream.send_raw(data).await?; } else { stream.send(&data).await?; } diff --git a/src/ui_cm_interface.rs b/src/ui_cm_interface.rs index 26b26bf92..5edf53507 100644 --- a/src/ui_cm_interface.rs +++ b/src/ui_cm_interface.rs @@ -1,3 +1,5 @@ +#[cfg(any(target_os = "android", target_os = "ios", feature = "flutter"))] +use std::iter::FromIterator; #[cfg(windows)] use std::sync::Arc; use std::{ @@ -8,8 +10,6 @@ use std::{ RwLock, }, }; -#[cfg(any(target_os = "android", target_os = "ios", feature = "flutter"))] -use std::iter::FromIterator; #[cfg(windows)] use clipboard::{cliprdr::CliprdrClientContext, empty_clipboard, set_conn_enabled, ContextSend}; @@ -343,8 +343,15 @@ impl IpcTaskRunner { Data::ChatMessage { text } => { self.cm.new_message(self.conn_id, text); } - Data::FS(fs) => { - handle_fs(fs, &mut write_jobs, &self.tx).await; + Data::FS(mut fs) => { + if let ipc::FS::WriteBlock { id, file_num, data: _, compressed } = fs { + if let Ok(bytes) = self.stream.next_raw().await { + fs = ipc::FS::WriteBlock{id, file_num, data:bytes.into(), compressed}; + handle_fs(fs, &mut write_jobs, &self.tx).await; + } + } else { + handle_fs(fs, &mut write_jobs, &self.tx).await; + } } #[cfg(windows)] Data::ClipbaordFile(_clip) => { @@ -597,16 +604,13 @@ async fn handle_fs(fs: ipc::FS, write_jobs: &mut Vec, tx: &Unbo } => { if let Some(job) = fs::get_job(id, write_jobs) { if let Err(err) = job - .write( - FileTransferBlock { - id, - file_num, - data, - compressed, - ..Default::default() - }, - None, - ) + .write(FileTransferBlock { + id, + file_num, + data, + compressed, + ..Default::default() + }) .await { send_raw(fs::new_error(id, err, file_num), &tx);